symtable.pas 77 KB

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