symtable.pas 78 KB

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