symtable.pas 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,symsym,
  28. { ppu }
  29. ppu,symppu,
  30. { assembler }
  31. aasm
  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);
  41. procedure check_forward(sym : TNamedIndexItem);
  42. procedure labeldefined(p : TNamedIndexItem);
  43. procedure unitsymbolused(p : TNamedIndexItem);
  44. procedure varsymbolused(p : TNamedIndexItem);
  45. procedure TestPrivate(p : TNamedIndexItem);
  46. procedure objectprivatesymbolused(p : TNamedIndexItem);
  47. {$ifdef GDB}
  48. private
  49. asmoutput : taasmoutput;
  50. procedure concatstab(p : TNamedIndexItem);
  51. procedure resetstab(p : TNamedIndexItem);
  52. procedure concattypestab(p : TNamedIndexItem);
  53. {$endif}
  54. procedure order_overloads(p : TNamedIndexItem);
  55. procedure loaddefs(ppufile:tcompilerppufile);
  56. procedure loadsyms(ppufile:tcompilerppufile);
  57. procedure writedefs(ppufile:tcompilerppufile);
  58. procedure writesyms(ppufile:tcompilerppufile);
  59. public
  60. { load/write }
  61. procedure load(ppufile:tcompilerppufile);virtual;
  62. procedure write(ppufile:tcompilerppufile);virtual;
  63. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  64. procedure write_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  65. procedure deref;virtual;
  66. procedure derefimpl;virtual;
  67. procedure insert(sym : tsymentry);override;
  68. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;override;
  69. procedure allsymbolsused;
  70. procedure allprivatesused;
  71. procedure allunitsused;
  72. procedure check_forwards;
  73. procedure checklabels;
  74. function needs_init_final : boolean;
  75. {$ifdef CHAINPROCSYMS}
  76. procedure chainprocsyms;
  77. {$endif CHAINPROCSYMS}
  78. procedure chainoperators;
  79. {$ifdef GDB}
  80. procedure concatstabto(asmlist : taasmoutput);virtual;
  81. function getnewtypecount : word; override;
  82. {$endif GDB}
  83. procedure testfordefaultproperty(p : TNamedIndexItem);
  84. end;
  85. tabstractrecordsymtable = class(tstoredsymtable)
  86. public
  87. procedure load(ppufile:tcompilerppufile);override;
  88. procedure write(ppufile:tcompilerppufile);override;
  89. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  90. procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
  91. end;
  92. trecordsymtable = class(tabstractrecordsymtable)
  93. public
  94. constructor create;
  95. procedure insert_in(tsymt : tsymtable;offset : longint);
  96. end;
  97. tobjectsymtable = class(tabstractrecordsymtable)
  98. public
  99. constructor create(const n:string);
  100. procedure insert(sym : tsymentry);override;
  101. end;
  102. tabstractlocalsymtable = class(tstoredsymtable)
  103. public
  104. procedure load(ppufile:tcompilerppufile);override;
  105. procedure write(ppufile:tcompilerppufile);override;
  106. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  107. procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
  108. end;
  109. tlocalsymtable = class(tabstractlocalsymtable)
  110. public
  111. constructor create;
  112. procedure insert(sym : tsymentry);override;
  113. end;
  114. tparasymtable = class(tabstractlocalsymtable)
  115. public
  116. constructor create;
  117. procedure insert(sym : tsymentry);override;
  118. { change alignment for args only parasymtable }
  119. procedure set_alignment(_alignment : longint);
  120. end;
  121. tabstractunitsymtable = class(tstoredsymtable)
  122. public
  123. {$ifdef GDB}
  124. dbx_count : longint;
  125. prev_dbx_counter : plongint;
  126. dbx_count_ok : boolean;
  127. is_stab_written : boolean;
  128. {$endif GDB}
  129. constructor create(const n : string);
  130. {$ifdef GDB}
  131. procedure concattypestabto(asmlist : taasmoutput);
  132. {$endif GDB}
  133. end;
  134. tglobalsymtable = class(tabstractunitsymtable)
  135. public
  136. unittypecount : word;
  137. unitsym : tunitsym;
  138. constructor create(const n : string);
  139. destructor destroy;override;
  140. procedure load(ppufile:tcompilerppufile);override;
  141. procedure write(ppufile:tcompilerppufile);override;
  142. procedure insert(sym : tsymentry);override;
  143. {$ifdef GDB}
  144. function getnewtypecount : word; override;
  145. {$endif}
  146. end;
  147. tstaticsymtable = class(tabstractunitsymtable)
  148. public
  149. constructor create(const n : string);
  150. procedure load(ppufile:tcompilerppufile);override;
  151. procedure write(ppufile:tcompilerppufile);override;
  152. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  153. procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
  154. procedure insert(sym : tsymentry);override;
  155. end;
  156. twithsymtable = class(tsymtable)
  157. direct_with : boolean;
  158. { in fact it is a tnode }
  159. withnode : pointer;
  160. { tnode to load of direct with var }
  161. { already usable before firstwith
  162. needed for firstpass of function parameters PM }
  163. withrefnode : pointer;
  164. constructor create(aowner:tdef;asymsearch:TDictionary);
  165. destructor destroy;override;
  166. procedure clear;override;
  167. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;override;
  168. end;
  169. tstt_exceptsymtable = class(tsymtable)
  170. public
  171. constructor create;
  172. end;
  173. var
  174. constsymtable : tsymtable; { symtable were the constants can be inserted }
  175. systemunit : tglobalsymtable; { pointer to the system unit }
  176. read_member : boolean; { reading members of an symtable }
  177. lexlevel : longint; { level of code }
  178. { 1 for main procedure }
  179. { 2 for normal function or proc }
  180. { higher for locals }
  181. {****************************************************************************
  182. Functions
  183. ****************************************************************************}
  184. {*** Misc ***}
  185. procedure globaldef(const s : string;var t:ttype);
  186. function findunitsymtable(st:tsymtable):tsymtable;
  187. procedure duplicatesym(sym:tsym);
  188. {*** Search ***}
  189. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  190. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  191. function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
  192. function searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
  193. function search_class_member(pd : tobjectdef;const s : string):tsym;
  194. {*** Object Helpers ***}
  195. function search_default_property(pd : tobjectdef) : tpropertysym;
  196. {*** symtable stack ***}
  197. procedure dellexlevel;
  198. procedure RestoreUnitSyms;
  199. {$ifdef DEBUG}
  200. procedure test_symtablestack;
  201. procedure list_symtablestack;
  202. {$endif DEBUG}
  203. {$ifdef UNITALIASES}
  204. type
  205. punit_alias = ^tunit_alias;
  206. tunit_alias = object(TNamedIndexItem)
  207. newname : pstring;
  208. constructor init(const n:string);
  209. destructor done;virtual;
  210. end;
  211. var
  212. unitaliases : pdictionary;
  213. procedure addunitalias(const n:string);
  214. function getunitalias(const n:string):string;
  215. {$endif UNITALIASES}
  216. {*** Init / Done ***}
  217. procedure InitSymtable;
  218. procedure DoneSymtable;
  219. type
  220. toverloaded_operators = array[NOTOKEN..last_overloaded] of tprocsym;
  221. var
  222. overloaded_operators : toverloaded_operators;
  223. { unequal is not equal}
  224. const
  225. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] =
  226. ('error',
  227. 'plus','minus','star','slash','equal',
  228. 'greater','lower','greater_or_equal',
  229. 'lower_or_equal',
  230. 'sym_diff','starstar',
  231. 'as','is','in','or',
  232. 'and','div','mod','not','shl','shr','xor',
  233. 'assign');
  234. implementation
  235. uses
  236. { global }
  237. version,verbose,globals,
  238. { target }
  239. systems,
  240. { module }
  241. finput,fmodule,
  242. {$ifdef GDB}
  243. gdb,
  244. {$endif GDB}
  245. { codegen }
  246. cgbase
  247. ;
  248. var
  249. in_loading : boolean; { remove !!! }
  250. {*****************************************************************************
  251. TStoredSymtable
  252. *****************************************************************************}
  253. procedure tstoredsymtable.load(ppufile:tcompilerppufile);
  254. begin
  255. { load definitions }
  256. loaddefs(ppufile);
  257. { load symbols }
  258. loadsyms(ppufile);
  259. end;
  260. procedure tstoredsymtable.write(ppufile:tcompilerppufile);
  261. begin
  262. { write definitions }
  263. writedefs(ppufile);
  264. { write symbols }
  265. writesyms(ppufile);
  266. end;
  267. procedure tstoredsymtable.loaddefs(ppufile:tcompilerppufile);
  268. var
  269. hp : tdef;
  270. b : byte;
  271. begin
  272. { load start of definition section, which holds the amount of defs }
  273. if ppufile.readentry<>ibstartdefs then
  274. Message(unit_f_ppu_read_error);
  275. ppufile.getlongint;
  276. { read definitions }
  277. repeat
  278. b:=ppufile.readentry;
  279. case b of
  280. ibpointerdef : hp:=tpointerdef.load(ppufile);
  281. ibarraydef : hp:=tarraydef.load(ppufile);
  282. iborddef : hp:=torddef.load(ppufile);
  283. ibfloatdef : hp:=tfloatdef.load(ppufile);
  284. ibprocdef : hp:=tprocdef.load(ppufile);
  285. ibshortstringdef : hp:=tstringdef.loadshort(ppufile);
  286. iblongstringdef : hp:=tstringdef.loadlong(ppufile);
  287. ibansistringdef : hp:=tstringdef.loadansi(ppufile);
  288. ibwidestringdef : hp:=tstringdef.loadwide(ppufile);
  289. ibrecorddef : hp:=trecorddef.load(ppufile);
  290. ibobjectdef : hp:=tobjectdef.load(ppufile);
  291. ibenumdef : hp:=tenumdef.load(ppufile);
  292. ibsetdef : hp:=tsetdef.load(ppufile);
  293. ibprocvardef : hp:=tprocvardef.load(ppufile);
  294. ibfiledef : hp:=tfiledef.load(ppufile);
  295. ibclassrefdef : hp:=tclassrefdef.load(ppufile);
  296. ibformaldef : hp:=tformaldef.load(ppufile);
  297. ibvariantdef : hp:=tvariantdef.load(ppufile);
  298. ibenddefs : break;
  299. ibend : Message(unit_f_ppu_read_error);
  300. else
  301. Message1(unit_f_ppu_invalid_entry,tostr(b));
  302. end;
  303. hp.owner:=self;
  304. defindex.insert(hp);
  305. until false;
  306. end;
  307. procedure tstoredsymtable.loadsyms(ppufile:tcompilerppufile);
  308. var
  309. b : byte;
  310. sym : tsym;
  311. begin
  312. { load start of definition section, which holds the amount of defs }
  313. if ppufile.readentry<>ibstartsyms then
  314. Message(unit_f_ppu_read_error);
  315. { skip amount of symbols, not used currently }
  316. ppufile.getlongint;
  317. { load datasize,dataalignment of this symboltable }
  318. datasize:=ppufile.getlongint;
  319. dataalignment:=ppufile.getlongint;
  320. { now read the symbols }
  321. repeat
  322. b:=ppufile.readentry;
  323. case b of
  324. ibtypesym : sym:=ttypesym.load(ppufile);
  325. ibprocsym : sym:=tprocsym.load(ppufile);
  326. ibconstsym : sym:=tconstsym.load(ppufile);
  327. ibvarsym : sym:=tvarsym.load(ppufile);
  328. ibfuncretsym : sym:=tfuncretsym.load(ppufile);
  329. ibabsolutesym : sym:=tabsolutesym.load(ppufile);
  330. ibenumsym : sym:=tenumsym.load(ppufile);
  331. ibtypedconstsym : sym:=ttypedconstsym.load(ppufile);
  332. ibpropertysym : sym:=tpropertysym.load(ppufile);
  333. ibunitsym : sym:=tunitsym.load(ppufile);
  334. iblabelsym : sym:=tlabelsym.load(ppufile);
  335. ibsyssym : sym:=tsyssym.load(ppufile);
  336. ibrttisym : sym:=trttisym.load(ppufile);
  337. ibendsyms : break;
  338. ibend : Message(unit_f_ppu_read_error);
  339. else
  340. Message1(unit_f_ppu_invalid_entry,tostr(b));
  341. end;
  342. sym.owner:=self;
  343. symindex.insert(sym);
  344. symsearch.insert(sym);
  345. until false;
  346. end;
  347. procedure tstoredsymtable.writedefs(ppufile:tcompilerppufile);
  348. var
  349. pd : tstoreddef;
  350. begin
  351. { each definition get a number, write then the amount of defs to the
  352. ibstartdef entry }
  353. ppufile.putlongint(defindex.count);
  354. ppufile.writeentry(ibstartdefs);
  355. { now write the definition }
  356. pd:=tstoreddef(defindex.first);
  357. while assigned(pd) do
  358. begin
  359. pd.write(ppufile);
  360. pd:=tstoreddef(pd.indexnext);
  361. end;
  362. { write end of definitions }
  363. ppufile.writeentry(ibenddefs);
  364. end;
  365. procedure tstoredsymtable.writesyms(ppufile:tcompilerppufile);
  366. var
  367. pd : tstoredsym;
  368. begin
  369. { each definition get a number, write then the amount of syms and the
  370. datasize to the ibsymdef entry }
  371. ppufile.putlongint(symindex.count);
  372. ppufile.putlongint(datasize);
  373. ppufile.putlongint(dataalignment);
  374. ppufile.writeentry(ibstartsyms);
  375. { foreach is used to write all symbols }
  376. pd:=tstoredsym(symindex.first);
  377. while assigned(pd) do
  378. begin
  379. pd.write(ppufile);
  380. pd:=tstoredsym(pd.indexnext);
  381. end;
  382. { end of symbols }
  383. ppufile.writeentry(ibendsyms);
  384. end;
  385. procedure tstoredsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  386. var
  387. b : byte;
  388. sym : tstoredsym;
  389. prdef : tstoreddef;
  390. begin
  391. b:=ppufile.readentry;
  392. if b <> ibbeginsymtablebrowser then
  393. Message1(unit_f_ppu_invalid_entry,tostr(b));
  394. repeat
  395. b:=ppufile.readentry;
  396. case b of
  397. ibsymref :
  398. begin
  399. sym:=tstoredsym(ppufile.getderef);
  400. resolvesym(tsym(sym));
  401. if assigned(sym) then
  402. sym.load_references(ppufile,locals);
  403. end;
  404. ibdefref :
  405. begin
  406. prdef:=tstoreddef(ppufile.getderef);
  407. resolvedef(tdef(prdef));
  408. if assigned(prdef) then
  409. begin
  410. if prdef.deftype<>procdef then
  411. Message(unit_f_ppu_read_error);
  412. tprocdef(prdef).load_references(ppufile,locals);
  413. end;
  414. end;
  415. ibendsymtablebrowser :
  416. break;
  417. else
  418. Message1(unit_f_ppu_invalid_entry,tostr(b));
  419. end;
  420. until false;
  421. end;
  422. procedure tstoredsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  423. var
  424. pd : tstoredsym;
  425. begin
  426. ppufile.writeentry(ibbeginsymtablebrowser);
  427. { write all symbols }
  428. pd:=tstoredsym(symindex.first);
  429. while assigned(pd) do
  430. begin
  431. pd.write_references(ppufile,locals);
  432. pd:=tstoredsym(pd.indexnext);
  433. end;
  434. ppufile.writeentry(ibendsymtablebrowser);
  435. end;
  436. procedure tstoredsymtable.deref;
  437. var
  438. hp : tdef;
  439. hs : tsym;
  440. begin
  441. { deref the interface definitions }
  442. hp:=tdef(defindex.first);
  443. while assigned(hp) do
  444. begin
  445. hp.deref;
  446. hp:=tdef(hp.indexnext);
  447. end;
  448. { first deref the interface ttype symbols }
  449. hs:=tsym(symindex.first);
  450. while assigned(hs) do
  451. begin
  452. if hs.typ=typesym then
  453. hs.deref;
  454. hs:=tsym(hs.indexnext);
  455. end;
  456. { deref the interface symbols }
  457. hs:=tsym(symindex.first);
  458. while assigned(hs) do
  459. begin
  460. if hs.typ<>typesym then
  461. hs.deref;
  462. hs:=tsym(hs.indexnext);
  463. end;
  464. end;
  465. procedure tstoredsymtable.derefimpl;
  466. var
  467. hp : tdef;
  468. begin
  469. { deref the implementation part of definitions }
  470. hp:=tdef(defindex.first);
  471. while assigned(hp) do
  472. begin
  473. hp.derefimpl;
  474. hp:=tdef(hp.indexnext);
  475. end;
  476. end;
  477. procedure tstoredsymtable.insert(sym:tsymentry);
  478. var
  479. hsym : tsym;
  480. begin
  481. { set owner and sym indexnb }
  482. sym.owner:=self;
  483. {$ifdef CHAINPROCSYMS}
  484. { set the nextprocsym field }
  485. if sym.typ=procsym then
  486. chainprocsym(sym);
  487. {$endif CHAINPROCSYMS}
  488. { writes the symbol in data segment if required }
  489. { also sets the datasize of owner }
  490. if not in_loading then
  491. tstoredsym(sym).insert_in_data;
  492. { check the current symtable }
  493. hsym:=tsym(search(sym.name));
  494. if assigned(hsym) then
  495. begin
  496. { in TP and Delphi you can have a local with the
  497. same name as the function, the function is then hidden for
  498. the user. (Under delphi it can still be accessed using result),
  499. but don't allow hiding of RESULT }
  500. if (m_tp in aktmodeswitches) and
  501. (hsym.typ=funcretsym) and
  502. not((m_result in aktmodeswitches) and
  503. (hsym.name='RESULT')) then
  504. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  505. else
  506. begin
  507. DuplicateSym(hsym);
  508. exit;
  509. end;
  510. end;
  511. { register definition of typesym }
  512. if (sym.typ = typesym) and
  513. assigned(ttypesym(sym).restype.def) then
  514. begin
  515. if not(assigned(ttypesym(sym).restype.def.owner)) and
  516. (ttypesym(sym).restype.def.deftype<>errordef) then
  517. registerdef(ttypesym(sym).restype.def);
  518. {$ifdef GDB}
  519. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  520. (symtabletype in [globalsymtable,staticsymtable]) then
  521. begin
  522. ttypesym(sym).isusedinstab := true;
  523. {sym.concatstabto(debuglist);}
  524. end;
  525. {$endif GDB}
  526. end;
  527. { insert in index and search hash }
  528. symindex.insert(sym);
  529. symsearch.insert(sym);
  530. end;
  531. function tstoredsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  532. var
  533. hp : tstoredsym;
  534. newref : tref;
  535. begin
  536. hp:=tstoredsym(inherited speedsearch(s,speedvalue));
  537. if assigned(hp) then
  538. begin
  539. { reject non static members in static procedures,
  540. be carefull aktprocsym.definition is not allways
  541. loaded already (PFV) }
  542. if (symtabletype=objectsymtable) and
  543. not(sp_static in hp.symoptions) and
  544. allow_only_static
  545. {assigned(aktprocsym) and
  546. assigned(aktprocsym.definition) and
  547. ((aktprocsym.definition.options and postaticmethod)<>0)} then
  548. Message(sym_e_only_static_in_static);
  549. if (unitid<>0) and
  550. (symtabletype = globalsymtable) and
  551. assigned(tglobalsymtable(self).unitsym) then
  552. inc(tglobalsymtable(self).unitsym.refs);
  553. {$ifdef GDB}
  554. { if it is a type, we need the stabs of this type
  555. this might be the cause of the class debug problems
  556. as TCHILDCLASS.Create did not generate appropriate
  557. stabs debug info if TCHILDCLASS wasn't used anywhere else PM }
  558. if (hp.typ=typesym) and make_ref then
  559. begin
  560. if assigned(ttypesym(hp).restype.def) then
  561. tstoreddef(ttypesym(hp).restype.def).numberstring
  562. else
  563. ttypesym(hp).isusedinstab:=true;
  564. end;
  565. {$endif GDB}
  566. { unitsym are only loaded for browsing PM }
  567. { this was buggy anyway because we could use }
  568. { unitsyms from other units in _USES !! }
  569. {if (symtabletype=unitsymtable) and (hp.typ=unitsym) and
  570. assigned(current_module) and (current_module.globalsymtable<>.load) then
  571. hp:=nil;}
  572. if assigned(hp) and
  573. (cs_browser in aktmoduleswitches) and make_ref then
  574. begin
  575. newref:=tref.create(hp.lastref,@akttokenpos);
  576. { for symbols that are in tables without
  577. browser info or syssyms (PM) }
  578. if hp.refcount=0 then
  579. begin
  580. hp.defref:=newref;
  581. hp.lastref:=newref;
  582. end
  583. else
  584. if resolving_forward and assigned(hp.defref) then
  585. { put it as second reference }
  586. begin
  587. newref.nextref:=hp.defref.nextref;
  588. hp.defref.nextref:=newref;
  589. hp.lastref.nextref:=nil;
  590. end
  591. else
  592. hp.lastref:=newref;
  593. inc(hp.refcount);
  594. end;
  595. if assigned(hp) and make_ref then
  596. begin
  597. inc(hp.refs);
  598. end;
  599. end;
  600. speedsearch:=hp;
  601. end;
  602. {**************************************
  603. Callbacks
  604. **************************************}
  605. procedure TStoredSymtable.check_forward(sym : TNamedIndexItem);
  606. begin
  607. if tsym(sym).typ=procsym then
  608. tprocsym(sym).check_forward
  609. { check also object method table }
  610. { we needn't to test the def list }
  611. { because each object has to have a type sym }
  612. else
  613. if (tsym(sym).typ=typesym) and
  614. assigned(ttypesym(sym).restype.def) and
  615. (ttypesym(sym).restype.def.deftype=objectdef) then
  616. tobjectdef(ttypesym(sym).restype.def).check_forwards;
  617. end;
  618. procedure TStoredSymtable.labeldefined(p : TNamedIndexItem);
  619. begin
  620. if (tsym(p).typ=labelsym) and
  621. not(tlabelsym(p).defined) then
  622. begin
  623. if tlabelsym(p).used then
  624. Message1(sym_e_label_used_and_not_defined,tlabelsym(p).realname)
  625. else
  626. Message1(sym_w_label_not_defined,tlabelsym(p).realname);
  627. end;
  628. end;
  629. procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem);
  630. begin
  631. if (tsym(p).typ=unitsym) and
  632. (tunitsym(p).refs=0) and
  633. { do not claim for unit name itself !! }
  634. (tunitsym(p).unitsymtable.symtabletype=globalsymtable) then
  635. MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,
  636. p.name,current_module.modulename^);
  637. end;
  638. procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem);
  639. begin
  640. if (tsym(p).typ=varsym) and
  641. ((tsym(p).owner.symtabletype in
  642. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  643. begin
  644. { unused symbol should be reported only if no }
  645. { error is reported }
  646. { if the symbol is in a register it is used }
  647. { also don't count the value parameters which have local copies }
  648. { also don't claim for high param of open parameters (PM) }
  649. if (Errorcount<>0) or
  650. (copy(p.name,1,3)='val') or
  651. (copy(p.name,1,4)='high') then
  652. exit;
  653. if (tvarsym(p).refs=0) then
  654. begin
  655. if (tsym(p).owner.symtabletype=parasymtable) or (vo_is_local_copy in tvarsym(p).varoptions) then
  656. begin
  657. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_not_used,tsym(p).realname);
  658. end
  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]) then
  669. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname)
  670. end
  671. else if (vo_is_local_copy in tvarsym(p).varoptions) then
  672. begin
  673. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  674. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname);
  675. end
  676. else if (tsym(p).owner.symtabletype=objectsymtable) then
  677. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_only_set,tsym(p).owner.realname^,tsym(p).realname)
  678. else if (tsym(p).owner.symtabletype<>parasymtable) then
  679. if not (vo_is_exported in tvarsym(p).varoptions) then
  680. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_only_set,tsym(p).realname);
  681. end;
  682. end
  683. else if ((tsym(p).owner.symtabletype in
  684. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  685. begin
  686. if (Errorcount<>0) then
  687. exit;
  688. { do not claim for inherited private fields !! }
  689. if (tstoredsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
  690. MessagePos2(tsym(p).fileinfo,sym_n_private_method_not_used,tsym(p).owner.realname^,tsym(p).realname)
  691. { units references are problematic }
  692. else if (tstoredsym(p).refs=0) and not(tsym(p).typ in [funcretsym,enumsym,unitsym]) then
  693. if (tsym(p).typ<>procsym) or not (tprocsym(p).is_global) or
  694. { all program functions are declared global
  695. but unused should still be signaled PM }
  696. ((tsym(p).owner.symtabletype=staticsymtable) and
  697. not current_module.is_unit) then
  698. MessagePos2(tsym(p).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(p).typ],tsym(p).realname);
  699. end;
  700. end;
  701. procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem);
  702. begin
  703. if sp_private in tsym(p).symoptions then
  704. varsymbolused(p);
  705. end;
  706. procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem);
  707. begin
  708. {
  709. Don't test simple object aliases PM
  710. }
  711. if (tsym(p).typ=typesym) and
  712. (ttypesym(p).restype.def.deftype=objectdef) and
  713. (ttypesym(p).restype.def.typesym=tsym(p)) then
  714. tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate);
  715. end;
  716. procedure tstoredsymtable.order_overloads(p : TNamedIndexItem);
  717. begin
  718. if tsym(p).typ=procsym then
  719. tprocsym(p).order_overloaded;
  720. end;
  721. {$ifdef GDB}
  722. procedure TStoredSymtable.concatstab(p : TNamedIndexItem);
  723. begin
  724. if tsym(p).typ <> procsym then
  725. tstoredsym(p).concatstabto(asmoutput);
  726. end;
  727. procedure TStoredSymtable.resetstab(p : TNamedIndexItem);
  728. begin
  729. if tsym(p).typ <> procsym then
  730. tstoredsym(p).isstabwritten:=false;
  731. end;
  732. procedure TStoredSymtable.concattypestab(p : TNamedIndexItem);
  733. begin
  734. if tsym(p).typ = typesym then
  735. begin
  736. tstoredsym(p).isstabwritten:=false;
  737. tstoredsym(p).concatstabto(asmoutput);
  738. end;
  739. end;
  740. function tstoredsymtable.getnewtypecount : word;
  741. begin
  742. getnewtypecount:=pglobaltypecount^;
  743. inc(pglobaltypecount^);
  744. end;
  745. {$endif GDB}
  746. {$ifdef CHAINPROCSYMS}
  747. procedure chainprocsym(p : tsym);
  748. var
  749. storesymtablestack : tsymtable;
  750. srsym : tsym;
  751. srsymtable : tsymtable;
  752. begin
  753. if p.typ=procsym then
  754. begin
  755. storesymtablestack:=symtablestack;
  756. symtablestack:=p.owner.next;
  757. while assigned(symtablestack) do
  758. begin
  759. { search for same procsym in other units }
  760. searchsym(p.name,srsym,srsymtable)
  761. if assigned(srsym) and
  762. (srsym.typ=procsym) then
  763. begin
  764. tprocsym(p).nextprocsym:=tprocsym(srsym);
  765. symtablestack:=storesymtablestack;
  766. exit;
  767. end
  768. else if srsym=nil then
  769. symtablestack:=nil
  770. else
  771. symtablestack:=srsymtable.next;
  772. end;
  773. symtablestack:=storesymtablestack;
  774. end;
  775. end;
  776. {$endif}
  777. procedure tstoredsymtable.chainoperators;
  778. var
  779. p : tprocsym;
  780. t : ttoken;
  781. def : tprocdef;
  782. srsym : tsym;
  783. srsymtable,
  784. storesymtablestack : tsymtable;
  785. begin
  786. storesymtablestack:=symtablestack;
  787. symtablestack:=self;
  788. make_ref:=false;
  789. for t:=first_overloaded to last_overloaded do
  790. begin
  791. p:=nil;
  792. def:=nil;
  793. overloaded_operators[t]:=nil;
  794. { each operator has a unique lowercased internal name PM }
  795. while assigned(symtablestack) do
  796. begin
  797. searchsym(overloaded_names[t],srsym,srsymtable);
  798. if not assigned(srsym) then
  799. begin
  800. if (t=_STARSTAR) then
  801. begin
  802. symtablestack:=systemunit;
  803. searchsym('POWER',srsym,srsymtable);
  804. end;
  805. end;
  806. if assigned(srsym) then
  807. begin
  808. if (srsym.typ<>procsym) then
  809. internalerror(12344321);
  810. if assigned(p) then
  811. begin
  812. {$ifdef CHAINPROCSYMS}
  813. p.nextprocsym:=tprocsym(srsym);
  814. {$endif CHAINPROCSYMS}
  815. def.nextoverloaded:=tprocsym(srsym).definition;
  816. end
  817. else
  818. overloaded_operators[t]:=tprocsym(srsym);
  819. p:=tprocsym(srsym);
  820. def:=p.definition;
  821. while assigned(def.nextoverloaded) and
  822. (def.nextoverloaded.owner=p.owner) do
  823. def:=def.nextoverloaded;
  824. def.nextoverloaded:=nil;
  825. symtablestack:=srsym.owner.next;
  826. end
  827. else
  828. begin
  829. symtablestack:=nil;
  830. {$ifdef CHAINPROCSYMS}
  831. if assigned(p) then
  832. p.nextprocsym:=nil;
  833. {$endif CHAINPROCSYMS}
  834. end;
  835. { search for same procsym in other units }
  836. end;
  837. symtablestack:=self;
  838. end;
  839. make_ref:=true;
  840. symtablestack:=storesymtablestack;
  841. end;
  842. {***********************************************
  843. Process all entries
  844. ***********************************************}
  845. { checks, if all procsyms and methods are defined }
  846. procedure tstoredsymtable.check_forwards;
  847. begin
  848. foreach({$ifdef FPCPROCVAR}@{$endif}check_forward);
  849. end;
  850. procedure tstoredsymtable.checklabels;
  851. begin
  852. foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined);
  853. end;
  854. procedure tstoredsymtable.allunitsused;
  855. begin
  856. foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
  857. end;
  858. procedure tstoredsymtable.allsymbolsused;
  859. begin
  860. foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused);
  861. end;
  862. procedure tstoredsymtable.allprivatesused;
  863. begin
  864. foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused);
  865. end;
  866. {$ifdef CHAINPROCSYMS}
  867. procedure tstoredsymtable.chainprocsyms;
  868. begin
  869. foreach({$ifdef FPCPROCVAR}@{$endif}chainprocsym);
  870. end;
  871. {$endif CHAINPROCSYMS}
  872. {$ifdef GDB}
  873. procedure tstoredsymtable.concatstabto(asmlist : taasmoutput);
  874. begin
  875. asmoutput:=asmlist;
  876. if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
  877. foreach({$ifdef FPCPROCVAR}@{$endif}resetstab);
  878. foreach({$ifdef FPCPROCVAR}@{$endif}concatstab);
  879. end;
  880. {$endif}
  881. { returns true, if p contains data which needs init/final code }
  882. function tstoredsymtable.needs_init_final : boolean;
  883. begin
  884. b_needs_init_final:=false;
  885. foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final);
  886. needs_init_final:=b_needs_init_final;
  887. end;
  888. {****************************************************************************
  889. TAbstractRecordSymtable
  890. ****************************************************************************}
  891. procedure tabstractrecordsymtable.load(ppufile:tcompilerppufile);
  892. var
  893. storesymtable : tsymtable;
  894. begin
  895. storesymtable:=aktrecordsymtable;
  896. aktrecordsymtable:=self;
  897. inherited load(ppufile);
  898. aktrecordsymtable:=storesymtable;
  899. end;
  900. procedure tabstractrecordsymtable.write(ppufile:tcompilerppufile);
  901. var
  902. oldtyp : byte;
  903. storesymtable : tsymtable;
  904. begin
  905. storesymtable:=aktrecordsymtable;
  906. aktrecordsymtable:=self;
  907. oldtyp:=ppufile.entrytyp;
  908. ppufile.entrytyp:=subentryid;
  909. { order procsym overloads }
  910. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  911. inherited write(ppufile);
  912. ppufile.entrytyp:=oldtyp;
  913. aktrecordsymtable:=storesymtable;
  914. end;
  915. procedure tabstractrecordsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  916. var
  917. storesymtable : tsymtable;
  918. begin
  919. storesymtable:=aktrecordsymtable;
  920. aktrecordsymtable:=self;
  921. inherited load_references(ppufile,locals);
  922. aktrecordsymtable:=storesymtable;
  923. end;
  924. procedure tabstractrecordsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  925. var
  926. storesymtable : tsymtable;
  927. begin
  928. storesymtable:=aktrecordsymtable;
  929. aktrecordsymtable:=self;
  930. inherited write_references(ppufile,locals);
  931. aktrecordsymtable:=storesymtable;
  932. end;
  933. procedure TStoredSymtable._needs_init_final(p : tnamedindexitem);
  934. begin
  935. if (not b_needs_init_final) and
  936. (tsym(p).typ=varsym) and
  937. assigned(tvarsym(p).vartype.def) and
  938. not is_class(tvarsym(p).vartype.def) and
  939. tstoreddef(tvarsym(p).vartype.def).needs_inittable then
  940. b_needs_init_final:=true;
  941. end;
  942. {****************************************************************************
  943. TRecordSymtable
  944. ****************************************************************************}
  945. constructor trecordsymtable.create;
  946. begin
  947. inherited create('');
  948. symtabletype:=recordsymtable;
  949. end;
  950. { this procedure is reserved for inserting case variant into
  951. a record symtable }
  952. { the offset is the location of the start of the variant
  953. and datasize and dataalignment corresponds to
  954. the complete size (see code in pdecl unit) PM }
  955. procedure trecordsymtable.insert_in(tsymt : tsymtable;offset : longint);
  956. var
  957. ps,nps : tvarsym;
  958. pd,npd : tdef;
  959. storesize,storealign : longint;
  960. begin
  961. storesize:=tsymt.datasize;
  962. storealign:=tsymt.dataalignment;
  963. tsymt.datasize:=offset;
  964. ps:=tvarsym(symindex.first);
  965. while assigned(ps) do
  966. begin
  967. { this is used to insert case variant into the main
  968. record }
  969. tsymt.datasize:=ps.address+offset;
  970. nps:=tvarsym(ps.indexnext);
  971. symindex.deleteindex(ps);
  972. ps.left:=nil;
  973. ps.right:=nil;
  974. tsymt.insert(ps);
  975. ps:=nps;
  976. end;
  977. pd:=tdef(defindex.first);
  978. while assigned(pd) do
  979. begin
  980. npd:=tdef(pd.indexnext);
  981. defindex.deleteindex(pd);
  982. pd.left:=nil;
  983. pd.right:=nil;
  984. tsymt.registerdef(pd);
  985. pd:=npd;
  986. end;
  987. tsymt.datasize:=storesize;
  988. tsymt.dataalignment:=storealign;
  989. end;
  990. {****************************************************************************
  991. TObjectSymtable
  992. ****************************************************************************}
  993. constructor tobjectsymtable.create(const n:string);
  994. begin
  995. inherited create(n);
  996. symtabletype:=objectsymtable;
  997. end;
  998. procedure tobjectsymtable.insert(sym:tsymentry);
  999. var
  1000. hsym : tsym;
  1001. begin
  1002. { check for duplicate field id in inherited classes }
  1003. if (sym.typ=varsym) and
  1004. assigned(defowner) and
  1005. (
  1006. not(m_delphi in aktmodeswitches) or
  1007. is_object(tdef(defowner))
  1008. ) then
  1009. begin
  1010. { but private ids can be reused }
  1011. hsym:=search_class_member(tobjectdef(defowner),sym.name);
  1012. if assigned(hsym) and
  1013. (not(sp_private in hsym.symoptions) or
  1014. (hsym.owner.defowner.owner.unitid=0)) then
  1015. begin
  1016. DuplicateSym(hsym);
  1017. exit;
  1018. end;
  1019. end;
  1020. inherited insert(sym);
  1021. end;
  1022. {****************************************************************************
  1023. TAbstractLocalSymtable
  1024. ****************************************************************************}
  1025. procedure tabstractlocalsymtable.load(ppufile:tcompilerppufile);
  1026. var
  1027. storesymtable : tsymtable;
  1028. begin
  1029. storesymtable:=aktlocalsymtable;
  1030. aktlocalsymtable:=self;
  1031. inherited load(ppufile);
  1032. aktlocalsymtable:=storesymtable;
  1033. end;
  1034. procedure tabstractlocalsymtable.write(ppufile:tcompilerppufile);
  1035. var
  1036. oldtyp : byte;
  1037. storesymtable : tsymtable;
  1038. begin
  1039. storesymtable:=aktlocalsymtable;
  1040. aktlocalsymtable:=self;
  1041. oldtyp:=ppufile.entrytyp;
  1042. ppufile.entrytyp:=subentryid;
  1043. { order procsym overloads }
  1044. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1045. { write definitions }
  1046. writedefs(ppufile);
  1047. { write symbols }
  1048. writesyms(ppufile);
  1049. ppufile.entrytyp:=oldtyp;
  1050. aktlocalsymtable:=storesymtable;
  1051. end;
  1052. procedure tabstractlocalsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1053. var
  1054. storesymtable : tsymtable;
  1055. begin
  1056. storesymtable:=aktlocalsymtable;
  1057. aktlocalsymtable:=self;
  1058. inherited load_references(ppufile,locals);
  1059. aktlocalsymtable:=storesymtable;
  1060. end;
  1061. procedure tabstractlocalsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1062. var
  1063. storesymtable : tsymtable;
  1064. begin
  1065. storesymtable:=aktlocalsymtable;
  1066. aktlocalsymtable:=self;
  1067. inherited write_references(ppufile,locals);
  1068. aktlocalsymtable:=storesymtable;
  1069. end;
  1070. {****************************************************************************
  1071. TLocalSymtable
  1072. ****************************************************************************}
  1073. constructor tlocalsymtable.create;
  1074. begin
  1075. inherited create('');
  1076. symtabletype:=localsymtable;
  1077. end;
  1078. procedure tlocalsymtable.insert(sym:tsymentry);
  1079. var
  1080. hsym : tsym;
  1081. begin
  1082. if assigned(next) then
  1083. begin
  1084. if (next.symtabletype=parasymtable) then
  1085. begin
  1086. hsym:=tsym(next.search(sym.name));
  1087. if assigned(hsym) then
  1088. begin
  1089. { a parameter and the function can have the same
  1090. name in TP and Delphi, but RESULT not }
  1091. if (m_tp in aktmodeswitches) and
  1092. (sym.typ=funcretsym) and
  1093. not((m_result in aktmodeswitches) and
  1094. (sym.name='RESULT')) then
  1095. sym.name:='hidden'+sym.name
  1096. else
  1097. begin
  1098. DuplicateSym(hsym);
  1099. exit;
  1100. end;
  1101. end;
  1102. end;
  1103. { check for duplicate id in local symtable of methods }
  1104. if assigned(next.next) and
  1105. { funcretsym is allowed !! }
  1106. (sym.typ <> funcretsym) and
  1107. (next.next.symtabletype=objectsymtable) then
  1108. begin
  1109. hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
  1110. if assigned(hsym) and
  1111. { private ids can be reused }
  1112. (not(sp_private in hsym.symoptions) or
  1113. (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
  1114. begin
  1115. { delphi allows to reuse the names in a class, but not
  1116. in object (tp7 compatible) }
  1117. if not((m_delphi in aktmodeswitches) and
  1118. is_class(tdef(next.next.defowner))) then
  1119. begin
  1120. DuplicateSym(hsym);
  1121. exit;
  1122. end;
  1123. end;
  1124. end;
  1125. end;
  1126. inherited insert(sym);
  1127. end;
  1128. {****************************************************************************
  1129. TParaSymtable
  1130. ****************************************************************************}
  1131. constructor tparasymtable.create;
  1132. begin
  1133. inherited create('');
  1134. symtabletype:=parasymtable;
  1135. dataalignment:=aktalignment.paraalign;
  1136. end;
  1137. procedure tparasymtable.insert(sym:tsymentry);
  1138. var
  1139. hsym : tsym;
  1140. begin
  1141. { check for duplicate id in para symtable of methods }
  1142. if assigned(procinfo^._class) and
  1143. { but not in nested procedures !}
  1144. (not(assigned(procinfo^.parent)) or
  1145. (assigned(procinfo^.parent) and
  1146. not(assigned(procinfo^.parent^._class)))
  1147. ) and
  1148. { funcretsym is allowed !! }
  1149. (sym.typ <> funcretsym) then
  1150. begin
  1151. hsym:=search_class_member(procinfo^._class,sym.name);
  1152. if assigned(hsym) and
  1153. { private ids can be reused }
  1154. (not(sp_private in hsym.symoptions) or
  1155. (hsym.owner.defowner.owner.unitid=0)) then
  1156. begin
  1157. { delphi allows to reuse the names in a class, but not
  1158. in object (tp7 compatible) }
  1159. if not((m_delphi in aktmodeswitches) and
  1160. is_class(procinfo^._class)) then
  1161. begin
  1162. DuplicateSym(hsym);
  1163. exit;
  1164. end;
  1165. end;
  1166. end;
  1167. inherited insert(sym);
  1168. end;
  1169. procedure tparasymtable.set_alignment(_alignment : longint);
  1170. var
  1171. sym : tvarsym;
  1172. l : longint;
  1173. begin
  1174. dataalignment:=_alignment;
  1175. sym:=tvarsym(symindex.first);
  1176. datasize:=0;
  1177. { there can be only varsyms }
  1178. while assigned(sym) do
  1179. begin
  1180. l:=sym.getpushsize;
  1181. sym.address:=datasize;
  1182. datasize:=align(datasize+l,dataalignment);
  1183. sym:=tvarsym(sym.indexnext);
  1184. end;
  1185. end;
  1186. {****************************************************************************
  1187. TAbstractUnitSymtable
  1188. ****************************************************************************}
  1189. constructor tabstractunitsymtable.create(const n : string);
  1190. begin
  1191. inherited create(n);
  1192. symsearch.usehash;
  1193. {$ifdef GDB}
  1194. { reset GDB things }
  1195. prev_dbx_counter := dbx_counter;
  1196. dbx_counter := nil;
  1197. is_stab_written:=false;
  1198. dbx_count := -1;
  1199. {$endif GDB}
  1200. end;
  1201. {$ifdef GDB}
  1202. procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
  1203. var prev_dbx_count : plongint;
  1204. begin
  1205. if is_stab_written then
  1206. exit;
  1207. if not assigned(name) then
  1208. name := stringdup('Main_program');
  1209. if (symtabletype = globalsymtable) and
  1210. (current_module.globalsymtable<>self) then
  1211. begin
  1212. unitid:=current_module.unitcount;
  1213. inc(current_module.unitcount);
  1214. end;
  1215. asmList.concat(Tai_asm_comment.Create(strpnew('Begin unit '+name^+' has index '+tostr(unitid))));
  1216. if cs_gdb_dbx in aktglobalswitches then
  1217. begin
  1218. if dbx_count_ok then
  1219. begin
  1220. asmList.concat(Tai_asm_comment.Create(strpnew('"repeated" unit '+name^
  1221. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count))));
  1222. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1223. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count))));
  1224. exit;
  1225. end
  1226. else if (current_module.globalsymtable<>self) then
  1227. begin
  1228. prev_dbx_count := dbx_counter;
  1229. dbx_counter := nil;
  1230. do_count_dbx:=false;
  1231. if (symtabletype = globalsymtable) and (unitid<>0) then
  1232. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1233. dbx_counter := @dbx_count;
  1234. dbx_count:=0;
  1235. do_count_dbx:=assigned(dbx_counter);
  1236. end;
  1237. end;
  1238. asmoutput:=asmlist;
  1239. foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab);
  1240. if cs_gdb_dbx in aktglobalswitches then
  1241. begin
  1242. if (current_module.globalsymtable<>self) then
  1243. begin
  1244. dbx_counter := prev_dbx_count;
  1245. do_count_dbx:=false;
  1246. asmList.concat(Tai_asm_comment.Create(strpnew('End unit '+name^
  1247. +' has index '+tostr(unitid))));
  1248. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1249. +tostr(N_EINCL)+',0,0,0')));
  1250. do_count_dbx:=assigned(dbx_counter);
  1251. dbx_count_ok := {true}false;
  1252. end;
  1253. end;
  1254. is_stab_written:=true;
  1255. end;
  1256. {$endif GDB}
  1257. {****************************************************************************
  1258. TStaticSymtable
  1259. ****************************************************************************}
  1260. constructor tstaticsymtable.create(const n : string);
  1261. begin
  1262. inherited create(n);
  1263. symtabletype:=staticsymtable;
  1264. end;
  1265. procedure tstaticsymtable.load(ppufile:tcompilerppufile);
  1266. begin
  1267. aktstaticsymtable:=self;
  1268. next:=symtablestack;
  1269. symtablestack:=self;
  1270. inherited load(ppufile);
  1271. { now we can deref the syms and defs }
  1272. deref;
  1273. { restore symtablestack }
  1274. symtablestack:=next;
  1275. end;
  1276. procedure tstaticsymtable.write(ppufile:tcompilerppufile);
  1277. begin
  1278. aktstaticsymtable:=self;
  1279. { order procsym overloads }
  1280. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1281. inherited write(ppufile);
  1282. end;
  1283. procedure tstaticsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1284. begin
  1285. aktstaticsymtable:=self;
  1286. inherited load_references(ppufile,locals);
  1287. end;
  1288. procedure tstaticsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1289. begin
  1290. aktstaticsymtable:=self;
  1291. inherited write_references(ppufile,locals);
  1292. end;
  1293. procedure tstaticsymtable.insert(sym:tsymentry);
  1294. var
  1295. hsym : tsym;
  1296. begin
  1297. { also check the global symtable }
  1298. if assigned(next) and
  1299. (next.unitid=0) then
  1300. begin
  1301. hsym:=tsym(next.search(sym.name));
  1302. if assigned(hsym) then
  1303. begin
  1304. DuplicateSym(hsym);
  1305. exit;
  1306. end;
  1307. end;
  1308. inherited insert(sym);
  1309. end;
  1310. {****************************************************************************
  1311. TGlobalSymtable
  1312. ****************************************************************************}
  1313. constructor tglobalsymtable.create(const n : string);
  1314. begin
  1315. inherited create(n);
  1316. symtabletype:=globalsymtable;
  1317. unitid:=0;
  1318. unitsym:=nil;
  1319. {$ifdef GDB}
  1320. if cs_gdb_dbx in aktglobalswitches then
  1321. begin
  1322. dbx_count := 0;
  1323. unittypecount:=1;
  1324. pglobaltypecount := @unittypecount;
  1325. {unitid:=current_module.unitcount;}
  1326. debugList.concat(Tai_asm_comment.Create(strpnew('Global '+name^+' has index '+tostr(unitid))));
  1327. debugList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1328. {inc(current_module.unitcount);}
  1329. dbx_count_ok:=false;
  1330. dbx_counter:=@dbx_count;
  1331. do_count_dbx:=true;
  1332. end;
  1333. {$endif GDB}
  1334. end;
  1335. destructor tglobalsymtable.destroy;
  1336. var
  1337. pus : tunitsym;
  1338. begin
  1339. pus:=unitsym;
  1340. while assigned(pus) do
  1341. begin
  1342. unitsym:=pus.prevsym;
  1343. pus.prevsym:=nil;
  1344. pus.unitsymtable:=nil;
  1345. pus:=unitsym;
  1346. end;
  1347. inherited destroy;
  1348. end;
  1349. procedure tglobalsymtable.load(ppufile:tcompilerppufile);
  1350. {$ifdef GDB}
  1351. var
  1352. storeGlobalTypeCount : pword;
  1353. {$endif GDB}
  1354. begin
  1355. {$ifdef GDB}
  1356. if cs_gdb_dbx in aktglobalswitches then
  1357. begin
  1358. UnitTypeCount:=1;
  1359. storeGlobalTypeCount:=PGlobalTypeCount;
  1360. PglobalTypeCount:=@UnitTypeCount;
  1361. end;
  1362. {$endif GDB}
  1363. symtablelevel:=0;
  1364. {$ifndef NEWMAP}
  1365. current_module.map^[0]:=self;
  1366. {$else NEWMAP}
  1367. current_module.globalsymtable:=self;
  1368. {$endif NEWMAP}
  1369. next:=symtablestack;
  1370. symtablestack:=self;
  1371. inherited load(ppufile);
  1372. { now we can deref the syms and defs }
  1373. deref;
  1374. { restore symtablestack }
  1375. symtablestack:=next;
  1376. {$ifdef NEWMAP}
  1377. { necessary for dependencies }
  1378. current_module.globalsymtable:=nil;
  1379. {$endif NEWMAP}
  1380. end;
  1381. procedure tglobalsymtable.write(ppufile:tcompilerppufile);
  1382. begin
  1383. { order procsym overloads }
  1384. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1385. { write the symtable entries }
  1386. inherited write(ppufile);
  1387. { write dbx count }
  1388. {$ifdef GDB}
  1389. if cs_gdb_dbx in aktglobalswitches then
  1390. begin
  1391. {$IfDef EXTDEBUG}
  1392. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1393. {$ENDIF EXTDEBUG}
  1394. ppufile.do_crc:=false;
  1395. ppufile.putlongint(dbx_count);
  1396. ppufile.writeentry(ibdbxcount);
  1397. ppufile.do_crc:=true;
  1398. end;
  1399. {$endif GDB}
  1400. end;
  1401. procedure tglobalsymtable.insert(sym:tsymentry);
  1402. var
  1403. hsym : tsym;
  1404. begin
  1405. { also check the global symtable }
  1406. if assigned(next) and
  1407. (next.unitid=0) then
  1408. begin
  1409. hsym:=tsym(next.search(sym.name));
  1410. if assigned(hsym) then
  1411. begin
  1412. DuplicateSym(hsym);
  1413. exit;
  1414. end;
  1415. end;
  1416. hsym:=tsym(search(sym.name));
  1417. if assigned(hsym) then
  1418. begin
  1419. { Delphi you can have a symbol with the same name as the
  1420. unit, the unit can then not be accessed anymore using
  1421. <unit>.<id>, so we can hide the symbol }
  1422. if (m_tp in aktmodeswitches) and
  1423. (hsym.typ=symconst.unitsym) then
  1424. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  1425. else
  1426. begin
  1427. DuplicateSym(hsym);
  1428. exit;
  1429. end;
  1430. end;
  1431. inherited insert(sym);
  1432. end;
  1433. {$ifdef GDB}
  1434. function tglobalsymtable.getnewtypecount : word;
  1435. begin
  1436. if not (cs_gdb_dbx in aktglobalswitches) then
  1437. getnewtypecount:=inherited getnewtypecount
  1438. else
  1439. begin
  1440. getnewtypecount:=unittypecount;
  1441. inc(unittypecount);
  1442. end;
  1443. end;
  1444. {$endif}
  1445. {****************************************************************************
  1446. TWITHSYMTABLE
  1447. ****************************************************************************}
  1448. constructor twithsymtable.create(aowner:tdef;asymsearch:TDictionary);
  1449. begin
  1450. inherited create('');
  1451. symtabletype:=withsymtable;
  1452. direct_with:=false;
  1453. withnode:=nil;
  1454. withrefnode:=nil;
  1455. { we don't need the symsearch }
  1456. symsearch.free;
  1457. { set the defaults }
  1458. symsearch:=asymsearch;
  1459. defowner:=aowner;
  1460. end;
  1461. destructor twithsymtable.destroy;
  1462. begin
  1463. symsearch:=nil;
  1464. inherited destroy;
  1465. end;
  1466. procedure twithsymtable.clear;
  1467. begin
  1468. { remove no entry from a withsymtable as it is only a pointer to the
  1469. recorddef or objectdef symtable }
  1470. end;
  1471. function twithsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  1472. var
  1473. hp : tsym;
  1474. begin
  1475. hp:=tsym(inherited speedsearch(s, speedvalue));
  1476. { skip private members that can't be seen }
  1477. if assigned(hp) and
  1478. (sp_private in hp.symoptions) and
  1479. (hp.owner.symtabletype=objectsymtable) and
  1480. (hp.owner.defowner.owner.symtabletype=globalsymtable) and
  1481. (hp.owner.defowner.owner.unitid<>0) then
  1482. hp:=nil;
  1483. speedsearch:=hp;
  1484. end;
  1485. {****************************************************************************
  1486. TSTT_ExceptionSymtable
  1487. ****************************************************************************}
  1488. constructor tstt_exceptsymtable.create;
  1489. begin
  1490. inherited create('');
  1491. symtabletype:=stt_exceptsymtable;
  1492. end;
  1493. {*****************************************************************************
  1494. Helper Routines
  1495. *****************************************************************************}
  1496. function findunitsymtable(st:tsymtable):tsymtable;
  1497. begin
  1498. findunitsymtable:=nil;
  1499. repeat
  1500. if not assigned(st) then
  1501. internalerror(5566561);
  1502. case st.symtabletype of
  1503. localsymtable,
  1504. parasymtable,
  1505. staticsymtable :
  1506. break;
  1507. globalsymtable :
  1508. begin
  1509. findunitsymtable:=st;
  1510. break;
  1511. end;
  1512. objectsymtable,
  1513. recordsymtable :
  1514. st:=st.defowner.owner;
  1515. else
  1516. internalerror(5566562);
  1517. end;
  1518. until false;
  1519. end;
  1520. procedure duplicatesym(sym:tsym);
  1521. var
  1522. st : tsymtable;
  1523. begin
  1524. Message1(sym_e_duplicate_id,sym.realname);
  1525. st:=findunitsymtable(sym.owner);
  1526. with sym.fileinfo do
  1527. begin
  1528. if assigned(st) and (st.unitid<>0) then
  1529. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line))
  1530. else
  1531. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line));
  1532. end;
  1533. end;
  1534. {*****************************************************************************
  1535. Search
  1536. *****************************************************************************}
  1537. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  1538. var
  1539. speedvalue : cardinal;
  1540. begin
  1541. speedvalue:=getspeedvalue(s);
  1542. srsymtable:=symtablestack;
  1543. while assigned(srsymtable) do
  1544. begin
  1545. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  1546. if assigned(srsym) then
  1547. begin
  1548. searchsym:=true;
  1549. exit;
  1550. end
  1551. else
  1552. srsymtable:=srsymtable.next;
  1553. end;
  1554. searchsym:=false;
  1555. end;
  1556. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  1557. var
  1558. srsym : tsym;
  1559. begin
  1560. { the caller have to take care if srsym=nil }
  1561. if assigned(p) then
  1562. begin
  1563. srsym:=tsym(p.search(s));
  1564. if assigned(srsym) then
  1565. begin
  1566. searchsymonlyin:=srsym;
  1567. exit;
  1568. end;
  1569. { also check in the local symtbale if it exists }
  1570. if (p=tsymtable(current_module.globalsymtable)) then
  1571. begin
  1572. srsym:=tsym(current_module.localsymtable.search(s));
  1573. if assigned(srsym) then
  1574. begin
  1575. searchsymonlyin:=srsym;
  1576. exit;
  1577. end;
  1578. end
  1579. end;
  1580. searchsymonlyin:=nil;
  1581. end;
  1582. function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
  1583. var
  1584. symowner: tsymtable;
  1585. begin
  1586. if not(cs_compilesystem in aktmoduleswitches) then
  1587. srsym := ttypesym(searchsymonlyin(systemunit,s))
  1588. else
  1589. searchsym(s,srsym,symowner);
  1590. searchsystype :=
  1591. assigned(srsym) and
  1592. (srsym.typ = typesym);
  1593. end;
  1594. function searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
  1595. begin
  1596. if not(cs_compilesystem in aktmoduleswitches) then
  1597. begin
  1598. srsym := tvarsym(searchsymonlyin(systemunit,s));
  1599. symowner := systemunit;
  1600. end
  1601. else
  1602. searchsym(s,srsym,symowner);
  1603. searchsysvar :=
  1604. assigned(srsym) and
  1605. (srsym.typ = varsym);
  1606. end;
  1607. function search_class_member(pd : tobjectdef;const s : string):tsym;
  1608. { searches n in symtable of pd and all anchestors }
  1609. var
  1610. speedvalue : cardinal;
  1611. srsym : tsym;
  1612. begin
  1613. speedvalue:=getspeedvalue(s);
  1614. while assigned(pd) do
  1615. begin
  1616. srsym:=tsym(pd.symtable.speedsearch(s,speedvalue));
  1617. if assigned(srsym) then
  1618. begin
  1619. search_class_member:=srsym;
  1620. exit;
  1621. end;
  1622. pd:=pd.childof;
  1623. end;
  1624. search_class_member:=nil;
  1625. end;
  1626. {*****************************************************************************
  1627. Definition Helpers
  1628. *****************************************************************************}
  1629. procedure globaldef(const s : string;var t:ttype);
  1630. var st : string;
  1631. symt : tsymtable;
  1632. srsym : tsym;
  1633. srsymtable : tsymtable;
  1634. begin
  1635. srsym := nil;
  1636. if pos('.',s) > 0 then
  1637. begin
  1638. st := copy(s,1,pos('.',s)-1);
  1639. searchsym(st,srsym,srsymtable);
  1640. st := copy(s,pos('.',s)+1,255);
  1641. if assigned(srsym) then
  1642. begin
  1643. if srsym.typ = unitsym then
  1644. begin
  1645. symt := tunitsym(srsym).unitsymtable;
  1646. srsym := tsym(symt.search(st));
  1647. end else srsym := nil;
  1648. end;
  1649. end else st := s;
  1650. if srsym = nil then
  1651. searchsym(st,srsym,srsymtable);
  1652. if srsym = nil then
  1653. srsym:=searchsymonlyin(systemunit,st);
  1654. if (not assigned(srsym)) or
  1655. (srsym.typ<>typesym) then
  1656. begin
  1657. Message(type_e_type_id_expected);
  1658. t:=generrortype;
  1659. exit;
  1660. end;
  1661. t := ttypesym(srsym).restype;
  1662. end;
  1663. {****************************************************************************
  1664. Object Helpers
  1665. ****************************************************************************}
  1666. var
  1667. _defaultprop : tpropertysym;
  1668. procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem);
  1669. begin
  1670. if (tsym(p).typ=propertysym) and
  1671. (ppo_defaultproperty in tpropertysym(p).propoptions) then
  1672. _defaultprop:=tpropertysym(p);
  1673. end;
  1674. function search_default_property(pd : tobjectdef) : tpropertysym;
  1675. { returns the default property of a class, searches also anchestors }
  1676. begin
  1677. _defaultprop:=nil;
  1678. while assigned(pd) do
  1679. begin
  1680. pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty);
  1681. if assigned(_defaultprop) then
  1682. break;
  1683. pd:=pd.childof;
  1684. end;
  1685. search_default_property:=_defaultprop;
  1686. end;
  1687. {$ifdef UNITALIASES}
  1688. {****************************************************************************
  1689. TUNIT_ALIAS
  1690. ****************************************************************************}
  1691. constructor tunit_alias.create(const n:string);
  1692. var
  1693. i : longint;
  1694. begin
  1695. i:=pos('=',n);
  1696. if i=0 then
  1697. fail;
  1698. inherited createname(Copy(n,1,i-1));
  1699. newname:=stringdup(Copy(n,i+1,255));
  1700. end;
  1701. destructor tunit_alias.destroy;
  1702. begin
  1703. stringdispose(newname);
  1704. inherited destroy;
  1705. end;
  1706. procedure addunitalias(const n:string);
  1707. begin
  1708. unitaliases^.insert(tunit_alias,init(Upper(n))));
  1709. end;
  1710. function getunitalias(const n:string):string;
  1711. var
  1712. p : punit_alias;
  1713. begin
  1714. p:=punit_alias(unitaliases^.search(Upper(n)));
  1715. if assigned(p) then
  1716. getunitalias:=punit_alias(p).newname^
  1717. else
  1718. getunitalias:=n;
  1719. end;
  1720. {$endif UNITALIASES}
  1721. {****************************************************************************
  1722. Symtable Stack
  1723. ****************************************************************************}
  1724. procedure dellexlevel;
  1725. var
  1726. p : tsymtable;
  1727. begin
  1728. p:=symtablestack;
  1729. symtablestack:=p.next;
  1730. { symbol tables of unit interfaces are never disposed }
  1731. { this is handle by the unit unitm }
  1732. if not(p.symtabletype in [globalsymtable,stt_exceptsymtable]) then
  1733. p.free;
  1734. end;
  1735. procedure RestoreUnitSyms;
  1736. var
  1737. p : tsymtable;
  1738. begin
  1739. p:=symtablestack;
  1740. while assigned(p) do
  1741. begin
  1742. if (p.symtabletype=globalsymtable) and
  1743. assigned(tglobalsymtable(p).unitsym) and
  1744. ((tglobalsymtable(p).unitsym.owner=current_module.globalsymtable) or
  1745. (tglobalsymtable(p).unitsym.owner=current_module.localsymtable)) then
  1746. tglobalsymtable(p).unitsym.restoreunitsym;
  1747. p:=p.next;
  1748. end;
  1749. end;
  1750. {$ifdef DEBUG}
  1751. procedure test_symtablestack;
  1752. var
  1753. p : tsymtable;
  1754. i : longint;
  1755. begin
  1756. p:=symtablestack;
  1757. i:=0;
  1758. while assigned(p) do
  1759. begin
  1760. inc(i);
  1761. p:=p.next;
  1762. if i>500 then
  1763. Message(sym_f_internal_error_in_symtablestack);
  1764. end;
  1765. end;
  1766. procedure list_symtablestack;
  1767. var
  1768. p : tsymtable;
  1769. i : longint;
  1770. begin
  1771. p:=symtablestack;
  1772. i:=0;
  1773. while assigned(p) do
  1774. begin
  1775. inc(i);
  1776. writeln(i,' ',p.name^);
  1777. p:=p.next;
  1778. if i>500 then
  1779. Message(sym_f_internal_error_in_symtablestack);
  1780. end;
  1781. end;
  1782. {$endif DEBUG}
  1783. {****************************************************************************
  1784. Init/Done Symtable
  1785. ****************************************************************************}
  1786. procedure InitSymtable;
  1787. var
  1788. token : ttoken;
  1789. begin
  1790. { Reset symbolstack }
  1791. registerdef:=false;
  1792. read_member:=false;
  1793. symtablestack:=nil;
  1794. systemunit:=nil;
  1795. {$ifdef GDB}
  1796. firstglobaldef:=nil;
  1797. lastglobaldef:=nil;
  1798. globaltypecount:=1;
  1799. pglobaltypecount:=@globaltypecount;
  1800. {$endif GDB}
  1801. { create error syms and def }
  1802. generrorsym:=terrorsym.create;
  1803. generrortype.setdef(terrordef.create);
  1804. {$ifdef UNITALIASES}
  1805. { unit aliases }
  1806. unitaliases:=tdictionary.create;
  1807. {$endif}
  1808. for token:=first_overloaded to last_overloaded do
  1809. overloaded_operators[token]:=nil;
  1810. end;
  1811. procedure DoneSymtable;
  1812. begin
  1813. generrorsym.free;
  1814. generrortype.def.free;
  1815. {$ifdef UNITALIASES}
  1816. unitaliases.free;
  1817. {$endif}
  1818. end;
  1819. end.
  1820. {
  1821. $Log$
  1822. Revision 1.47 2001-10-12 20:27:43 jonas
  1823. * fixed crashing bug in unit reference counting
  1824. Revision 1.46 2001/09/30 21:29:47 peter
  1825. * gdb fixes merged
  1826. Revision 1.45 2001/09/19 11:06:03 michael
  1827. * realname updated for some hints
  1828. * realname used for consts,labels
  1829. Revision 1.44 2001/09/04 11:38:55 jonas
  1830. + searchsystype() and searchsystype() functions in symtable
  1831. * changed ninl and nadd to use these functions
  1832. * i386 set comparison functions now return their results in al instead
  1833. of in the flags so that they can be sued as compilerprocs
  1834. - removed all processor specific code from n386add.pas that has to do
  1835. with set handling, it's now all done in nadd.pas
  1836. * fixed fpc_set_contains_sets in genset.inc
  1837. * fpc_set_in_byte is now coded inline in n386set.pas and doesn't use a
  1838. helper anymore
  1839. * some small fixes in compproc.inc/set.inc regarding the declaration of
  1840. internal helper types (fpc_small_set and fpc_normal_set)
  1841. Revision 1.43 2001/08/30 20:13:56 peter
  1842. * rtti/init table updates
  1843. * rttisym for reusable global rtti/init info
  1844. * support published for interfaces
  1845. Revision 1.42 2001/08/26 13:36:51 florian
  1846. * some cg reorganisation
  1847. * some PPC updates
  1848. Revision 1.41 2001/08/19 09:39:29 peter
  1849. * local browser support fixed
  1850. Revision 1.40 2001/08/06 21:40:49 peter
  1851. * funcret moved from tprocinfo to tprocdef
  1852. Revision 1.39 2001/07/29 22:12:58 peter
  1853. * skip private symbols when found in withsymtable
  1854. Revision 1.38 2001/07/01 20:16:18 peter
  1855. * alignmentinfo record added
  1856. * -Oa argument supports more alignment settings that can be specified
  1857. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1858. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1859. required alignment and the maximum usefull alignment. The final
  1860. alignment will be choosen per variable size dependent on these
  1861. settings
  1862. Revision 1.37 2001/06/04 11:53:14 peter
  1863. + varargs directive
  1864. Revision 1.36 2001/06/03 21:57:38 peter
  1865. + hint directive parsing support
  1866. Revision 1.35 2001/05/06 14:49:18 peter
  1867. * ppu object to class rewrite
  1868. * move ppu read and write stuff to fppu
  1869. Revision 1.34 2001/04/18 22:01:59 peter
  1870. * registration of targets and assemblers
  1871. Revision 1.33 2001/04/13 20:05:15 peter
  1872. * better check for globalsymtable
  1873. Revision 1.32 2001/04/13 18:08:37 peter
  1874. * scanner object to class
  1875. Revision 1.31 2001/04/13 01:22:16 peter
  1876. * symtable change to classes
  1877. * range check generation and errors fixed, make cycle DEBUG=1 works
  1878. * memory leaks fixed
  1879. Revision 1.30 2001/04/02 21:20:35 peter
  1880. * resulttype rewrite
  1881. Revision 1.29 2001/03/22 00:10:58 florian
  1882. + basic variant type support in the compiler
  1883. Revision 1.28 2001/03/13 18:45:07 peter
  1884. * fixed some memory leaks
  1885. Revision 1.27 2001/03/11 22:58:51 peter
  1886. * getsym redesign, removed the globals srsym,srsymtable
  1887. Revision 1.26 2001/02/21 19:37:19 peter
  1888. * moved deref to be done after loading of implementation units. prederef
  1889. is still done directly after loading of symbols and definitions.
  1890. Revision 1.25 2001/02/20 21:41:16 peter
  1891. * new fixfilename, findfile for unix. Look first for lowercase, then
  1892. NormalCase and last for UPPERCASE names.
  1893. Revision 1.24 2001/01/08 21:40:27 peter
  1894. * fixed crash with unsupported token overloading
  1895. Revision 1.23 2000/12/25 00:07:30 peter
  1896. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1897. tlinkedlist objects)
  1898. Revision 1.22 2000/12/23 19:50:09 peter
  1899. * fixed mem leak with withsymtable
  1900. Revision 1.21 2000/12/10 20:25:32 peter
  1901. * fixed missing typecast
  1902. Revision 1.20 2000/12/10 14:14:51 florian
  1903. * fixed web bug 1203: class fields can be now redefined
  1904. in Delphi mode though I don't like this :/
  1905. Revision 1.19 2000/11/30 22:16:49 florian
  1906. * moved to i386
  1907. Revision 1.18 2000/11/29 00:30:42 florian
  1908. * unused units removed from uses clause
  1909. * some changes for widestrings
  1910. Revision 1.17 2000/11/28 00:28:07 pierre
  1911. * stabs fixing
  1912. Revision 1.1.2.8 2000/11/17 11:14:37 pierre
  1913. * one more class stabs fix
  1914. Revision 1.16 2000/11/12 22:17:47 peter
  1915. * some realname updates for messages
  1916. Revision 1.15 2000/11/06 15:54:15 florian
  1917. * fixed two bugs to get make cycle work, but it's not enough
  1918. Revision 1.14 2000/11/04 14:25:22 florian
  1919. + merged Attila's changes for interfaces, not tested yet
  1920. Revision 1.13 2000/11/01 23:04:38 peter
  1921. * tprocdef.fullprocname added for better casesensitve writing of
  1922. procedures
  1923. Revision 1.12 2000/10/31 22:02:52 peter
  1924. * symtable splitted, no real code changes
  1925. Revision 1.1.2.7 2000/10/16 19:43:04 pierre
  1926. * trying to correct class stabss once more
  1927. Revision 1.11 2000/10/15 07:47:53 peter
  1928. * unit names and procedure names are stored mixed case
  1929. Revision 1.10 2000/10/14 10:14:53 peter
  1930. * moehrendorf oct 2000 rewrite
  1931. Revision 1.9 2000/10/01 19:48:25 peter
  1932. * lot of compile updates for cg11
  1933. Revision 1.8 2000/09/24 15:06:29 peter
  1934. * use defines.inc
  1935. Revision 1.7 2000/08/27 16:11:54 peter
  1936. * moved some util functions from globals,cobjects to cutils
  1937. * splitted files into finput,fmodule
  1938. Revision 1.6 2000/08/21 11:27:45 pierre
  1939. * fix the stabs problems
  1940. Revision 1.5 2000/08/20 14:58:41 peter
  1941. * give fatal if objfpc/delphi mode things are found (merged)
  1942. Revision 1.1.2.6 2000/08/20 14:56:46 peter
  1943. * give fatal if objfpc/delphi mode things are found
  1944. Revision 1.4 2000/08/16 18:33:54 peter
  1945. * splitted namedobjectitem.next into indexnext and listnext so it
  1946. can be used in both lists
  1947. * don't allow "word = word" type definitions (merged)
  1948. Revision 1.3 2000/08/08 19:28:57 peter
  1949. * memdebug/memory patches (merged)
  1950. * only once illegal directive (merged)
  1951. }