symtable.pas 82 KB

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