symtable.pas 70 KB

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