2
0

symtable.pas 83 KB

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