symtable.pas 75 KB

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