symtable.pas 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. This unit handles the symbol tables
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symtable;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cobjects,
  24. { global }
  25. globtype,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,symsym,
  28. { assembler }
  29. aasm
  30. ;
  31. {****************************************************************************
  32. Symtable types
  33. ****************************************************************************}
  34. type
  35. pstoredsymtable = ^tstoredsymtable;
  36. tstoredsymtable = object(tsymtable)
  37. constructor init(t : tsymtabletype);
  38. { load/write }
  39. constructor loadas(typ : tsymtabletype);
  40. procedure writeas;
  41. procedure loaddefs;
  42. procedure loadsyms;
  43. procedure writedefs;
  44. procedure writesyms;
  45. procedure deref;
  46. procedure insert(sym : psymentry);virtual;
  47. procedure insert_in(psymt : psymtable;offset : longint);
  48. function speedsearch(const s : stringid;speedvalue : longint) : psymentry;virtual;
  49. procedure allsymbolsused;
  50. procedure allprivatesused;
  51. procedure allunitsused;
  52. procedure check_forwards;
  53. procedure checklabels;
  54. { change alignment for args only parasymtable }
  55. procedure set_alignment(_alignment : longint);
  56. {$ifdef CHAINPROCSYMS}
  57. procedure chainprocsyms;
  58. {$endif CHAINPROCSYMS}
  59. {$ifndef DONOTCHAINOPERATORS}
  60. procedure chainoperators;
  61. {$endif DONOTCHAINOPERATORS}
  62. procedure load_browser;
  63. procedure write_browser;
  64. {$ifdef GDB}
  65. procedure concatstabto(asmlist : paasmoutput);virtual;
  66. function getnewtypecount : word; virtual;
  67. {$endif GDB}
  68. end;
  69. punitsymtable = ^tunitsymtable;
  70. tunitsymtable = object(tstoredsymtable)
  71. unittypecount : word;
  72. unitsym : punitsym;
  73. {$ifdef GDB}
  74. dbx_count : longint;
  75. prev_dbx_counter : plongint;
  76. dbx_count_ok : boolean;
  77. is_stab_written : boolean;
  78. {$endif GDB}
  79. constructor init(t : tsymtabletype;const n : string);
  80. constructor loadasunit;
  81. destructor done;virtual;
  82. procedure writeasunit;
  83. {$ifdef GDB}
  84. procedure concattypestabto(asmlist : paasmoutput);
  85. function getnewtypecount : word; virtual;
  86. {$endif GDB}
  87. procedure load_symtable_refs;
  88. end;
  89. pwithsymtable = ^twithsymtable;
  90. twithsymtable = object(tsymtable)
  91. { used for withsymtable for allowing constructors }
  92. direct_with : boolean;
  93. { in fact it is a ptree }
  94. withnode : pointer;
  95. { ptree to load of direct with var }
  96. { already usable before firstwith
  97. needed for firstpass of function parameters PM }
  98. withrefnode : pointer;
  99. constructor init;
  100. destructor done;virtual;
  101. procedure clear;virtual;
  102. end;
  103. var
  104. srsym : psym; { result of the last search }
  105. srsymtable : psymtable;
  106. lastsrsym : psym; { last sym found in statement }
  107. lastsrsymtable : psymtable;
  108. lastsymknown : boolean;
  109. constsymtable : psymtable; { symtable were the constants can be inserted }
  110. systemunit : punitsymtable; { pointer to the system unit }
  111. read_member : boolean; { reading members of an symtable }
  112. aktprocsym : pprocsym; { pointer to the symbol for the
  113. currently be parsed procedure }
  114. aktcallprocsym : pprocsym; { pointer to the symbol for the
  115. currently be called procedure,
  116. only set/unset in firstcall }
  117. aktvarsym : pvarsym; { pointer to the symbol for the
  118. currently read var, only used
  119. for variable directives }
  120. procprefix : string; { eindeutige Namen bei geschachtel- }
  121. { ten Unterprogrammen erzeugen }
  122. lexlevel : longint; { level of code }
  123. { 1 for main procedure }
  124. { 2 for normal function or proc }
  125. { higher for locals }
  126. {****************************************************************************
  127. Functions
  128. ****************************************************************************}
  129. {*** Misc ***}
  130. function globaldef(const s : string) : pdef;
  131. function findunitsymtable(st:psymtable):psymtable;
  132. procedure duplicatesym(sym:psym);
  133. {*** Search ***}
  134. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
  135. procedure getsym(const s : stringid;notfounderror : boolean);
  136. procedure getsymonlyin(p : psymtable;const s : stringid);
  137. {*** PPU Write/Loading ***}
  138. procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
  139. procedure numberunits;
  140. procedure load_interface;
  141. {*** Object Helpers ***}
  142. function search_class_member(pd : pobjectdef;const n : string) : psym;
  143. function search_default_property(pd : pobjectdef) : ppropertysym;
  144. {*** symtable stack ***}
  145. procedure dellexlevel;
  146. procedure RestoreUnitSyms;
  147. {$ifdef DEBUG}
  148. procedure test_symtablestack;
  149. procedure list_symtablestack;
  150. {$endif DEBUG}
  151. {$ifdef UNITALIASES}
  152. type
  153. punit_alias = ^tunit_alias;
  154. tunit_alias = object(tnamedindexobject)
  155. newname : pstring;
  156. constructor init(const n:string);
  157. destructor done;virtual;
  158. end;
  159. var
  160. unitaliases : pdictionary;
  161. procedure addunitalias(const n:string);
  162. function getunitalias(const n:string):string;
  163. {$endif UNITALIASES}
  164. {*** Init / Done ***}
  165. procedure InitSymtable;
  166. procedure DoneSymtable;
  167. const
  168. { last operator which can be overloaded }
  169. first_overloaded = _PLUS;
  170. last_overloaded = _ASSIGNMENT;
  171. type
  172. toverloaded_operators = array[first_overloaded..last_overloaded] of pprocsym;
  173. var
  174. overloaded_operators : toverloaded_operators;
  175. { unequal is not equal}
  176. const
  177. overloaded_names : array [first_overloaded..last_overloaded] of string[16] =
  178. ('plus','minus','star','slash','equal',
  179. 'greater','lower','greater_or_equal',
  180. 'lower_or_equal',
  181. 'sym_diff','starstar',
  182. 'as','is','in','or',
  183. 'and','div','mod','not','shl','shr','xor',
  184. 'assign');
  185. implementation
  186. uses
  187. { global }
  188. version,verbose,globals,
  189. { target }
  190. systems,
  191. { ppu }
  192. symppu,ppu,
  193. { module }
  194. finput,fmodule,
  195. {$ifdef GDB}
  196. gdb,
  197. {$endif GDB}
  198. { type helpers }
  199. types,
  200. { scanner }
  201. scanner,
  202. { codegen }
  203. hcodegen { remove !!! }
  204. ;
  205. var
  206. in_loading : boolean; { remove !!! }
  207. {*****************************************************************************
  208. Symbol Call Back Functions
  209. *****************************************************************************}
  210. procedure write_refs(sym : pnamedindexobject);
  211. begin
  212. pstoredsym(sym)^.write_references;
  213. end;
  214. procedure derefsym(p : pnamedindexobject);
  215. begin
  216. psym(p)^.deref;
  217. end;
  218. procedure check_forward(sym : pnamedindexobject);
  219. begin
  220. if psym(sym)^.typ=procsym then
  221. pprocsym(sym)^.check_forward
  222. { check also object method table }
  223. { we needn't to test the def list }
  224. { because each object has to have a type sym }
  225. else
  226. if (psym(sym)^.typ=typesym) and
  227. assigned(ptypesym(sym)^.restype.def) and
  228. (ptypesym(sym)^.restype.def^.deftype=objectdef) then
  229. pobjectdef(ptypesym(sym)^.restype.def)^.check_forwards;
  230. end;
  231. procedure labeldefined(p : pnamedindexobject);
  232. begin
  233. if (psym(p)^.typ=labelsym) and
  234. not(plabelsym(p)^.defined) then
  235. begin
  236. if plabelsym(p)^.used then
  237. Message1(sym_e_label_used_and_not_defined,p^.name)
  238. else
  239. Message1(sym_w_label_not_defined,p^.name);
  240. end;
  241. end;
  242. procedure unitsymbolused(p : pnamedindexobject);
  243. begin
  244. if (psym(p)^.typ=unitsym) and
  245. (punitsym(p)^.refs=0) and
  246. { do not claim for unit name itself !! }
  247. (punitsym(p)^.unitsymtable^.symtabletype=unitsymtable) then
  248. MessagePos2(psym(p)^.fileinfo,sym_n_unit_not_used,
  249. p^.name,current_module^.modulename^);
  250. end;
  251. procedure varsymbolused(p : pnamedindexobject);
  252. begin
  253. if (psym(p)^.typ=varsym) and
  254. ((psym(p)^.owner^.symtabletype in
  255. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  256. begin
  257. { unused symbol should be reported only if no }
  258. { error is reported }
  259. { if the symbol is in a register it is used }
  260. { also don't count the value parameters which have local copies }
  261. { also don't claim for high param of open parameters (PM) }
  262. if (Errorcount<>0) or
  263. (copy(p^.name,1,3)='val') or
  264. (copy(p^.name,1,4)='high') then
  265. exit;
  266. if (pvarsym(p)^.refs=0) then
  267. begin
  268. if (psym(p)^.owner^.symtabletype=parasymtable) or (vo_is_local_copy in pvarsym(p)^.varoptions) then
  269. begin
  270. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_not_used,p^.name);
  271. end
  272. else if (psym(p)^.owner^.symtabletype=objectsymtable) then
  273. MessagePos2(psym(p)^.fileinfo,sym_n_private_identifier_not_used,psym(p)^.owner^.name^,p^.name)
  274. else
  275. MessagePos1(psym(p)^.fileinfo,sym_n_local_identifier_not_used,p^.name);
  276. end
  277. else if pvarsym(p)^.varstate=vs_assigned then
  278. begin
  279. if (psym(p)^.owner^.symtabletype=parasymtable) then
  280. begin
  281. if not(pvarsym(p)^.varspez in [vs_var,vs_out]) then
  282. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name)
  283. end
  284. else if (vo_is_local_copy in pvarsym(p)^.varoptions) then
  285. begin
  286. if not(pvarsym(p)^.varspez in [vs_var,vs_out]) then
  287. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name);
  288. end
  289. else if (psym(p)^.owner^.symtabletype=objectsymtable) then
  290. MessagePos2(psym(p)^.fileinfo,sym_n_private_identifier_only_set,psym(p)^.owner^.name^,p^.name)
  291. else if (psym(p)^.owner^.symtabletype<>parasymtable) then
  292. if not (vo_is_exported in pvarsym(p)^.varoptions) then
  293. MessagePos1(psym(p)^.fileinfo,sym_n_local_identifier_only_set,p^.name);
  294. end;
  295. end
  296. else if ((psym(p)^.owner^.symtabletype in
  297. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  298. begin
  299. if (Errorcount<>0) then
  300. exit;
  301. { do not claim for inherited private fields !! }
  302. if (pstoredsym(p)^.refs=0) and (psym(p)^.owner^.symtabletype=objectsymtable) then
  303. MessagePos2(psym(p)^.fileinfo,sym_n_private_method_not_used,psym(p)^.owner^.name^,p^.name)
  304. { units references are problematic }
  305. else if (pstoredsym(p)^.refs=0) and not(psym(p)^.typ in [funcretsym,enumsym,unitsym]) then
  306. if (psym(p)^.typ<>procsym) or not (pprocsym(p)^.is_global) or
  307. { all program functions are declared global
  308. but unused should still be signaled PM }
  309. ((psym(p)^.owner^.symtabletype=staticsymtable) and
  310. not current_module^.is_unit) then
  311. MessagePos2(psym(p)^.fileinfo,sym_h_local_symbol_not_used,SymTypeName[psym(p)^.typ],p^.name);
  312. end;
  313. end;
  314. procedure TestPrivate(p : pnamedindexobject);
  315. begin
  316. if sp_private in psym(p)^.symoptions then
  317. varsymbolused(p);
  318. end;
  319. procedure objectprivatesymbolused(p : pnamedindexobject);
  320. begin
  321. {
  322. Don't test simple object aliases PM
  323. }
  324. if (psym(p)^.typ=typesym) and
  325. (ptypesym(p)^.restype.def^.deftype=objectdef) and
  326. (ptypesym(p)^.restype.def^.typesym=psym(p)) then
  327. pobjectdef(ptypesym(p)^.restype.def)^.symtable^.foreach(
  328. {$ifdef FPCPROCVAR}@{$endif}TestPrivate);
  329. end;
  330. {$ifdef GDB}
  331. var
  332. asmoutput : paasmoutput;
  333. procedure concatstab(p : pnamedindexobject);
  334. begin
  335. if psym(p)^.typ <> procsym then
  336. pstoredsym(p)^.concatstabto(asmoutput);
  337. end;
  338. procedure resetstab(p : pnamedindexobject);
  339. begin
  340. if psym(p)^.typ <> procsym then
  341. pstoredsym(p)^.isstabwritten:=false;
  342. end;
  343. procedure concattypestab(p : pnamedindexobject);
  344. begin
  345. if psym(p)^.typ = typesym then
  346. begin
  347. pstoredsym(p)^.isstabwritten:=false;
  348. pstoredsym(p)^.concatstabto(asmoutput);
  349. end;
  350. end;
  351. {$endif GDB}
  352. {$ifdef CHAINPROCSYMS}
  353. procedure chainprocsym(p : psym);
  354. var
  355. storesymtablestack : psymtable;
  356. begin
  357. if p^.typ=procsym then
  358. begin
  359. storesymtablestack:=symtablestack;
  360. symtablestack:=p^.owner^.next;
  361. while assigned(symtablestack) do
  362. begin
  363. { search for same procsym in other units }
  364. getsym(p^.name,false);
  365. if assigned(srsym) and (srsym^.typ=procsym) then
  366. begin
  367. pprocsym(p)^.nextprocsym:=pprocsym(srsym);
  368. symtablestack:=storesymtablestack;
  369. exit;
  370. end
  371. else if srsym=nil then
  372. symtablestack:=nil
  373. else
  374. symtablestack:=srsymtable^.next;
  375. end;
  376. symtablestack:=storesymtablestack;
  377. end;
  378. end;
  379. {$endif}
  380. {****************************************************************************
  381. STORED SYMTABLE
  382. ****************************************************************************}
  383. constructor tstoredsymtable.init(t : tsymtabletype);
  384. begin
  385. symtabletype:=t;
  386. symtablelevel:=0;
  387. defowner:=nil;
  388. unitid:=0;
  389. next:=nil;
  390. name:=nil;
  391. address_fixup:=0;
  392. datasize:=0;
  393. if t=parasymtable then
  394. dataalignment:=4
  395. else
  396. dataalignment:=1;
  397. new(symindex,init(indexgrowsize));
  398. new(defindex,init(indexgrowsize));
  399. if symtabletype<>withsymtable then
  400. begin
  401. new(symsearch,init);
  402. symsearch^.noclear:=true;
  403. end
  404. else
  405. symsearch:=nil;
  406. end;
  407. {$ifndef DONOTCHAINOPERATORS}
  408. procedure tstoredsymtable.chainoperators;
  409. var
  410. p : pprocsym;
  411. t : ttoken;
  412. def : pprocdef;
  413. storesymtablestack : psymtable;
  414. begin
  415. storesymtablestack:=symtablestack;
  416. symtablestack:=@self;
  417. make_ref:=false;
  418. for t:=first_overloaded to last_overloaded do
  419. begin
  420. p:=nil;
  421. def:=nil;
  422. overloaded_operators[t]:=nil;
  423. { each operator has a unique lowercased internal name PM }
  424. while assigned(symtablestack) do
  425. begin
  426. getsym(overloaded_names[t],false);
  427. if (t=_STARSTAR) and (srsym=nil) then
  428. begin
  429. symtablestack:=systemunit;
  430. getsym('POWER',false);
  431. end;
  432. if assigned(srsym) then
  433. begin
  434. if (srsym^.typ<>procsym) then
  435. internalerror(12344321);
  436. if assigned(p) then
  437. begin
  438. {$ifdef CHAINPROCSYMS}
  439. p^.nextprocsym:=pprocsym(srsym);
  440. {$endif CHAINPROCSYMS}
  441. def^.nextoverloaded:=pprocsym(srsym)^.definition;
  442. end
  443. else
  444. overloaded_operators[t]:=pprocsym(srsym);
  445. p:=pprocsym(srsym);
  446. def:=p^.definition;
  447. while assigned(def^.nextoverloaded) and
  448. (def^.nextoverloaded^.owner=p^.owner) do
  449. def:=def^.nextoverloaded;
  450. def^.nextoverloaded:=nil;
  451. symtablestack:=srsymtable^.next;
  452. end
  453. else
  454. begin
  455. symtablestack:=nil;
  456. {$ifdef CHAINPROCSYMS}
  457. if assigned(p) then
  458. p^.nextprocsym:=nil;
  459. {$endif CHAINPROCSYMS}
  460. end;
  461. { search for same procsym in other units }
  462. end;
  463. symtablestack:=@self;
  464. end;
  465. make_ref:=true;
  466. symtablestack:=storesymtablestack;
  467. end;
  468. {$endif DONOTCHAINOPERATORS}
  469. procedure tstoredsymtable.loaddefs;
  470. var
  471. hp : pdef;
  472. b : byte;
  473. begin
  474. { load start of definition section, which holds the amount of defs }
  475. if current_ppu^.readentry<>ibstartdefs then
  476. Message(unit_f_ppu_read_error);
  477. current_ppu^.getlongint;
  478. { read definitions }
  479. repeat
  480. b:=current_ppu^.readentry;
  481. case b of
  482. ibpointerdef : hp:=new(ppointerdef,load);
  483. ibarraydef : hp:=new(parraydef,load);
  484. iborddef : hp:=new(porddef,load);
  485. ibfloatdef : hp:=new(pfloatdef,load);
  486. ibprocdef : hp:=new(pprocdef,load);
  487. ibshortstringdef : hp:=new(pstringdef,shortload);
  488. iblongstringdef : hp:=new(pstringdef,longload);
  489. ibansistringdef : hp:=new(pstringdef,ansiload);
  490. ibwidestringdef : hp:=new(pstringdef,wideload);
  491. ibrecorddef : hp:=new(precorddef,load);
  492. ibobjectdef : hp:=new(pobjectdef,load);
  493. ibenumdef : hp:=new(penumdef,load);
  494. ibsetdef : hp:=new(psetdef,load);
  495. ibprocvardef : hp:=new(pprocvardef,load);
  496. ibfiledef : hp:=new(pfiledef,load);
  497. ibclassrefdef : hp:=new(pclassrefdef,load);
  498. ibformaldef : hp:=new(pformaldef,load);
  499. ibenddefs : break;
  500. ibend : Message(unit_f_ppu_read_error);
  501. else
  502. Message1(unit_f_ppu_invalid_entry,tostr(b));
  503. end;
  504. hp^.owner:=@self;
  505. defindex^.insert(hp);
  506. until false;
  507. end;
  508. procedure tstoredsymtable.loadsyms;
  509. var
  510. b : byte;
  511. sym : psym;
  512. begin
  513. { load start of definition section, which holds the amount of defs }
  514. if current_ppu^.readentry<>ibstartsyms then
  515. Message(unit_f_ppu_read_error);
  516. { skip amount of symbols, not used currently }
  517. current_ppu^.getlongint;
  518. { load datasize,dataalignment of this symboltable }
  519. datasize:=current_ppu^.getlongint;
  520. dataalignment:=current_ppu^.getlongint;
  521. { now read the symbols }
  522. repeat
  523. b:=current_ppu^.readentry;
  524. case b of
  525. ibtypesym : sym:=new(ptypesym,load);
  526. ibprocsym : sym:=new(pprocsym,load);
  527. ibconstsym : sym:=new(pconstsym,load);
  528. ibvarsym : sym:=new(pvarsym,load);
  529. ibfuncretsym : sym:=new(pfuncretsym,load);
  530. ibabsolutesym : sym:=new(pabsolutesym,load);
  531. ibenumsym : sym:=new(penumsym,load);
  532. ibtypedconstsym : sym:=new(ptypedconstsym,load);
  533. ibpropertysym : sym:=new(ppropertysym,load);
  534. ibunitsym : sym:=new(punitsym,load);
  535. iblabelsym : sym:=new(plabelsym,load);
  536. ibsyssym : sym:=new(psyssym,load);
  537. ibendsyms : break;
  538. ibend : Message(unit_f_ppu_read_error);
  539. else
  540. Message1(unit_f_ppu_invalid_entry,tostr(b));
  541. end;
  542. sym^.owner:=@self;
  543. symindex^.insert(sym);
  544. symsearch^.insert(sym);
  545. until false;
  546. end;
  547. procedure tstoredsymtable.writedefs;
  548. var
  549. pd : pstoreddef;
  550. begin
  551. { each definition get a number, write then the amount of defs to the
  552. ibstartdef entry }
  553. current_ppu^.putlongint(defindex^.count);
  554. current_ppu^.writeentry(ibstartdefs);
  555. { now write the definition }
  556. pd:=pstoreddef(defindex^.first);
  557. while assigned(pd) do
  558. begin
  559. pd^.write;
  560. pd:=pstoreddef(pd^.indexnext);
  561. end;
  562. { write end of definitions }
  563. current_ppu^.writeentry(ibenddefs);
  564. end;
  565. procedure tstoredsymtable.writesyms;
  566. var
  567. pd : pstoredsym;
  568. begin
  569. { each definition get a number, write then the amount of syms and the
  570. datasize to the ibsymdef entry }
  571. current_ppu^.putlongint(symindex^.count);
  572. current_ppu^.putlongint(datasize);
  573. current_ppu^.putlongint(dataalignment);
  574. current_ppu^.writeentry(ibstartsyms);
  575. { foreach is used to write all symbols }
  576. pd:=pstoredsym(symindex^.first);
  577. while assigned(pd) do
  578. begin
  579. pd^.write;
  580. pd:=pstoredsym(pd^.indexnext);
  581. end;
  582. { end of symbols }
  583. current_ppu^.writeentry(ibendsyms);
  584. end;
  585. {***********************************************
  586. Browser
  587. ***********************************************}
  588. procedure tstoredsymtable.load_browser;
  589. var
  590. b : byte;
  591. sym : pstoredsym;
  592. prdef : pstoreddef;
  593. oldrecsyms : psymtable;
  594. begin
  595. if symtabletype in [recordsymtable,objectsymtable] then
  596. begin
  597. oldrecsyms:=aktrecordsymtable;
  598. aktrecordsymtable:=@self;
  599. end;
  600. if symtabletype in [parasymtable,localsymtable] then
  601. begin
  602. oldrecsyms:=aktlocalsymtable;
  603. aktlocalsymtable:=@self;
  604. end;
  605. if symtabletype=staticppusymtable then
  606. aktstaticsymtable:=@self;
  607. b:=current_ppu^.readentry;
  608. if b <> ibbeginsymtablebrowser then
  609. Message1(unit_f_ppu_invalid_entry,tostr(b));
  610. repeat
  611. b:=current_ppu^.readentry;
  612. case b of
  613. ibsymref : begin
  614. sym:=pstoredsym(readderef);
  615. resolvesym(sym);
  616. if assigned(sym) then
  617. sym^.load_references;
  618. end;
  619. ibdefref : begin
  620. prdef:=pstoreddef(readderef);
  621. resolvedef(prdef);
  622. if assigned(prdef) then
  623. begin
  624. if prdef^.deftype<>procdef then
  625. Message(unit_f_ppu_read_error);
  626. pprocdef(prdef)^.load_references;
  627. end;
  628. end;
  629. ibendsymtablebrowser : break;
  630. else
  631. Message1(unit_f_ppu_invalid_entry,tostr(b));
  632. end;
  633. until false;
  634. if symtabletype in [recordsymtable,objectsymtable] then
  635. aktrecordsymtable:=oldrecsyms;
  636. if symtabletype in [parasymtable,localsymtable] then
  637. aktlocalsymtable:=oldrecsyms;
  638. end;
  639. procedure tstoredsymtable.write_browser;
  640. var
  641. oldrecsyms : psymtable;
  642. begin
  643. { symbol numbering for references
  644. should have been done in write PM
  645. number_symbols;
  646. number_defs; }
  647. if symtabletype in [recordsymtable,objectsymtable] then
  648. begin
  649. oldrecsyms:=aktrecordsymtable;
  650. aktrecordsymtable:=@self;
  651. end;
  652. if symtabletype in [parasymtable,localsymtable] then
  653. begin
  654. oldrecsyms:=aktlocalsymtable;
  655. aktlocalsymtable:=@self;
  656. end;
  657. current_ppu^.writeentry(ibbeginsymtablebrowser);
  658. foreach({$ifdef FPCPROCVAR}@{$endif}write_refs);
  659. current_ppu^.writeentry(ibendsymtablebrowser);
  660. if symtabletype in [recordsymtable,objectsymtable] then
  661. aktrecordsymtable:=oldrecsyms;
  662. if symtabletype in [parasymtable,localsymtable] then
  663. aktlocalsymtable:=oldrecsyms;
  664. end;
  665. {$ifdef GDB}
  666. function tstoredsymtable.getnewtypecount : word;
  667. begin
  668. getnewtypecount:=pglobaltypecount^;
  669. inc(pglobaltypecount^);
  670. end;
  671. {$endif GDB}
  672. procedure order_overloads(p : Pnamedindexobject);
  673. begin
  674. if psym(p)^.typ=procsym then
  675. pprocsym(p)^.order_overloaded;
  676. end;
  677. procedure tstoredsymtable.deref;
  678. var
  679. hp : pdef;
  680. hs : psym;
  681. begin
  682. { first deref the ttypesyms }
  683. hs:=psym(symindex^.first);
  684. while assigned(hs) do
  685. begin
  686. hs^.prederef;
  687. hs:=psym(hs^.indexnext);
  688. end;
  689. { deref the definitions }
  690. hp:=pdef(defindex^.first);
  691. while assigned(hp) do
  692. begin
  693. hp^.deref;
  694. hp:=pdef(hp^.indexnext);
  695. end;
  696. { deref the symbols }
  697. hs:=psym(symindex^.first);
  698. while assigned(hs) do
  699. begin
  700. hs^.deref;
  701. hs:=psym(hs^.indexnext);
  702. end;
  703. end;
  704. { this procedure is reserved for inserting case variant into
  705. a record symtable }
  706. { the offset is the location of the start of the variant
  707. and datasize and dataalignment corresponds to
  708. the complete size (see code in pdecl unit) PM }
  709. procedure tstoredsymtable.insert_in(psymt : psymtable;offset : longint);
  710. var
  711. ps,nps : pvarsym;
  712. pd,npd : pdef;
  713. storesize,storealign : longint;
  714. begin
  715. storesize:=psymt^.datasize;
  716. storealign:=psymt^.dataalignment;
  717. psymt^.datasize:=offset;
  718. ps:=pvarsym(symindex^.first);
  719. while assigned(ps) do
  720. begin
  721. { this is used to insert case variant into the main
  722. record }
  723. psymt^.datasize:=ps^.address+offset;
  724. nps:=pvarsym(ps^.indexnext);
  725. symindex^.deleteindex(ps);
  726. ps^.indexnext:=nil;
  727. ps^.left:=nil;
  728. ps^.right:=nil;
  729. psymt^.insert(ps);
  730. ps:=nps;
  731. end;
  732. pd:=pdef(defindex^.first);
  733. while assigned(pd) do
  734. begin
  735. npd:=pdef(pd^.indexnext);
  736. defindex^.deleteindex(pd);
  737. pd^.indexnext:=nil;
  738. pd^.left:=nil;
  739. pd^.right:=nil;
  740. psymt^.registerdef(pd);
  741. pd:=npd;
  742. end;
  743. psymt^.datasize:=storesize;
  744. psymt^.dataalignment:=storealign;
  745. end;
  746. constructor tstoredsymtable.loadas(typ : tsymtabletype);
  747. var
  748. storesymtable : psymtable;
  749. st_loading : boolean;
  750. begin
  751. st_loading:=in_loading;
  752. in_loading:=true;
  753. symtabletype:=typ;
  754. new(symindex,init(indexgrowsize));
  755. new(defindex,init(indexgrowsize));
  756. new(symsearch,init);
  757. symsearch^.noclear:=true;
  758. { reset }
  759. defowner:=nil;
  760. name:=nil;
  761. if typ=parasymtable then
  762. dataalignment:=4
  763. else
  764. dataalignment:=1;
  765. datasize:=0;
  766. address_fixup:= 0;
  767. unitid:=0;
  768. { setup symtabletype specific things }
  769. case typ of
  770. unitsymtable :
  771. begin
  772. symtablelevel:=0;
  773. {$ifndef NEWMAP}
  774. current_module^.map^[0]:=@self;
  775. {$else NEWMAP}
  776. current_module^.globalsymtable:=@self;
  777. {$endif NEWMAP}
  778. end;
  779. recordsymtable,
  780. objectsymtable :
  781. begin
  782. storesymtable:=aktrecordsymtable;
  783. aktrecordsymtable:=@self;
  784. end;
  785. parasymtable,
  786. localsymtable :
  787. begin
  788. storesymtable:=aktlocalsymtable;
  789. aktlocalsymtable:=@self;
  790. end;
  791. { used for local browser }
  792. staticppusymtable :
  793. begin
  794. aktstaticsymtable:=@self;
  795. symsearch^.usehash;
  796. end;
  797. end;
  798. { we need the correct symtable for registering }
  799. if not (typ in [localsymtable,parasymtable,recordsymtable,objectsymtable]) then
  800. begin
  801. next:=symtablestack;
  802. symtablestack:=@self;
  803. end;
  804. { load definitions }
  805. loaddefs;
  806. { load symbols }
  807. loadsyms;
  808. if not (typ in [localsymtable,parasymtable,recordsymtable,objectsymtable]) then
  809. begin
  810. { now we can deref the syms and defs }
  811. deref;
  812. { restore symtablestack }
  813. symtablestack:=next;
  814. end;
  815. case typ of
  816. unitsymtable :
  817. begin
  818. {$ifdef NEWMAP}
  819. { necessary for dependencies }
  820. current_module^.globalsymtable:=nil;
  821. {$endif NEWMAP}
  822. end;
  823. recordsymtable,
  824. objectsymtable :
  825. aktrecordsymtable:=storesymtable;
  826. localsymtable,
  827. parasymtable :
  828. aktlocalsymtable:=storesymtable;
  829. end;
  830. in_loading:=st_loading;
  831. end;
  832. procedure tstoredsymtable.writeas;
  833. var
  834. oldtyp : byte;
  835. storesymtable : psymtable;
  836. begin
  837. storesymtable:=aktrecordsymtable;
  838. case symtabletype of
  839. recordsymtable,
  840. objectsymtable :
  841. begin
  842. storesymtable:=aktrecordsymtable;
  843. aktrecordsymtable:=@self;
  844. oldtyp:=current_ppu^.entrytyp;
  845. current_ppu^.entrytyp:=subentryid;
  846. end;
  847. parasymtable,
  848. localsymtable :
  849. begin
  850. storesymtable:=aktlocalsymtable;
  851. aktlocalsymtable:=@self;
  852. end;
  853. end;
  854. { order procsym overloads }
  855. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  856. { write definitions }
  857. writedefs;
  858. { write symbols }
  859. writesyms;
  860. case symtabletype of
  861. recordsymtable,
  862. objectsymtable :
  863. begin
  864. current_ppu^.entrytyp:=oldtyp;
  865. aktrecordsymtable:=storesymtable;
  866. end;
  867. localsymtable,
  868. parasymtable :
  869. aktlocalsymtable:=storesymtable;
  870. end;
  871. end;
  872. procedure tstoredsymtable.insert(sym:psymentry);
  873. var
  874. hp : psymtable;
  875. hsym : psym;
  876. begin
  877. { set owner and sym indexnb }
  878. sym^.owner:=@self;
  879. {$ifdef CHAINPROCSYMS}
  880. { set the nextprocsym field }
  881. if sym^.typ=procsym then
  882. chainprocsym(sym);
  883. {$endif CHAINPROCSYMS}
  884. { writes the symbol in data segment if required }
  885. { also sets the datasize of owner }
  886. if not in_loading then
  887. pstoredsym(sym)^.insert_in_data;
  888. if (symtabletype in [staticsymtable,globalsymtable]) then
  889. begin
  890. hp:=symtablestack;
  891. while assigned(hp) do
  892. begin
  893. if hp^.symtabletype in [staticsymtable,globalsymtable] then
  894. begin
  895. hsym:=psym(hp^.search(sym^.name));
  896. if assigned(hsym) then
  897. DuplicateSym(hsym);
  898. end;
  899. hp:=hp^.next;
  900. end;
  901. end;
  902. { check the current symtable }
  903. hsym:=psym(search(sym^.name));
  904. if assigned(hsym) then
  905. begin
  906. { in TP and Delphi you can have a local with the
  907. same name as the function, the function is then hidden for
  908. the user. (Under delphi it can still be accessed using result),
  909. but don't allow hiding of RESULT }
  910. if (m_tp in aktmodeswitches) and
  911. (hsym^.typ=funcretsym) and
  912. not((m_result in aktmodeswitches) and
  913. (hsym^.name='RESULT')) then
  914. hsym^.owner^.rename(hsym^.name,'hidden'+hsym^.name)
  915. else
  916. begin
  917. DuplicateSym(hsym);
  918. exit;
  919. end;
  920. end;
  921. { check for duplicate id in local and parasymtable symtable }
  922. if (symtabletype=localsymtable) then
  923. { to be on the save side: }
  924. begin
  925. if assigned(next) and
  926. (next^.symtabletype=parasymtable) then
  927. begin
  928. hsym:=psym(next^.search(sym^.name));
  929. if assigned(hsym) then
  930. begin
  931. { a parameter and the function can have the same
  932. name in TP and Delphi, but RESULT not }
  933. if (m_tp in aktmodeswitches) and
  934. (sym^.typ=funcretsym) and
  935. not((m_result in aktmodeswitches) and
  936. (sym^.name='RESULT')) then
  937. sym^.setname('hidden'+sym^.name)
  938. else
  939. begin
  940. DuplicateSym(hsym);
  941. exit;
  942. end;
  943. end;
  944. end
  945. else if (current_module^.flags and uf_local_browser)=0 then
  946. internalerror(43789);
  947. end;
  948. { check for duplicate id in local symtable of methods }
  949. if (symtabletype=localsymtable) and
  950. assigned(next) and
  951. assigned(next^.next) and
  952. { funcretsym is allowed !! }
  953. (sym^.typ <> funcretsym) and
  954. (next^.next^.symtabletype=objectsymtable) then
  955. begin
  956. hsym:=search_class_member(pobjectdef(next^.next^.defowner),sym^.name);
  957. if assigned(hsym) and
  958. { private ids can be reused }
  959. (not(sp_private in hsym^.symoptions) or
  960. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  961. begin
  962. { delphi allows to reuse the names in a class, but not
  963. in object (tp7 compatible) }
  964. if not((m_delphi in aktmodeswitches) and
  965. is_class(pdef(next^.next^.defowner))) then
  966. begin
  967. DuplicateSym(hsym);
  968. exit;
  969. end;
  970. end;
  971. end;
  972. { check for duplicate id in para symtable of methods }
  973. if (symtabletype=parasymtable) and
  974. assigned(procinfo^._class) and
  975. { but not in nested procedures !}
  976. (not(assigned(procinfo^.parent)) or
  977. (assigned(procinfo^.parent) and
  978. not(assigned(procinfo^.parent^._class)))
  979. ) and
  980. { funcretsym is allowed !! }
  981. (sym^.typ <> funcretsym) then
  982. begin
  983. hsym:=search_class_member(procinfo^._class,sym^.name);
  984. if assigned(hsym) and
  985. { private ids can be reused }
  986. (not(sp_private in hsym^.symoptions) or
  987. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  988. begin
  989. { delphi allows to reuse the names in a class, but not
  990. in object (tp7 compatible) }
  991. if not((m_delphi in aktmodeswitches) and
  992. is_class(procinfo^._class)) then
  993. begin
  994. DuplicateSym(hsym);
  995. exit;
  996. end;
  997. end;
  998. end;
  999. { check for duplicate field id in inherited classes }
  1000. if (sym^.typ=varsym) and
  1001. (symtabletype=objectsymtable) and
  1002. assigned(defowner) then
  1003. begin
  1004. hsym:=search_class_member(pobjectdef(defowner),sym^.name);
  1005. { but private ids can be reused }
  1006. if assigned(hsym) and
  1007. (not(sp_private in hsym^.symoptions) or
  1008. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  1009. begin
  1010. DuplicateSym(hsym);
  1011. exit;
  1012. end;
  1013. end;
  1014. { register definition of typesym }
  1015. if (sym^.typ = typesym) and
  1016. assigned(ptypesym(sym)^.restype.def) then
  1017. begin
  1018. if not(assigned(ptypesym(sym)^.restype.def^.owner)) and
  1019. (ptypesym(sym)^.restype.def^.deftype<>errordef) then
  1020. registerdef(ptypesym(sym)^.restype.def);
  1021. {$ifdef GDB}
  1022. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  1023. (symtabletype in [globalsymtable,staticsymtable]) then
  1024. begin
  1025. ptypesym(sym)^.isusedinstab := true;
  1026. {sym^.concatstabto(debuglist);}
  1027. end;
  1028. {$endif GDB}
  1029. end;
  1030. { insert in index and search hash }
  1031. symindex^.insert(sym);
  1032. symsearch^.insert(sym);
  1033. end;
  1034. function tstoredsymtable.speedsearch(const s : stringid;speedvalue : longint) : psymentry;
  1035. var
  1036. hp : pstoredsym;
  1037. newref : pref;
  1038. begin
  1039. hp:=pstoredsym(inherited speedsearch(s,speedvalue));
  1040. if assigned(hp) then
  1041. begin
  1042. { reject non static members in static procedures,
  1043. be carefull aktprocsym^.definition is not allways
  1044. loaded already (PFV) }
  1045. if (symtabletype=objectsymtable) and
  1046. not(sp_static in hp^.symoptions) and
  1047. allow_only_static
  1048. {assigned(aktprocsym) and
  1049. assigned(aktprocsym^.definition) and
  1050. ((aktprocsym^.definition^.options and postaticmethod)<>0)} then
  1051. Message(sym_e_only_static_in_static);
  1052. if (symtabletype=unitsymtable) and
  1053. assigned(punitsymtable(@self)^.unitsym) then
  1054. inc(punitsymtable(@self)^.unitsym^.refs);
  1055. { unitsym are only loaded for browsing PM }
  1056. { this was buggy anyway because we could use }
  1057. { unitsyms from other units in _USES !! }
  1058. {if (symtabletype=unitsymtable) and (hp^.typ=unitsym) and
  1059. assigned(current_module) and (current_module^.globalsymtable<>@self) then
  1060. hp:=nil;}
  1061. if assigned(hp) and
  1062. (cs_browser in aktmoduleswitches) and make_ref then
  1063. begin
  1064. new(newref,init(hp^.lastref,@akttokenpos));
  1065. { for symbols that are in tables without
  1066. browser info or syssyms (PM) }
  1067. if hp^.refcount=0 then
  1068. begin
  1069. hp^.defref:=newref;
  1070. hp^.lastref:=newref;
  1071. end
  1072. else
  1073. if resolving_forward and assigned(hp^.defref) then
  1074. { put it as second reference }
  1075. begin
  1076. newref^.nextref:=hp^.defref^.nextref;
  1077. hp^.defref^.nextref:=newref;
  1078. hp^.lastref^.nextref:=nil;
  1079. end
  1080. else
  1081. hp^.lastref:=newref;
  1082. inc(hp^.refcount);
  1083. end;
  1084. if assigned(hp) and make_ref then
  1085. begin
  1086. inc(hp^.refs);
  1087. end;
  1088. end;
  1089. speedsearch:=hp;
  1090. end;
  1091. {***********************************************
  1092. Process all entries
  1093. ***********************************************}
  1094. { checks, if all procsyms and methods are defined }
  1095. procedure tstoredsymtable.check_forwards;
  1096. begin
  1097. foreach({$ifdef FPCPROCVAR}@{$endif}check_forward);
  1098. end;
  1099. procedure tstoredsymtable.checklabels;
  1100. begin
  1101. foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined);
  1102. end;
  1103. procedure tstoredsymtable.set_alignment(_alignment : longint);
  1104. var
  1105. sym : pvarsym;
  1106. l : longint;
  1107. begin
  1108. dataalignment:=_alignment;
  1109. if (symtabletype<>parasymtable) then
  1110. internalerror(1111);
  1111. sym:=pvarsym(symindex^.first);
  1112. datasize:=0;
  1113. { there can be only varsyms }
  1114. while assigned(sym) do
  1115. begin
  1116. l:=sym^.getpushsize;
  1117. sym^.address:=datasize;
  1118. datasize:=align(datasize+l,dataalignment);
  1119. sym:=pvarsym(sym^.indexnext);
  1120. end;
  1121. end;
  1122. procedure tstoredsymtable.allunitsused;
  1123. begin
  1124. foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
  1125. end;
  1126. procedure tstoredsymtable.allsymbolsused;
  1127. begin
  1128. foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused);
  1129. end;
  1130. procedure tstoredsymtable.allprivatesused;
  1131. begin
  1132. foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused);
  1133. end;
  1134. {$ifdef CHAINPROCSYMS}
  1135. procedure tstoredsymtable.chainprocsyms;
  1136. begin
  1137. foreach({$ifdef FPCPROCVAR}@{$endif}chainprocsym);
  1138. end;
  1139. {$endif CHAINPROCSYMS}
  1140. {$ifdef GDB}
  1141. procedure tstoredsymtable.concatstabto(asmlist : paasmoutput);
  1142. begin
  1143. asmoutput:=asmlist;
  1144. if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
  1145. foreach({$ifdef FPCPROCVAR}@{$endif}resetstab);
  1146. foreach({$ifdef FPCPROCVAR}@{$endif}concatstab);
  1147. end;
  1148. {$endif}
  1149. {****************************************************************************
  1150. TWITHSYMTABLE
  1151. ****************************************************************************}
  1152. constructor twithsymtable.init;
  1153. begin
  1154. inherited init(withsymtable);
  1155. direct_with:=false;
  1156. withnode:=nil;
  1157. withrefnode:=nil;
  1158. end;
  1159. destructor twithsymtable.done;
  1160. begin
  1161. symsearch:=nil;
  1162. inherited done;
  1163. end;
  1164. procedure twithsymtable.clear;
  1165. begin
  1166. { remove no entry from a withsymtable as it is only a pointer to the
  1167. recorddef or objectdef symtable }
  1168. end;
  1169. {****************************************************************************
  1170. PPU Writing Helpers
  1171. ****************************************************************************}
  1172. procedure writesourcefiles;
  1173. var
  1174. hp : pinputfile;
  1175. i,j : longint;
  1176. begin
  1177. { second write the used source files }
  1178. current_ppu^.do_crc:=false;
  1179. hp:=current_module^.sourcefiles^.files;
  1180. { write source files directly in good order }
  1181. j:=0;
  1182. while assigned(hp) do
  1183. begin
  1184. inc(j);
  1185. hp:=hp^.ref_next;
  1186. end;
  1187. while j>0 do
  1188. begin
  1189. hp:=current_module^.sourcefiles^.files;
  1190. for i:=1 to j-1 do
  1191. hp:=hp^.ref_next;
  1192. current_ppu^.putstring(hp^.name^);
  1193. dec(j);
  1194. end;
  1195. current_ppu^.writeentry(ibsourcefiles);
  1196. current_ppu^.do_crc:=true;
  1197. end;
  1198. procedure writeusedmacro(p:pnamedindexobject);
  1199. begin
  1200. if pmacro(p)^.is_used or pmacro(p)^.defined_at_startup then
  1201. begin
  1202. current_ppu^.putstring(p^.name);
  1203. current_ppu^.putbyte(byte(pmacro(p)^.defined_at_startup));
  1204. current_ppu^.putbyte(byte(pmacro(p)^.is_used));
  1205. end;
  1206. end;
  1207. procedure writeusedmacros;
  1208. begin
  1209. current_ppu^.do_crc:=false;
  1210. current_scanner^.macros^.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro);
  1211. current_ppu^.writeentry(ibusedmacros);
  1212. current_ppu^.do_crc:=true;
  1213. end;
  1214. procedure writeusedunit;
  1215. var
  1216. hp : pused_unit;
  1217. begin
  1218. numberunits;
  1219. hp:=pused_unit(current_module^.used_units.first);
  1220. while assigned(hp) do
  1221. begin
  1222. { implementation units should not change
  1223. the CRC PM }
  1224. current_ppu^.do_crc:=hp^.in_interface;
  1225. current_ppu^.putstring(hp^.name^);
  1226. { the checksum should not affect the crc of this unit ! (PFV) }
  1227. current_ppu^.do_crc:=false;
  1228. current_ppu^.putlongint(hp^.checksum);
  1229. current_ppu^.putlongint(hp^.interface_checksum);
  1230. current_ppu^.putbyte(byte(hp^.in_interface));
  1231. current_ppu^.do_crc:=true;
  1232. hp:=pused_unit(hp^.next);
  1233. end;
  1234. current_ppu^.do_interface_crc:=true;
  1235. current_ppu^.writeentry(ibloadunit);
  1236. end;
  1237. procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  1238. var
  1239. hcontainer : tlinkcontainer;
  1240. s : string;
  1241. mask : longint;
  1242. begin
  1243. hcontainer.init;
  1244. while not p.empty do
  1245. begin
  1246. s:=p.get(mask);
  1247. if strippath then
  1248. current_ppu^.putstring(SplitFileName(s))
  1249. else
  1250. current_ppu^.putstring(s);
  1251. current_ppu^.putlongint(mask);
  1252. hcontainer.insert(s,mask);
  1253. end;
  1254. current_ppu^.writeentry(id);
  1255. p:=hcontainer;
  1256. end;
  1257. procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
  1258. begin
  1259. Message1(unit_u_ppu_write,s);
  1260. { create unit flags }
  1261. with Current_Module^ do
  1262. begin
  1263. {$ifdef GDB}
  1264. if cs_gdb_dbx in aktglobalswitches then
  1265. flags:=flags or uf_has_dbx;
  1266. {$endif GDB}
  1267. if target_os.endian=endian_big then
  1268. flags:=flags or uf_big_endian;
  1269. if cs_browser in aktmoduleswitches then
  1270. flags:=flags or uf_has_browser;
  1271. if cs_local_browser in aktmoduleswitches then
  1272. flags:=flags or uf_local_browser;
  1273. end;
  1274. {$ifdef Test_Double_checksum_write}
  1275. If only_crc then
  1276. Assign(CRCFile,s+'.INT')
  1277. else
  1278. Assign(CRCFile,s+'.IMP');
  1279. Rewrite(CRCFile);
  1280. {$endif def Test_Double_checksum_write}
  1281. { open ppufile }
  1282. current_ppu:=new(pppufile,init(s));
  1283. current_ppu^.crc_only:=only_crc;
  1284. if not current_ppu^.create then
  1285. Message(unit_f_ppu_cannot_write);
  1286. {$ifdef Test_Double_checksum}
  1287. if only_crc then
  1288. begin
  1289. new(current_ppu^.crc_test);
  1290. new(current_ppu^.crc_test2);
  1291. end
  1292. else
  1293. begin
  1294. current_ppu^.crc_test:=Current_Module^.crc_array;
  1295. current_ppu^.crc_index:=Current_Module^.crc_size;
  1296. current_ppu^.crc_test2:=Current_Module^.crc_array2;
  1297. current_ppu^.crc_index2:=Current_Module^.crc_size2;
  1298. end;
  1299. {$endif def Test_Double_checksum}
  1300. current_ppu^.change_endian:=source_os.endian<>target_os.endian;
  1301. { write symbols and definitions }
  1302. unittable^.writeasunit;
  1303. { flush to be sure }
  1304. current_ppu^.flush;
  1305. { create and write header }
  1306. current_ppu^.header.size:=current_ppu^.size;
  1307. current_ppu^.header.checksum:=current_ppu^.crc;
  1308. current_ppu^.header.interface_checksum:=current_ppu^.interface_crc;
  1309. current_ppu^.header.compiler:=wordversion;
  1310. current_ppu^.header.cpu:=word(target_cpu);
  1311. current_ppu^.header.target:=word(target_info.target);
  1312. current_ppu^.header.flags:=current_module^.flags;
  1313. If not only_crc then
  1314. current_ppu^.writeheader;
  1315. { save crc in current_module also }
  1316. current_module^.crc:=current_ppu^.crc;
  1317. current_module^.interface_crc:=current_ppu^.interface_crc;
  1318. if only_crc then
  1319. begin
  1320. {$ifdef Test_Double_checksum}
  1321. Current_Module^.crc_array:=current_ppu^.crc_test;
  1322. current_ppu^.crc_test:=nil;
  1323. Current_Module^.crc_size:=current_ppu^.crc_index2;
  1324. Current_Module^.crc_array2:=current_ppu^.crc_test2;
  1325. current_ppu^.crc_test2:=nil;
  1326. Current_Module^.crc_size2:=current_ppu^.crc_index2;
  1327. {$endif def Test_Double_checksum}
  1328. closecurrentppu;
  1329. end;
  1330. {$ifdef Test_Double_checksum_write}
  1331. close(CRCFile);
  1332. {$endif Test_Double_checksum_write}
  1333. end;
  1334. procedure readusedmacros;
  1335. var
  1336. hs : string;
  1337. mac : pmacro;
  1338. was_defined_at_startup,
  1339. was_used : boolean;
  1340. begin
  1341. while not current_ppu^.endofentry do
  1342. begin
  1343. hs:=current_ppu^.getstring;
  1344. was_defined_at_startup:=boolean(current_ppu^.getbyte);
  1345. was_used:=boolean(current_ppu^.getbyte);
  1346. mac:=pmacro(current_scanner^.macros^.search(hs));
  1347. if assigned(mac) then
  1348. begin
  1349. {$ifndef EXTDEBUG}
  1350. { if we don't have the sources why tell }
  1351. if current_module^.sources_avail then
  1352. {$endif ndef EXTDEBUG}
  1353. if (not was_defined_at_startup) and
  1354. was_used and
  1355. mac^.defined_at_startup then
  1356. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
  1357. end
  1358. else { not assigned }
  1359. if was_defined_at_startup and
  1360. was_used then
  1361. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
  1362. end;
  1363. end;
  1364. procedure readsourcefiles;
  1365. var
  1366. temp,hs : string;
  1367. temp_dir : string;
  1368. main_dir : string;
  1369. incfile_found,
  1370. main_found,
  1371. is_main : boolean;
  1372. ppufiletime,
  1373. source_time : longint;
  1374. hp : pinputfile;
  1375. begin
  1376. ppufiletime:=getnamedfiletime(current_module^.ppufilename^);
  1377. current_module^.sources_avail:=true;
  1378. is_main:=true;
  1379. main_dir:='';
  1380. while not current_ppu^.endofentry do
  1381. begin
  1382. hs:=current_ppu^.getstring;
  1383. temp_dir:='';
  1384. if (current_module^.flags and uf_in_library)<>0 then
  1385. begin
  1386. current_module^.sources_avail:=false;
  1387. temp:=' library';
  1388. end
  1389. else if pos('Macro ',hs)=1 then
  1390. begin
  1391. { we don't want to find this file }
  1392. { but there is a problem with file indexing !! }
  1393. temp:='';
  1394. end
  1395. else
  1396. begin
  1397. { check the date of the source files }
  1398. Source_Time:=GetNamedFileTime(current_module^.path^+hs);
  1399. incfile_found:=false;
  1400. main_found:=false;
  1401. if Source_Time<>-1 then
  1402. hs:=current_module^.path^+hs
  1403. else
  1404. if not(is_main) then
  1405. begin
  1406. Source_Time:=GetNamedFileTime(main_dir+hs);
  1407. if Source_Time<>-1 then
  1408. hs:=main_dir+hs;
  1409. end;
  1410. if (Source_Time=-1) then
  1411. begin
  1412. if is_main then
  1413. temp_dir:=unitsearchpath.FindFile(hs,main_found)
  1414. else
  1415. temp_dir:=includesearchpath.FindFile(hs,incfile_found);
  1416. if incfile_found or main_found then
  1417. begin
  1418. hs:=temp_dir+hs;
  1419. Source_Time:=GetNamedFileTime(hs);
  1420. end
  1421. end;
  1422. if Source_Time=-1 then
  1423. begin
  1424. current_module^.sources_avail:=false;
  1425. temp:=' not found';
  1426. end
  1427. else
  1428. begin
  1429. if main_found then
  1430. main_dir:=temp_dir;
  1431. { time newer? But only allow if the file is not searched
  1432. in the include path (PFV), else you've problems with
  1433. units which use the same includefile names }
  1434. if incfile_found then
  1435. temp:=' found'
  1436. else
  1437. begin
  1438. temp:=' time '+filetimestring(source_time);
  1439. if (source_time>ppufiletime) then
  1440. begin
  1441. current_module^.do_compile:=true;
  1442. current_module^.recompile_reason:=rr_sourcenewer;
  1443. temp:=temp+' *'
  1444. end;
  1445. end;
  1446. end;
  1447. new(hp,init(hs));
  1448. { the indexing is wrong here PM }
  1449. current_module^.sourcefiles^.register_file(hp);
  1450. end;
  1451. if is_main then
  1452. begin
  1453. stringdispose(current_module^.mainsource);
  1454. current_module^.mainsource:=stringdup(hs);
  1455. end;
  1456. Message1(unit_u_ppu_source,hs+temp);
  1457. is_main:=false;
  1458. end;
  1459. { check if we want to rebuild every unit, only if the sources are
  1460. available }
  1461. if do_build and current_module^.sources_avail then
  1462. begin
  1463. current_module^.do_compile:=true;
  1464. current_module^.recompile_reason:=rr_build;
  1465. end;
  1466. end;
  1467. procedure readloadunit;
  1468. var
  1469. hs : string;
  1470. intfchecksum,
  1471. checksum : longint;
  1472. in_interface : boolean;
  1473. begin
  1474. while not current_ppu^.endofentry do
  1475. begin
  1476. hs:=current_ppu^.getstring;
  1477. checksum:=current_ppu^.getlongint;
  1478. intfchecksum:=current_ppu^.getlongint;
  1479. in_interface:=(current_ppu^.getbyte<>0);
  1480. current_module^.used_units.concat(new(pused_unit,init_to_load(hs,checksum,intfchecksum,in_interface)));
  1481. end;
  1482. end;
  1483. procedure readlinkcontainer(var p:tlinkcontainer);
  1484. var
  1485. s : string;
  1486. m : longint;
  1487. begin
  1488. while not current_ppu^.endofentry do
  1489. begin
  1490. s:=current_ppu^.getstring;
  1491. m:=current_ppu^.getlongint;
  1492. p.insert(s,m);
  1493. end;
  1494. end;
  1495. procedure load_interface;
  1496. var
  1497. b : byte;
  1498. newmodulename : string;
  1499. begin
  1500. { read interface part }
  1501. repeat
  1502. b:=current_ppu^.readentry;
  1503. case b of
  1504. ibmodulename :
  1505. begin
  1506. newmodulename:=current_ppu^.getstring;
  1507. if upper(newmodulename)<>current_module^.modulename^ then
  1508. Message2(unit_f_unit_name_error,current_module^.realmodulename^,newmodulename);
  1509. stringdispose(current_module^.modulename);
  1510. stringdispose(current_module^.realmodulename);
  1511. current_module^.modulename:=stringdup(upper(newmodulename));
  1512. current_module^.realmodulename:=stringdup(newmodulename);
  1513. end;
  1514. ibsourcefiles :
  1515. readsourcefiles;
  1516. ibusedmacros :
  1517. readusedmacros;
  1518. ibloadunit :
  1519. readloadunit;
  1520. iblinkunitofiles :
  1521. readlinkcontainer(current_module^.LinkUnitOFiles);
  1522. iblinkunitstaticlibs :
  1523. readlinkcontainer(current_module^.LinkUnitStaticLibs);
  1524. iblinkunitsharedlibs :
  1525. readlinkcontainer(current_module^.LinkUnitSharedLibs);
  1526. iblinkotherofiles :
  1527. readlinkcontainer(current_module^.LinkotherOFiles);
  1528. iblinkotherstaticlibs :
  1529. readlinkcontainer(current_module^.LinkotherStaticLibs);
  1530. iblinkothersharedlibs :
  1531. readlinkcontainer(current_module^.LinkotherSharedLibs);
  1532. ibendinterface :
  1533. break;
  1534. else
  1535. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1536. end;
  1537. until false;
  1538. end;
  1539. {****************************************************************************
  1540. TUNITSYMTABLE
  1541. ****************************************************************************}
  1542. constructor tunitsymtable.init(t : tsymtabletype; const n : string);
  1543. begin
  1544. inherited init(t);
  1545. name:=stringdup(upper(n));
  1546. unitid:=0;
  1547. unitsym:=nil;
  1548. symsearch^.usehash;
  1549. { reset GDB things }
  1550. {$ifdef GDB}
  1551. if (t = globalsymtable) then
  1552. begin
  1553. prev_dbx_counter := dbx_counter;
  1554. dbx_counter := nil;
  1555. end;
  1556. is_stab_written:=false;
  1557. dbx_count := -1;
  1558. if cs_gdb_dbx in aktglobalswitches then
  1559. begin
  1560. dbx_count := 0;
  1561. unittypecount:=1;
  1562. if (symtabletype=globalsymtable) then
  1563. pglobaltypecount := @unittypecount;
  1564. unitid:=current_module^.unitcount;
  1565. debuglist^.concat(new(pai_asm_comment,init(strpnew('Global '+name^+' has index '+tostr(unitid)))));
  1566. debuglist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0'))));
  1567. inc(current_module^.unitcount);
  1568. dbx_count_ok:=false;
  1569. dbx_counter:=@dbx_count;
  1570. do_count_dbx:=true;
  1571. end;
  1572. {$endif GDB}
  1573. end;
  1574. constructor tunitsymtable.loadasunit;
  1575. var
  1576. {$ifdef GDB}
  1577. storeGlobalTypeCount : pword;
  1578. {$endif GDB}
  1579. b : byte;
  1580. begin
  1581. unitsym:=nil;
  1582. unitid:=0;
  1583. {$ifdef GDB}
  1584. if cs_gdb_dbx in aktglobalswitches then
  1585. begin
  1586. UnitTypeCount:=1;
  1587. storeGlobalTypeCount:=PGlobalTypeCount;
  1588. PglobalTypeCount:=@UnitTypeCount;
  1589. end;
  1590. {$endif GDB}
  1591. { load symtables }
  1592. inherited loadas(unitsymtable);
  1593. { set the name after because it is set to nil in tstoredsymtable.load !! }
  1594. name:=stringdup(current_module^.modulename^);
  1595. { dbx count }
  1596. {$ifdef GDB}
  1597. if (current_module^.flags and uf_has_dbx)<>0 then
  1598. begin
  1599. b := current_ppu^.readentry;
  1600. if b <> ibdbxcount then
  1601. Message(unit_f_ppu_dbx_count_problem)
  1602. else
  1603. dbx_count := readlong;
  1604. dbx_count_ok := {true}false;
  1605. end
  1606. else
  1607. begin
  1608. dbx_count := -1;
  1609. dbx_count_ok:=false;
  1610. end;
  1611. if cs_gdb_dbx in aktglobalswitches then
  1612. PGlobalTypeCount:=storeGlobalTypeCount;
  1613. is_stab_written:=false;
  1614. {$endif GDB}
  1615. b:=current_ppu^.readentry;
  1616. if b<>ibendimplementation then
  1617. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1618. end;
  1619. destructor tunitsymtable.done;
  1620. var
  1621. pus : punitsym;
  1622. begin
  1623. pus:=unitsym;
  1624. while assigned(pus) do
  1625. begin
  1626. unitsym:=pus^.prevsym;
  1627. pus^.prevsym:=nil;
  1628. pus^.unitsymtable:=nil;
  1629. pus:=unitsym;
  1630. end;
  1631. inherited done;
  1632. end;
  1633. procedure tunitsymtable.load_symtable_refs;
  1634. var
  1635. b : byte;
  1636. unitindex : word;
  1637. begin
  1638. if ((current_module^.flags and uf_local_browser)<>0) then
  1639. begin
  1640. current_module^.localsymtable:=new(punitsymtable,loadas(staticppusymtable));
  1641. psymtable(current_module^.localsymtable)^.name:=
  1642. stringdup('implementation of '+psymtable(current_module^.globalsymtable)^.name^);
  1643. end;
  1644. { load browser }
  1645. if (current_module^.flags and uf_has_browser)<>0 then
  1646. begin
  1647. {if not (cs_browser in aktmoduleswitches) then
  1648. current_ppu^.skipuntilentry(ibendbrowser)
  1649. else }
  1650. begin
  1651. load_browser;
  1652. unitindex:=1;
  1653. while assigned(current_module^.map^[unitindex]) do
  1654. begin
  1655. {each unit wrote one browser entry }
  1656. load_browser;
  1657. inc(unitindex);
  1658. end;
  1659. b:=current_ppu^.readentry;
  1660. if b<>ibendbrowser then
  1661. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1662. end;
  1663. end;
  1664. if ((current_module^.flags and uf_local_browser)<>0) then
  1665. pstoredsymtable(current_module^.localsymtable)^.load_browser;
  1666. end;
  1667. procedure tunitsymtable.writeasunit;
  1668. var
  1669. pu : pused_unit;
  1670. begin
  1671. { first the unitname }
  1672. current_ppu^.putstring(current_module^.realmodulename^);
  1673. current_ppu^.writeentry(ibmodulename);
  1674. writesourcefiles;
  1675. writeusedmacros;
  1676. writeusedunit;
  1677. { write the objectfiles and libraries that come for this unit,
  1678. preserve the containers becuase they are still needed to load
  1679. the link.res. All doesn't depend on the crc! It doesn't matter
  1680. if a unit is in a .o or .a file }
  1681. current_ppu^.do_crc:=false;
  1682. writelinkcontainer(current_module^.linkunitofiles,iblinkunitofiles,true);
  1683. writelinkcontainer(current_module^.linkunitstaticlibs,iblinkunitstaticlibs,true);
  1684. writelinkcontainer(current_module^.linkunitsharedlibs,iblinkunitsharedlibs,true);
  1685. writelinkcontainer(current_module^.linkotherofiles,iblinkotherofiles,false);
  1686. writelinkcontainer(current_module^.linkotherstaticlibs,iblinkotherstaticlibs,true);
  1687. writelinkcontainer(current_module^.linkothersharedlibs,iblinkothersharedlibs,true);
  1688. current_ppu^.do_crc:=true;
  1689. current_ppu^.writeentry(ibendinterface);
  1690. { write the symtable entries }
  1691. inherited writeas;
  1692. { all after doesn't affect crc }
  1693. current_ppu^.do_crc:=false;
  1694. { write dbx count }
  1695. {$ifdef GDB}
  1696. if cs_gdb_dbx in aktglobalswitches then
  1697. begin
  1698. {$IfDef EXTDEBUG}
  1699. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1700. {$ENDIF EXTDEBUG}
  1701. current_ppu^.putlongint(dbx_count);
  1702. current_ppu^.writeentry(ibdbxcount);
  1703. end;
  1704. {$endif GDB}
  1705. current_ppu^.writeentry(ibendimplementation);
  1706. { write static symtable
  1707. needed for local debugging of unit functions }
  1708. if ((current_module^.flags and uf_local_browser)<>0) and
  1709. assigned(current_module^.localsymtable) then
  1710. pstoredsymtable(current_module^.localsymtable)^.writeas;
  1711. { write all browser section }
  1712. if (current_module^.flags and uf_has_browser)<>0 then
  1713. begin
  1714. write_browser;
  1715. pu:=pused_unit(current_module^.used_units.first);
  1716. while assigned(pu) do
  1717. begin
  1718. pstoredsymtable(pu^.u^.globalsymtable)^.write_browser;
  1719. pu:=pused_unit(pu^.next);
  1720. end;
  1721. current_ppu^.writeentry(ibendbrowser);
  1722. end;
  1723. if ((current_module^.flags and uf_local_browser)<>0) and
  1724. assigned(current_module^.localsymtable) then
  1725. pstoredsymtable(current_module^.localsymtable)^.write_browser;
  1726. { the last entry ibend is written automaticly }
  1727. end;
  1728. {$ifdef GDB}
  1729. function tunitsymtable.getnewtypecount : word;
  1730. begin
  1731. if not (cs_gdb_dbx in aktglobalswitches) then
  1732. getnewtypecount:=tsymtable.getnewtypecount
  1733. else
  1734. if symtabletype = staticsymtable then
  1735. getnewtypecount:=tsymtable.getnewtypecount
  1736. else
  1737. begin
  1738. getnewtypecount:=unittypecount;
  1739. inc(unittypecount);
  1740. end;
  1741. end;
  1742. procedure tunitsymtable.concattypestabto(asmlist : paasmoutput);
  1743. var prev_dbx_count : plongint;
  1744. begin
  1745. if is_stab_written then exit;
  1746. if not assigned(name) then name := stringdup('Main_program');
  1747. if (symtabletype = unitsymtable) and
  1748. (current_module^.globalsymtable<>@Self) then
  1749. begin
  1750. unitid:=current_module^.unitcount;
  1751. inc(current_module^.unitcount);
  1752. end;
  1753. asmlist^.concat(new(pai_asm_comment,init(strpnew('Begin unit '+name^
  1754. +' has index '+tostr(unitid)))));
  1755. if cs_gdb_dbx in aktglobalswitches then
  1756. begin
  1757. if dbx_count_ok then
  1758. begin
  1759. asmlist^.concat(new(pai_asm_comment,init(strpnew('"repeated" unit '+name^
  1760. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count)))));
  1761. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1762. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count)))));
  1763. exit;
  1764. end
  1765. else if (current_module^.globalsymtable<>@Self) then
  1766. begin
  1767. prev_dbx_count := dbx_counter;
  1768. dbx_counter := nil;
  1769. do_count_dbx:=false;
  1770. if symtabletype = unitsymtable then
  1771. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1772. +tostr(N_BINCL)+',0,0,0'))));
  1773. dbx_counter := @dbx_count;
  1774. dbx_count:=0;
  1775. do_count_dbx:=assigned(dbx_counter);
  1776. end;
  1777. end;
  1778. asmoutput:=asmlist;
  1779. foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab);
  1780. if cs_gdb_dbx in aktglobalswitches then
  1781. begin
  1782. if (current_module^.globalsymtable<>@Self) then
  1783. begin
  1784. dbx_counter := prev_dbx_count;
  1785. do_count_dbx:=false;
  1786. asmlist^.concat(new(pai_asm_comment,init(strpnew('End unit '+name^
  1787. +' has index '+tostr(unitid)))));
  1788. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1789. +tostr(N_EINCL)+',0,0,0'))));
  1790. do_count_dbx:=assigned(dbx_counter);
  1791. dbx_count_ok := {true}false;
  1792. end;
  1793. end;
  1794. is_stab_written:=true;
  1795. end;
  1796. {$endif}
  1797. {*****************************************************************************
  1798. Helper Routines
  1799. *****************************************************************************}
  1800. procedure numberunits;
  1801. var
  1802. counter : longint;
  1803. hp : pused_unit;
  1804. hp1 : pmodule;
  1805. begin
  1806. { Reset all numbers to -1 }
  1807. hp1:=pmodule(loaded_units.first);
  1808. while assigned(hp1) do
  1809. begin
  1810. if assigned(hp1^.globalsymtable) then
  1811. psymtable(hp1^.globalsymtable)^.unitid:=$ffff;
  1812. hp1:=pmodule(hp1^.next);
  1813. end;
  1814. { Our own symtable gets unitid 0, for a program there is
  1815. no globalsymtable }
  1816. if assigned(current_module^.globalsymtable) then
  1817. psymtable(current_module^.globalsymtable)^.unitid:=0;
  1818. { number units }
  1819. counter:=1;
  1820. hp:=pused_unit(current_module^.used_units.first);
  1821. while assigned(hp) do
  1822. begin
  1823. psymtable(hp^.u^.globalsymtable)^.unitid:=counter;
  1824. inc(counter);
  1825. hp:=pused_unit(hp^.next);
  1826. end;
  1827. end;
  1828. function findunitsymtable(st:psymtable):psymtable;
  1829. begin
  1830. findunitsymtable:=nil;
  1831. repeat
  1832. if not assigned(st) then
  1833. internalerror(5566561);
  1834. case st^.symtabletype of
  1835. localsymtable,
  1836. parasymtable,
  1837. staticsymtable :
  1838. break;
  1839. globalsymtable,
  1840. unitsymtable :
  1841. begin
  1842. findunitsymtable:=st;
  1843. break;
  1844. end;
  1845. objectsymtable,
  1846. recordsymtable :
  1847. st:=st^.defowner^.owner;
  1848. else
  1849. internalerror(5566562);
  1850. end;
  1851. until false;
  1852. end;
  1853. procedure duplicatesym(sym:psym);
  1854. var
  1855. st : psymtable;
  1856. begin
  1857. Message1(sym_e_duplicate_id,sym^.name);
  1858. st:=findunitsymtable(sym^.owner);
  1859. with sym^.fileinfo do
  1860. begin
  1861. if assigned(st) and (st^.unitid<>0) then
  1862. Message2(sym_h_duplicate_id_where,'unit '+st^.name^,tostr(line))
  1863. else
  1864. Message2(sym_h_duplicate_id_where,current_module^.sourcefiles^.get_file_name(fileindex),tostr(line));
  1865. end;
  1866. end;
  1867. procedure identifier_not_found(const s:string);
  1868. begin
  1869. Message1(sym_e_id_not_found,s);
  1870. { show a fatal that you need -S2 or -Sd, but only
  1871. if we just parsed the a token that has m_class }
  1872. if not(m_class in aktmodeswitches) and
  1873. (s=pattern) and
  1874. (tokeninfo^[idtoken].keyword=m_class) then
  1875. Message(parser_f_need_objfpc_or_delphi_mode);
  1876. end;
  1877. {*****************************************************************************
  1878. Search
  1879. *****************************************************************************}
  1880. procedure getsym(const s : stringid;notfounderror : boolean);
  1881. var
  1882. speedvalue : longint;
  1883. begin
  1884. speedvalue:=getspeedvalue(s);
  1885. lastsrsym:=nil;
  1886. srsymtable:=symtablestack;
  1887. while assigned(srsymtable) do
  1888. begin
  1889. srsym:=psym(srsymtable^.speedsearch(s,speedvalue));
  1890. if assigned(srsym) then
  1891. exit
  1892. else
  1893. srsymtable:=srsymtable^.next;
  1894. end;
  1895. if notfounderror then
  1896. begin
  1897. identifier_not_found(s);
  1898. srsym:=generrorsym;
  1899. end
  1900. else
  1901. srsym:=nil;
  1902. end;
  1903. procedure getsymonlyin(p : psymtable;const s : stringid);
  1904. begin
  1905. { the caller have to take care if srsym=nil (FK) }
  1906. srsym:=nil;
  1907. if assigned(p) then
  1908. begin
  1909. srsymtable:=p;
  1910. srsym:=psym(srsymtable^.search(s));
  1911. if assigned(srsym) then
  1912. exit
  1913. else
  1914. begin
  1915. if (punitsymtable(srsymtable)=punitsymtable(current_module^.globalsymtable)) then
  1916. begin
  1917. getsymonlyin(psymtable(current_module^.localsymtable),s);
  1918. if assigned(srsym) then
  1919. srsymtable:=psymtable(current_module^.localsymtable)
  1920. else
  1921. identifier_not_found(s);
  1922. end
  1923. else
  1924. identifier_not_found(s);
  1925. end;
  1926. end;
  1927. end;
  1928. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
  1929. {Search for a symbol in a specified symbol table. Returns nil if
  1930. the symtable is not found, and also if the symbol cannot be found
  1931. in the desired symtable }
  1932. var hsymtab:Psymtable;
  1933. res:Psym;
  1934. begin
  1935. res:=nil;
  1936. hsymtab:=symtablestack;
  1937. while (hsymtab<>nil) and (hsymtab^.symtabletype<>symtabletype) do
  1938. hsymtab:=hsymtab^.next;
  1939. if hsymtab<>nil then
  1940. {We found the desired symtable. Now check if the symbol we
  1941. search for is defined in it }
  1942. res:=psym(hsymtab^.search(symbol));
  1943. search_a_symtable:=res;
  1944. end;
  1945. {*****************************************************************************
  1946. Definition Helpers
  1947. *****************************************************************************}
  1948. function globaldef(const s : string) : pdef;
  1949. var st : string;
  1950. symt : psymtable;
  1951. begin
  1952. srsym := nil;
  1953. if pos('.',s) > 0 then
  1954. begin
  1955. st := copy(s,1,pos('.',s)-1);
  1956. getsym(st,false);
  1957. st := copy(s,pos('.',s)+1,255);
  1958. if assigned(srsym) then
  1959. begin
  1960. if srsym^.typ = unitsym then
  1961. begin
  1962. symt := punitsym(srsym)^.unitsymtable;
  1963. srsym := psym(symt^.search(st));
  1964. end else srsym := nil;
  1965. end;
  1966. end else st := s;
  1967. if srsym = nil then getsym(st,false);
  1968. if srsym = nil then
  1969. getsymonlyin(systemunit,st);
  1970. if srsym^.typ<>typesym then
  1971. begin
  1972. Message(type_e_type_id_expected);
  1973. exit;
  1974. end;
  1975. globaldef := pdef(ptypesym(srsym)^.restype.def);
  1976. end;
  1977. {****************************************************************************
  1978. Object Helpers
  1979. ****************************************************************************}
  1980. function search_class_member(pd : pobjectdef;const n : string) : psym;
  1981. { searches n in symtable of pd and all anchestors }
  1982. var
  1983. sym : psym;
  1984. begin
  1985. sym:=nil;
  1986. while assigned(pd) do
  1987. begin
  1988. sym:=psym(pd^.symtable^.search(n));
  1989. if assigned(sym) then
  1990. break;
  1991. pd:=pd^.childof;
  1992. end;
  1993. { this is needed for static methods in do_member_read pexpr unit PM
  1994. caused bug0214 }
  1995. if assigned(sym) then
  1996. begin
  1997. srsymtable:=pd^.symtable;
  1998. end;
  1999. search_class_member:=sym;
  2000. end;
  2001. var
  2002. _defaultprop : ppropertysym;
  2003. procedure testfordefaultproperty(p : pnamedindexobject);
  2004. begin
  2005. if (psym(p)^.typ=propertysym) and
  2006. (ppo_defaultproperty in ppropertysym(p)^.propoptions) then
  2007. _defaultprop:=ppropertysym(p);
  2008. end;
  2009. function search_default_property(pd : pobjectdef) : ppropertysym;
  2010. { returns the default property of a class, searches also anchestors }
  2011. begin
  2012. _defaultprop:=nil;
  2013. while assigned(pd) do
  2014. begin
  2015. pd^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}testfordefaultproperty);
  2016. if assigned(_defaultprop) then
  2017. break;
  2018. pd:=pd^.childof;
  2019. end;
  2020. search_default_property:=_defaultprop;
  2021. end;
  2022. {$ifdef UNITALIASES}
  2023. {****************************************************************************
  2024. TUNIT_ALIAS
  2025. ****************************************************************************}
  2026. constructor tunit_alias.init(const n:string);
  2027. var
  2028. i : longint;
  2029. begin
  2030. i:=pos('=',n);
  2031. if i=0 then
  2032. fail;
  2033. inherited initname(Copy(n,1,i-1));
  2034. newname:=stringdup(Copy(n,i+1,255));
  2035. end;
  2036. destructor tunit_alias.done;
  2037. begin
  2038. stringdispose(newname);
  2039. inherited done;
  2040. end;
  2041. procedure addunitalias(const n:string);
  2042. begin
  2043. unitaliases^.insert(new(punit_alias,init(Upper(n))));
  2044. end;
  2045. function getunitalias(const n:string):string;
  2046. var
  2047. p : punit_alias;
  2048. begin
  2049. p:=punit_alias(unitaliases^.search(Upper(n)));
  2050. if assigned(p) then
  2051. getunitalias:=punit_alias(p)^.newname^
  2052. else
  2053. getunitalias:=n;
  2054. end;
  2055. {$endif UNITALIASES}
  2056. {****************************************************************************
  2057. Symtable Stack
  2058. ****************************************************************************}
  2059. procedure dellexlevel;
  2060. var
  2061. p : psymtable;
  2062. begin
  2063. p:=symtablestack;
  2064. symtablestack:=p^.next;
  2065. { symbol tables of unit interfaces are never disposed }
  2066. { this is handle by the unit unitm }
  2067. if not(p^.symtabletype in [unitsymtable,globalsymtable,stt_exceptsymtable]) then
  2068. dispose(p,done);
  2069. end;
  2070. procedure RestoreUnitSyms;
  2071. var
  2072. p : psymtable;
  2073. begin
  2074. p:=symtablestack;
  2075. while assigned(p) do
  2076. begin
  2077. if (p^.symtabletype=unitsymtable) and
  2078. assigned(punitsymtable(p)^.unitsym) and
  2079. ((punitsymtable(p)^.unitsym^.owner=psymtable(current_module^.globalsymtable)) or
  2080. (punitsymtable(p)^.unitsym^.owner=psymtable(current_module^.localsymtable))) then
  2081. punitsymtable(p)^.unitsym^.restoreunitsym;
  2082. p:=p^.next;
  2083. end;
  2084. end;
  2085. {$ifdef DEBUG}
  2086. procedure test_symtablestack;
  2087. var
  2088. p : psymtable;
  2089. i : longint;
  2090. begin
  2091. p:=symtablestack;
  2092. i:=0;
  2093. while assigned(p) do
  2094. begin
  2095. inc(i);
  2096. p:=p^.next;
  2097. if i>500 then
  2098. Message(sym_f_internal_error_in_symtablestack);
  2099. end;
  2100. end;
  2101. procedure list_symtablestack;
  2102. var
  2103. p : psymtable;
  2104. i : longint;
  2105. begin
  2106. p:=symtablestack;
  2107. i:=0;
  2108. while assigned(p) do
  2109. begin
  2110. inc(i);
  2111. writeln(i,' ',p^.name^);
  2112. p:=p^.next;
  2113. if i>500 then
  2114. Message(sym_f_internal_error_in_symtablestack);
  2115. end;
  2116. end;
  2117. {$endif DEBUG}
  2118. {****************************************************************************
  2119. Init/Done Symtable
  2120. ****************************************************************************}
  2121. procedure InitSymtable;
  2122. var
  2123. token : ttoken;
  2124. begin
  2125. { Reset symbolstack }
  2126. registerdef:=false;
  2127. read_member:=false;
  2128. symtablestack:=nil;
  2129. systemunit:=nil;
  2130. {$ifdef GDB}
  2131. firstglobaldef:=nil;
  2132. lastglobaldef:=nil;
  2133. globaltypecount:=1;
  2134. pglobaltypecount:=@globaltypecount;
  2135. {$endif GDB}
  2136. { create error syms and def }
  2137. generrorsym:=new(perrorsym,init);
  2138. generrordef:=new(perrordef,init);
  2139. {$ifdef UNITALIASES}
  2140. { unit aliases }
  2141. unitaliases:=new(pdictionary,init);
  2142. {$endif}
  2143. for token:=first_overloaded to last_overloaded do
  2144. overloaded_operators[token]:=nil;
  2145. end;
  2146. procedure DoneSymtable;
  2147. begin
  2148. dispose(generrorsym,done);
  2149. dispose(generrordef,done);
  2150. {$ifdef UNITALIASES}
  2151. dispose(unitaliases,done);
  2152. {$endif}
  2153. {$ifdef MEMDEBUG}
  2154. writeln('Manglednames: ',manglenamesize,' bytes');
  2155. {$endif}
  2156. end;
  2157. end.
  2158. {
  2159. $Log$
  2160. Revision 1.14 2000-11-04 14:25:22 florian
  2161. + merged Attila's changes for interfaces, not tested yet
  2162. Revision 1.13 2000/11/01 23:04:38 peter
  2163. * tprocdef.fullprocname added for better casesensitve writing of
  2164. procedures
  2165. Revision 1.12 2000/10/31 22:02:52 peter
  2166. * symtable splitted, no real code changes
  2167. Revision 1.11 2000/10/15 07:47:53 peter
  2168. * unit names and procedure names are stored mixed case
  2169. Revision 1.10 2000/10/14 10:14:53 peter
  2170. * moehrendorf oct 2000 rewrite
  2171. Revision 1.9 2000/10/01 19:48:25 peter
  2172. * lot of compile updates for cg11
  2173. Revision 1.8 2000/09/24 15:06:29 peter
  2174. * use defines.inc
  2175. Revision 1.7 2000/08/27 16:11:54 peter
  2176. * moved some util functions from globals,cobjects to cutils
  2177. * splitted files into finput,fmodule
  2178. Revision 1.6 2000/08/21 11:27:45 pierre
  2179. * fix the stabs problems
  2180. Revision 1.5 2000/08/20 14:58:41 peter
  2181. * give fatal if objfpc/delphi mode things are found (merged)
  2182. Revision 1.4 2000/08/16 18:33:54 peter
  2183. * splitted namedobjectitem.next into indexnext and listnext so it
  2184. can be used in both lists
  2185. * don't allow "word = word" type definitions (merged)
  2186. Revision 1.3 2000/08/08 19:28:57 peter
  2187. * memdebug/memory patches (merged)
  2188. * only once illegal directive (merged)
  2189. Revision 1.2 2000/07/13 11:32:50 michael
  2190. + removed logs
  2191. }