symtable.pas 77 KB

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