symtable.pas 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291
  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. end
  592. else if ((tsym(p).owner.symtabletype in
  593. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  594. begin
  595. if (Errorcount<>0) or
  596. (sp_internal in tsym(p).symoptions) then
  597. exit;
  598. { do not claim for inherited private fields !! }
  599. if (Tsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
  600. MessagePos2(tsym(p).fileinfo,sym_n_private_method_not_used,tsym(p).owner.realname^,tsym(p).realname)
  601. { units references are problematic }
  602. else
  603. begin
  604. if (Tsym(p).refs=0) and
  605. not(tsym(p).typ in [enumsym,unitsym]) and
  606. not(is_funcret_sym(tsym(p))) and
  607. (
  608. (tsym(p).typ<>procsym) or
  609. ((tsym(p).owner.symtabletype=staticsymtable) and
  610. not current_module.is_unit)
  611. ) then
  612. MessagePos2(tsym(p).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(p).typ],tsym(p).realname);
  613. end;
  614. end;
  615. end;
  616. procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem;arg:pointer);
  617. begin
  618. if sp_private in tsym(p).symoptions then
  619. varsymbolused(p,arg);
  620. end;
  621. procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem;arg:pointer);
  622. begin
  623. {
  624. Don't test simple object aliases PM
  625. }
  626. if (tsym(p).typ=typesym) and
  627. (ttypesym(p).restype.def.deftype=objectdef) and
  628. (ttypesym(p).restype.def.typesym=tsym(p)) then
  629. tobjectdef(ttypesym(p).restype.def).symtable.foreach(@TestPrivate,nil);
  630. end;
  631. procedure tstoredsymtable.unchain_overloads(p : TNamedIndexItem;arg:pointer);
  632. begin
  633. if tsym(p).typ=procsym then
  634. tprocsym(p).unchain_overload;
  635. end;
  636. procedure Tstoredsymtable.reset_def(def:Tnamedindexitem;arg:pointer);
  637. begin
  638. Tstoreddef(def).reset;
  639. end;
  640. {***********************************************
  641. Process all entries
  642. ***********************************************}
  643. procedure Tstoredsymtable.reset_all_defs;
  644. begin
  645. defindex.foreach(@reset_def,nil);
  646. end;
  647. { checks, if all procsyms and methods are defined }
  648. procedure tstoredsymtable.check_forwards;
  649. begin
  650. foreach(@check_forward,nil);
  651. end;
  652. procedure tstoredsymtable.checklabels;
  653. begin
  654. foreach(@labeldefined,nil);
  655. end;
  656. procedure tstoredsymtable.allsymbolsused;
  657. begin
  658. foreach(@varsymbolused,nil);
  659. end;
  660. procedure tstoredsymtable.allprivatesused;
  661. begin
  662. foreach(@objectprivatesymbolused,nil);
  663. end;
  664. procedure tstoredsymtable.unchain_overloaded;
  665. begin
  666. foreach(@unchain_overloads,nil);
  667. end;
  668. procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
  669. begin
  670. if b_needs_init_final then
  671. exit;
  672. case tsym(p).typ of
  673. fieldvarsym,
  674. globalvarsym,
  675. localvarsym,
  676. paravarsym :
  677. begin
  678. if not(is_class(tabstractvarsym(p).vartype.def)) and
  679. tstoreddef(tabstractvarsym(p).vartype.def).needs_inittable then
  680. b_needs_init_final:=true;
  681. end;
  682. typedconstsym :
  683. begin
  684. if ttypedconstsym(p).is_writable and
  685. tstoreddef(ttypedconstsym(p).typedconsttype.def).needs_inittable then
  686. b_needs_init_final:=true;
  687. end;
  688. end;
  689. end;
  690. { returns true, if p contains data which needs init/final code }
  691. function tstoredsymtable.needs_init_final : boolean;
  692. begin
  693. b_needs_init_final:=false;
  694. foreach(@_needs_init_final,nil);
  695. needs_init_final:=b_needs_init_final;
  696. end;
  697. {****************************************************************************
  698. TAbstractRecordSymtable
  699. ****************************************************************************}
  700. constructor tabstractrecordsymtable.create(const n:string;usealign:shortint);
  701. begin
  702. inherited create(n);
  703. datasize:=0;
  704. recordalignment:=1;
  705. usefieldalignment:=usealign;
  706. padalignment:=1;
  707. { recordalign -1 means C record packing, that starts
  708. with an alignment of 1 }
  709. if usealign=-1 then
  710. fieldalignment:=1
  711. else
  712. fieldalignment:=usealign;
  713. end;
  714. procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
  715. var
  716. storesymtable : tsymtable;
  717. begin
  718. storesymtable:=aktrecordsymtable;
  719. aktrecordsymtable:=self;
  720. inherited ppuload(ppufile);
  721. aktrecordsymtable:=storesymtable;
  722. end;
  723. procedure tabstractrecordsymtable.ppuwrite(ppufile:tcompilerppufile);
  724. var
  725. oldtyp : byte;
  726. storesymtable : tsymtable;
  727. begin
  728. storesymtable:=aktrecordsymtable;
  729. aktrecordsymtable:=self;
  730. oldtyp:=ppufile.entrytyp;
  731. ppufile.entrytyp:=subentryid;
  732. inherited ppuwrite(ppufile);
  733. ppufile.entrytyp:=oldtyp;
  734. aktrecordsymtable:=storesymtable;
  735. end;
  736. procedure tabstractrecordsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  737. var
  738. storesymtable : tsymtable;
  739. begin
  740. storesymtable:=aktrecordsymtable;
  741. aktrecordsymtable:=self;
  742. inherited load_references(ppufile,locals);
  743. aktrecordsymtable:=storesymtable;
  744. end;
  745. procedure tabstractrecordsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  746. var
  747. storesymtable : tsymtable;
  748. begin
  749. storesymtable:=aktrecordsymtable;
  750. aktrecordsymtable:=self;
  751. inherited write_references(ppufile,locals);
  752. aktrecordsymtable:=storesymtable;
  753. end;
  754. procedure tabstractrecordsymtable.addfield(sym:tfieldvarsym);
  755. var
  756. l : aint;
  757. varalignrecord,
  758. varalignfield,
  759. varalign : longint;
  760. vardef : tdef;
  761. begin
  762. if (sym.owner<>self) then
  763. internalerror(200602031);
  764. if sym.fieldoffset<>-1 then
  765. internalerror(200602032);
  766. { this symbol can't be loaded to a register }
  767. sym.varregable:=vr_none;
  768. { Calculate field offset }
  769. l:=sym.getsize;
  770. vardef:=sym.vartype.def;
  771. varalign:=vardef.alignment;
  772. { Calc the alignment size for C style records }
  773. if (usefieldalignment=-1) then
  774. begin
  775. if (varalign>4) and
  776. ((varalign mod 4)<>0) and
  777. (vardef.deftype=arraydef) then
  778. Message1(sym_w_wrong_C_pack,vardef.typename);
  779. if varalign=0 then
  780. varalign:=l;
  781. if (fieldalignment<aktalignment.maxCrecordalign) then
  782. begin
  783. if (varalign>16) and (fieldalignment<32) then
  784. fieldalignment:=32
  785. else if (varalign>12) and (fieldalignment<16) then
  786. fieldalignment:=16
  787. { 12 is needed for long double }
  788. else if (varalign>8) and (fieldalignment<12) then
  789. fieldalignment:=12
  790. else if (varalign>4) and (fieldalignment<8) then
  791. fieldalignment:=8
  792. else if (varalign>2) and (fieldalignment<4) then
  793. fieldalignment:=4
  794. else if (varalign>1) and (fieldalignment<2) then
  795. fieldalignment:=2;
  796. { darwin/x86 aligns long doubles on 16 bytes }
  797. if (target_info.system = system_i386_darwin) and
  798. (fieldalignment = 12) then
  799. fieldalignment := 16;
  800. end;
  801. fieldalignment:=min(fieldalignment,aktalignment.maxCrecordalign);
  802. end;
  803. if varalign=0 then
  804. varalign:=size_2_align(l);
  805. varalignfield:=used_align(varalign,aktalignment.recordalignmin,fieldalignment);
  806. sym.fieldoffset:=align(datasize,varalignfield);
  807. if (int64(l)+sym.fieldoffset)>high(aint) then
  808. begin
  809. Message(sym_e_segment_too_large);
  810. datasize:=high(aint);
  811. end
  812. else
  813. datasize:=sym.fieldoffset+l;
  814. { Calc alignment needed for this record }
  815. if (usefieldalignment=-1) then
  816. varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
  817. else
  818. if (usefieldalignment=0) then
  819. varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.recordalignmax)
  820. else
  821. begin
  822. { packrecords is set explicit, ignore recordalignmax limit }
  823. varalignrecord:=used_align(varalign,aktalignment.recordalignmin,usefieldalignment);
  824. end;
  825. recordalignment:=max(recordalignment,varalignrecord);
  826. end;
  827. procedure tabstractrecordsymtable.insertfield(sym:tfieldvarsym);
  828. begin
  829. insert(sym);
  830. addfield(sym);
  831. end;
  832. procedure tabstractrecordsymtable.addalignmentpadding;
  833. begin
  834. { make the record size aligned correctly so it can be
  835. used as elements in an array. For C records we
  836. use the fieldalignment, because that is updated with the
  837. used alignment. }
  838. if (padalignment = 1) then
  839. if usefieldalignment=-1 then
  840. padalignment:=fieldalignment
  841. else
  842. padalignment:=recordalignment;
  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.deftype=enumdef then
  850. defowner.owner.insertdef(def)
  851. else
  852. inherited insertdef(def);
  853. end;
  854. {****************************************************************************
  855. TRecordSymtable
  856. ****************************************************************************}
  857. constructor trecordsymtable.create(usealign:shortint);
  858. begin
  859. inherited create('',usealign);
  860. symtabletype:=recordsymtable;
  861. end;
  862. { this procedure is reserved for inserting case variant into
  863. a record symtable }
  864. { the offset is the location of the start of the variant
  865. and datasize and dataalignment corresponds to
  866. the complete size (see code in pdecl unit) PM }
  867. procedure trecordsymtable.insertunionst(unionst : trecordsymtable;offset : longint);
  868. var
  869. ps,nps : tsym;
  870. pd,npd : tdef;
  871. varalignrecord,varalign,
  872. storesize,storealign : longint;
  873. begin
  874. { copy symbols }
  875. storesize:=datasize;
  876. storealign:=fieldalignment;
  877. datasize:=offset;
  878. ps:=tsym(unionst.symindex.first);
  879. while assigned(ps) do
  880. begin
  881. if ps.typ<>fieldvarsym then
  882. internalerror(200601272);
  883. nps:=tsym(ps.indexnext);
  884. { remove from current symtable }
  885. unionst.symindex.deleteindex(ps);
  886. ps.left:=nil;
  887. ps.right:=nil;
  888. { add to this record }
  889. ps.owner:=self;
  890. datasize:=tfieldvarsym(ps).fieldoffset+offset;
  891. symindex.insert(ps);
  892. symsearch.insert(ps);
  893. { update address }
  894. tfieldvarsym(ps).fieldoffset:=datasize;
  895. { update alignment of this record }
  896. varalign:=tfieldvarsym(ps).vartype.def.alignment;
  897. if varalign=0 then
  898. varalign:=size_2_align(tfieldvarsym(ps).getsize);
  899. varalignrecord:=used_align(varalign,aktalignment.recordalignmin,fieldalignment);
  900. recordalignment:=max(recordalignment,varalignrecord);
  901. { next }
  902. ps:=nps;
  903. end;
  904. { copy defs }
  905. pd:=tdef(unionst.defindex.first);
  906. while assigned(pd) do
  907. begin
  908. npd:=tdef(pd.indexnext);
  909. unionst.defindex.deleteindex(pd);
  910. pd.left:=nil;
  911. pd.right:=nil;
  912. pd.owner:=self;
  913. defindex.insert(pd);
  914. pd:=npd;
  915. end;
  916. datasize:=storesize;
  917. fieldalignment:=storealign;
  918. end;
  919. {****************************************************************************
  920. TObjectSymtable
  921. ****************************************************************************}
  922. constructor tobjectsymtable.create(const n:string;usealign:shortint);
  923. begin
  924. inherited create(n,usealign);
  925. symtabletype:=objectsymtable;
  926. end;
  927. function tobjectsymtable.checkduplicate(sym:tsymentry):boolean;
  928. var
  929. hsym : tsym;
  930. begin
  931. result:=false;
  932. if not assigned(defowner) then
  933. internalerror(200602061);
  934. if (m_duplicate_names in aktmodeswitches) and
  935. (sym.typ in [paravarsym,localvarsym]) then
  936. exit;
  937. { check for duplicate field, parameter or local names
  938. also in inherited classes }
  939. if (sym.typ in [fieldvarsym,paravarsym,localvarsym]) and
  940. (
  941. not(m_delphi in aktmodeswitches) or
  942. is_object(tdef(defowner))
  943. ) then
  944. begin
  945. { but private ids can be reused }
  946. hsym:=search_class_member(tobjectdef(defowner),sym.name);
  947. if assigned(hsym) and
  948. tsym(hsym).is_visible_for_object(tobjectdef(defowner),tobjectdef(defowner)) then
  949. begin
  950. DuplicateSym(sym,hsym);
  951. result:=true;
  952. end;
  953. end
  954. else
  955. begin
  956. result:=inherited checkduplicate(sym);
  957. if result then
  958. exit;
  959. end;
  960. end;
  961. {****************************************************************************
  962. TAbstractLocalSymtable
  963. ****************************************************************************}
  964. procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
  965. var
  966. oldtyp : byte;
  967. begin
  968. oldtyp:=ppufile.entrytyp;
  969. ppufile.entrytyp:=subentryid;
  970. { write definitions }
  971. writedefs(ppufile);
  972. { write symbols }
  973. writesyms(ppufile);
  974. ppufile.entrytyp:=oldtyp;
  975. end;
  976. {****************************************************************************
  977. TLocalSymtable
  978. ****************************************************************************}
  979. constructor tlocalsymtable.create(level:byte);
  980. begin
  981. inherited create('');
  982. symtabletype:=localsymtable;
  983. symtablelevel:=level;
  984. end;
  985. function tlocalsymtable.checkduplicate(sym:tsymentry):boolean;
  986. var
  987. hsym : tsym;
  988. begin
  989. if not assigned(defowner) or
  990. (defowner.deftype<>procdef) then
  991. internalerror(200602042);
  992. result:=false;
  993. hsym:=tsym(speedsearch(sym.name,sym.speedvalue));
  994. if assigned(hsym) then
  995. begin
  996. { a local and the function can have the same
  997. name in TP and Delphi, but RESULT not }
  998. if (m_duplicate_names in aktmodeswitches) and
  999. (hsym.typ in [absolutevarsym,localvarsym]) and
  1000. (vo_is_funcret in tabstractvarsym(hsym).varoptions) and
  1001. not((m_result in aktmodeswitches) and
  1002. (vo_is_result in tabstractvarsym(hsym).varoptions)) then
  1003. HideSym(hsym)
  1004. else
  1005. DuplicateSym(sym,hsym);
  1006. result:=true;
  1007. exit;
  1008. end;
  1009. { check also parasymtable, this needs to be done here becuase
  1010. of the special situation with the funcret sym that needs to be
  1011. hidden for tp and delphi modes }
  1012. hsym:=tsym(tabstractprocdef(defowner).parast.speedsearch(sym.name,sym.speedvalue));
  1013. if assigned(hsym) then
  1014. begin
  1015. { a local and the function can have the same
  1016. name in TP and Delphi, but RESULT not }
  1017. if (m_duplicate_names in aktmodeswitches) and
  1018. (sym.typ in [absolutevarsym,localvarsym]) and
  1019. (vo_is_funcret in tabstractvarsym(sym).varoptions) and
  1020. not((m_result in aktmodeswitches) and
  1021. (vo_is_result in tabstractvarsym(sym).varoptions)) then
  1022. HideSym(sym)
  1023. else
  1024. DuplicateSym(sym,hsym);
  1025. end;
  1026. { check objectsymtable, skip this for funcret sym because
  1027. that will always be positive because it has the same name
  1028. as the procsym }
  1029. if not(m_duplicate_names in aktmodeswitches) and
  1030. not is_funcret_sym(sym) and
  1031. (defowner.deftype=procdef) and
  1032. assigned(tprocdef(defowner)._class) and
  1033. (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) then
  1034. result:=tprocdef(defowner)._class.symtable.checkduplicate(sym);
  1035. end;
  1036. {****************************************************************************
  1037. TParaSymtable
  1038. ****************************************************************************}
  1039. constructor tparasymtable.create(level:byte);
  1040. begin
  1041. inherited create('');
  1042. symtabletype:=parasymtable;
  1043. symtablelevel:=level;
  1044. end;
  1045. function tparasymtable.checkduplicate(sym:tsymentry):boolean;
  1046. begin
  1047. result:=inherited checkduplicate(sym);
  1048. if result then
  1049. exit;
  1050. if not(m_duplicate_names in aktmodeswitches) and
  1051. (defowner.deftype=procdef) and
  1052. assigned(tprocdef(defowner)._class) and
  1053. (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) then
  1054. result:=tprocdef(defowner)._class.symtable.checkduplicate(sym);
  1055. end;
  1056. {****************************************************************************
  1057. TAbstractUnitSymtable
  1058. ****************************************************************************}
  1059. constructor tabstractunitsymtable.create(const n : string;id:word);
  1060. begin
  1061. inherited create(n);
  1062. moduleid:=id;
  1063. symsearch.usehash;
  1064. end;
  1065. function tabstractunitsymtable.iscurrentunit:boolean;
  1066. begin
  1067. result:=assigned(current_module) and
  1068. (
  1069. (current_module.globalsymtable=self) or
  1070. (current_module.localsymtable=self)
  1071. );
  1072. end;
  1073. {****************************************************************************
  1074. TStaticSymtable
  1075. ****************************************************************************}
  1076. constructor tstaticsymtable.create(const n : string;id:word);
  1077. begin
  1078. inherited create(n,id);
  1079. symtabletype:=staticsymtable;
  1080. symtablelevel:=main_program_level;
  1081. end;
  1082. procedure tstaticsymtable.ppuload(ppufile:tcompilerppufile);
  1083. begin
  1084. inherited ppuload(ppufile);
  1085. { now we can deref the syms and defs }
  1086. deref;
  1087. end;
  1088. procedure tstaticsymtable.ppuwrite(ppufile:tcompilerppufile);
  1089. begin
  1090. inherited ppuwrite(ppufile);
  1091. end;
  1092. procedure tstaticsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1093. begin
  1094. inherited load_references(ppufile,locals);
  1095. end;
  1096. procedure tstaticsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1097. begin
  1098. inherited write_references(ppufile,locals);
  1099. end;
  1100. function tstaticsymtable.checkduplicate(sym:tsymentry):boolean;
  1101. var
  1102. hsym : tsym;
  1103. begin
  1104. result:=false;
  1105. hsym:=tsym(speedsearch(sym.name,sym.speedvalue));
  1106. if assigned(hsym) then
  1107. begin
  1108. { Delphi you can have a symbol with the same name as the
  1109. unit, the unit can then not be accessed anymore using
  1110. <unit>.<id>, so we can hide the symbol }
  1111. if (m_duplicate_names in aktmodeswitches) and
  1112. (hsym.typ=symconst.unitsym) then
  1113. HideSym(hsym)
  1114. else
  1115. DuplicateSym(sym,hsym);
  1116. result:=true;
  1117. exit;
  1118. end;
  1119. if (current_module.localsymtable=self) and
  1120. assigned(current_module.globalsymtable) then
  1121. result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(sym);
  1122. end;
  1123. {****************************************************************************
  1124. TGlobalSymtable
  1125. ****************************************************************************}
  1126. constructor tglobalsymtable.create(const n : string;id:word);
  1127. begin
  1128. inherited create(n,id);
  1129. symtabletype:=globalsymtable;
  1130. symtablelevel:=main_program_level;
  1131. end;
  1132. procedure tglobalsymtable.ppuload(ppufile:tcompilerppufile);
  1133. begin
  1134. inherited ppuload(ppufile);
  1135. { now we can deref the syms and defs }
  1136. deref;
  1137. end;
  1138. procedure tglobalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1139. begin
  1140. { write the symtable entries }
  1141. inherited ppuwrite(ppufile);
  1142. end;
  1143. procedure tglobalsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1144. begin
  1145. inherited load_references(ppufile,locals);
  1146. end;
  1147. procedure tglobalsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1148. begin
  1149. inherited write_references(ppufile,locals);
  1150. end;
  1151. function tglobalsymtable.checkduplicate(sym:tsymentry):boolean;
  1152. var
  1153. hsym : tsym;
  1154. begin
  1155. result:=false;
  1156. hsym:=tsym(speedsearch(sym.name,sym.speedvalue));
  1157. if assigned(hsym) then
  1158. begin
  1159. { Delphi you can have a symbol with the same name as the
  1160. unit, the unit can then not be accessed anymore using
  1161. <unit>.<id>, so we can hide the symbol }
  1162. if (m_duplicate_names in aktmodeswitches) and
  1163. (hsym.typ=symconst.unitsym) then
  1164. HideSym(hsym)
  1165. else
  1166. DuplicateSym(sym,hsym);
  1167. result:=true;
  1168. exit;
  1169. end;
  1170. end;
  1171. {****************************************************************************
  1172. TWITHSYMTABLE
  1173. ****************************************************************************}
  1174. constructor twithsymtable.create(aowner:tdef;asymsearch:TDictionary;refnode:tobject{tnode});
  1175. begin
  1176. inherited create('');
  1177. symtabletype:=withsymtable;
  1178. withrefnode:=refnode;
  1179. { we don't need the symsearch }
  1180. symsearch.free;
  1181. { set the defaults }
  1182. symsearch:=asymsearch;
  1183. defowner:=aowner;
  1184. end;
  1185. destructor twithsymtable.destroy;
  1186. begin
  1187. withrefnode.free;
  1188. symsearch:=nil;
  1189. inherited destroy;
  1190. end;
  1191. procedure twithsymtable.clear;
  1192. begin
  1193. { remove no entry from a withsymtable as it is only a pointer to the
  1194. recorddef or objectdef symtable }
  1195. end;
  1196. procedure twithsymtable.insertdef(def:tdefentry);
  1197. begin
  1198. { Definitions can't be registered in the withsymtable
  1199. because the withsymtable is removed after the with block.
  1200. We can't easily solve it here because the next symtable in the
  1201. stack is not known. }
  1202. internalerror(200602046);
  1203. end;
  1204. {****************************************************************************
  1205. TSTT_ExceptionSymtable
  1206. ****************************************************************************}
  1207. constructor tstt_exceptsymtable.create;
  1208. begin
  1209. inherited create('');
  1210. symtabletype:=stt_exceptsymtable;
  1211. end;
  1212. {****************************************************************************
  1213. TMacroSymtable
  1214. ****************************************************************************}
  1215. constructor tmacrosymtable.create(exported: boolean);
  1216. begin
  1217. inherited create('');
  1218. if exported then
  1219. symtabletype:=exportedmacrosymtable
  1220. else
  1221. symtabletype:=localmacrosymtable;
  1222. symtablelevel:=main_program_level;
  1223. end;
  1224. {*****************************************************************************
  1225. Helper Routines
  1226. *****************************************************************************}
  1227. function findunitsymtable(st:tsymtable):tsymtable;
  1228. begin
  1229. result:=nil;
  1230. repeat
  1231. if not assigned(st) then
  1232. internalerror(200602034);
  1233. case st.symtabletype of
  1234. localmacrosymtable,
  1235. exportedmacrosymtable,
  1236. staticsymtable,
  1237. globalsymtable :
  1238. begin
  1239. result:=st;
  1240. exit;
  1241. end;
  1242. recordsymtable,
  1243. localsymtable,
  1244. parasymtable,
  1245. objectsymtable :
  1246. st:=st.defowner.owner;
  1247. else
  1248. internalerror(200602035);
  1249. end;
  1250. until false;
  1251. end;
  1252. function FullTypeName(def,otherdef:tdef):string;
  1253. var
  1254. s1,s2 : string;
  1255. begin
  1256. s1:=def.typename;
  1257. { When the names are the same try to include the unit name }
  1258. if assigned(otherdef) and
  1259. (def.owner.symtabletype in [globalsymtable,staticsymtable]) then
  1260. begin
  1261. s2:=otherdef.typename;
  1262. if upper(s1)=upper(s2) then
  1263. s1:=def.owner.realname^+'.'+s1;
  1264. end;
  1265. FullTypeName:=s1;
  1266. end;
  1267. procedure incompatibletypes(def1,def2:tdef);
  1268. begin
  1269. { When there is an errordef there is already an error message show }
  1270. if (def2.deftype=errordef) or
  1271. (def1.deftype=errordef) then
  1272. exit;
  1273. CGMessage2(type_e_incompatible_types,FullTypeName(def1,def2),FullTypeName(def2,def1));
  1274. end;
  1275. procedure hidesym(sym:tsymentry);
  1276. var
  1277. s : string;
  1278. begin
  1279. if assigned(sym.owner) then
  1280. sym.owner.rename(sym.name,'hidden'+sym.name)
  1281. else
  1282. sym.name:='hidden'+sym.name;
  1283. s:='hidden'+tsym(sym).realname;
  1284. stringdispose(tsym(sym)._realname);
  1285. tsym(sym)._realname:=stringdup(s);
  1286. end;
  1287. var
  1288. dupnr : longint; { unique number for duplicate symbols }
  1289. procedure duplicatesym(dupsym,sym:tsymentry);
  1290. var
  1291. st : tsymtable;
  1292. begin
  1293. Message1(sym_e_duplicate_id,tsym(sym).realname);
  1294. st:=findunitsymtable(sym.owner);
  1295. with tsym(sym).fileinfo do
  1296. begin
  1297. if assigned(st) and
  1298. (st.symtabletype=globalsymtable) and
  1299. (not st.iscurrentunit) then
  1300. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line))
  1301. else
  1302. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line));
  1303. end;
  1304. { Rename duplicate sym to an unreachable name, but it can be
  1305. inserted in the symtable without errors }
  1306. if assigned(dupsym) then
  1307. begin
  1308. inc(dupnr);
  1309. dupsym.name:='dup'+tostr(dupnr)+dupsym.name;
  1310. include(tsym(dupsym).symoptions,sp_implicitrename);
  1311. end;
  1312. end;
  1313. {*****************************************************************************
  1314. Search
  1315. *****************************************************************************}
  1316. procedure addsymref(sym:tsym);
  1317. var
  1318. newref : tref;
  1319. begin
  1320. { unit uses count }
  1321. if assigned(current_module) and
  1322. (sym.owner.symtabletype=globalsymtable) then
  1323. begin
  1324. if tglobalsymtable(sym.owner).moduleid>=current_module.unitmapsize then
  1325. internalerror(200501152);
  1326. inc(current_module.unitmap[tglobalsymtable(sym.owner).moduleid].refs);
  1327. end;
  1328. inc(sym.refs);
  1329. if (cs_browser in aktmoduleswitches) then
  1330. begin
  1331. newref:=tref.create(sym.lastref,@akttokenpos);
  1332. { for symbols that are in tables without browser info or syssyms }
  1333. if sym.refcount=0 then
  1334. begin
  1335. sym.defref:=newref;
  1336. sym.lastref:=newref;
  1337. end
  1338. else
  1339. if resolving_forward and assigned(sym.defref) then
  1340. { put it as second reference }
  1341. begin
  1342. newref.nextref:=sym.defref.nextref;
  1343. sym.defref.nextref:=newref;
  1344. sym.lastref.nextref:=nil;
  1345. end
  1346. else
  1347. sym.lastref:=newref;
  1348. inc(sym.refcount);
  1349. end;
  1350. end;
  1351. function searchsym(const s : stringid;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1352. var
  1353. speedvalue : cardinal;
  1354. topclass : tobjectdef;
  1355. context : tobjectdef;
  1356. stackitem : psymtablestackitem;
  1357. begin
  1358. result:=false;
  1359. speedvalue:=getspeedvalue(s);
  1360. stackitem:=symtablestack.stack;
  1361. while assigned(stackitem) do
  1362. begin
  1363. srsymtable:=stackitem^.symtable;
  1364. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  1365. if assigned(srsym) then
  1366. begin
  1367. topclass:=nil;
  1368. { use the class from withsymtable only when it is
  1369. defined in this unit }
  1370. if (srsymtable.symtabletype=withsymtable) and
  1371. assigned(srsymtable.defowner) and
  1372. (srsymtable.defowner.deftype=objectdef) and
  1373. (srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1374. (srsymtable.defowner.owner.iscurrentunit) then
  1375. topclass:=tobjectdef(srsymtable.defowner)
  1376. else
  1377. begin
  1378. if assigned(current_procinfo) then
  1379. topclass:=current_procinfo.procdef._class;
  1380. end;
  1381. if assigned(current_procinfo) then
  1382. context:=current_procinfo.procdef._class
  1383. else
  1384. context:=nil;
  1385. if tsym(srsym).is_visible_for_object(topclass,context) then
  1386. begin
  1387. { we need to know if a procedure references symbols
  1388. in the static symtable, because then it can't be
  1389. inlined from outside this unit }
  1390. if assigned(current_procinfo) and
  1391. (srsym.owner.symtabletype=staticsymtable) then
  1392. include(current_procinfo.flags,pi_uses_static_symtable);
  1393. addsymref(srsym);
  1394. result:=true;
  1395. exit;
  1396. end;
  1397. end;
  1398. stackitem:=stackitem^.next;
  1399. end;
  1400. srsym:=nil;
  1401. srsymtable:=nil;
  1402. end;
  1403. function searchsym_type(const s : stringid;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1404. var
  1405. speedvalue : cardinal;
  1406. stackitem : psymtablestackitem;
  1407. begin
  1408. result:=false;
  1409. speedvalue:=getspeedvalue(s);
  1410. stackitem:=symtablestack.stack;
  1411. while assigned(stackitem) do
  1412. begin
  1413. {
  1414. It is not possible to have type symbols in:
  1415. records
  1416. objects
  1417. parameters
  1418. Exception are generic definitions and specializations
  1419. that have the parameterized types inserted in the symtable.
  1420. }
  1421. srsymtable:=stackitem^.symtable;
  1422. if not(srsymtable.symtabletype in [recordsymtable,objectsymtable,parasymtable]) or
  1423. (assigned(srsymtable.defowner) and
  1424. (
  1425. (df_generic in tdef(srsymtable.defowner).defoptions) or
  1426. (df_specialization in tdef(srsymtable.defowner).defoptions))
  1427. ) then
  1428. begin
  1429. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  1430. if assigned(srsym) and
  1431. not(srsym.typ in [fieldvarsym,paravarsym]) and
  1432. (not assigned(current_procinfo) or
  1433. tsym(srsym).is_visible_for_object(current_procinfo.procdef._class,current_procinfo.procdef._class)) then
  1434. begin
  1435. { we need to know if a procedure references symbols
  1436. in the static symtable, because then it can't be
  1437. inlined from outside this unit }
  1438. if assigned(current_procinfo) and
  1439. (srsym.owner.symtabletype=staticsymtable) then
  1440. include(current_procinfo.flags,pi_uses_static_symtable);
  1441. addsymref(srsym);
  1442. result:=true;
  1443. exit;
  1444. end;
  1445. end;
  1446. stackitem:=stackitem^.next;
  1447. end;
  1448. result:=false;
  1449. srsym:=nil;
  1450. srsymtable:=nil;
  1451. end;
  1452. function searchsym_in_module(pm:pointer;const s : stringid;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1453. var
  1454. pmod : tmodule;
  1455. begin
  1456. pmod:=tmodule(pm);
  1457. result:=false;
  1458. if assigned(pmod.globalsymtable) then
  1459. begin
  1460. srsym:=tsym(pmod.globalsymtable.search(s));
  1461. if assigned(srsym) then
  1462. begin
  1463. srsymtable:=pmod.globalsymtable;
  1464. addsymref(srsym);
  1465. result:=true;
  1466. exit;
  1467. end;
  1468. end;
  1469. { If the module is the current unit we also need
  1470. to search the local symtable }
  1471. if (pmod=current_module) and
  1472. assigned(pmod.localsymtable) then
  1473. begin
  1474. srsym:=tsym(pmod.localsymtable.search(s));
  1475. if assigned(srsym) then
  1476. begin
  1477. srsymtable:=pmod.localsymtable;
  1478. addsymref(srsym);
  1479. result:=true;
  1480. exit;
  1481. end;
  1482. end;
  1483. srsym:=nil;
  1484. srsymtable:=nil;
  1485. end;
  1486. function searchsym_in_class(classh:tobjectdef;const s : stringid;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1487. var
  1488. speedvalue : cardinal;
  1489. topclassh : tobjectdef;
  1490. begin
  1491. result:=false;
  1492. speedvalue:=getspeedvalue(s);
  1493. { when the class passed is defined in this unit we
  1494. need to use the scope of that class. This is a trick
  1495. that can be used to access protected members in other
  1496. units. At least kylix supports it this way (PFV) }
  1497. if assigned(classh) and
  1498. (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1499. classh.owner.iscurrentunit then
  1500. topclassh:=classh
  1501. else
  1502. begin
  1503. if assigned(current_procinfo) then
  1504. topclassh:=current_procinfo.procdef._class
  1505. else
  1506. topclassh:=nil;
  1507. end;
  1508. while assigned(classh) do
  1509. begin
  1510. srsymtable:=classh.symtable;
  1511. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  1512. if assigned(srsym) and
  1513. tsym(srsym).is_visible_for_object(topclassh,current_procinfo.procdef._class) then
  1514. begin
  1515. result:=true;
  1516. exit;
  1517. end;
  1518. classh:=classh.childof;
  1519. end;
  1520. srsym:=nil;
  1521. srsymtable:=nil;
  1522. end;
  1523. function searchsym_in_class_by_msgint(classh:tobjectdef;i:longint;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1524. var
  1525. topclassh : tobjectdef;
  1526. def : tdef;
  1527. begin
  1528. result:=false;
  1529. { when the class passed is defined in this unit we
  1530. need to use the scope of that class. This is a trick
  1531. that can be used to access protected members in other
  1532. units. At least kylix supports it this way (PFV) }
  1533. if assigned(classh) and
  1534. (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1535. classh.owner.iscurrentunit then
  1536. topclassh:=classh
  1537. else
  1538. begin
  1539. if assigned(current_procinfo) then
  1540. topclassh:=current_procinfo.procdef._class
  1541. else
  1542. topclassh:=nil;
  1543. end;
  1544. def:=nil;
  1545. while assigned(classh) do
  1546. begin
  1547. def:=tdef(classh.symtable.defindex.first);
  1548. while assigned(def) do
  1549. begin
  1550. if (def.deftype=procdef) and
  1551. tprocdef(def).is_visible_for_object(topclassh) and
  1552. (po_msgint in tprocdef(def).procoptions) and
  1553. (tprocdef(def).messageinf.i=i) then
  1554. begin
  1555. srsym:=tprocdef(def).procsym;
  1556. srsymtable:=classh.symtable;
  1557. result:=true;
  1558. exit;
  1559. end;
  1560. def:=tdef(def.indexnext);
  1561. end;
  1562. classh:=classh.childof;
  1563. end;
  1564. srsym:=nil;
  1565. srsymtable:=nil;
  1566. end;
  1567. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:tsymtable):boolean;
  1568. var
  1569. topclassh : tobjectdef;
  1570. def : tdef;
  1571. begin
  1572. result:=false;
  1573. { when the class passed is defined in this unit we
  1574. need to use the scope of that class. This is a trick
  1575. that can be used to access protected members in other
  1576. units. At least kylix supports it this way (PFV) }
  1577. if assigned(classh) and
  1578. (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1579. classh.owner.iscurrentunit then
  1580. topclassh:=classh
  1581. else
  1582. begin
  1583. if assigned(current_procinfo) then
  1584. topclassh:=current_procinfo.procdef._class
  1585. else
  1586. topclassh:=nil;
  1587. end;
  1588. def:=nil;
  1589. while assigned(classh) do
  1590. begin
  1591. def:=tdef(classh.symtable.defindex.first);
  1592. while assigned(def) do
  1593. begin
  1594. if (def.deftype=procdef) and
  1595. tprocdef(def).is_visible_for_object(topclassh) and
  1596. (po_msgstr in tprocdef(def).procoptions) and
  1597. (tprocdef(def).messageinf.str=s) then
  1598. begin
  1599. srsym:=tprocdef(def).procsym;
  1600. srsymtable:=classh.symtable;
  1601. result:=true;
  1602. exit;
  1603. end;
  1604. def:=tdef(def.indexnext);
  1605. end;
  1606. classh:=classh.childof;
  1607. end;
  1608. srsym:=nil;
  1609. srsymtable:=nil;
  1610. end;
  1611. function search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
  1612. var
  1613. sym : Tprocsym;
  1614. speedvalue : cardinal;
  1615. curreq,
  1616. besteq : tequaltype;
  1617. currpd,
  1618. bestpd : tprocdef;
  1619. stackitem : psymtablestackitem;
  1620. begin
  1621. speedvalue:=getspeedvalue('assign');
  1622. besteq:=te_incompatible;
  1623. bestpd:=nil;
  1624. stackitem:=symtablestack.stack;
  1625. while assigned(stackitem) do
  1626. begin
  1627. sym:=Tprocsym(stackitem^.symtable.speedsearch('assign',speedvalue));
  1628. if sym<>nil then
  1629. begin
  1630. if sym.typ<>procsym then
  1631. internalerror(200402031);
  1632. { if the source type is an alias then this is only the second choice,
  1633. if you mess with this code, check tw4093 }
  1634. currpd:=sym.search_procdef_assignment_operator(from_def,to_def,curreq);
  1635. if curreq>besteq then
  1636. begin
  1637. besteq:=curreq;
  1638. bestpd:=currpd;
  1639. if (besteq=te_exact) then
  1640. break;
  1641. end;
  1642. end;
  1643. stackitem:=stackitem^.next;
  1644. end;
  1645. result:=bestpd;
  1646. end;
  1647. function search_system_type(const s: stringid): ttypesym;
  1648. var
  1649. sym : tsym;
  1650. begin
  1651. sym:=tsym(systemunit.search(s));
  1652. if not assigned(sym) or
  1653. (sym.typ<>typesym) then
  1654. internalerror(200501251);
  1655. result:=ttypesym(sym);
  1656. end;
  1657. function search_class_member(pd : tobjectdef;const s : string):tsym;
  1658. { searches n in symtable of pd and all anchestors }
  1659. var
  1660. speedvalue : cardinal;
  1661. srsym : tsym;
  1662. begin
  1663. speedvalue:=getspeedvalue(s);
  1664. while assigned(pd) do
  1665. begin
  1666. srsym:=tsym(pd.symtable.speedsearch(s,speedvalue));
  1667. if assigned(srsym) then
  1668. begin
  1669. search_class_member:=srsym;
  1670. exit;
  1671. end;
  1672. pd:=pd.childof;
  1673. end;
  1674. search_class_member:=nil;
  1675. end;
  1676. function search_macro(const s : string):tsym;
  1677. var
  1678. stackitem : psymtablestackitem;
  1679. speedvalue : cardinal;
  1680. srsym : tsym;
  1681. begin
  1682. speedvalue:= getspeedvalue(s);
  1683. { First search the localmacrosymtable before searching the
  1684. global macrosymtables from the units }
  1685. if assigned(current_module) then
  1686. begin
  1687. srsym:=tsym(current_module.localmacrosymtable.speedsearch(s,speedvalue));
  1688. if assigned(srsym) then
  1689. begin
  1690. result:= srsym;
  1691. exit;
  1692. end;
  1693. end;
  1694. stackitem:=macrosymtablestack.stack;
  1695. while assigned(stackitem) do
  1696. begin
  1697. srsym:=tsym(stackitem^.symtable.speedsearch(s,speedvalue));
  1698. if assigned(srsym) then
  1699. begin
  1700. result:= srsym;
  1701. exit;
  1702. end;
  1703. stackitem:=stackitem^.next;
  1704. end;
  1705. result:= nil;
  1706. end;
  1707. {****************************************************************************
  1708. Object Helpers
  1709. ****************************************************************************}
  1710. procedure search_class_overloads(aprocsym : tprocsym);
  1711. { searches n in symtable of pd and all anchestors }
  1712. var
  1713. speedvalue : cardinal;
  1714. srsym : tprocsym;
  1715. s : string;
  1716. objdef : tobjectdef;
  1717. begin
  1718. if aprocsym.overloadchecked then
  1719. exit;
  1720. aprocsym.overloadchecked:=true;
  1721. if (aprocsym.owner.symtabletype<>objectsymtable) then
  1722. internalerror(200111021);
  1723. objdef:=tobjectdef(aprocsym.owner.defowner);
  1724. { we start in the parent }
  1725. if not assigned(objdef.childof) then
  1726. exit;
  1727. objdef:=objdef.childof;
  1728. s:=aprocsym.name;
  1729. speedvalue:=getspeedvalue(s);
  1730. while assigned(objdef) do
  1731. begin
  1732. srsym:=tprocsym(objdef.symtable.speedsearch(s,speedvalue));
  1733. if assigned(srsym) then
  1734. begin
  1735. if (srsym.typ<>procsym) then
  1736. internalerror(200111022);
  1737. if srsym.is_visible_for_object(tobjectdef(aprocsym.owner.defowner),tobjectdef(aprocsym.owner.defowner)) then
  1738. begin
  1739. srsym.add_para_match_to(Aprocsym,[cpo_ignorehidden,cpo_allowdefaults]);
  1740. { we can stop if the overloads were already added
  1741. for the found symbol }
  1742. if srsym.overloadchecked then
  1743. break;
  1744. end;
  1745. end;
  1746. { next parent }
  1747. objdef:=objdef.childof;
  1748. end;
  1749. end;
  1750. procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem;arg:pointer);
  1751. begin
  1752. if (tsym(p).typ=propertysym) and
  1753. (ppo_defaultproperty in tpropertysym(p).propoptions) then
  1754. ppointer(arg)^:=p;
  1755. end;
  1756. function search_default_property(pd : tobjectdef) : tpropertysym;
  1757. { returns the default property of a class, searches also anchestors }
  1758. var
  1759. _defaultprop : tpropertysym;
  1760. begin
  1761. _defaultprop:=nil;
  1762. while assigned(pd) do
  1763. begin
  1764. pd.symtable.foreach(@tstoredsymtable(pd.symtable).testfordefaultproperty,@_defaultprop);
  1765. if assigned(_defaultprop) then
  1766. break;
  1767. pd:=pd.childof;
  1768. end;
  1769. search_default_property:=_defaultprop;
  1770. end;
  1771. {****************************************************************************
  1772. Macro Helpers
  1773. ****************************************************************************}
  1774. procedure def_system_macro(const name : string);
  1775. var
  1776. mac : tmacro;
  1777. s: string;
  1778. begin
  1779. if name = '' then
  1780. internalerror(2004121201);
  1781. s:= upper(name);
  1782. mac:=tmacro(search_macro(s));
  1783. if not assigned(mac) then
  1784. begin
  1785. mac:=tmacro.create(s);
  1786. if assigned(current_module) then
  1787. current_module.localmacrosymtable.insert(mac)
  1788. else
  1789. initialmacrosymtable.insert(mac);
  1790. end;
  1791. if not mac.defined then
  1792. Message1(parser_c_macro_defined,mac.name);
  1793. mac.defined:=true;
  1794. end;
  1795. procedure set_system_macro(const name, value : string);
  1796. var
  1797. mac : tmacro;
  1798. s: string;
  1799. begin
  1800. if name = '' then
  1801. internalerror(2004121201);
  1802. s:= upper(name);
  1803. mac:=tmacro(search_macro(s));
  1804. if not assigned(mac) then
  1805. begin
  1806. mac:=tmacro.create(s);
  1807. if assigned(current_module) then
  1808. current_module.localmacrosymtable.insert(mac)
  1809. else
  1810. initialmacrosymtable.insert(mac);
  1811. end
  1812. else
  1813. begin
  1814. mac.is_compiler_var:=false;
  1815. if assigned(mac.buftext) then
  1816. freemem(mac.buftext,mac.buflen);
  1817. end;
  1818. Message2(parser_c_macro_set_to,mac.name,value);
  1819. mac.buflen:=length(value);
  1820. getmem(mac.buftext,mac.buflen);
  1821. move(value[1],mac.buftext^,mac.buflen);
  1822. mac.defined:=true;
  1823. end;
  1824. procedure set_system_compvar(const name, value : string);
  1825. var
  1826. mac : tmacro;
  1827. s: string;
  1828. begin
  1829. if name = '' then
  1830. internalerror(2004121201);
  1831. s:= upper(name);
  1832. mac:=tmacro(search_macro(s));
  1833. if not assigned(mac) then
  1834. begin
  1835. mac:=tmacro.create(s);
  1836. mac.is_compiler_var:=true;
  1837. if assigned(current_module) then
  1838. current_module.localmacrosymtable.insert(mac)
  1839. else
  1840. initialmacrosymtable.insert(mac);
  1841. end
  1842. else
  1843. begin
  1844. mac.is_compiler_var:=true;
  1845. if assigned(mac.buftext) then
  1846. freemem(mac.buftext,mac.buflen);
  1847. end;
  1848. Message2(parser_c_macro_set_to,mac.name,value);
  1849. mac.buflen:=length(value);
  1850. getmem(mac.buftext,mac.buflen);
  1851. move(value[1],mac.buftext^,mac.buflen);
  1852. mac.defined:=true;
  1853. end;
  1854. procedure undef_system_macro(const name : string);
  1855. var
  1856. mac : tmacro;
  1857. s: string;
  1858. begin
  1859. if name = '' then
  1860. internalerror(2004121201);
  1861. s:= upper(name);
  1862. mac:=tmacro(search_macro(s));
  1863. if not assigned(mac) then
  1864. {If not found, then it's already undefined.}
  1865. else
  1866. begin
  1867. if mac.defined then
  1868. Message1(parser_c_macro_undefined,mac.name);
  1869. mac.defined:=false;
  1870. mac.is_compiler_var:=false;
  1871. { delete old definition }
  1872. if assigned(mac.buftext) then
  1873. begin
  1874. freemem(mac.buftext,mac.buflen);
  1875. mac.buftext:=nil;
  1876. end;
  1877. end;
  1878. end;
  1879. {$ifdef UNITALIASES}
  1880. {****************************************************************************
  1881. TUNIT_ALIAS
  1882. ****************************************************************************}
  1883. constructor tunit_alias.create(const n:string);
  1884. var
  1885. i : longint;
  1886. begin
  1887. i:=pos('=',n);
  1888. if i=0 then
  1889. fail;
  1890. inherited createname(Copy(n,1,i-1));
  1891. newname:=stringdup(Copy(n,i+1,255));
  1892. end;
  1893. destructor tunit_alias.destroy;
  1894. begin
  1895. stringdispose(newname);
  1896. inherited destroy;
  1897. end;
  1898. procedure addunitalias(const n:string);
  1899. begin
  1900. unitaliases^.insert(tunit_alias,init(Upper(n))));
  1901. end;
  1902. function getunitalias(const n:string):string;
  1903. var
  1904. p : punit_alias;
  1905. begin
  1906. p:=punit_alias(unitaliases^.search(Upper(n)));
  1907. if assigned(p) then
  1908. getunitalias:=punit_alias(p).newname^
  1909. else
  1910. getunitalias:=n;
  1911. end;
  1912. {$endif UNITALIASES}
  1913. {****************************************************************************
  1914. Symtable Stack
  1915. ****************************************************************************}
  1916. constructor tsymtablestack.create;
  1917. begin
  1918. stack:=nil;
  1919. end;
  1920. destructor tsymtablestack.destroy;
  1921. begin
  1922. clear;
  1923. end;
  1924. procedure tsymtablestack.clear;
  1925. var
  1926. hp : psymtablestackitem;
  1927. begin
  1928. while assigned(stack) do
  1929. begin
  1930. hp:=stack;
  1931. stack:=hp^.next;
  1932. dispose(hp);
  1933. end;
  1934. end;
  1935. procedure tsymtablestack.push(st:tsymtable);
  1936. var
  1937. hp : psymtablestackitem;
  1938. begin
  1939. new(hp);
  1940. hp^.symtable:=st;
  1941. hp^.next:=stack;
  1942. stack:=hp;
  1943. end;
  1944. procedure tsymtablestack.pop(st:tsymtable);
  1945. var
  1946. hp : psymtablestackitem;
  1947. begin
  1948. if not assigned(stack) then
  1949. internalerror(200601231);
  1950. if stack^.symtable<>st then
  1951. internalerror(200601232);
  1952. hp:=stack;
  1953. stack:=hp^.next;
  1954. dispose(hp);
  1955. end;
  1956. function tsymtablestack.top:tsymtable;
  1957. begin
  1958. if not assigned(stack) then
  1959. internalerror(200601233);
  1960. result:=stack^.symtable;
  1961. end;
  1962. {****************************************************************************
  1963. Init/Done Symtable
  1964. ****************************************************************************}
  1965. procedure InitSymtable;
  1966. begin
  1967. { Reset symbolstack }
  1968. symtablestack:=nil;
  1969. systemunit:=nil;
  1970. { create error syms and def }
  1971. generrorsym:=terrorsym.create;
  1972. generrortype.setdef(terrordef.create);
  1973. { macros }
  1974. initialmacrosymtable:=tmacrosymtable.create(false);
  1975. macrosymtablestack:=tsymtablestack.create;
  1976. macrosymtablestack.push(initialmacrosymtable);
  1977. {$ifdef UNITALIASES}
  1978. { unit aliases }
  1979. unitaliases:=tdictionary.create;
  1980. {$endif}
  1981. { set some global vars to nil, might be important for the ide }
  1982. class_tobject:=nil;
  1983. interface_iunknown:=nil;
  1984. rec_tguid:=nil;
  1985. dupnr:=0;
  1986. end;
  1987. procedure DoneSymtable;
  1988. begin
  1989. generrorsym.owner:=nil;
  1990. generrorsym.free;
  1991. generrortype.def.owner:=nil;
  1992. generrortype.def.free;
  1993. initialmacrosymtable.free;
  1994. macrosymtablestack.free;
  1995. {$ifdef UNITALIASES}
  1996. unitaliases.free;
  1997. {$endif}
  1998. end;
  1999. end.