symtable.pas 78 KB

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