symtable.pas 75 KB

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