symtable.pas 75 KB

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