symtable.pas 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  3. This unit handles the symbol tables
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit symtable;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,cclasses,
  23. { global }
  24. cpuinfo,globtype,tokens,
  25. { symtable }
  26. symconst,symbase,symtype,symdef,symsym,
  27. { ppu }
  28. ppu,
  29. { assembler }
  30. aasmtai,aasmdata
  31. ;
  32. {****************************************************************************
  33. Symtable types
  34. ****************************************************************************}
  35. type
  36. tstoredsymtable = class(TSymtable)
  37. private
  38. b_needs_init_final : boolean;
  39. procedure _needs_init_final(sym:TObject;arg:pointer);
  40. procedure check_forward(sym:TObject;arg:pointer);
  41. procedure labeldefined(sym:TObject;arg:pointer);
  42. procedure varsymbolused(sym:TObject;arg:pointer);
  43. procedure TestPrivate(sym:TObject;arg:pointer);
  44. procedure objectprivatesymbolused(sym:TObject;arg:pointer);
  45. procedure loaddefs(ppufile:tcompilerppufile);
  46. procedure loadsyms(ppufile:tcompilerppufile);
  47. procedure writedefs(ppufile:tcompilerppufile);
  48. procedure writesyms(ppufile:tcompilerppufile);
  49. public
  50. procedure insert(sym:TSymEntry;checkdup:boolean=true);override;
  51. procedure delete(sym:TSymEntry);override;
  52. { load/write }
  53. procedure ppuload(ppufile:tcompilerppufile);virtual;
  54. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  55. procedure buildderef;virtual;
  56. procedure buildderefimpl;virtual;
  57. procedure deref;virtual;
  58. procedure derefimpl;virtual;
  59. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  60. procedure reset_all_defs;virtual;
  61. procedure allsymbolsused;
  62. procedure allprivatesused;
  63. procedure check_forwards;
  64. procedure checklabels;
  65. function needs_init_final : boolean;
  66. procedure testfordefaultproperty(sym:TObject;arg:pointer);
  67. end;
  68. tabstractrecordsymtable = class(tstoredsymtable)
  69. public
  70. usefieldalignment, { alignment to use for fields (PACKRECORDS value), C_alignment is C style }
  71. recordalignment, { alignment desired when inserting this record }
  72. fieldalignment, { alignment current alignment used when fields are inserted }
  73. padalignment : shortint; { size to a multiple of which the symtable has to be rounded up }
  74. constructor create(const n:string;usealign:shortint);
  75. procedure ppuload(ppufile:tcompilerppufile);override;
  76. procedure ppuwrite(ppufile:tcompilerppufile);override;
  77. procedure alignrecord(fieldoffset:aint;varalign:shortint);
  78. procedure addfield(sym:tfieldvarsym;vis:tvisibility);
  79. procedure addalignmentpadding;
  80. procedure insertdef(def:TDefEntry);override;
  81. function is_packed: boolean;
  82. protected
  83. _datasize : aint;
  84. { size in bits of the data in case of bitpacked record. Only important during construction, }
  85. { no need to save in/restore from ppu file. datasize is always (databitsize+7) div 8. }
  86. databitsize : aint;
  87. procedure setdatasize(val: aint);
  88. public
  89. property datasize : aint read _datasize write setdatasize;
  90. end;
  91. trecordsymtable = class(tabstractrecordsymtable)
  92. public
  93. constructor create(usealign:shortint);
  94. procedure insertunionst(unionst : trecordsymtable;offset : longint);
  95. end;
  96. tObjectSymtable = class(tabstractrecordsymtable)
  97. public
  98. constructor create(adefowner:tdef;const n:string;usealign:shortint);
  99. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  100. end;
  101. { tabstractlocalsymtable }
  102. tabstractlocalsymtable = class(tstoredsymtable)
  103. public
  104. procedure ppuwrite(ppufile:tcompilerppufile);override;
  105. function count_locals:longint;
  106. end;
  107. tlocalsymtable = class(tabstractlocalsymtable)
  108. public
  109. constructor create(adefowner:tdef;level:byte);
  110. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  111. end;
  112. tparasymtable = class(tabstractlocalsymtable)
  113. public
  114. constructor create(adefowner:tdef;level:byte);
  115. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  116. end;
  117. tabstractuniTSymtable = class(tstoredsymtable)
  118. public
  119. constructor create(const n : string;id:word);
  120. function iscurrentunit:boolean;override;
  121. end;
  122. tglobalsymtable = class(tabstractuniTSymtable)
  123. public
  124. unittypecount : word;
  125. constructor create(const n : string;id:word);
  126. procedure ppuload(ppufile:tcompilerppufile);override;
  127. procedure ppuwrite(ppufile:tcompilerppufile);override;
  128. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  129. end;
  130. tstaticsymtable = class(tabstractuniTSymtable)
  131. public
  132. constructor create(const n : string;id:word);
  133. procedure ppuload(ppufile:tcompilerppufile);override;
  134. procedure ppuwrite(ppufile:tcompilerppufile);override;
  135. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  136. end;
  137. twithsymtable = class(TSymtable)
  138. withrefnode : tobject; { tnode }
  139. constructor create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  140. destructor destroy;override;
  141. procedure clear;override;
  142. procedure insertdef(def:TDefEntry);override;
  143. end;
  144. tstt_excepTSymtable = class(TSymtable)
  145. public
  146. constructor create;
  147. end;
  148. tmacrosymtable = class(tstoredsymtable)
  149. public
  150. constructor create(exported: boolean);
  151. end;
  152. var
  153. systemunit : tglobalsymtable; { pointer to the system unit }
  154. {****************************************************************************
  155. Functions
  156. ****************************************************************************}
  157. {*** Misc ***}
  158. function FullTypeName(def,otherdef:tdef):string;
  159. procedure incompatibletypes(def1,def2:tdef);
  160. procedure hidesym(sym:TSymEntry);
  161. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  162. {*** Search ***}
  163. procedure addsymref(sym:tsym);
  164. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tobjectdef):boolean;
  165. function is_visible_for_object(pd:tprocdef;contextobjdef:tobjectdef):boolean;
  166. function is_visible_for_object(sym:tsym;contextobjdef:tobjectdef):boolean;
  167. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  168. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  169. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  170. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  171. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  172. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  173. function search_system_type(const s: TIDString): ttypesym;
  174. function search_class_member(pd : tobjectdef;const s : string):tsym;
  175. function search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
  176. {Looks for macro s (must be given in upper case) in the macrosymbolstack, }
  177. {and returns it if found. Returns nil otherwise.}
  178. function search_macro(const s : string):tsym;
  179. { Additionally to searching for a macro, also checks whether it's still }
  180. { actually defined (could be disable using "undef") }
  181. function defined_macro(const s : string):boolean;
  182. {*** Object Helpers ***}
  183. function search_default_property(pd : tobjectdef) : tpropertysym;
  184. {*** Macro Helpers ***}
  185. {If called initially, the following procedures manipulate macros in }
  186. {initialmacrotable, otherwise they manipulate system macros local to a module.}
  187. {Name can be given in any case (it will be converted to upper case).}
  188. procedure def_system_macro(const name : string);
  189. procedure set_system_macro(const name, value : string);
  190. procedure set_system_compvar(const name, value : string);
  191. procedure undef_system_macro(const name : string);
  192. {*** symtable stack ***}
  193. { $ifdef DEBUG
  194. procedure test_symtablestack;
  195. procedure list_symtablestack;
  196. $endif DEBUG}
  197. {$ifdef UNITALIASES}
  198. type
  199. punit_alias = ^tunit_alias;
  200. tunit_alias = object(TNamedIndexItem)
  201. newname : pshortstring;
  202. constructor init(const n:string);
  203. destructor done;virtual;
  204. end;
  205. var
  206. unitaliases : pdictionary;
  207. procedure addunitalias(const n:string);
  208. function getunitalias(const n:string):string;
  209. {$endif UNITALIASES}
  210. {*** Init / Done ***}
  211. procedure IniTSymtable;
  212. procedure DoneSymtable;
  213. const
  214. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] =
  215. ('error',
  216. 'plus','minus','star','slash','equal',
  217. 'greater','lower','greater_or_equal',
  218. 'lower_or_equal',
  219. 'sym_diff','starstar',
  220. 'as','is','in','or',
  221. 'and','div','mod','not','shl','shr','xor',
  222. 'assign');
  223. implementation
  224. uses
  225. { global }
  226. verbose,globals,
  227. { target }
  228. systems,
  229. { symtable }
  230. symutil,defcmp,defutil,
  231. { module }
  232. fmodule,
  233. { codegen }
  234. procinfo
  235. ;
  236. var
  237. dupnr : longint; { unique number for duplicate symbols }
  238. {*****************************************************************************
  239. TStoredSymtable
  240. *****************************************************************************}
  241. procedure tstoredsymtable.insert(sym:TSymEntry;checkdup:boolean=true);
  242. begin
  243. inherited insert(sym,checkdup);
  244. end;
  245. procedure tstoredsymtable.delete(sym:TSymEntry);
  246. begin
  247. inherited delete(sym);
  248. end;
  249. procedure tstoredsymtable.ppuload(ppufile:tcompilerppufile);
  250. begin
  251. { load definitions }
  252. loaddefs(ppufile);
  253. { load symbols }
  254. loadsyms(ppufile);
  255. end;
  256. procedure tstoredsymtable.ppuwrite(ppufile:tcompilerppufile);
  257. begin
  258. { write definitions }
  259. writedefs(ppufile);
  260. { write symbols }
  261. writesyms(ppufile);
  262. end;
  263. procedure tstoredsymtable.loaddefs(ppufile:tcompilerppufile);
  264. var
  265. def : tdef;
  266. b : byte;
  267. begin
  268. { load start of definition section, which holds the amount of defs }
  269. if ppufile.readentry<>ibstartdefs then
  270. Message(unit_f_ppu_read_error);
  271. { read definitions }
  272. repeat
  273. b:=ppufile.readentry;
  274. case b of
  275. ibpointerdef : def:=tpointerdef.ppuload(ppufile);
  276. ibarraydef : def:=tarraydef.ppuload(ppufile);
  277. iborddef : def:=torddef.ppuload(ppufile);
  278. ibfloatdef : def:=tfloatdef.ppuload(ppufile);
  279. ibprocdef : def:=tprocdef.ppuload(ppufile);
  280. ibshortstringdef : def:=tstringdef.loadshort(ppufile);
  281. iblongstringdef : def:=tstringdef.loadlong(ppufile);
  282. ibansistringdef : def:=tstringdef.loadansi(ppufile);
  283. ibwidestringdef : def:=tstringdef.loadwide(ppufile);
  284. ibunicodestringdef : def:=tstringdef.loadunicode(ppufile);
  285. ibrecorddef : def:=trecorddef.ppuload(ppufile);
  286. ibobjectdef : def:=tobjectdef.ppuload(ppufile);
  287. ibenumdef : def:=tenumdef.ppuload(ppufile);
  288. ibsetdef : def:=tsetdef.ppuload(ppufile);
  289. ibprocvardef : def:=tprocvardef.ppuload(ppufile);
  290. ibfiledef : def:=tfiledef.ppuload(ppufile);
  291. ibclassrefdef : def:=tclassrefdef.ppuload(ppufile);
  292. ibformaldef : def:=tformaldef.ppuload(ppufile);
  293. ibvariantdef : def:=tvariantdef.ppuload(ppufile);
  294. ibundefineddef : def:=tundefineddef.ppuload(ppufile);
  295. ibenddefs : break;
  296. ibend : Message(unit_f_ppu_read_error);
  297. else
  298. Message1(unit_f_ppu_invalid_entry,tostr(b));
  299. end;
  300. InsertDef(def);
  301. until false;
  302. end;
  303. procedure tstoredsymtable.loadsyms(ppufile:tcompilerppufile);
  304. var
  305. b : byte;
  306. sym : tsym;
  307. begin
  308. { load start of definition section, which holds the amount of defs }
  309. if ppufile.readentry<>ibstartsyms then
  310. Message(unit_f_ppu_read_error);
  311. { now read the symbols }
  312. repeat
  313. b:=ppufile.readentry;
  314. case b of
  315. ibtypesym : sym:=ttypesym.ppuload(ppufile);
  316. ibprocsym : sym:=tprocsym.ppuload(ppufile);
  317. ibconstsym : sym:=tconstsym.ppuload(ppufile);
  318. ibstaticvarsym : sym:=tstaticvarsym.ppuload(ppufile);
  319. iblocalvarsym : sym:=tlocalvarsym.ppuload(ppufile);
  320. ibparavarsym : sym:=tparavarsym.ppuload(ppufile);
  321. ibfieldvarsym : sym:=tfieldvarsym.ppuload(ppufile);
  322. ibabsolutevarsym : sym:=tabsolutevarsym.ppuload(ppufile);
  323. ibenumsym : sym:=tenumsym.ppuload(ppufile);
  324. ibpropertysym : sym:=tpropertysym.ppuload(ppufile);
  325. ibunitsym : sym:=tunitsym.ppuload(ppufile);
  326. iblabelsym : sym:=tlabelsym.ppuload(ppufile);
  327. ibsyssym : sym:=tsyssym.ppuload(ppufile);
  328. ibmacrosym : sym:=tmacro.ppuload(ppufile);
  329. ibendsyms : break;
  330. ibend : Message(unit_f_ppu_read_error);
  331. else
  332. Message1(unit_f_ppu_invalid_entry,tostr(b));
  333. end;
  334. Insert(sym,false);
  335. until false;
  336. end;
  337. procedure tstoredsymtable.writedefs(ppufile:tcompilerppufile);
  338. var
  339. i : longint;
  340. def : tstoreddef;
  341. begin
  342. { each definition get a number, write then the amount of defs to the
  343. ibstartdef entry }
  344. ppufile.putlongint(DefList.count);
  345. ppufile.writeentry(ibstartdefs);
  346. { now write the definition }
  347. for i:=0 to DefList.Count-1 do
  348. begin
  349. def:=tstoreddef(DefList[i]);
  350. def.ppuwrite(ppufile);
  351. end;
  352. { write end of definitions }
  353. ppufile.writeentry(ibenddefs);
  354. end;
  355. procedure tstoredsymtable.writesyms(ppufile:tcompilerppufile);
  356. var
  357. i : longint;
  358. sym : Tstoredsym;
  359. begin
  360. { each definition get a number, write then the amount of syms and the
  361. datasize to the ibsymdef entry }
  362. ppufile.putlongint(SymList.count);
  363. ppufile.writeentry(ibstartsyms);
  364. { foreach is used to write all symbols }
  365. for i:=0 to SymList.Count-1 do
  366. begin
  367. sym:=tstoredsym(SymList[i]);
  368. sym.ppuwrite(ppufile);
  369. end;
  370. { end of symbols }
  371. ppufile.writeentry(ibendsyms);
  372. end;
  373. procedure tstoredsymtable.buildderef;
  374. var
  375. i : longint;
  376. def : tstoreddef;
  377. sym : tstoredsym;
  378. begin
  379. { interface definitions }
  380. for i:=0 to DefList.Count-1 do
  381. begin
  382. def:=tstoreddef(DefList[i]);
  383. def.buildderef;
  384. end;
  385. { interface symbols }
  386. for i:=0 to SymList.Count-1 do
  387. begin
  388. sym:=tstoredsym(SymList[i]);
  389. sym.buildderef;
  390. end;
  391. end;
  392. procedure tstoredsymtable.buildderefimpl;
  393. var
  394. i : longint;
  395. def : tstoreddef;
  396. begin
  397. { implementation definitions }
  398. for i:=0 to DefList.Count-1 do
  399. begin
  400. def:=tstoreddef(DefList[i]);
  401. def.buildderefimpl;
  402. end;
  403. end;
  404. procedure tstoredsymtable.deref;
  405. var
  406. i : longint;
  407. def : tstoreddef;
  408. sym : tstoredsym;
  409. begin
  410. { first deref the interface ttype symbols. This is needs
  411. to be done before the interface defs are derefed, because
  412. the interface defs can contain references to the type symbols
  413. which then already need to contain a resolved typedef field (PFV) }
  414. for i:=0 to SymList.Count-1 do
  415. begin
  416. sym:=tstoredsym(SymList[i]);
  417. if sym.typ=typesym then
  418. sym.deref;
  419. end;
  420. { interface definitions }
  421. for i:=0 to DefList.Count-1 do
  422. begin
  423. def:=tstoreddef(DefList[i]);
  424. def.deref;
  425. end;
  426. { interface symbols }
  427. for i:=0 to SymList.Count-1 do
  428. begin
  429. sym:=tstoredsym(SymList[i]);
  430. if sym.typ<>typesym then
  431. sym.deref;
  432. end;
  433. end;
  434. procedure tstoredsymtable.derefimpl;
  435. var
  436. i : longint;
  437. def : tstoreddef;
  438. begin
  439. { implementation definitions }
  440. for i:=0 to DefList.Count-1 do
  441. begin
  442. def:=tstoreddef(DefList[i]);
  443. def.derefimpl;
  444. end;
  445. end;
  446. function tstoredsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  447. var
  448. hsym : tsym;
  449. begin
  450. hsym:=tsym(FindWithHash(hashedid));
  451. if assigned(hsym) then
  452. DuplicateSym(hashedid,sym,hsym);
  453. result:=assigned(hsym);
  454. end;
  455. {**************************************
  456. Callbacks
  457. **************************************}
  458. procedure TStoredSymtable.check_forward(sym:TObject;arg:pointer);
  459. begin
  460. if tsym(sym).typ=procsym then
  461. tprocsym(sym).check_forward
  462. { check also object method table }
  463. { we needn't to test the def list }
  464. { because each object has to have a type sym,
  465. only test objects declarations, not type renamings }
  466. else
  467. if (tsym(sym).typ=typesym) and
  468. assigned(ttypesym(sym).typedef) and
  469. (ttypesym(sym).typedef.typesym=ttypesym(sym)) and
  470. (ttypesym(sym).typedef.typ=objectdef) then
  471. tobjectdef(ttypesym(sym).typedef).check_forwards;
  472. end;
  473. procedure TStoredSymtable.labeldefined(sym:TObject;arg:pointer);
  474. begin
  475. if (tsym(sym).typ=labelsym) and
  476. not(tlabelsym(sym).defined) then
  477. begin
  478. if tlabelsym(sym).used then
  479. Message1(sym_e_label_used_and_not_defined,tlabelsym(sym).realname)
  480. else
  481. Message1(sym_w_label_not_defined,tlabelsym(sym).realname);
  482. end;
  483. end;
  484. procedure TStoredSymtable.varsymbolused(sym:TObject;arg:pointer);
  485. begin
  486. if (tsym(sym).typ in [staticvarsym,localvarsym,paravarsym,fieldvarsym]) and
  487. ((tsym(sym).owner.symtabletype in
  488. [parasymtable,localsymtable,ObjectSymtable,staticsymtable])) then
  489. begin
  490. { unused symbol should be reported only if no }
  491. { error is reported }
  492. { if the symbol is in a register it is used }
  493. { also don't count the value parameters which have local copies }
  494. { also don't claim for high param of open parameters (PM) }
  495. if (Errorcount<>0) or
  496. ([vo_is_hidden_para,vo_is_funcret] * tabstractvarsym(sym).varoptions = [vo_is_hidden_para]) then
  497. exit;
  498. if (tstoredsym(sym).refs=0) then
  499. begin
  500. if (vo_is_funcret in tabstractvarsym(sym).varoptions) then
  501. begin
  502. { don't warn about the result of constructors }
  503. if ((tsym(sym).owner.symtabletype<>localsymtable) or
  504. (tprocdef(tsym(sym).owner.defowner).proctypeoption<>potype_constructor)) and
  505. not(cs_opt_nodedfa in current_settings.optimizerswitches) then
  506. MessagePos(tsym(sym).fileinfo,sym_w_function_result_not_set)
  507. end
  508. else if (tsym(sym).owner.symtabletype=parasymtable) then
  509. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_not_used,tsym(sym).realname)
  510. else if (tsym(sym).owner.symtabletype=ObjectSymtable) then
  511. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_not_used,tsym(sym).owner.realname^,tsym(sym).realname)
  512. else
  513. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_not_used,tsym(sym).realname);
  514. end
  515. else if tabstractvarsym(sym).varstate in [vs_written,vs_initialised] then
  516. begin
  517. if (tsym(sym).owner.symtabletype=parasymtable) then
  518. begin
  519. if not(tabstractvarsym(sym).varspez in [vs_var,vs_out]) and
  520. not(vo_is_funcret in tabstractvarsym(sym).varoptions) then
  521. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_only_set,tsym(sym).realname)
  522. end
  523. else if (tsym(sym).owner.symtabletype=ObjectSymtable) then
  524. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_only_set,tsym(sym).owner.realname^,tsym(sym).realname)
  525. else if tabstractvarsym(sym).varoptions*[vo_is_funcret,vo_is_public,vo_is_external]=[] then
  526. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_only_set,tsym(sym).realname);
  527. end
  528. else if (tabstractvarsym(sym).varstate = vs_read_not_warned) and
  529. ([vo_is_public,vo_is_external] * tabstractvarsym(sym).varoptions = []) then
  530. MessagePos1(tsym(sym).fileinfo,sym_w_identifier_only_read,tsym(sym).realname)
  531. end
  532. else if ((tsym(sym).owner.symtabletype in
  533. [ObjectSymtable,parasymtable,localsymtable,staticsymtable])) then
  534. begin
  535. if (Errorcount<>0) or
  536. (sp_internal in tsym(sym).symoptions) then
  537. exit;
  538. { do not claim for inherited private fields !! }
  539. if (Tsym(sym).refs=0) and (tsym(sym).owner.symtabletype=ObjectSymtable) then
  540. MessagePos2(tsym(sym).fileinfo,sym_n_private_method_not_used,tsym(sym).owner.realname^,tsym(sym).realname)
  541. { units references are problematic }
  542. else
  543. begin
  544. if (Tsym(sym).refs=0) and
  545. not(tsym(sym).typ in [enumsym,unitsym]) and
  546. not(is_funcret_sym(tsym(sym))) and
  547. (
  548. (tsym(sym).typ<>procsym) or
  549. ((tsym(sym).owner.symtabletype=staticsymtable) and
  550. not current_module.is_unit)
  551. ) then
  552. MessagePos2(tsym(sym).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(sym).typ],tsym(sym).realname);
  553. end;
  554. end;
  555. end;
  556. procedure TStoredSymtable.TestPrivate(sym:TObject;arg:pointer);
  557. begin
  558. if tsym(sym).visibility=vis_private then
  559. varsymbolused(sym,arg);
  560. end;
  561. procedure TStoredSymtable.objectprivatesymbolused(sym:TObject;arg:pointer);
  562. begin
  563. {
  564. Don't test simple object aliases PM
  565. }
  566. if (tsym(sym).typ=typesym) and
  567. (ttypesym(sym).typedef.typ=objectdef) and
  568. (ttypesym(sym).typedef.typesym=tsym(sym)) then
  569. tobjectdef(ttypesym(sym).typedef).symtable.SymList.ForEachCall(@TestPrivate,nil);
  570. end;
  571. procedure tstoredsymtable.testfordefaultproperty(sym:TObject;arg:pointer);
  572. begin
  573. if (tsym(sym).typ=propertysym) and
  574. (ppo_defaultproperty in tpropertysym(sym).propoptions) then
  575. ppointer(arg)^:=sym;
  576. end;
  577. {***********************************************
  578. Process all entries
  579. ***********************************************}
  580. procedure Tstoredsymtable.reset_all_defs;
  581. var
  582. i : longint;
  583. def : tstoreddef;
  584. begin
  585. for i:=0 to DefList.Count-1 do
  586. begin
  587. def:=tstoreddef(DefList[i]);
  588. def.reset;
  589. end;
  590. end;
  591. { checks, if all procsyms and methods are defined }
  592. procedure tstoredsymtable.check_forwards;
  593. begin
  594. SymList.ForEachCall(@check_forward,nil);
  595. end;
  596. procedure tstoredsymtable.checklabels;
  597. begin
  598. SymList.ForEachCall(@labeldefined,nil);
  599. end;
  600. procedure tstoredsymtable.allsymbolsused;
  601. begin
  602. SymList.ForEachCall(@varsymbolused,nil);
  603. end;
  604. procedure tstoredsymtable.allprivatesused;
  605. begin
  606. SymList.ForEachCall(@objectprivatesymbolused,nil);
  607. end;
  608. procedure TStoredSymtable._needs_init_final(sym:TObject;arg:pointer);
  609. begin
  610. if b_needs_init_final then
  611. exit;
  612. case tsym(sym).typ of
  613. fieldvarsym,
  614. staticvarsym,
  615. localvarsym,
  616. paravarsym :
  617. begin
  618. if not(is_class(tabstractvarsym(sym).vardef)) and
  619. tstoreddef(tabstractvarsym(sym).vardef).needs_inittable then
  620. b_needs_init_final:=true;
  621. end;
  622. end;
  623. end;
  624. { returns true, if p contains data which needs init/final code }
  625. function tstoredsymtable.needs_init_final : boolean;
  626. begin
  627. b_needs_init_final:=false;
  628. SymList.ForEachCall(@_needs_init_final,nil);
  629. needs_init_final:=b_needs_init_final;
  630. end;
  631. {****************************************************************************
  632. TAbstractRecordSymtable
  633. ****************************************************************************}
  634. constructor tabstractrecordsymtable.create(const n:string;usealign:shortint);
  635. begin
  636. inherited create(n);
  637. _datasize:=0;
  638. databitsize:=0;
  639. recordalignment:=1;
  640. usefieldalignment:=usealign;
  641. padalignment:=1;
  642. { recordalign C_alignment means C record packing, that starts
  643. with an alignment of 1 }
  644. case usealign of
  645. C_alignment,
  646. bit_alignment:
  647. fieldalignment:=1
  648. else
  649. fieldalignment:=usealign;
  650. end;
  651. end;
  652. procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
  653. begin
  654. inherited ppuload(ppufile);
  655. end;
  656. procedure tabstractrecordsymtable.ppuwrite(ppufile:tcompilerppufile);
  657. var
  658. oldtyp : byte;
  659. begin
  660. oldtyp:=ppufile.entrytyp;
  661. ppufile.entrytyp:=subentryid;
  662. inherited ppuwrite(ppufile);
  663. ppufile.entrytyp:=oldtyp;
  664. end;
  665. function field2recordalignment(fieldoffs, fieldalign: aint): aint;
  666. begin
  667. { optimal alignment of the record when declaring a variable of this }
  668. { type is independent of the packrecords setting }
  669. if (fieldoffs mod fieldalign) = 0 then
  670. result:=fieldalign
  671. else if (fieldalign >= 16) and
  672. ((fieldoffs mod 16) = 0) and
  673. ((fieldalign mod 16) = 0) then
  674. result:=16
  675. else if (fieldalign >= 8) and
  676. ((fieldoffs mod 8) = 0) and
  677. ((fieldalign mod 8) = 0) then
  678. result:=8
  679. else if (fieldalign >= 4) and
  680. ((fieldoffs mod 4) = 0) and
  681. ((fieldalign mod 4) = 0) then
  682. result:=4
  683. else if (fieldalign >= 2) and
  684. ((fieldoffs mod 2) = 0) and
  685. ((fieldalign mod 2) = 0) then
  686. result:=2
  687. else
  688. result:=1;
  689. end;
  690. procedure tabstractrecordsymtable.alignrecord(fieldoffset:aint;varalign:shortint);
  691. var
  692. varalignrecord: shortint;
  693. begin
  694. if (usefieldalignment=C_alignment) then
  695. varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign)
  696. else
  697. varalignrecord:=field2recordalignment(fieldoffset,varalign);
  698. recordalignment:=max(recordalignment,varalignrecord);
  699. end;
  700. procedure tabstractrecordsymtable.addfield(sym:tfieldvarsym;vis:tvisibility);
  701. var
  702. l : aint;
  703. varalignfield,
  704. varalign : shortint;
  705. vardef : tdef;
  706. begin
  707. if (sym.owner<>self) then
  708. internalerror(200602031);
  709. if sym.fieldoffset<>-1 then
  710. internalerror(200602032);
  711. { set visibility for the symbol }
  712. sym.visibility:=vis;
  713. { this symbol can't be loaded to a register }
  714. sym.varregable:=vr_none;
  715. { Calculate field offset }
  716. l:=sym.getsize;
  717. vardef:=sym.vardef;
  718. varalign:=vardef.alignment;
  719. if (usefieldalignment=bit_alignment) then
  720. begin
  721. { bitpacking only happens for ordinals, the rest is aligned at }
  722. { 1 byte (compatible with GPC/GCC) }
  723. if is_ordinal(vardef) then
  724. begin
  725. sym.fieldoffset:=databitsize;
  726. l:=sym.getpackedbitsize;
  727. end
  728. else
  729. begin
  730. databitsize:=_datasize*8;
  731. sym.fieldoffset:=databitsize;
  732. if (l>high(aint) div 8) then
  733. Message(sym_e_segment_too_large);
  734. l:=l*8;
  735. end;
  736. if varalign=0 then
  737. varalign:=size_2_align(l);
  738. recordalignment:=max(recordalignment,field2recordalignment(databitsize mod 8,varalign));
  739. { bit packed records are limited to high(aint) bits }
  740. { instead of bytes to avoid double precision }
  741. { arithmetic in offset calculations }
  742. if int64(l)>high(aint)-sym.fieldoffset then
  743. begin
  744. Message(sym_e_segment_too_large);
  745. _datasize:=high(aint);
  746. databitsize:=high(aint);
  747. end
  748. else
  749. begin
  750. databitsize:=sym.fieldoffset+l;
  751. _datasize:=(databitsize+7) div 8;
  752. end;
  753. { rest is not applicable }
  754. exit;
  755. end;
  756. { Calc the alignment size for C style records }
  757. if (usefieldalignment=C_alignment) then
  758. begin
  759. if (varalign>4) and
  760. ((varalign mod 4)<>0) and
  761. (vardef.typ=arraydef) then
  762. Message1(sym_w_wrong_C_pack,vardef.typename);
  763. if varalign=0 then
  764. varalign:=l;
  765. if (fieldalignment<current_settings.alignment.maxCrecordalign) then
  766. begin
  767. if (varalign>16) and (fieldalignment<32) then
  768. fieldalignment:=32
  769. else if (varalign>12) and (fieldalignment<16) then
  770. fieldalignment:=16
  771. { 12 is needed for long double }
  772. else if (varalign>8) and (fieldalignment<12) then
  773. fieldalignment:=12
  774. else if (varalign>4) and (fieldalignment<8) then
  775. fieldalignment:=8
  776. else if (varalign>2) and (fieldalignment<4) then
  777. fieldalignment:=4
  778. else if (varalign>1) and (fieldalignment<2) then
  779. fieldalignment:=2;
  780. end;
  781. fieldalignment:=min(fieldalignment,current_settings.alignment.maxCrecordalign);
  782. end;
  783. if varalign=0 then
  784. varalign:=size_2_align(l);
  785. varalignfield:=used_align(varalign,current_settings.alignment.recordalignmin,fieldalignment);
  786. sym.fieldoffset:=align(_datasize,varalignfield);
  787. if l>high(aint)-sym.fieldoffset then
  788. begin
  789. Message(sym_e_segment_too_large);
  790. _datasize:=high(aint);
  791. end
  792. else
  793. _datasize:=sym.fieldoffset+l;
  794. { Calc alignment needed for this record }
  795. alignrecord(sym.fieldoffset,varalign);
  796. end;
  797. procedure tabstractrecordsymtable.addalignmentpadding;
  798. begin
  799. { make the record size aligned correctly so it can be
  800. used as elements in an array. For C records we
  801. use the fieldalignment, because that is updated with the
  802. used alignment. }
  803. if (padalignment = 1) then
  804. case usefieldalignment of
  805. C_alignment:
  806. padalignment:=fieldalignment;
  807. { bitpacked }
  808. bit_alignment:
  809. padalignment:=1;
  810. { default/no packrecords specified }
  811. 0:
  812. padalignment:=recordalignment
  813. { specific packrecords setting -> use as upper limit }
  814. else
  815. padalignment:=min(recordalignment,usefieldalignment);
  816. end;
  817. _datasize:=align(_datasize,padalignment);
  818. end;
  819. procedure tabstractrecordsymtable.insertdef(def:TDefEntry);
  820. begin
  821. { Enums must also be available outside the record scope,
  822. insert in the owner of this symtable }
  823. if def.typ=enumdef then
  824. defowner.owner.insertdef(def)
  825. else
  826. inherited insertdef(def);
  827. end;
  828. function tabstractrecordsymtable.is_packed: boolean;
  829. begin
  830. result:=usefieldalignment=bit_alignment;
  831. end;
  832. procedure tabstractrecordsymtable.setdatasize(val: aint);
  833. begin
  834. _datasize:=val;
  835. if (usefieldalignment=bit_alignment) then
  836. { can overflow in non bitpacked records }
  837. databitsize:=val*8;
  838. end;
  839. {****************************************************************************
  840. TRecordSymtable
  841. ****************************************************************************}
  842. constructor trecordsymtable.create(usealign:shortint);
  843. begin
  844. inherited create('',usealign);
  845. symtabletype:=recordsymtable;
  846. end;
  847. { this procedure is reserved for inserting case variant into
  848. a record symtable }
  849. { the offset is the location of the start of the variant
  850. and datasize and dataalignment corresponds to
  851. the complete size (see code in pdecl unit) PM }
  852. procedure trecordsymtable.insertunionst(unionst : trecordsymtable;offset : longint);
  853. var
  854. sym : tsym;
  855. def : tdef;
  856. i : integer;
  857. varalignrecord,varalign,
  858. storesize,storealign : aint;
  859. bitsize: aint;
  860. begin
  861. storesize:=_datasize;
  862. storealign:=fieldalignment;
  863. _datasize:=offset;
  864. if (usefieldalignment=bit_alignment) then
  865. databitsize:=offset*8;
  866. { We move the ownership of the defs and symbols to the new recordsymtable.
  867. The old unionsymtable keeps the references, but doesn't own the
  868. objects anymore }
  869. unionst.DefList.OwnsObjects:=false;
  870. unionst.SymList.OwnsObjects:=false;
  871. { copy symbols }
  872. for i:=0 to unionst.SymList.Count-1 do
  873. begin
  874. sym:=TSym(unionst.SymList[i]);
  875. if sym.typ<>fieldvarsym then
  876. internalerror(200601272);
  877. { add to this record symtable }
  878. // unionst.SymList.List.List^[i].Data:=nil;
  879. sym.ChangeOwner(self);
  880. varalign:=tfieldvarsym(sym).vardef.alignment;
  881. if varalign=0 then
  882. varalign:=size_2_align(tfieldvarsym(sym).getsize);
  883. { retrieve size }
  884. if (usefieldalignment=bit_alignment) then
  885. begin
  886. { bit packed records are limited to high(aint) bits }
  887. { instead of bytes to avoid double precision }
  888. { arithmetic in offset calculations }
  889. if is_ordinal(tfieldvarsym(sym).vardef) then
  890. bitsize:=tfieldvarsym(sym).getpackedbitsize
  891. else
  892. begin
  893. bitsize:=tfieldvarsym(sym).getsize;
  894. if (bitsize>high(aint) div 8) then
  895. Message(sym_e_segment_too_large);
  896. bitsize:=bitsize*8;
  897. end;
  898. if bitsize>high(aint)-databitsize then
  899. begin
  900. Message(sym_e_segment_too_large);
  901. _datasize:=high(aint);
  902. databitsize:=high(aint);
  903. end
  904. else
  905. begin
  906. databitsize:=tfieldvarsym(sym).fieldoffset+offset*8;
  907. _datasize:=(databitsize+7) div 8;
  908. end;
  909. tfieldvarsym(sym).fieldoffset:=databitsize;
  910. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset div 8,varalign);
  911. end
  912. else
  913. begin
  914. if tfieldvarsym(sym).getsize>high(aint)-_datasize then
  915. begin
  916. Message(sym_e_segment_too_large);
  917. _datasize:=high(aint);
  918. end
  919. else
  920. _datasize:=tfieldvarsym(sym).fieldoffset+offset;
  921. { update address }
  922. tfieldvarsym(sym).fieldoffset:=_datasize;
  923. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset,varalign);
  924. end;
  925. { update alignment of this record }
  926. if (usefieldalignment<>C_alignment) then
  927. recordalignment:=max(recordalignment,varalignrecord);
  928. end;
  929. { update alignment for C records }
  930. if (usefieldalignment=C_alignment) then
  931. recordalignment:=max(recordalignment,unionst.recordalignment);
  932. { Register defs in the new record symtable }
  933. for i:=0 to unionst.DefList.Count-1 do
  934. begin
  935. def:=TDef(unionst.DefList[i]);
  936. def.ChangeOwner(self);
  937. end;
  938. _datasize:=storesize;
  939. fieldalignment:=storealign;
  940. end;
  941. {****************************************************************************
  942. TObjectSymtable
  943. ****************************************************************************}
  944. constructor tObjectSymtable.create(adefowner:tdef;const n:string;usealign:shortint);
  945. begin
  946. inherited create(n,usealign);
  947. symtabletype:=ObjectSymtable;
  948. defowner:=adefowner;
  949. end;
  950. function tObjectSymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  951. var
  952. hsym : tsym;
  953. begin
  954. result:=false;
  955. if not assigned(defowner) then
  956. internalerror(200602061);
  957. { procsym and propertysym have special code
  958. to override values in inherited classes. For other
  959. symbols check for duplicates }
  960. if not(sym.typ in [procsym,propertysym]) then
  961. begin
  962. { but private ids can be reused }
  963. hsym:=search_class_member(tobjectdef(defowner),hashedid.id);
  964. if assigned(hsym) and
  965. (
  966. (
  967. not(m_delphi in current_settings.modeswitches) and
  968. is_visible_for_object(hsym,tobjectdef(defowner))
  969. ) or
  970. (
  971. { In Delphi, you can repeat members of a parent class. You can't }
  972. { do this for objects however, and you (obviouly) can't }
  973. { declare two fields with the same name in a single class }
  974. (m_delphi in current_settings.modeswitches) and
  975. (
  976. is_object(tdef(defowner)) or
  977. (hsym.owner = self)
  978. )
  979. )
  980. ) then
  981. begin
  982. DuplicateSym(hashedid,sym,hsym);
  983. result:=true;
  984. end;
  985. end
  986. else
  987. begin
  988. if not(m_duplicate_names in current_settings.modeswitches) then
  989. result:=inherited checkduplicate(hashedid,sym);
  990. end;
  991. end;
  992. {****************************************************************************
  993. TAbstractLocalSymtable
  994. ****************************************************************************}
  995. procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
  996. var
  997. oldtyp : byte;
  998. begin
  999. oldtyp:=ppufile.entrytyp;
  1000. ppufile.entrytyp:=subentryid;
  1001. { write definitions }
  1002. writedefs(ppufile);
  1003. { write symbols }
  1004. writesyms(ppufile);
  1005. ppufile.entrytyp:=oldtyp;
  1006. end;
  1007. function tabstractlocalsymtable.count_locals:longint;
  1008. var
  1009. i : longint;
  1010. sym : tsym;
  1011. begin
  1012. result:=0;
  1013. for i:=0 to SymList.Count-1 do
  1014. begin
  1015. sym:=tsym(SymList[i]);
  1016. { Count only varsyms, but ignore the funcretsym }
  1017. if (tsym(sym).typ in [localvarsym,paravarsym]) and
  1018. (tsym(sym)<>current_procinfo.procdef.funcretsym) and
  1019. (not(vo_is_parentfp in tabstractvarsym(sym).varoptions) or
  1020. (tstoredsym(sym).refs>0)) then
  1021. inc(result);
  1022. end;
  1023. end;
  1024. {****************************************************************************
  1025. TLocalSymtable
  1026. ****************************************************************************}
  1027. constructor tlocalsymtable.create(adefowner:tdef;level:byte);
  1028. begin
  1029. inherited create('');
  1030. defowner:=adefowner;
  1031. symtabletype:=localsymtable;
  1032. symtablelevel:=level;
  1033. end;
  1034. function tlocalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1035. var
  1036. hsym : tsym;
  1037. begin
  1038. if not assigned(defowner) or
  1039. (defowner.typ<>procdef) then
  1040. internalerror(200602042);
  1041. result:=false;
  1042. hsym:=tsym(FindWithHash(hashedid));
  1043. if assigned(hsym) then
  1044. begin
  1045. { a local and the function can have the same
  1046. name in TP and Delphi, but RESULT not }
  1047. if (m_duplicate_names in current_settings.modeswitches) and
  1048. (hsym.typ in [absolutevarsym,localvarsym]) and
  1049. (vo_is_funcret in tabstractvarsym(hsym).varoptions) and
  1050. not((m_result in current_settings.modeswitches) and
  1051. (vo_is_result in tabstractvarsym(hsym).varoptions)) then
  1052. HideSym(hsym)
  1053. else
  1054. DuplicateSym(hashedid,sym,hsym);
  1055. result:=true;
  1056. exit;
  1057. end;
  1058. { check also parasymtable, this needs to be done here becuase
  1059. of the special situation with the funcret sym that needs to be
  1060. hidden for tp and delphi modes }
  1061. hsym:=tsym(tabstractprocdef(defowner).parast.FindWithHash(hashedid));
  1062. if assigned(hsym) then
  1063. begin
  1064. { a local and the function can have the same
  1065. name in TP and Delphi, but RESULT not }
  1066. if (m_duplicate_names in current_settings.modeswitches) and
  1067. (sym.typ in [absolutevarsym,localvarsym]) and
  1068. (vo_is_funcret in tabstractvarsym(sym).varoptions) and
  1069. not((m_result in current_settings.modeswitches) and
  1070. (vo_is_result in tabstractvarsym(sym).varoptions)) then
  1071. Hidesym(sym)
  1072. else
  1073. DuplicateSym(hashedid,sym,hsym);
  1074. result:=true;
  1075. exit;
  1076. end;
  1077. { check ObjectSymtable, skip this for funcret sym because
  1078. that will always be positive because it has the same name
  1079. as the procsym }
  1080. if not is_funcret_sym(sym) and
  1081. (defowner.typ=procdef) and
  1082. assigned(tprocdef(defowner)._class) and
  1083. (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) and
  1084. (
  1085. not(m_delphi in current_settings.modeswitches) or
  1086. is_object(tprocdef(defowner)._class)
  1087. ) then
  1088. result:=tprocdef(defowner)._class.symtable.checkduplicate(hashedid,sym);
  1089. end;
  1090. {****************************************************************************
  1091. TParaSymtable
  1092. ****************************************************************************}
  1093. constructor tparasymtable.create(adefowner:tdef;level:byte);
  1094. begin
  1095. inherited create('');
  1096. defowner:=adefowner;
  1097. symtabletype:=parasymtable;
  1098. symtablelevel:=level;
  1099. end;
  1100. function tparasymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1101. begin
  1102. result:=inherited checkduplicate(hashedid,sym);
  1103. if result then
  1104. exit;
  1105. if not(m_duplicate_names in current_settings.modeswitches) and
  1106. (defowner.typ=procdef) and
  1107. assigned(tprocdef(defowner)._class) and
  1108. (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) and
  1109. (
  1110. not(m_delphi in current_settings.modeswitches) or
  1111. is_object(tprocdef(defowner)._class)
  1112. ) then
  1113. result:=tprocdef(defowner)._class.symtable.checkduplicate(hashedid,sym);
  1114. end;
  1115. {****************************************************************************
  1116. TAbstractUniTSymtable
  1117. ****************************************************************************}
  1118. constructor tabstractuniTSymtable.create(const n : string;id:word);
  1119. begin
  1120. inherited create(n);
  1121. moduleid:=id;
  1122. end;
  1123. function tabstractuniTSymtable.iscurrentunit:boolean;
  1124. begin
  1125. result:=assigned(current_module) and
  1126. (
  1127. (current_module.globalsymtable=self) or
  1128. (current_module.localsymtable=self)
  1129. );
  1130. end;
  1131. {****************************************************************************
  1132. TStaticSymtable
  1133. ****************************************************************************}
  1134. constructor tstaticsymtable.create(const n : string;id:word);
  1135. begin
  1136. inherited create(n,id);
  1137. symtabletype:=staticsymtable;
  1138. symtablelevel:=main_program_level;
  1139. end;
  1140. procedure tstaticsymtable.ppuload(ppufile:tcompilerppufile);
  1141. begin
  1142. inherited ppuload(ppufile);
  1143. { now we can deref the syms and defs }
  1144. deref;
  1145. end;
  1146. procedure tstaticsymtable.ppuwrite(ppufile:tcompilerppufile);
  1147. begin
  1148. inherited ppuwrite(ppufile);
  1149. end;
  1150. function tstaticsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1151. var
  1152. hsym : tsym;
  1153. begin
  1154. result:=false;
  1155. hsym:=tsym(FindWithHash(hashedid));
  1156. if assigned(hsym) then
  1157. begin
  1158. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1159. unit, the unit can then not be accessed anymore using
  1160. <unit>.<id>, so we can hide the symbol }
  1161. if (m_delphi in current_settings.modeswitches) and
  1162. (hsym.typ=symconst.unitsym) then
  1163. HideSym(hsym)
  1164. else
  1165. DuplicateSym(hashedid,sym,hsym);
  1166. result:=true;
  1167. exit;
  1168. end;
  1169. if (current_module.localsymtable=self) and
  1170. assigned(current_module.globalsymtable) then
  1171. result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(hashedid,sym);
  1172. end;
  1173. {****************************************************************************
  1174. TGlobalSymtable
  1175. ****************************************************************************}
  1176. constructor tglobalsymtable.create(const n : string;id:word);
  1177. begin
  1178. inherited create(n,id);
  1179. symtabletype:=globalsymtable;
  1180. symtablelevel:=main_program_level;
  1181. end;
  1182. procedure tglobalsymtable.ppuload(ppufile:tcompilerppufile);
  1183. begin
  1184. inherited ppuload(ppufile);
  1185. { now we can deref the syms and defs }
  1186. deref;
  1187. end;
  1188. procedure tglobalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1189. begin
  1190. { write the symtable entries }
  1191. inherited ppuwrite(ppufile);
  1192. end;
  1193. function tglobalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1194. var
  1195. hsym : tsym;
  1196. begin
  1197. result:=false;
  1198. hsym:=tsym(FindWithHash(hashedid));
  1199. if assigned(hsym) then
  1200. begin
  1201. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1202. unit, the unit can then not be accessed anymore using
  1203. <unit>.<id>, so we can hide the symbol }
  1204. if (m_delphi in current_settings.modeswitches) and
  1205. (hsym.typ=symconst.unitsym) then
  1206. HideSym(hsym)
  1207. else
  1208. DuplicateSym(hashedid,sym,hsym);
  1209. result:=true;
  1210. exit;
  1211. end;
  1212. end;
  1213. {****************************************************************************
  1214. TWITHSYMTABLE
  1215. ****************************************************************************}
  1216. constructor twithsymtable.create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  1217. begin
  1218. inherited create('');
  1219. symtabletype:=withsymtable;
  1220. withrefnode:=refnode;
  1221. { Replace SymList with the passed symlist }
  1222. SymList.free;
  1223. SymList:=ASymList;
  1224. defowner:=aowner;
  1225. end;
  1226. destructor twithsymtable.destroy;
  1227. begin
  1228. withrefnode.free;
  1229. { Disable SymList because we don't Own it }
  1230. SymList:=nil;
  1231. inherited destroy;
  1232. end;
  1233. procedure twithsymtable.clear;
  1234. begin
  1235. { remove no entry from a withsymtable as it is only a pointer to the
  1236. recorddef or objectdef symtable }
  1237. end;
  1238. procedure twithsymtable.insertdef(def:TDefEntry);
  1239. begin
  1240. { Definitions can't be registered in the withsymtable
  1241. because the withsymtable is removed after the with block.
  1242. We can't easily solve it here because the next symtable in the
  1243. stack is not known. }
  1244. internalerror(200602046);
  1245. end;
  1246. {****************************************************************************
  1247. TSTT_ExceptionSymtable
  1248. ****************************************************************************}
  1249. constructor tstt_excepTSymtable.create;
  1250. begin
  1251. inherited create('');
  1252. symtabletype:=stt_excepTSymtable;
  1253. end;
  1254. {****************************************************************************
  1255. TMacroSymtable
  1256. ****************************************************************************}
  1257. constructor tmacrosymtable.create(exported: boolean);
  1258. begin
  1259. inherited create('');
  1260. if exported then
  1261. symtabletype:=exportedmacrosymtable
  1262. else
  1263. symtabletype:=localmacrosymtable;
  1264. symtablelevel:=main_program_level;
  1265. end;
  1266. {*****************************************************************************
  1267. Helper Routines
  1268. *****************************************************************************}
  1269. function FullTypeName(def,otherdef:tdef):string;
  1270. var
  1271. s1,s2 : string;
  1272. begin
  1273. s1:=def.typename;
  1274. { When the names are the same try to include the unit name }
  1275. if assigned(otherdef) and
  1276. (def.owner.symtabletype in [globalsymtable,staticsymtable]) then
  1277. begin
  1278. s2:=otherdef.typename;
  1279. if upper(s1)=upper(s2) then
  1280. s1:=def.owner.realname^+'.'+s1;
  1281. end;
  1282. FullTypeName:=s1;
  1283. end;
  1284. procedure incompatibletypes(def1,def2:tdef);
  1285. begin
  1286. { When there is an errordef there is already an error message show }
  1287. if (def2.typ=errordef) or
  1288. (def1.typ=errordef) then
  1289. exit;
  1290. CGMessage2(type_e_incompatible_types,FullTypeName(def1,def2),FullTypeName(def2,def1));
  1291. end;
  1292. procedure hidesym(sym:TSymEntry);
  1293. begin
  1294. sym.realname:='$hidden'+sym.realname;
  1295. tsym(sym).visibility:=vis_hidden;
  1296. end;
  1297. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  1298. var
  1299. st : TSymtable;
  1300. begin
  1301. Message1(sym_e_duplicate_id,tsym(origsym).realname);
  1302. { Write hint where the original symbol was found }
  1303. st:=finduniTSymtable(origsym.owner);
  1304. with tsym(origsym).fileinfo do
  1305. begin
  1306. if assigned(st) and
  1307. (st.symtabletype=globalsymtable) and
  1308. st.iscurrentunit then
  1309. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line))
  1310. else if assigned(st.name) then
  1311. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line));
  1312. end;
  1313. { Rename duplicate sym to an unreachable name, but it can be
  1314. inserted in the symtable without errors }
  1315. inc(dupnr);
  1316. hashedid.id:='dup'+tostr(dupnr)+hashedid.id;
  1317. if assigned(dupsym) then
  1318. include(tsym(dupsym).symoptions,sp_implicitrename);
  1319. end;
  1320. {*****************************************************************************
  1321. Search
  1322. *****************************************************************************}
  1323. procedure addsymref(sym:tsym);
  1324. begin
  1325. { symbol uses count }
  1326. sym.IncRefCount;
  1327. { unit uses count }
  1328. if assigned(current_module) and
  1329. (sym.owner.symtabletype=globalsymtable) then
  1330. begin
  1331. if tglobalsymtable(sym.owner).moduleid>=current_module.unitmapsize then
  1332. internalerror(200501152);
  1333. inc(current_module.unitmap[tglobalsymtable(sym.owner).moduleid].refs);
  1334. end;
  1335. end;
  1336. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tobjectdef):boolean;
  1337. var
  1338. symownerdef : tobjectdef;
  1339. begin
  1340. result:=false;
  1341. { Get objdectdef owner of the symtable for the is_related checks }
  1342. if not assigned(symst) or
  1343. (symst.symtabletype<>objectsymtable) then
  1344. internalerror(200810285);
  1345. symownerdef:=tobjectdef(symst.defowner);
  1346. case symvisibility of
  1347. vis_private :
  1348. begin
  1349. { private symbols are allowed when we are in the same
  1350. module as they are defined }
  1351. result:=(symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1352. (symownerdef.owner.iscurrentunit);
  1353. end;
  1354. vis_strictprivate :
  1355. begin
  1356. result:=assigned(current_objectdef) and
  1357. (current_objectdef=symownerdef);
  1358. end;
  1359. vis_strictprotected :
  1360. begin
  1361. result:=assigned(current_objectdef) and
  1362. current_objectdef.is_related(symownerdef);
  1363. end;
  1364. vis_protected :
  1365. begin
  1366. { protected symbols are visible in the module that defines them and
  1367. also visible to related objects. The related object must be defined
  1368. in the current module }
  1369. result:=(
  1370. (
  1371. (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1372. (symownerdef.owner.iscurrentunit)
  1373. ) or
  1374. (
  1375. assigned(contextobjdef) and
  1376. (contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1377. (contextobjdef.owner.iscurrentunit) and
  1378. contextobjdef.is_related(symownerdef)
  1379. )
  1380. );
  1381. end;
  1382. vis_public,
  1383. vis_published :
  1384. result:=true;
  1385. end;
  1386. end;
  1387. function is_visible_for_object(pd:tprocdef;contextobjdef:tobjectdef):boolean;
  1388. begin
  1389. result:=is_visible_for_object(pd.owner,pd.visibility,contextobjdef);
  1390. end;
  1391. function is_visible_for_object(sym:tsym;contextobjdef:tobjectdef):boolean;
  1392. var
  1393. i : longint;
  1394. pd : tprocdef;
  1395. begin
  1396. if sym.typ=procsym then
  1397. begin
  1398. { A procsym is visible, when there is at least one of the procdefs visible }
  1399. result:=false;
  1400. for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
  1401. begin
  1402. pd:=tprocdef(tprocsym(sym).ProcdefList[i]);
  1403. if (pd.owner=sym.owner) and
  1404. is_visible_for_object(pd,contextobjdef) then
  1405. begin
  1406. result:=true;
  1407. exit;
  1408. end;
  1409. end;
  1410. end
  1411. else
  1412. result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
  1413. end;
  1414. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1415. var
  1416. hashedid : THashedIDString;
  1417. contextobjdef : tobjectdef;
  1418. stackitem : psymtablestackitem;
  1419. begin
  1420. result:=false;
  1421. hashedid.id:=s;
  1422. stackitem:=symtablestack.stack;
  1423. while assigned(stackitem) do
  1424. begin
  1425. srsymtable:=stackitem^.symtable;
  1426. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1427. if assigned(srsym) then
  1428. begin
  1429. { use the class from withsymtable only when it is
  1430. defined in this unit }
  1431. if (srsymtable.symtabletype=withsymtable) and
  1432. assigned(srsymtable.defowner) and
  1433. (srsymtable.defowner.typ=objectdef) and
  1434. (srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1435. (srsymtable.defowner.owner.iscurrentunit) then
  1436. contextobjdef:=tobjectdef(srsymtable.defowner)
  1437. else
  1438. contextobjdef:=current_objectdef;
  1439. if (srsym.owner.symtabletype<>objectsymtable) or
  1440. is_visible_for_object(srsym,contextobjdef) then
  1441. begin
  1442. { we need to know if a procedure references symbols
  1443. in the static symtable, because then it can't be
  1444. inlined from outside this unit }
  1445. if assigned(current_procinfo) and
  1446. (srsym.owner.symtabletype=staticsymtable) then
  1447. include(current_procinfo.flags,pi_uses_static_symtable);
  1448. addsymref(srsym);
  1449. result:=true;
  1450. exit;
  1451. end;
  1452. end;
  1453. stackitem:=stackitem^.next;
  1454. end;
  1455. srsym:=nil;
  1456. srsymtable:=nil;
  1457. end;
  1458. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1459. var
  1460. hashedid : THashedIDString;
  1461. stackitem : psymtablestackitem;
  1462. begin
  1463. result:=false;
  1464. hashedid.id:=s;
  1465. stackitem:=symtablestack.stack;
  1466. while assigned(stackitem) do
  1467. begin
  1468. {
  1469. It is not possible to have type symbols in:
  1470. records
  1471. objects
  1472. parameters
  1473. Exception are generic definitions and specializations
  1474. that have the parameterized types inserted in the symtable.
  1475. }
  1476. srsymtable:=stackitem^.symtable;
  1477. if not(srsymtable.symtabletype in [recordsymtable,ObjectSymtable,parasymtable]) or
  1478. (assigned(srsymtable.defowner) and
  1479. (
  1480. (df_generic in tdef(srsymtable.defowner).defoptions) or
  1481. (df_specialization in tdef(srsymtable.defowner).defoptions))
  1482. ) then
  1483. begin
  1484. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1485. if assigned(srsym) and
  1486. not(srsym.typ in [fieldvarsym,paravarsym]) and
  1487. (
  1488. (srsym.owner.symtabletype<>objectsymtable) or
  1489. is_visible_for_object(srsym,current_objectdef)
  1490. ) then
  1491. begin
  1492. { we need to know if a procedure references symbols
  1493. in the static symtable, because then it can't be
  1494. inlined from outside this unit }
  1495. if assigned(current_procinfo) and
  1496. (srsym.owner.symtabletype=staticsymtable) then
  1497. include(current_procinfo.flags,pi_uses_static_symtable);
  1498. addsymref(srsym);
  1499. result:=true;
  1500. exit;
  1501. end;
  1502. end;
  1503. stackitem:=stackitem^.next;
  1504. end;
  1505. result:=false;
  1506. srsym:=nil;
  1507. srsymtable:=nil;
  1508. end;
  1509. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1510. var
  1511. pmod : tmodule;
  1512. begin
  1513. pmod:=tmodule(pm);
  1514. result:=false;
  1515. if assigned(pmod.globalsymtable) then
  1516. begin
  1517. srsym:=tsym(pmod.globalsymtable.Find(s));
  1518. if assigned(srsym) then
  1519. begin
  1520. srsymtable:=pmod.globalsymtable;
  1521. addsymref(srsym);
  1522. result:=true;
  1523. exit;
  1524. end;
  1525. end;
  1526. { If the module is the current unit we also need
  1527. to search the local symtable }
  1528. if (pmod=current_module) and
  1529. assigned(pmod.localsymtable) then
  1530. begin
  1531. srsym:=tsym(pmod.localsymtable.Find(s));
  1532. if assigned(srsym) then
  1533. begin
  1534. srsymtable:=pmod.localsymtable;
  1535. addsymref(srsym);
  1536. result:=true;
  1537. exit;
  1538. end;
  1539. end;
  1540. srsym:=nil;
  1541. srsymtable:=nil;
  1542. end;
  1543. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1544. var
  1545. hashedid : THashedIDString;
  1546. begin
  1547. { The contextclassh is used for visibility. The classh must be equal to
  1548. or be a parent of contextclassh. E.g. for inherited searches the classh is the
  1549. parent. }
  1550. if assigned(classh) and
  1551. not contextclassh.is_related(classh) then
  1552. internalerror(200811161);
  1553. result:=false;
  1554. hashedid.id:=s;
  1555. while assigned(classh) do
  1556. begin
  1557. srsymtable:=classh.symtable;
  1558. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1559. if assigned(srsym) and
  1560. is_visible_for_object(srsym,contextclassh) then
  1561. begin
  1562. addsymref(srsym);
  1563. result:=true;
  1564. exit;
  1565. end;
  1566. classh:=classh.childof;
  1567. end;
  1568. srsym:=nil;
  1569. srsymtable:=nil;
  1570. end;
  1571. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1572. var
  1573. def : tdef;
  1574. i : longint;
  1575. begin
  1576. result:=false;
  1577. def:=nil;
  1578. while assigned(classh) do
  1579. begin
  1580. for i:=0 to classh.symtable.DefList.Count-1 do
  1581. begin
  1582. def:=tstoreddef(classh.symtable.DefList[i]);
  1583. { Find also all hidden private methods to
  1584. be compatible with delphi, see tw6203 (PFV) }
  1585. if (def.typ=procdef) and
  1586. (po_msgint in tprocdef(def).procoptions) and
  1587. (tprocdef(def).messageinf.i=msgid) then
  1588. begin
  1589. srdef:=def;
  1590. srsym:=tprocdef(def).procsym;
  1591. srsymtable:=classh.symtable;
  1592. addsymref(srsym);
  1593. result:=true;
  1594. exit;
  1595. end;
  1596. end;
  1597. classh:=classh.childof;
  1598. end;
  1599. srdef:=nil;
  1600. srsym:=nil;
  1601. srsymtable:=nil;
  1602. end;
  1603. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1604. var
  1605. def : tdef;
  1606. i : longint;
  1607. begin
  1608. result:=false;
  1609. def:=nil;
  1610. while assigned(classh) do
  1611. begin
  1612. for i:=0 to classh.symtable.DefList.Count-1 do
  1613. begin
  1614. def:=tstoreddef(classh.symtable.DefList[i]);
  1615. { Find also all hidden private methods to
  1616. be compatible with delphi, see tw6203 (PFV) }
  1617. if (def.typ=procdef) and
  1618. (po_msgstr in tprocdef(def).procoptions) and
  1619. (tprocdef(def).messageinf.str^=s) then
  1620. begin
  1621. srsym:=tprocdef(def).procsym;
  1622. srsymtable:=classh.symtable;
  1623. addsymref(srsym);
  1624. result:=true;
  1625. exit;
  1626. end;
  1627. end;
  1628. classh:=classh.childof;
  1629. end;
  1630. srsym:=nil;
  1631. srsymtable:=nil;
  1632. end;
  1633. function search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
  1634. var
  1635. sym : Tprocsym;
  1636. hashedid : THashedIDString;
  1637. curreq,
  1638. besteq : tequaltype;
  1639. currpd,
  1640. bestpd : tprocdef;
  1641. stackitem : psymtablestackitem;
  1642. begin
  1643. hashedid.id:='assign';
  1644. besteq:=te_incompatible;
  1645. bestpd:=nil;
  1646. stackitem:=symtablestack.stack;
  1647. while assigned(stackitem) do
  1648. begin
  1649. sym:=Tprocsym(stackitem^.symtable.FindWithHash(hashedid));
  1650. if sym<>nil then
  1651. begin
  1652. if sym.typ<>procsym then
  1653. internalerror(200402031);
  1654. { if the source type is an alias then this is only the second choice,
  1655. if you mess with this code, check tw4093 }
  1656. currpd:=sym.find_procdef_assignment_operator(from_def,to_def,curreq);
  1657. if curreq>besteq then
  1658. begin
  1659. besteq:=curreq;
  1660. bestpd:=currpd;
  1661. if (besteq=te_exact) then
  1662. break;
  1663. end;
  1664. end;
  1665. stackitem:=stackitem^.next;
  1666. end;
  1667. result:=bestpd;
  1668. end;
  1669. function search_system_type(const s: TIDString): ttypesym;
  1670. var
  1671. sym : tsym;
  1672. begin
  1673. sym:=tsym(systemunit.Find(s));
  1674. if not assigned(sym) or
  1675. (sym.typ<>typesym) then
  1676. cgmessage1(cg_f_unknown_system_type,s);
  1677. result:=ttypesym(sym);
  1678. end;
  1679. function search_class_member(pd : tobjectdef;const s : string):tsym;
  1680. { searches n in symtable of pd and all anchestors }
  1681. var
  1682. hashedid : THashedIDString;
  1683. srsym : tsym;
  1684. begin
  1685. hashedid.id:=s;
  1686. while assigned(pd) do
  1687. begin
  1688. srsym:=tsym(pd.symtable.FindWithHash(hashedid));
  1689. if assigned(srsym) then
  1690. begin
  1691. search_class_member:=srsym;
  1692. exit;
  1693. end;
  1694. pd:=pd.childof;
  1695. end;
  1696. search_class_member:=nil;
  1697. end;
  1698. function search_macro(const s : string):tsym;
  1699. var
  1700. stackitem : psymtablestackitem;
  1701. hashedid : THashedIDString;
  1702. srsym : tsym;
  1703. begin
  1704. hashedid.id:=s;
  1705. { First search the localmacrosymtable before searching the
  1706. global macrosymtables from the units }
  1707. if assigned(current_module) then
  1708. begin
  1709. srsym:=tsym(current_module.localmacrosymtable.FindWithHash(hashedid));
  1710. if assigned(srsym) then
  1711. begin
  1712. result:= srsym;
  1713. exit;
  1714. end;
  1715. end;
  1716. stackitem:=macrosymtablestack.stack;
  1717. while assigned(stackitem) do
  1718. begin
  1719. srsym:=tsym(stackitem^.symtable.FindWithHash(hashedid));
  1720. if assigned(srsym) then
  1721. begin
  1722. result:= srsym;
  1723. exit;
  1724. end;
  1725. stackitem:=stackitem^.next;
  1726. end;
  1727. result:= nil;
  1728. end;
  1729. function defined_macro(const s : string):boolean;
  1730. var
  1731. mac: tmacro;
  1732. begin
  1733. mac:=tmacro(search_macro(s));
  1734. if assigned(mac) then
  1735. begin
  1736. mac.is_used:=true;
  1737. defined_macro:=mac.defined;
  1738. end
  1739. else
  1740. defined_macro:=false;
  1741. end;
  1742. {****************************************************************************
  1743. Object Helpers
  1744. ****************************************************************************}
  1745. function search_default_property(pd : tobjectdef) : tpropertysym;
  1746. { returns the default property of a class, searches also anchestors }
  1747. var
  1748. _defaultprop : tpropertysym;
  1749. begin
  1750. _defaultprop:=nil;
  1751. while assigned(pd) do
  1752. begin
  1753. pd.symtable.SymList.ForEachCall(@tstoredsymtable(pd.symtable).testfordefaultproperty,@_defaultprop);
  1754. if assigned(_defaultprop) then
  1755. break;
  1756. pd:=pd.childof;
  1757. end;
  1758. search_default_property:=_defaultprop;
  1759. end;
  1760. {****************************************************************************
  1761. Macro Helpers
  1762. ****************************************************************************}
  1763. procedure def_system_macro(const name : string);
  1764. var
  1765. mac : tmacro;
  1766. s: string;
  1767. begin
  1768. if name = '' then
  1769. internalerror(2004121202);
  1770. s:= upper(name);
  1771. mac:=tmacro(search_macro(s));
  1772. if not assigned(mac) then
  1773. begin
  1774. mac:=tmacro.create(s);
  1775. if assigned(current_module) then
  1776. current_module.localmacrosymtable.insert(mac)
  1777. else
  1778. initialmacrosymtable.insert(mac);
  1779. end;
  1780. if not mac.defined then
  1781. Message1(parser_c_macro_defined,mac.name);
  1782. mac.defined:=true;
  1783. end;
  1784. procedure set_system_macro(const name, value : string);
  1785. var
  1786. mac : tmacro;
  1787. s: string;
  1788. begin
  1789. if name = '' then
  1790. internalerror(2004121203);
  1791. s:= upper(name);
  1792. mac:=tmacro(search_macro(s));
  1793. if not assigned(mac) then
  1794. begin
  1795. mac:=tmacro.create(s);
  1796. if assigned(current_module) then
  1797. current_module.localmacrosymtable.insert(mac)
  1798. else
  1799. initialmacrosymtable.insert(mac);
  1800. end
  1801. else
  1802. begin
  1803. mac.is_compiler_var:=false;
  1804. if assigned(mac.buftext) then
  1805. freemem(mac.buftext,mac.buflen);
  1806. end;
  1807. Message2(parser_c_macro_set_to,mac.name,value);
  1808. mac.buflen:=length(value);
  1809. getmem(mac.buftext,mac.buflen);
  1810. move(value[1],mac.buftext^,mac.buflen);
  1811. mac.defined:=true;
  1812. end;
  1813. procedure set_system_compvar(const name, value : string);
  1814. var
  1815. mac : tmacro;
  1816. s: string;
  1817. begin
  1818. if name = '' then
  1819. internalerror(2004121204);
  1820. s:= upper(name);
  1821. mac:=tmacro(search_macro(s));
  1822. if not assigned(mac) then
  1823. begin
  1824. mac:=tmacro.create(s);
  1825. mac.is_compiler_var:=true;
  1826. if assigned(current_module) then
  1827. current_module.localmacrosymtable.insert(mac)
  1828. else
  1829. initialmacrosymtable.insert(mac);
  1830. end
  1831. else
  1832. begin
  1833. mac.is_compiler_var:=true;
  1834. if assigned(mac.buftext) then
  1835. freemem(mac.buftext,mac.buflen);
  1836. end;
  1837. Message2(parser_c_macro_set_to,mac.name,value);
  1838. mac.buflen:=length(value);
  1839. getmem(mac.buftext,mac.buflen);
  1840. move(value[1],mac.buftext^,mac.buflen);
  1841. mac.defined:=true;
  1842. end;
  1843. procedure undef_system_macro(const name : string);
  1844. var
  1845. mac : tmacro;
  1846. s: string;
  1847. begin
  1848. if name = '' then
  1849. internalerror(2004121205);
  1850. s:= upper(name);
  1851. mac:=tmacro(search_macro(s));
  1852. if not assigned(mac) then
  1853. {If not found, then it's already undefined.}
  1854. else
  1855. begin
  1856. if mac.defined then
  1857. Message1(parser_c_macro_undefined,mac.name);
  1858. mac.defined:=false;
  1859. mac.is_compiler_var:=false;
  1860. { delete old definition }
  1861. if assigned(mac.buftext) then
  1862. begin
  1863. freemem(mac.buftext,mac.buflen);
  1864. mac.buftext:=nil;
  1865. end;
  1866. end;
  1867. end;
  1868. {$ifdef UNITALIASES}
  1869. {****************************************************************************
  1870. TUNIT_ALIAS
  1871. ****************************************************************************}
  1872. constructor tunit_alias.create(const n:string);
  1873. var
  1874. i : longint;
  1875. begin
  1876. i:=pos('=',n);
  1877. if i=0 then
  1878. fail;
  1879. inherited createname(Copy(n,1,i-1));
  1880. newname:=stringdup(Copy(n,i+1,255));
  1881. end;
  1882. destructor tunit_alias.destroy;
  1883. begin
  1884. stringdispose(newname);
  1885. inherited destroy;
  1886. end;
  1887. procedure addunitalias(const n:string);
  1888. begin
  1889. unitaliases^.insert(tunit_alias,init(Upper(n))));
  1890. end;
  1891. function getunitalias(const n:string):string;
  1892. var
  1893. p : punit_alias;
  1894. begin
  1895. p:=punit_alias(unitaliases^.Find(Upper(n)));
  1896. if assigned(p) then
  1897. getunitalias:=punit_alias(p).newname^
  1898. else
  1899. getunitalias:=n;
  1900. end;
  1901. {$endif UNITALIASES}
  1902. {****************************************************************************
  1903. Init/Done Symtable
  1904. ****************************************************************************}
  1905. procedure InitSymtable;
  1906. begin
  1907. { Reset symbolstack }
  1908. symtablestack:=nil;
  1909. systemunit:=nil;
  1910. { create error syms and def }
  1911. generrorsym:=terrorsym.create;
  1912. generrordef:=terrordef.create;
  1913. { macros }
  1914. initialmacrosymtable:=tmacrosymtable.create(false);
  1915. macrosymtablestack:=TSymtablestack.create;
  1916. macrosymtablestack.push(initialmacrosymtable);
  1917. {$ifdef UNITALIASES}
  1918. { unit aliases }
  1919. unitaliases:=TFPHashObjectList.create;
  1920. {$endif}
  1921. { set some global vars to nil, might be important for the ide }
  1922. class_tobject:=nil;
  1923. interface_iunknown:=nil;
  1924. rec_tguid:=nil;
  1925. dupnr:=0;
  1926. end;
  1927. procedure DoneSymtable;
  1928. begin
  1929. generrorsym.owner:=nil;
  1930. generrorsym.free;
  1931. generrordef.owner:=nil;
  1932. generrordef.free;
  1933. initialmacrosymtable.free;
  1934. macrosymtablestack.free;
  1935. {$ifdef UNITALIASES}
  1936. unitaliases.free;
  1937. {$endif}
  1938. end;
  1939. end.