2
0

symtable.pas 71 KB

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