symtable.pas 71 KB

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