symtable.pas 77 KB

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