symtable.pas 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  4. This unit handles the symbol tables
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symtable;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. cpuinfo,globtype,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,symsym,
  28. { ppu }
  29. ppu,symppu,
  30. { assembler }
  31. aasmbase,aasmtai,aasmcpu,
  32. { cg }
  33. paramgr
  34. ;
  35. {****************************************************************************
  36. Symtable types
  37. ****************************************************************************}
  38. type
  39. tstoredsymtable = class(tsymtable)
  40. private
  41. b_needs_init_final : boolean;
  42. procedure _needs_init_final(p : tnamedindexitem;arg:pointer);
  43. procedure check_forward(sym : TNamedIndexItem;arg:pointer);
  44. procedure labeldefined(p : TNamedIndexItem;arg:pointer);
  45. procedure unitsymbolused(p : TNamedIndexItem;arg:pointer);
  46. procedure varsymbolused(p : TNamedIndexItem;arg:pointer);
  47. procedure TestPrivate(p : TNamedIndexItem;arg:pointer);
  48. procedure objectprivatesymbolused(p : TNamedIndexItem;arg:pointer);
  49. {$ifdef GDB}
  50. private
  51. procedure concatstab(p : TNamedIndexItem;arg:pointer);
  52. procedure resetstab(p : TNamedIndexItem;arg:pointer);
  53. procedure concattypestab(p : TNamedIndexItem;arg:pointer);
  54. {$endif}
  55. procedure unchain_overloads(p : TNamedIndexItem;arg:pointer);
  56. procedure loaddefs(ppufile:tcompilerppufile);
  57. procedure loadsyms(ppufile:tcompilerppufile);
  58. procedure writedefs(ppufile:tcompilerppufile);
  59. procedure writesyms(ppufile:tcompilerppufile);
  60. public
  61. { load/write }
  62. procedure ppuload(ppufile:tcompilerppufile);virtual;
  63. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  64. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  65. procedure write_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  66. procedure deref;virtual;
  67. procedure derefimpl;virtual;
  68. procedure insert(sym : tsymentry);override;
  69. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;override;
  70. procedure allsymbolsused;
  71. procedure allprivatesused;
  72. procedure allunitsused;
  73. procedure check_forwards;
  74. procedure checklabels;
  75. function needs_init_final : boolean;
  76. procedure unchain_overloaded;
  77. procedure chainoperators;
  78. {$ifdef GDB}
  79. procedure concatstabto(asmlist : taasmoutput);virtual;
  80. function getnewtypecount : word; override;
  81. {$endif GDB}
  82. procedure testfordefaultproperty(p : TNamedIndexItem;arg:pointer);
  83. end;
  84. tabstractrecordsymtable = class(tstoredsymtable)
  85. public
  86. procedure ppuload(ppufile:tcompilerppufile);override;
  87. procedure ppuwrite(ppufile:tcompilerppufile);override;
  88. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  89. procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
  90. procedure insertvardata(sym : tsymentry);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 ppuload(ppufile:tcompilerppufile);override;
  105. procedure ppuwrite(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. procedure insertvardata(sym : tsymentry);override;
  114. procedure insertconstdata(sym : tsymentry);override;
  115. end;
  116. tparasymtable = class(tabstractlocalsymtable)
  117. public
  118. constructor create;
  119. procedure insert(sym : tsymentry);override;
  120. procedure insertvardata(sym : tsymentry);override;
  121. end;
  122. tabstractunitsymtable = class(tstoredsymtable)
  123. public
  124. {$ifdef GDB}
  125. dbx_count : longint;
  126. prev_dbx_counter : plongint;
  127. dbx_count_ok : boolean;
  128. is_stab_written : boolean;
  129. {$endif GDB}
  130. constructor create(const n : string);
  131. {$ifdef GDB}
  132. procedure concattypestabto(asmlist : taasmoutput);
  133. {$endif GDB}
  134. procedure insertvardata(sym : tsymentry);override;
  135. procedure insertconstdata(sym : tsymentry);override;
  136. end;
  137. tglobalsymtable = class(tabstractunitsymtable)
  138. public
  139. unittypecount : word;
  140. unitsym : tunitsym;
  141. constructor create(const n : string);
  142. destructor destroy;override;
  143. procedure ppuload(ppufile:tcompilerppufile);override;
  144. procedure ppuwrite(ppufile:tcompilerppufile);override;
  145. procedure insert(sym : tsymentry);override;
  146. procedure insertvardata(sym : tsymentry);override;
  147. {$ifdef GDB}
  148. function getnewtypecount : word; override;
  149. {$endif}
  150. end;
  151. tstaticsymtable = class(tabstractunitsymtable)
  152. public
  153. constructor create(const n : string);
  154. procedure ppuload(ppufile:tcompilerppufile);override;
  155. procedure ppuwrite(ppufile:tcompilerppufile);override;
  156. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  157. procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
  158. procedure insert(sym : tsymentry);override;
  159. procedure insertvardata(sym : tsymentry);override;
  160. end;
  161. twithsymtable = class(tsymtable)
  162. direct_with : boolean;
  163. { in fact it is a tnode }
  164. withnode : pointer;
  165. { tnode to load of direct with var }
  166. { already usable before firstwith
  167. needed for firstpass of function parameters PM }
  168. withrefnode : pointer;
  169. use_count : longint;
  170. constructor create(aowner:tdef;asymsearch:TDictionary);
  171. destructor destroy;override;
  172. procedure clear;override;
  173. end;
  174. tstt_exceptsymtable = class(tsymtable)
  175. public
  176. constructor create;
  177. end;
  178. var
  179. constsymtable : tsymtable; { symtable were the constants can be inserted }
  180. systemunit : tglobalsymtable; { pointer to the system unit }
  181. read_member : boolean; { reading members of an symtable }
  182. lexlevel : longint; { level of code }
  183. { 1 for main procedure }
  184. { 2 for normal function or proc }
  185. { higher for locals }
  186. {****************************************************************************
  187. Functions
  188. ****************************************************************************}
  189. {*** Misc ***}
  190. procedure globaldef(const s : string;var t:ttype);
  191. function findunitsymtable(st:tsymtable):tsymtable;
  192. procedure duplicatesym(sym:tsym);
  193. {*** Search ***}
  194. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  195. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  196. function searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
  197. function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
  198. function searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
  199. function search_class_member(pd : tobjectdef;const s : string):tsym;
  200. {*** Object Helpers ***}
  201. function search_default_property(pd : tobjectdef) : tpropertysym;
  202. {*** symtable stack ***}
  203. procedure dellexlevel;
  204. procedure RestoreUnitSyms;
  205. {$ifdef DEBUG}
  206. procedure test_symtablestack;
  207. procedure list_symtablestack;
  208. {$endif DEBUG}
  209. {$ifdef UNITALIASES}
  210. type
  211. punit_alias = ^tunit_alias;
  212. tunit_alias = object(TNamedIndexItem)
  213. newname : pstring;
  214. constructor init(const n:string);
  215. destructor done;virtual;
  216. end;
  217. var
  218. unitaliases : pdictionary;
  219. procedure addunitalias(const n:string);
  220. function getunitalias(const n:string):string;
  221. {$endif UNITALIASES}
  222. {*** Init / Done ***}
  223. procedure InitSymtable;
  224. procedure DoneSymtable;
  225. type
  226. toverloaded_operators = array[NOTOKEN..last_overloaded] of tprocsym;
  227. var
  228. overloaded_operators : toverloaded_operators;
  229. { unequal is not equal}
  230. const
  231. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] =
  232. ('error',
  233. 'plus','minus','star','slash','equal',
  234. 'greater','lower','greater_or_equal',
  235. 'lower_or_equal',
  236. 'sym_diff','starstar',
  237. 'as','is','in','or',
  238. 'and','div','mod','not','shl','shr','xor',
  239. 'assign');
  240. implementation
  241. uses
  242. { global }
  243. verbose,globals,
  244. { target }
  245. systems,
  246. { module }
  247. fmodule,
  248. {$ifdef GDB}
  249. gdb,
  250. {$endif GDB}
  251. { codegen }
  252. cgbase
  253. ;
  254. {*****************************************************************************
  255. TStoredSymtable
  256. *****************************************************************************}
  257. procedure tstoredsymtable.ppuload(ppufile:tcompilerppufile);
  258. begin
  259. { load definitions }
  260. loaddefs(ppufile);
  261. { load symbols }
  262. loadsyms(ppufile);
  263. end;
  264. procedure tstoredsymtable.ppuwrite(ppufile:tcompilerppufile);
  265. begin
  266. { write definitions }
  267. writedefs(ppufile);
  268. { write symbols }
  269. writesyms(ppufile);
  270. end;
  271. procedure tstoredsymtable.loaddefs(ppufile:tcompilerppufile);
  272. var
  273. hp : tdef;
  274. b : byte;
  275. begin
  276. { load start of definition section, which holds the amount of defs }
  277. if ppufile.readentry<>ibstartdefs then
  278. Message(unit_f_ppu_read_error);
  279. ppufile.getlongint;
  280. { read definitions }
  281. repeat
  282. b:=ppufile.readentry;
  283. case b of
  284. ibpointerdef : hp:=tpointerdef.ppuload(ppufile);
  285. ibarraydef : hp:=tarraydef.ppuload(ppufile);
  286. iborddef : hp:=torddef.ppuload(ppufile);
  287. ibfloatdef : hp:=tfloatdef.ppuload(ppufile);
  288. ibprocdef : hp:=tprocdef.ppuload(ppufile);
  289. ibshortstringdef : hp:=tstringdef.loadshort(ppufile);
  290. iblongstringdef : hp:=tstringdef.loadlong(ppufile);
  291. ibansistringdef : hp:=tstringdef.loadansi(ppufile);
  292. ibwidestringdef : hp:=tstringdef.loadwide(ppufile);
  293. ibrecorddef : hp:=trecorddef.ppuload(ppufile);
  294. ibobjectdef : hp:=tobjectdef.ppuload(ppufile);
  295. ibenumdef : hp:=tenumdef.ppuload(ppufile);
  296. ibsetdef : hp:=tsetdef.ppuload(ppufile);
  297. ibprocvardef : hp:=tprocvardef.ppuload(ppufile);
  298. ibfiledef : hp:=tfiledef.ppuload(ppufile);
  299. ibclassrefdef : hp:=tclassrefdef.ppuload(ppufile);
  300. ibformaldef : hp:=tformaldef.ppuload(ppufile);
  301. ibvariantdef : hp:=tvariantdef.ppuload(ppufile);
  302. ibenddefs : break;
  303. ibend : Message(unit_f_ppu_read_error);
  304. else
  305. Message1(unit_f_ppu_invalid_entry,tostr(b));
  306. end;
  307. hp.owner:=self;
  308. defindex.insert(hp);
  309. until false;
  310. end;
  311. procedure tstoredsymtable.loadsyms(ppufile:tcompilerppufile);
  312. var
  313. b : byte;
  314. sym : tsym;
  315. begin
  316. { load start of definition section, which holds the amount of defs }
  317. if ppufile.readentry<>ibstartsyms then
  318. Message(unit_f_ppu_read_error);
  319. { skip amount of symbols, not used currently }
  320. ppufile.getlongint;
  321. { load datasize,dataalignment of this symboltable }
  322. datasize:=ppufile.getlongint;
  323. dataalignment:=ppufile.getlongint;
  324. { now read the symbols }
  325. repeat
  326. b:=ppufile.readentry;
  327. case b of
  328. ibtypesym : sym:=ttypesym.ppuload(ppufile);
  329. ibprocsym : sym:=tprocsym.ppuload(ppufile);
  330. ibconstsym : sym:=tconstsym.ppuload(ppufile);
  331. ibvarsym : sym:=tvarsym.ppuload(ppufile);
  332. ibfuncretsym : sym:=tfuncretsym.ppuload(ppufile);
  333. ibabsolutesym : sym:=tabsolutesym.ppuload(ppufile);
  334. ibenumsym : sym:=tenumsym.ppuload(ppufile);
  335. ibtypedconstsym : sym:=ttypedconstsym.ppuload(ppufile);
  336. ibpropertysym : sym:=tpropertysym.ppuload(ppufile);
  337. ibunitsym : sym:=tunitsym.ppuload(ppufile);
  338. iblabelsym : sym:=tlabelsym.ppuload(ppufile);
  339. ibsyssym : sym:=tsyssym.ppuload(ppufile);
  340. ibrttisym : sym:=trttisym.ppuload(ppufile);
  341. ibendsyms : break;
  342. ibend : Message(unit_f_ppu_read_error);
  343. else
  344. Message1(unit_f_ppu_invalid_entry,tostr(b));
  345. end;
  346. sym.owner:=self;
  347. symindex.insert(sym);
  348. symsearch.insert(sym);
  349. until false;
  350. end;
  351. procedure tstoredsymtable.writedefs(ppufile:tcompilerppufile);
  352. var
  353. pd : tstoreddef;
  354. begin
  355. { each definition get a number, write then the amount of defs to the
  356. ibstartdef entry }
  357. ppufile.putlongint(defindex.count);
  358. ppufile.writeentry(ibstartdefs);
  359. { now write the definition }
  360. pd:=tstoreddef(defindex.first);
  361. while assigned(pd) do
  362. begin
  363. pd.ppuwrite(ppufile);
  364. pd:=tstoreddef(pd.indexnext);
  365. end;
  366. { write end of definitions }
  367. ppufile.writeentry(ibenddefs);
  368. end;
  369. procedure tstoredsymtable.writesyms(ppufile:tcompilerppufile);
  370. var
  371. pd : tstoredsym;
  372. begin
  373. { each definition get a number, write then the amount of syms and the
  374. datasize to the ibsymdef entry }
  375. ppufile.putlongint(symindex.count);
  376. ppufile.putlongint(datasize);
  377. ppufile.putlongint(dataalignment);
  378. ppufile.writeentry(ibstartsyms);
  379. { foreach is used to write all symbols }
  380. pd:=tstoredsym(symindex.first);
  381. while assigned(pd) do
  382. begin
  383. pd.ppuwrite(ppufile);
  384. pd:=tstoredsym(pd.indexnext);
  385. end;
  386. { end of symbols }
  387. ppufile.writeentry(ibendsyms);
  388. end;
  389. procedure tstoredsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  390. var
  391. b : byte;
  392. sym : tstoredsym;
  393. prdef : tstoreddef;
  394. begin
  395. b:=ppufile.readentry;
  396. if b <> ibbeginsymtablebrowser then
  397. Message1(unit_f_ppu_invalid_entry,tostr(b));
  398. repeat
  399. b:=ppufile.readentry;
  400. case b of
  401. ibsymref :
  402. begin
  403. sym:=tstoredsym(ppufile.getderef);
  404. resolvesym(pointer(sym));
  405. if assigned(sym) then
  406. sym.load_references(ppufile,locals);
  407. end;
  408. ibdefref :
  409. begin
  410. prdef:=tstoreddef(ppufile.getderef);
  411. resolvedef(pointer(prdef));
  412. if assigned(prdef) then
  413. begin
  414. if prdef.deftype<>procdef then
  415. Message(unit_f_ppu_read_error);
  416. tprocdef(prdef).load_references(ppufile,locals);
  417. end;
  418. end;
  419. ibendsymtablebrowser :
  420. break;
  421. else
  422. Message1(unit_f_ppu_invalid_entry,tostr(b));
  423. end;
  424. until false;
  425. end;
  426. procedure tstoredsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  427. var
  428. pd : tstoredsym;
  429. begin
  430. ppufile.writeentry(ibbeginsymtablebrowser);
  431. { write all symbols }
  432. pd:=tstoredsym(symindex.first);
  433. while assigned(pd) do
  434. begin
  435. pd.write_references(ppufile,locals);
  436. pd:=tstoredsym(pd.indexnext);
  437. end;
  438. ppufile.writeentry(ibendsymtablebrowser);
  439. end;
  440. procedure tstoredsymtable.deref;
  441. var
  442. hp : tdef;
  443. hs : tsym;
  444. begin
  445. { deref the interface definitions }
  446. hp:=tdef(defindex.first);
  447. while assigned(hp) do
  448. begin
  449. hp.deref;
  450. hp:=tdef(hp.indexnext);
  451. end;
  452. { first deref the interface ttype symbols }
  453. hs:=tsym(symindex.first);
  454. while assigned(hs) do
  455. begin
  456. if hs.typ=typesym then
  457. hs.deref;
  458. hs:=tsym(hs.indexnext);
  459. end;
  460. { deref the interface symbols }
  461. hs:=tsym(symindex.first);
  462. while assigned(hs) do
  463. begin
  464. if hs.typ<>typesym then
  465. hs.deref;
  466. hs:=tsym(hs.indexnext);
  467. end;
  468. end;
  469. procedure tstoredsymtable.derefimpl;
  470. var
  471. hp : tdef;
  472. begin
  473. { deref the implementation part of definitions }
  474. hp:=tdef(defindex.first);
  475. while assigned(hp) do
  476. begin
  477. hp.derefimpl;
  478. hp:=tdef(hp.indexnext);
  479. end;
  480. end;
  481. procedure tstoredsymtable.insert(sym:tsymentry);
  482. var
  483. hsym : tsym;
  484. begin
  485. { set owner and sym indexnb }
  486. sym.owner:=self;
  487. { check the current symtable }
  488. hsym:=tsym(search(sym.name));
  489. if assigned(hsym) then
  490. begin
  491. { in TP and Delphi you can have a local with the
  492. same name as the function, the function is then hidden for
  493. the user. (Under delphi it can still be accessed using result),
  494. but don't allow hiding of RESULT }
  495. if (m_duplicate_names in aktmodeswitches) and
  496. (hsym.typ=funcretsym) and
  497. not((m_result in aktmodeswitches) and
  498. (hsym.name='RESULT')) then
  499. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  500. else
  501. begin
  502. DuplicateSym(hsym);
  503. exit;
  504. end;
  505. end;
  506. { register definition of typesym }
  507. if (sym.typ = typesym) and
  508. assigned(ttypesym(sym).restype.def) then
  509. begin
  510. if not(assigned(ttypesym(sym).restype.def.owner)) and
  511. (ttypesym(sym).restype.def.deftype<>errordef) then
  512. registerdef(ttypesym(sym).restype.def);
  513. {$ifdef GDB}
  514. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  515. (symtabletype in [globalsymtable,staticsymtable]) then
  516. begin
  517. ttypesym(sym).isusedinstab := true;
  518. {sym.concatstabto(debuglist);}
  519. end;
  520. {$endif GDB}
  521. end;
  522. { insert in index and search hash }
  523. symindex.insert(sym);
  524. symsearch.insert(sym);
  525. end;
  526. function tstoredsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  527. var
  528. hp : tstoredsym;
  529. newref : tref;
  530. begin
  531. hp:=tstoredsym(inherited speedsearch(s,speedvalue));
  532. if assigned(hp) then
  533. begin
  534. { reject non static members in static procedures }
  535. if (symtabletype=objectsymtable) and
  536. not(sp_static in hp.symoptions) and
  537. allow_only_static then
  538. Message(sym_e_only_static_in_static);
  539. { unit uses count }
  540. if (unitid<>0) and
  541. (symtabletype = globalsymtable) and
  542. assigned(tglobalsymtable(self).unitsym) then
  543. inc(tglobalsymtable(self).unitsym.refs);
  544. {$ifdef GDB}
  545. { if it is a type, we need the stabs of this type
  546. this might be the cause of the class debug problems
  547. as TCHILDCLASS.Create did not generate appropriate
  548. stabs debug info if TCHILDCLASS wasn't used anywhere else PM }
  549. if (cs_debuginfo in aktmoduleswitches) and
  550. (hp.typ=typesym) and
  551. make_ref then
  552. begin
  553. if assigned(ttypesym(hp).restype.def) then
  554. tstoreddef(ttypesym(hp).restype.def).numberstring
  555. else
  556. ttypesym(hp).isusedinstab:=true;
  557. end;
  558. {$endif GDB}
  559. { unitsym are only loaded for browsing PM }
  560. { this was buggy anyway because we could use }
  561. { unitsyms from other units in _USES !! }
  562. {if (symtabletype=unitsymtable) and (hp.typ=unitsym) and
  563. assigned(current_module) and (current_module.globalsymtable<>.load) then
  564. hp:=nil;}
  565. if make_ref and (cs_browser in aktmoduleswitches) then
  566. begin
  567. newref:=tref.create(hp.lastref,@akttokenpos);
  568. { for symbols that are in tables without browser info or syssyms }
  569. if hp.refcount=0 then
  570. begin
  571. hp.defref:=newref;
  572. hp.lastref:=newref;
  573. end
  574. else
  575. if resolving_forward and assigned(hp.defref) then
  576. { put it as second reference }
  577. begin
  578. newref.nextref:=hp.defref.nextref;
  579. hp.defref.nextref:=newref;
  580. hp.lastref.nextref:=nil;
  581. end
  582. else
  583. hp.lastref:=newref;
  584. inc(hp.refcount);
  585. end;
  586. if make_ref then
  587. inc(hp.refs);
  588. end; { value was not found }
  589. speedsearch:=hp;
  590. end;
  591. {**************************************
  592. Callbacks
  593. **************************************}
  594. procedure TStoredSymtable.check_forward(sym : TNamedIndexItem;arg:pointer);
  595. begin
  596. if tsym(sym).typ=procsym then
  597. tprocsym(sym).check_forward
  598. { check also object method table }
  599. { we needn't to test the def list }
  600. { because each object has to have a type sym }
  601. else
  602. if (tsym(sym).typ=typesym) and
  603. assigned(ttypesym(sym).restype.def) and
  604. (ttypesym(sym).restype.def.deftype=objectdef) then
  605. tobjectdef(ttypesym(sym).restype.def).check_forwards;
  606. end;
  607. procedure TStoredSymtable.labeldefined(p : TNamedIndexItem;arg:pointer);
  608. begin
  609. if (tsym(p).typ=labelsym) and
  610. not(tlabelsym(p).defined) then
  611. begin
  612. if tlabelsym(p).used then
  613. Message1(sym_e_label_used_and_not_defined,tlabelsym(p).realname)
  614. else
  615. Message1(sym_w_label_not_defined,tlabelsym(p).realname);
  616. end;
  617. end;
  618. procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem;arg:pointer);
  619. begin
  620. if (tsym(p).typ=unitsym) and
  621. (tunitsym(p).refs=0) and
  622. { do not claim for unit name itself !! }
  623. assigned(tunitsym(p).unitsymtable) and
  624. (tunitsym(p).unitsymtable.symtabletype=globalsymtable) then
  625. MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,p.name,current_module.modulename^);
  626. end;
  627. procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem;arg:pointer);
  628. begin
  629. if (tsym(p).typ=varsym) and
  630. ((tsym(p).owner.symtabletype in
  631. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  632. begin
  633. { unused symbol should be reported only if no }
  634. { error is reported }
  635. { if the symbol is in a register it is used }
  636. { also don't count the value parameters which have local copies }
  637. { also don't claim for high param of open parameters (PM) }
  638. if (Errorcount<>0) or
  639. (copy(p.name,1,3)='val') or
  640. (copy(p.name,1,6)='hidden') or
  641. (copy(p.name,1,4)='high') then
  642. exit;
  643. if (tvarsym(p).refs=0) then
  644. begin
  645. if (tsym(p).owner.symtabletype=parasymtable) or (vo_is_local_copy in tvarsym(p).varoptions) then
  646. begin
  647. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_not_used,tsym(p).realname);
  648. end
  649. else if (tsym(p).owner.symtabletype=objectsymtable) then
  650. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_not_used,tsym(p).owner.realname^,tsym(p).realname)
  651. else
  652. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_not_used,tsym(p).realname);
  653. end
  654. else if tvarsym(p).varstate=vs_assigned then
  655. begin
  656. if (tsym(p).owner.symtabletype=parasymtable) then
  657. begin
  658. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  659. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname)
  660. end
  661. else if (vo_is_local_copy in tvarsym(p).varoptions) then
  662. begin
  663. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  664. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname);
  665. end
  666. else if (tsym(p).owner.symtabletype=objectsymtable) then
  667. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_only_set,tsym(p).owner.realname^,tsym(p).realname)
  668. else if (tsym(p).owner.symtabletype<>parasymtable) then
  669. if not (vo_is_exported in tvarsym(p).varoptions) then
  670. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_only_set,tsym(p).realname);
  671. end;
  672. end
  673. else if ((tsym(p).owner.symtabletype in
  674. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  675. begin
  676. if (Errorcount<>0) then
  677. exit;
  678. { do not claim for inherited private fields !! }
  679. if (tstoredsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
  680. MessagePos2(tsym(p).fileinfo,sym_n_private_method_not_used,tsym(p).owner.realname^,tsym(p).realname)
  681. { units references are problematic }
  682. else if (tstoredsym(p).refs=0) and not(tsym(p).typ in [funcretsym,enumsym,unitsym]) then
  683. if (tsym(p).typ<>procsym) or not (tprocsym(p).is_global) or
  684. { all program functions are declared global
  685. but unused should still be signaled PM }
  686. ((tsym(p).owner.symtabletype=staticsymtable) and
  687. not current_module.is_unit) then
  688. MessagePos2(tsym(p).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(p).typ],tsym(p).realname);
  689. end;
  690. end;
  691. procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem;arg:pointer);
  692. begin
  693. if sp_private in tsym(p).symoptions then
  694. varsymbolused(p,arg);
  695. end;
  696. procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem;arg:pointer);
  697. begin
  698. {
  699. Don't test simple object aliases PM
  700. }
  701. if (tsym(p).typ=typesym) and
  702. (ttypesym(p).restype.def.deftype=objectdef) and
  703. (ttypesym(p).restype.def.typesym=tsym(p)) then
  704. tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate,nil);
  705. end;
  706. procedure tstoredsymtable.unchain_overloads(p : TNamedIndexItem;arg:pointer);
  707. begin
  708. if tsym(p).typ=procsym then
  709. tprocsym(p).unchain_overload;
  710. end;
  711. {$ifdef GDB}
  712. procedure TStoredSymtable.concatstab(p : TNamedIndexItem;arg:pointer);
  713. begin
  714. if tsym(p).typ <> procsym then
  715. tstoredsym(p).concatstabto(TAAsmOutput(arg));
  716. end;
  717. procedure TStoredSymtable.resetstab(p : TNamedIndexItem;arg:pointer);
  718. begin
  719. if tsym(p).typ <> procsym then
  720. tstoredsym(p).isstabwritten:=false;
  721. end;
  722. procedure TStoredSymtable.concattypestab(p : TNamedIndexItem;arg:pointer);
  723. begin
  724. if tsym(p).typ = typesym then
  725. begin
  726. tstoredsym(p).isstabwritten:=false;
  727. tstoredsym(p).concatstabto(TAAsmOutput(arg));
  728. end;
  729. end;
  730. function tstoredsymtable.getnewtypecount : word;
  731. begin
  732. getnewtypecount:=pglobaltypecount^;
  733. inc(pglobaltypecount^);
  734. end;
  735. {$endif GDB}
  736. procedure tstoredsymtable.chainoperators;
  737. var
  738. t : ttoken;
  739. srsym : tsym;
  740. srsymtable,
  741. storesymtablestack : tsymtable;
  742. begin
  743. storesymtablestack:=symtablestack;
  744. symtablestack:=self;
  745. make_ref:=false;
  746. for t:=first_overloaded to last_overloaded do
  747. begin
  748. overloaded_operators[t]:=nil;
  749. { each operator has a unique lowercased internal name PM }
  750. while assigned(symtablestack) do
  751. begin
  752. searchsym(overloaded_names[t],srsym,srsymtable);
  753. if not assigned(srsym) then
  754. begin
  755. if (t=_STARSTAR) then
  756. begin
  757. symtablestack:=systemunit;
  758. searchsym('POWER',srsym,srsymtable);
  759. end;
  760. end;
  761. if assigned(srsym) then
  762. begin
  763. if (srsym.typ<>procsym) then
  764. internalerror(12344321);
  765. { use this procsym as start ? }
  766. if not assigned(overloaded_operators[t]) then
  767. overloaded_operators[t]:=tprocsym(srsym)
  768. else
  769. { already got a procsym, only add defs of the current procsym }
  770. Tprocsym(srsym).concat_procdefs_to(overloaded_operators[t]);
  771. symtablestack:=srsym.owner.next;
  772. end
  773. else
  774. begin
  775. symtablestack:=nil;
  776. end;
  777. { search for same procsym in other units }
  778. end;
  779. symtablestack:=self;
  780. end;
  781. make_ref:=true;
  782. symtablestack:=storesymtablestack;
  783. end;
  784. {***********************************************
  785. Process all entries
  786. ***********************************************}
  787. { checks, if all procsyms and methods are defined }
  788. procedure tstoredsymtable.check_forwards;
  789. begin
  790. foreach({$ifdef FPCPROCVAR}@{$endif}check_forward,nil);
  791. end;
  792. procedure tstoredsymtable.checklabels;
  793. begin
  794. foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined,nil);
  795. end;
  796. procedure tstoredsymtable.allunitsused;
  797. begin
  798. foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused,nil);
  799. end;
  800. procedure tstoredsymtable.allsymbolsused;
  801. begin
  802. foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused,nil);
  803. end;
  804. procedure tstoredsymtable.allprivatesused;
  805. begin
  806. foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused,nil);
  807. end;
  808. procedure tstoredsymtable.unchain_overloaded;
  809. begin
  810. foreach({$ifdef FPCPROCVAR}@{$endif}unchain_overloads,nil);
  811. end;
  812. {$ifdef GDB}
  813. procedure tstoredsymtable.concatstabto(asmlist : taasmoutput);
  814. begin
  815. if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
  816. foreach({$ifdef FPCPROCVAR}@{$endif}resetstab,nil);
  817. foreach({$ifdef FPCPROCVAR}@{$endif}concatstab,asmlist);
  818. end;
  819. {$endif}
  820. procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
  821. begin
  822. if b_needs_init_final then
  823. exit;
  824. case tsym(p).typ of
  825. varsym :
  826. begin
  827. if not(is_class(tvarsym(p).vartype.def)) and
  828. tstoreddef(tvarsym(p).vartype.def).needs_inittable then
  829. b_needs_init_final:=true;
  830. end;
  831. typedconstsym :
  832. begin
  833. if ttypedconstsym(p).is_writable and
  834. tstoreddef(ttypedconstsym(p).typedconsttype.def).needs_inittable then
  835. b_needs_init_final:=true;
  836. end;
  837. end;
  838. end;
  839. { returns true, if p contains data which needs init/final code }
  840. function tstoredsymtable.needs_init_final : boolean;
  841. begin
  842. b_needs_init_final:=false;
  843. foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final,nil);
  844. needs_init_final:=b_needs_init_final;
  845. end;
  846. {****************************************************************************
  847. TAbstractRecordSymtable
  848. ****************************************************************************}
  849. procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
  850. var
  851. storesymtable : tsymtable;
  852. begin
  853. storesymtable:=aktrecordsymtable;
  854. aktrecordsymtable:=self;
  855. inherited ppuload(ppufile);
  856. aktrecordsymtable:=storesymtable;
  857. end;
  858. procedure tabstractrecordsymtable.ppuwrite(ppufile:tcompilerppufile);
  859. var
  860. oldtyp : byte;
  861. storesymtable : tsymtable;
  862. begin
  863. storesymtable:=aktrecordsymtable;
  864. aktrecordsymtable:=self;
  865. oldtyp:=ppufile.entrytyp;
  866. ppufile.entrytyp:=subentryid;
  867. inherited ppuwrite(ppufile);
  868. ppufile.entrytyp:=oldtyp;
  869. aktrecordsymtable:=storesymtable;
  870. end;
  871. procedure tabstractrecordsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  872. var
  873. storesymtable : tsymtable;
  874. begin
  875. storesymtable:=aktrecordsymtable;
  876. aktrecordsymtable:=self;
  877. inherited load_references(ppufile,locals);
  878. aktrecordsymtable:=storesymtable;
  879. end;
  880. procedure tabstractrecordsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  881. var
  882. storesymtable : tsymtable;
  883. begin
  884. storesymtable:=aktrecordsymtable;
  885. aktrecordsymtable:=self;
  886. inherited write_references(ppufile,locals);
  887. aktrecordsymtable:=storesymtable;
  888. end;
  889. procedure tabstractrecordsymtable.insertvardata(sym : tsymentry);
  890. var
  891. l,varalign : longint;
  892. vardef : tdef;
  893. begin
  894. if sym.typ<>varsym then
  895. internalerror(200208251);
  896. l:=tvarsym(sym).getvaluesize;
  897. vardef:=tvarsym(sym).vartype.def;
  898. { this symbol can't be loaded to a register }
  899. exclude(tvarsym(sym).varoptions,vo_regable);
  900. exclude(tvarsym(sym).varoptions,vo_fpuregable);
  901. { get the alignment size }
  902. if (aktalignment.recordalignmax=-1) then
  903. begin
  904. varalign:=vardef.alignment;
  905. if (varalign>4) and
  906. ((varalign mod 4)<>0) and
  907. (vardef.deftype=arraydef) then
  908. Message1(sym_w_wrong_C_pack,vardef.typename);
  909. if varalign=0 then
  910. varalign:=l;
  911. if (dataalignment<aktalignment.maxCrecordalign) then
  912. begin
  913. if (varalign>16) and (dataalignment<32) then
  914. dataalignment:=32
  915. else if (varalign>12) and (dataalignment<16) then
  916. dataalignment:=16
  917. { 12 is needed for long double }
  918. else if (varalign>8) and (dataalignment<12) then
  919. dataalignment:=12
  920. else if (varalign>4) and (dataalignment<8) then
  921. dataalignment:=8
  922. else if (varalign>2) and (dataalignment<4) then
  923. dataalignment:=4
  924. else if (varalign>1) and (dataalignment<2) then
  925. dataalignment:=2;
  926. end;
  927. dataalignment:=min(dataalignment,aktalignment.maxCrecordalign);
  928. end
  929. else
  930. varalign:=vardef.alignment;
  931. if varalign=0 then
  932. varalign:=size_2_align(l);
  933. varalign:=used_align(varalign,aktalignment.recordalignmin,dataalignment);
  934. tvarsym(sym).address:=align(datasize,varalign);
  935. datasize:=tvarsym(sym).address+l;
  936. end;
  937. {****************************************************************************
  938. TRecordSymtable
  939. ****************************************************************************}
  940. constructor trecordsymtable.create;
  941. begin
  942. inherited create('');
  943. symtabletype:=recordsymtable;
  944. end;
  945. { this procedure is reserved for inserting case variant into
  946. a record symtable }
  947. { the offset is the location of the start of the variant
  948. and datasize and dataalignment corresponds to
  949. the complete size (see code in pdecl unit) PM }
  950. procedure trecordsymtable.insert_in(tsymt : tsymtable;offset : longint);
  951. var
  952. ps,nps : tvarsym;
  953. pd,npd : tdef;
  954. storesize,storealign : longint;
  955. begin
  956. storesize:=tsymt.datasize;
  957. storealign:=tsymt.dataalignment;
  958. tsymt.datasize:=offset;
  959. ps:=tvarsym(symindex.first);
  960. while assigned(ps) do
  961. begin
  962. nps:=tvarsym(ps.indexnext);
  963. { remove from current symtable }
  964. symindex.deleteindex(ps);
  965. ps.left:=nil;
  966. ps.right:=nil;
  967. { add to symt }
  968. ps.owner:=tsymt;
  969. tsymt.datasize:=ps.address+offset;
  970. tsymt.symindex.insert(ps);
  971. tsymt.symsearch.insert(ps);
  972. { update address }
  973. ps.address:=tsymt.datasize;
  974. { next }
  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. tstoredsym(hsym).is_visible_for_object(tobjectdef(defowner)) then
  1014. begin
  1015. DuplicateSym(hsym);
  1016. exit;
  1017. end;
  1018. end;
  1019. inherited insert(sym);
  1020. end;
  1021. {****************************************************************************
  1022. TAbstractLocalSymtable
  1023. ****************************************************************************}
  1024. procedure tabstractlocalsymtable.ppuload(ppufile:tcompilerppufile);
  1025. var
  1026. storesymtable : tsymtable;
  1027. begin
  1028. storesymtable:=aktlocalsymtable;
  1029. aktlocalsymtable:=self;
  1030. inherited ppuload(ppufile);
  1031. aktlocalsymtable:=storesymtable;
  1032. end;
  1033. procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1034. var
  1035. oldtyp : byte;
  1036. storesymtable : tsymtable;
  1037. begin
  1038. storesymtable:=aktlocalsymtable;
  1039. aktlocalsymtable:=self;
  1040. oldtyp:=ppufile.entrytyp;
  1041. ppufile.entrytyp:=subentryid;
  1042. { write definitions }
  1043. writedefs(ppufile);
  1044. { write symbols }
  1045. writesyms(ppufile);
  1046. ppufile.entrytyp:=oldtyp;
  1047. aktlocalsymtable:=storesymtable;
  1048. end;
  1049. procedure tabstractlocalsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1050. var
  1051. storesymtable : tsymtable;
  1052. begin
  1053. storesymtable:=aktlocalsymtable;
  1054. aktlocalsymtable:=self;
  1055. inherited load_references(ppufile,locals);
  1056. aktlocalsymtable:=storesymtable;
  1057. end;
  1058. procedure tabstractlocalsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1059. var
  1060. storesymtable : tsymtable;
  1061. begin
  1062. storesymtable:=aktlocalsymtable;
  1063. aktlocalsymtable:=self;
  1064. inherited write_references(ppufile,locals);
  1065. aktlocalsymtable:=storesymtable;
  1066. end;
  1067. {****************************************************************************
  1068. TLocalSymtable
  1069. ****************************************************************************}
  1070. constructor tlocalsymtable.create;
  1071. begin
  1072. inherited create('');
  1073. symtabletype:=localsymtable;
  1074. end;
  1075. procedure tlocalsymtable.insert(sym:tsymentry);
  1076. var
  1077. hsym : tsym;
  1078. begin
  1079. if assigned(next) then
  1080. begin
  1081. if (next.symtabletype=parasymtable) then
  1082. begin
  1083. hsym:=tsym(next.search(sym.name));
  1084. if assigned(hsym) then
  1085. begin
  1086. { a parameter and the function can have the same
  1087. name in TP and Delphi, but RESULT not }
  1088. if (m_duplicate_names in aktmodeswitches) and
  1089. (sym.typ=funcretsym) and
  1090. not((m_result in aktmodeswitches) and
  1091. (sym.name='RESULT')) then
  1092. sym.name:='hidden'+sym.name
  1093. else
  1094. begin
  1095. DuplicateSym(hsym);
  1096. exit;
  1097. end;
  1098. end;
  1099. end;
  1100. { check for duplicate id in local symtable of methods }
  1101. if assigned(next.next) and
  1102. { funcretsym is allowed !! }
  1103. (sym.typ <> funcretsym) and
  1104. (next.next.symtabletype=objectsymtable) then
  1105. begin
  1106. hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
  1107. if assigned(hsym) and
  1108. { private ids can be reused }
  1109. (not(sp_private in hsym.symoptions) or
  1110. (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
  1111. begin
  1112. { delphi allows to reuse the names in a class, but not
  1113. in object (tp7 compatible) }
  1114. if not((m_delphi in aktmodeswitches) and
  1115. is_class(tdef(next.next.defowner))) then
  1116. begin
  1117. DuplicateSym(hsym);
  1118. exit;
  1119. end;
  1120. end;
  1121. end;
  1122. end;
  1123. inherited insert(sym);
  1124. end;
  1125. procedure tlocalsymtable.insertvardata(sym : tsymentry);
  1126. var
  1127. l,varalign : longint;
  1128. begin
  1129. if not(sym.typ in [varsym,funcretsym]) then
  1130. internalerror(200208255);
  1131. case sym.typ of
  1132. varsym :
  1133. begin
  1134. tvarsym(sym).varstate:=vs_declared;
  1135. l:=tvarsym(sym).getvaluesize;
  1136. varalign:=size_2_align(l);
  1137. varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
  1138. {$ifdef powerpc}
  1139. { on the powerpc, the local variables are accessed with a positiv offset }
  1140. tvarsym(sym).address:=align(datasize,varalign);
  1141. datasize:=tvarsym(sym).address+l;
  1142. {$else powerpc}
  1143. tvarsym(sym).address:=align(datasize+l,varalign);
  1144. datasize:=tvarsym(sym).address;
  1145. {$endif powerpc}
  1146. end;
  1147. funcretsym :
  1148. begin
  1149. { if retoffset is already set then reuse it, this is needed
  1150. when inserting the result variable }
  1151. if procinfo.return_offset<>0 then
  1152. tfuncretsym(sym).address:=procinfo.return_offset
  1153. else
  1154. begin
  1155. { allocate space in local if ret in register }
  1156. if paramanager.ret_in_reg(tfuncretsym(sym).returntype.def,
  1157. tprocdef(sym.owner.defowner).proccalloption) then
  1158. begin
  1159. l:=tfuncretsym(sym).returntype.def.size;
  1160. varalign:=size_2_align(l);
  1161. varalign:=used_align(varalign,aktalignment.localalignmin,dataalignment);
  1162. tfuncretsym(sym).address:=align(datasize+l,varalign);
  1163. datasize:=tfuncretsym(sym).address;
  1164. procinfo.return_offset:=-tfuncretsym(sym).address;
  1165. end;
  1166. end;
  1167. end;
  1168. end;
  1169. end;
  1170. procedure tlocalsymtable.insertconstdata(sym : tsymentry);
  1171. { this does not affect the local stack space, since all
  1172. typed constansts and initialized variables are always
  1173. put in the .data / .rodata section
  1174. }
  1175. var
  1176. storefilepos : tfileposinfo;
  1177. curconstsegment : taasmoutput;
  1178. l : longint;
  1179. begin
  1180. { Note: this is the same code as tabstractunitsymtable.insertconstdata }
  1181. if sym.typ<>typedconstsym then
  1182. internalerror(200208254);
  1183. storefilepos:=aktfilepos;
  1184. aktfilepos:=tsym(sym).fileinfo;
  1185. if ttypedconstsym(sym).is_writable then
  1186. curconstsegment:=datasegment
  1187. else
  1188. curconstsegment:=consts;
  1189. l:=ttypedconstsym(sym).getsize;
  1190. { insert cut for smartlinking or alignment }
  1191. if (cs_create_smart in aktmoduleswitches) then
  1192. curconstSegment.concat(Tai_cut.Create);
  1193. curconstSegment.concat(Tai_align.create(const_align(l)));
  1194. {$ifdef GDB}
  1195. if cs_debuginfo in aktmoduleswitches then
  1196. ttypedconstsym(sym).concatstabto(curconstsegment);
  1197. {$endif GDB}
  1198. if (cs_create_smart in aktmoduleswitches) or
  1199. DLLSource then
  1200. begin
  1201. curconstSegment.concat(Tai_symbol.Createdataname_global(
  1202. ttypedconstsym(sym).mangledname,l));
  1203. end
  1204. else
  1205. begin
  1206. curconstSegment.concat(Tai_symbol.Createdataname(
  1207. ttypedconstsym(sym).mangledname,l));
  1208. end;
  1209. aktfilepos:=storefilepos;
  1210. end;
  1211. {****************************************************************************
  1212. TParaSymtable
  1213. ****************************************************************************}
  1214. constructor tparasymtable.create;
  1215. begin
  1216. inherited create('');
  1217. symtabletype:=parasymtable;
  1218. dataalignment:=aktalignment.paraalign;
  1219. end;
  1220. procedure tparasymtable.insert(sym:tsymentry);
  1221. var
  1222. hsym : tsym;
  1223. begin
  1224. { check for duplicate id in para symtable of methods }
  1225. if assigned(procinfo) and
  1226. assigned(procinfo._class) and
  1227. { but not in nested procedures !}
  1228. (not(assigned(procinfo.parent)) or
  1229. (assigned(procinfo.parent) and
  1230. not(assigned(procinfo.parent._class)))
  1231. ) and
  1232. { funcretsym is allowed !! }
  1233. (sym.typ<>funcretsym) then
  1234. begin
  1235. hsym:=search_class_member(procinfo._class,sym.name);
  1236. { private ids can be reused }
  1237. if assigned(hsym) and
  1238. tstoredsym(hsym).is_visible_for_object(procinfo._class) then
  1239. begin
  1240. { delphi allows to reuse the names in a class, but not
  1241. in object (tp7 compatible) }
  1242. if not((m_delphi in aktmodeswitches) and
  1243. is_class_or_interface(procinfo._class)) then
  1244. begin
  1245. DuplicateSym(hsym);
  1246. exit;
  1247. end;
  1248. end;
  1249. end;
  1250. inherited insert(sym);
  1251. end;
  1252. procedure tparasymtable.insertvardata(sym : tsymentry);
  1253. var
  1254. l,varalign : longint;
  1255. begin
  1256. if sym.typ<>varsym then
  1257. internalerror(200208253);
  1258. { retrieve cdecl status }
  1259. if defowner.deftype<>procdef then
  1260. internalerror(200208256);
  1261. { here we need the size of a push instead of the
  1262. size of the data }
  1263. l:=paramanager.push_size(tvarsym(sym).varspez,tvarsym(sym).vartype.def,tprocdef(defowner).proccalloption);
  1264. varalign:=size_2_align(l);
  1265. tvarsym(sym).varstate:=vs_assigned;
  1266. { we need the new datasize already aligned so we can't
  1267. use the align_address here }
  1268. tvarsym(sym).address:=datasize;
  1269. varalign:=used_align(varalign,dataalignment,dataalignment);
  1270. datasize:=align(tvarsym(sym).address+l,varalign);
  1271. end;
  1272. {****************************************************************************
  1273. TAbstractUnitSymtable
  1274. ****************************************************************************}
  1275. constructor tabstractunitsymtable.create(const n : string);
  1276. begin
  1277. inherited create(n);
  1278. symsearch.usehash;
  1279. {$ifdef GDB}
  1280. { reset GDB things }
  1281. prev_dbx_counter := dbx_counter;
  1282. dbx_counter := nil;
  1283. is_stab_written:=false;
  1284. dbx_count := -1;
  1285. {$endif GDB}
  1286. end;
  1287. procedure tabstractunitsymtable.insertvardata(sym : tsymentry);
  1288. var
  1289. l,varalign : longint;
  1290. storefilepos : tfileposinfo;
  1291. begin
  1292. if sym.typ<>varsym then
  1293. internalerror(200208252);
  1294. storefilepos:=aktfilepos;
  1295. aktfilepos:=tsym(sym).fileinfo;
  1296. l:=tvarsym(sym).getvaluesize;
  1297. if (vo_is_thread_var in tvarsym(sym).varoptions) then
  1298. inc(l,pointer_size);
  1299. varalign:=var_align(l);
  1300. tvarsym(sym).address:=align(datasize,varalign);
  1301. { insert cut for smartlinking or alignment }
  1302. if (cs_create_smart in aktmoduleswitches) then
  1303. bssSegment.concat(Tai_cut.Create);
  1304. bssSegment.concat(Tai_align.create(varalign));
  1305. datasize:=tvarsym(sym).address+l;
  1306. {$ifdef GDB}
  1307. if cs_debuginfo in aktmoduleswitches then
  1308. tvarsym(sym).concatstabto(bsssegment);
  1309. {$endif GDB}
  1310. if (symtabletype=globalsymtable) or
  1311. (cs_create_smart in aktmoduleswitches) or
  1312. DLLSource or
  1313. (vo_is_exported in tvarsym(sym).varoptions) or
  1314. (vo_is_C_var in tvarsym(sym).varoptions) then
  1315. bssSegment.concat(Tai_datablock.Create_global(tvarsym(sym).mangledname,l))
  1316. else
  1317. bssSegment.concat(Tai_datablock.Create(tvarsym(sym).mangledname,l));
  1318. aktfilepos:=storefilepos;
  1319. end;
  1320. procedure tabstractunitsymtable.insertconstdata(sym : tsymentry);
  1321. var
  1322. storefilepos : tfileposinfo;
  1323. curconstsegment : taasmoutput;
  1324. l : longint;
  1325. begin
  1326. if sym.typ<>typedconstsym then
  1327. internalerror(200208254);
  1328. storefilepos:=aktfilepos;
  1329. aktfilepos:=tsym(sym).fileinfo;
  1330. if ttypedconstsym(sym).is_writable then
  1331. curconstsegment:=datasegment
  1332. else
  1333. curconstsegment:=consts;
  1334. l:=ttypedconstsym(sym).getsize;
  1335. { insert cut for smartlinking or alignment }
  1336. if (cs_create_smart in aktmoduleswitches) then
  1337. curconstSegment.concat(Tai_cut.Create);
  1338. curconstSegment.concat(Tai_align.create(const_align(l)));
  1339. {$ifdef GDB}
  1340. if cs_debuginfo in aktmoduleswitches then
  1341. ttypedconstsym(sym).concatstabto(curconstsegment);
  1342. {$endif GDB}
  1343. if (symtabletype=globalsymtable) or
  1344. (cs_create_smart in aktmoduleswitches) or
  1345. DLLSource then
  1346. begin
  1347. curconstSegment.concat(Tai_symbol.Createdataname_global(
  1348. ttypedconstsym(sym).mangledname,l));
  1349. end
  1350. else
  1351. begin
  1352. curconstSegment.concat(Tai_symbol.Createdataname(
  1353. ttypedconstsym(sym).mangledname,l));
  1354. end;
  1355. aktfilepos:=storefilepos;
  1356. end;
  1357. {$ifdef GDB}
  1358. procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
  1359. var prev_dbx_count : plongint;
  1360. begin
  1361. if is_stab_written then
  1362. exit;
  1363. if not assigned(name) then
  1364. name := stringdup('Main_program');
  1365. if (symtabletype = globalsymtable) and
  1366. (current_module.globalsymtable<>self) then
  1367. begin
  1368. unitid:=current_module.unitcount;
  1369. inc(current_module.unitcount);
  1370. end;
  1371. asmList.concat(tai_comment.Create(strpnew('Begin unit '+name^+' has index '+tostr(unitid))));
  1372. if cs_gdb_dbx in aktglobalswitches then
  1373. begin
  1374. if dbx_count_ok then
  1375. begin
  1376. asmList.concat(tai_comment.Create(strpnew('"repeated" unit '+name^
  1377. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count))));
  1378. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1379. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count))));
  1380. exit;
  1381. end
  1382. else if (current_module.globalsymtable<>self) then
  1383. begin
  1384. prev_dbx_count := dbx_counter;
  1385. dbx_counter := nil;
  1386. do_count_dbx:=false;
  1387. if (symtabletype = globalsymtable) and (unitid<>0) then
  1388. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1389. dbx_counter := @dbx_count;
  1390. dbx_count:=0;
  1391. do_count_dbx:=assigned(dbx_counter);
  1392. end;
  1393. end;
  1394. foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab,asmlist);
  1395. if cs_gdb_dbx in aktglobalswitches then
  1396. begin
  1397. if (current_module.globalsymtable<>self) then
  1398. begin
  1399. dbx_counter := prev_dbx_count;
  1400. do_count_dbx:=false;
  1401. asmList.concat(tai_comment.Create(strpnew('End unit '+name^
  1402. +' has index '+tostr(unitid))));
  1403. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1404. +tostr(N_EINCL)+',0,0,0')));
  1405. do_count_dbx:=assigned(dbx_counter);
  1406. dbx_count_ok := {true}false;
  1407. end;
  1408. end;
  1409. is_stab_written:=true;
  1410. end;
  1411. {$endif GDB}
  1412. {****************************************************************************
  1413. TStaticSymtable
  1414. ****************************************************************************}
  1415. constructor tstaticsymtable.create(const n : string);
  1416. begin
  1417. inherited create(n);
  1418. symtabletype:=staticsymtable;
  1419. end;
  1420. procedure tstaticsymtable.ppuload(ppufile:tcompilerppufile);
  1421. begin
  1422. aktstaticsymtable:=self;
  1423. next:=symtablestack;
  1424. symtablestack:=self;
  1425. inherited ppuload(ppufile);
  1426. { now we can deref the syms and defs }
  1427. deref;
  1428. { restore symtablestack }
  1429. symtablestack:=next;
  1430. end;
  1431. procedure tstaticsymtable.ppuwrite(ppufile:tcompilerppufile);
  1432. begin
  1433. aktstaticsymtable:=self;
  1434. inherited ppuwrite(ppufile);
  1435. end;
  1436. procedure tstaticsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
  1437. begin
  1438. aktstaticsymtable:=self;
  1439. inherited load_references(ppufile,locals);
  1440. end;
  1441. procedure tstaticsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
  1442. begin
  1443. aktstaticsymtable:=self;
  1444. inherited write_references(ppufile,locals);
  1445. end;
  1446. procedure tstaticsymtable.insert(sym:tsymentry);
  1447. var
  1448. hsym : tsym;
  1449. begin
  1450. { also check the global symtable }
  1451. if assigned(next) and
  1452. (next.unitid=0) then
  1453. begin
  1454. hsym:=tsym(next.search(sym.name));
  1455. if assigned(hsym) then
  1456. begin
  1457. DuplicateSym(hsym);
  1458. exit;
  1459. end;
  1460. end;
  1461. inherited insert(sym);
  1462. end;
  1463. procedure tstaticsymtable.insertvardata(sym : tsymentry);
  1464. begin
  1465. inherited insertvardata(sym);
  1466. { enable unitialized warning for local symbols }
  1467. if sym.typ=varsym then
  1468. tvarsym(sym).varstate:=vs_declared;
  1469. end;
  1470. {****************************************************************************
  1471. TGlobalSymtable
  1472. ****************************************************************************}
  1473. constructor tglobalsymtable.create(const n : string);
  1474. begin
  1475. inherited create(n);
  1476. symtabletype:=globalsymtable;
  1477. unitid:=0;
  1478. unitsym:=nil;
  1479. {$ifdef GDB}
  1480. if cs_gdb_dbx in aktglobalswitches then
  1481. begin
  1482. dbx_count := 0;
  1483. unittypecount:=1;
  1484. pglobaltypecount := @unittypecount;
  1485. {unitid:=current_module.unitcount;}
  1486. debugList.concat(tai_comment.Create(strpnew('Global '+name^+' has index '+tostr(unitid))));
  1487. debugList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1488. {inc(current_module.unitcount);}
  1489. { we can't use dbx_vcount, because we don't know
  1490. if the object file will be loaded before or afeter PM }
  1491. dbx_count_ok:=false;
  1492. dbx_counter:=@dbx_count;
  1493. do_count_dbx:=true;
  1494. end;
  1495. {$endif GDB}
  1496. end;
  1497. destructor tglobalsymtable.destroy;
  1498. var
  1499. pus : tunitsym;
  1500. begin
  1501. pus:=unitsym;
  1502. while assigned(pus) do
  1503. begin
  1504. unitsym:=pus.prevsym;
  1505. pus.prevsym:=nil;
  1506. pus.unitsymtable:=nil;
  1507. pus:=unitsym;
  1508. end;
  1509. inherited destroy;
  1510. end;
  1511. procedure tglobalsymtable.ppuload(ppufile:tcompilerppufile);
  1512. {$ifdef GDB}
  1513. var
  1514. b : byte;
  1515. {$endif GDB}
  1516. begin
  1517. {$ifdef GDB}
  1518. if cs_gdb_dbx in aktglobalswitches then
  1519. begin
  1520. UnitTypeCount:=1;
  1521. PglobalTypeCount:=@UnitTypeCount;
  1522. end;
  1523. {$endif GDB}
  1524. symtablelevel:=0;
  1525. {$ifndef NEWMAP}
  1526. current_module.map^[0]:=self;
  1527. {$else NEWMAP}
  1528. current_module.globalsymtable:=self;
  1529. {$endif NEWMAP}
  1530. next:=symtablestack;
  1531. symtablestack:=self;
  1532. inherited ppuload(ppufile);
  1533. { now we can deref the syms and defs }
  1534. deref;
  1535. { restore symtablestack }
  1536. symtablestack:=next;
  1537. {$ifdef NEWMAP}
  1538. { necessary for dependencies }
  1539. current_module.globalsymtable:=nil;
  1540. {$endif NEWMAP}
  1541. { read dbx count }
  1542. {$ifdef GDB}
  1543. if (current_module.flags and uf_has_dbx)<>0 then
  1544. begin
  1545. b:=ppufile.readentry;
  1546. if b<>ibdbxcount then
  1547. Message(unit_f_ppu_dbx_count_problem)
  1548. else
  1549. dbx_count:=ppufile.getlongint;
  1550. {$IfDef EXTDEBUG}
  1551. writeln('Read dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1552. {$ENDIF EXTDEBUG}
  1553. { we can't use dbx_vcount, because we don't know
  1554. if the object file will be loaded before or afeter PM }
  1555. dbx_count_ok := {true}false;
  1556. end
  1557. else
  1558. begin
  1559. dbx_count:=-1;
  1560. dbx_count_ok:=false;
  1561. end;
  1562. {$endif GDB}
  1563. end;
  1564. procedure tglobalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1565. begin
  1566. { write the symtable entries }
  1567. inherited ppuwrite(ppufile);
  1568. { write dbx count }
  1569. {$ifdef GDB}
  1570. if cs_gdb_dbx in aktglobalswitches then
  1571. begin
  1572. {$IfDef EXTDEBUG}
  1573. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1574. {$ENDIF EXTDEBUG}
  1575. ppufile.do_crc:=false;
  1576. ppufile.putlongint(dbx_count);
  1577. ppufile.writeentry(ibdbxcount);
  1578. ppufile.do_crc:=true;
  1579. end;
  1580. {$endif GDB}
  1581. end;
  1582. procedure tglobalsymtable.insert(sym:tsymentry);
  1583. var
  1584. hsym : tsym;
  1585. begin
  1586. { also check the global symtable }
  1587. if assigned(next) and
  1588. (next.unitid=0) then
  1589. begin
  1590. hsym:=tsym(next.search(sym.name));
  1591. if assigned(hsym) then
  1592. begin
  1593. DuplicateSym(hsym);
  1594. exit;
  1595. end;
  1596. end;
  1597. hsym:=tsym(search(sym.name));
  1598. if assigned(hsym) then
  1599. begin
  1600. { Delphi you can have a symbol with the same name as the
  1601. unit, the unit can then not be accessed anymore using
  1602. <unit>.<id>, so we can hide the symbol }
  1603. if (m_duplicate_names in aktmodeswitches) and
  1604. (hsym.typ=symconst.unitsym) then
  1605. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  1606. else
  1607. begin
  1608. DuplicateSym(hsym);
  1609. exit;
  1610. end;
  1611. end;
  1612. inherited insert(sym);
  1613. end;
  1614. procedure tglobalsymtable.insertvardata(sym : tsymentry);
  1615. begin
  1616. inherited insertvardata(sym);
  1617. { this symbol can't be loaded to a register }
  1618. if sym.typ=varsym then
  1619. begin
  1620. exclude(tvarsym(sym).varoptions,vo_regable);
  1621. exclude(tvarsym(sym).varoptions,vo_fpuregable);
  1622. end;
  1623. end;
  1624. {$ifdef GDB}
  1625. function tglobalsymtable.getnewtypecount : word;
  1626. begin
  1627. if not (cs_gdb_dbx in aktglobalswitches) then
  1628. getnewtypecount:=inherited getnewtypecount
  1629. else
  1630. begin
  1631. getnewtypecount:=unittypecount;
  1632. inc(unittypecount);
  1633. end;
  1634. end;
  1635. {$endif}
  1636. {****************************************************************************
  1637. TWITHSYMTABLE
  1638. ****************************************************************************}
  1639. constructor twithsymtable.create(aowner:tdef;asymsearch:TDictionary);
  1640. begin
  1641. inherited create('');
  1642. symtabletype:=withsymtable;
  1643. direct_with:=false;
  1644. withnode:=nil;
  1645. withrefnode:=nil;
  1646. use_count:=1;
  1647. { we don't need the symsearch }
  1648. symsearch.free;
  1649. { set the defaults }
  1650. symsearch:=asymsearch;
  1651. defowner:=aowner;
  1652. end;
  1653. destructor twithsymtable.destroy;
  1654. begin
  1655. symsearch:=nil;
  1656. inherited destroy;
  1657. end;
  1658. procedure twithsymtable.clear;
  1659. begin
  1660. { remove no entry from a withsymtable as it is only a pointer to the
  1661. recorddef or objectdef symtable }
  1662. end;
  1663. {****************************************************************************
  1664. TSTT_ExceptionSymtable
  1665. ****************************************************************************}
  1666. constructor tstt_exceptsymtable.create;
  1667. begin
  1668. inherited create('');
  1669. symtabletype:=stt_exceptsymtable;
  1670. end;
  1671. {*****************************************************************************
  1672. Helper Routines
  1673. *****************************************************************************}
  1674. function findunitsymtable(st:tsymtable):tsymtable;
  1675. begin
  1676. findunitsymtable:=nil;
  1677. repeat
  1678. if not assigned(st) then
  1679. internalerror(5566561);
  1680. case st.symtabletype of
  1681. localsymtable,
  1682. parasymtable,
  1683. staticsymtable :
  1684. exit;
  1685. globalsymtable :
  1686. begin
  1687. findunitsymtable:=st;
  1688. exit;
  1689. end;
  1690. objectsymtable :
  1691. st:=st.defowner.owner;
  1692. recordsymtable :
  1693. begin
  1694. { don't continue when the current
  1695. symtable is used for variant records }
  1696. if trecorddef(st.defowner).isunion then
  1697. begin
  1698. findunitsymtable:=nil;
  1699. exit;
  1700. end
  1701. else
  1702. st:=st.defowner.owner;
  1703. end;
  1704. else
  1705. internalerror(5566562);
  1706. end;
  1707. until false;
  1708. end;
  1709. procedure duplicatesym(sym:tsym);
  1710. var
  1711. st : tsymtable;
  1712. begin
  1713. Message1(sym_e_duplicate_id,sym.realname);
  1714. st:=findunitsymtable(sym.owner);
  1715. with sym.fileinfo do
  1716. begin
  1717. if assigned(st) and (st.unitid<>0) then
  1718. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line))
  1719. else
  1720. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line));
  1721. end;
  1722. end;
  1723. {*****************************************************************************
  1724. Search
  1725. *****************************************************************************}
  1726. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  1727. var
  1728. speedvalue : cardinal;
  1729. begin
  1730. speedvalue:=getspeedvalue(s);
  1731. srsymtable:=symtablestack;
  1732. while assigned(srsymtable) do
  1733. begin
  1734. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  1735. if assigned(srsym) and
  1736. tstoredsym(srsym).is_visible_for_proc(aktprocdef) then
  1737. begin
  1738. searchsym:=true;
  1739. exit;
  1740. end
  1741. else
  1742. srsymtable:=srsymtable.next;
  1743. end;
  1744. searchsym:=false;
  1745. end;
  1746. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  1747. var
  1748. srsym : tsym;
  1749. begin
  1750. { the caller have to take care if srsym=nil }
  1751. if assigned(p) then
  1752. begin
  1753. srsym:=tsym(p.search(s));
  1754. if assigned(srsym) then
  1755. begin
  1756. searchsymonlyin:=srsym;
  1757. exit;
  1758. end;
  1759. { also check in the local symtbale if it exists }
  1760. if (p=tsymtable(current_module.globalsymtable)) then
  1761. begin
  1762. srsym:=tsym(current_module.localsymtable.search(s));
  1763. if assigned(srsym) then
  1764. begin
  1765. searchsymonlyin:=srsym;
  1766. exit;
  1767. end;
  1768. end
  1769. end;
  1770. searchsymonlyin:=nil;
  1771. end;
  1772. function searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
  1773. var
  1774. speedvalue : cardinal;
  1775. topclassh : tobjectdef;
  1776. sym : tsym;
  1777. begin
  1778. speedvalue:=getspeedvalue(s);
  1779. { when the class passed is defined in this unit we
  1780. need to use the scope of that class. This is a trick
  1781. that can be used to access protected members in other
  1782. units. At least kylix supports it this way (PFV) }
  1783. if (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1784. (classh.owner.unitid=0) then
  1785. topclassh:=classh
  1786. else
  1787. topclassh:=nil;
  1788. sym:=nil;
  1789. while assigned(classh) do
  1790. begin
  1791. sym:=tsym(classh.symtable.speedsearch(s,speedvalue));
  1792. if assigned(sym) then
  1793. begin
  1794. if assigned(topclassh) then
  1795. begin
  1796. if tstoredsym(sym).is_visible_for_object(topclassh) then
  1797. break;
  1798. end
  1799. else
  1800. begin
  1801. if tstoredsym(sym).is_visible_for_proc(aktprocdef) then
  1802. break;
  1803. end;
  1804. end;
  1805. classh:=classh.childof;
  1806. end;
  1807. searchsym_in_class:=sym;
  1808. end;
  1809. function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
  1810. var
  1811. symowner: tsymtable;
  1812. begin
  1813. if not(cs_compilesystem in aktmoduleswitches) then
  1814. srsym := ttypesym(searchsymonlyin(systemunit,s))
  1815. else
  1816. searchsym(s,tsym(srsym),symowner);
  1817. searchsystype :=
  1818. assigned(srsym) and
  1819. (srsym.typ = typesym);
  1820. end;
  1821. function searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
  1822. begin
  1823. if not(cs_compilesystem in aktmoduleswitches) then
  1824. begin
  1825. srsym := tvarsym(searchsymonlyin(systemunit,s));
  1826. symowner := systemunit;
  1827. end
  1828. else
  1829. searchsym(s,tsym(srsym),symowner);
  1830. searchsysvar :=
  1831. assigned(srsym) and
  1832. (srsym.typ = varsym);
  1833. end;
  1834. function search_class_member(pd : tobjectdef;const s : string):tsym;
  1835. { searches n in symtable of pd and all anchestors }
  1836. var
  1837. speedvalue : cardinal;
  1838. srsym : tsym;
  1839. begin
  1840. speedvalue:=getspeedvalue(s);
  1841. while assigned(pd) do
  1842. begin
  1843. srsym:=tsym(pd.symtable.speedsearch(s,speedvalue));
  1844. if assigned(srsym) then
  1845. begin
  1846. search_class_member:=srsym;
  1847. exit;
  1848. end;
  1849. pd:=pd.childof;
  1850. end;
  1851. search_class_member:=nil;
  1852. end;
  1853. {*****************************************************************************
  1854. Definition Helpers
  1855. *****************************************************************************}
  1856. procedure globaldef(const s : string;var t:ttype);
  1857. var st : string;
  1858. symt : tsymtable;
  1859. srsym : tsym;
  1860. srsymtable : tsymtable;
  1861. begin
  1862. srsym := nil;
  1863. if pos('.',s) > 0 then
  1864. begin
  1865. st := copy(s,1,pos('.',s)-1);
  1866. searchsym(st,srsym,srsymtable);
  1867. st := copy(s,pos('.',s)+1,255);
  1868. if assigned(srsym) then
  1869. begin
  1870. if srsym.typ = unitsym then
  1871. begin
  1872. symt := tunitsym(srsym).unitsymtable;
  1873. srsym := tsym(symt.search(st));
  1874. end else srsym := nil;
  1875. end;
  1876. end else st := s;
  1877. if srsym = nil then
  1878. searchsym(st,srsym,srsymtable);
  1879. if srsym = nil then
  1880. srsym:=searchsymonlyin(systemunit,st);
  1881. if (not assigned(srsym)) or
  1882. (srsym.typ<>typesym) then
  1883. begin
  1884. Message(type_e_type_id_expected);
  1885. t:=generrortype;
  1886. exit;
  1887. end;
  1888. t := ttypesym(srsym).restype;
  1889. end;
  1890. {****************************************************************************
  1891. Object Helpers
  1892. ****************************************************************************}
  1893. var
  1894. _defaultprop : tpropertysym;
  1895. procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem;arg:pointer);
  1896. begin
  1897. if (tsym(p).typ=propertysym) and
  1898. (ppo_defaultproperty in tpropertysym(p).propoptions) then
  1899. _defaultprop:=tpropertysym(p);
  1900. end;
  1901. function search_default_property(pd : tobjectdef) : tpropertysym;
  1902. { returns the default property of a class, searches also anchestors }
  1903. begin
  1904. _defaultprop:=nil;
  1905. while assigned(pd) do
  1906. begin
  1907. pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty,nil);
  1908. if assigned(_defaultprop) then
  1909. break;
  1910. pd:=pd.childof;
  1911. end;
  1912. search_default_property:=_defaultprop;
  1913. end;
  1914. {$ifdef UNITALIASES}
  1915. {****************************************************************************
  1916. TUNIT_ALIAS
  1917. ****************************************************************************}
  1918. constructor tunit_alias.create(const n:string);
  1919. var
  1920. i : longint;
  1921. begin
  1922. i:=pos('=',n);
  1923. if i=0 then
  1924. fail;
  1925. inherited createname(Copy(n,1,i-1));
  1926. newname:=stringdup(Copy(n,i+1,255));
  1927. end;
  1928. destructor tunit_alias.destroy;
  1929. begin
  1930. stringdispose(newname);
  1931. inherited destroy;
  1932. end;
  1933. procedure addunitalias(const n:string);
  1934. begin
  1935. unitaliases^.insert(tunit_alias,init(Upper(n))));
  1936. end;
  1937. function getunitalias(const n:string):string;
  1938. var
  1939. p : punit_alias;
  1940. begin
  1941. p:=punit_alias(unitaliases^.search(Upper(n)));
  1942. if assigned(p) then
  1943. getunitalias:=punit_alias(p).newname^
  1944. else
  1945. getunitalias:=n;
  1946. end;
  1947. {$endif UNITALIASES}
  1948. {****************************************************************************
  1949. Symtable Stack
  1950. ****************************************************************************}
  1951. procedure dellexlevel;
  1952. var
  1953. p : tsymtable;
  1954. begin
  1955. p:=symtablestack;
  1956. symtablestack:=p.next;
  1957. { symbol tables of unit interfaces are never disposed }
  1958. { this is handle by the unit unitm }
  1959. if not(p.symtabletype in [globalsymtable,stt_exceptsymtable]) then
  1960. p.free;
  1961. end;
  1962. procedure RestoreUnitSyms;
  1963. var
  1964. p : tsymtable;
  1965. begin
  1966. p:=symtablestack;
  1967. while assigned(p) do
  1968. begin
  1969. if (p.symtabletype=globalsymtable) and
  1970. assigned(tglobalsymtable(p).unitsym) and
  1971. ((tglobalsymtable(p).unitsym.owner=current_module.globalsymtable) or
  1972. (tglobalsymtable(p).unitsym.owner=current_module.localsymtable)) then
  1973. tglobalsymtable(p).unitsym.restoreunitsym;
  1974. p:=p.next;
  1975. end;
  1976. end;
  1977. {$ifdef DEBUG}
  1978. procedure test_symtablestack;
  1979. var
  1980. p : tsymtable;
  1981. i : longint;
  1982. begin
  1983. p:=symtablestack;
  1984. i:=0;
  1985. while assigned(p) do
  1986. begin
  1987. inc(i);
  1988. p:=p.next;
  1989. if i>500 then
  1990. Message(sym_f_internal_error_in_symtablestack);
  1991. end;
  1992. end;
  1993. procedure list_symtablestack;
  1994. var
  1995. p : tsymtable;
  1996. i : longint;
  1997. begin
  1998. p:=symtablestack;
  1999. i:=0;
  2000. while assigned(p) do
  2001. begin
  2002. inc(i);
  2003. writeln(i,' ',p.name^);
  2004. p:=p.next;
  2005. if i>500 then
  2006. Message(sym_f_internal_error_in_symtablestack);
  2007. end;
  2008. end;
  2009. {$endif DEBUG}
  2010. {****************************************************************************
  2011. Init/Done Symtable
  2012. ****************************************************************************}
  2013. procedure InitSymtable;
  2014. var
  2015. token : ttoken;
  2016. begin
  2017. { Reset symbolstack }
  2018. registerdef:=false;
  2019. read_member:=false;
  2020. symtablestack:=nil;
  2021. systemunit:=nil;
  2022. {$ifdef GDB}
  2023. firstglobaldef:=nil;
  2024. lastglobaldef:=nil;
  2025. globaltypecount:=1;
  2026. pglobaltypecount:=@globaltypecount;
  2027. {$endif GDB}
  2028. { create error syms and def }
  2029. generrorsym:=terrorsym.create;
  2030. generrortype.setdef(terrordef.create);
  2031. {$ifdef UNITALIASES}
  2032. { unit aliases }
  2033. unitaliases:=tdictionary.create;
  2034. {$endif}
  2035. for token:=first_overloaded to last_overloaded do
  2036. overloaded_operators[token]:=nil;
  2037. end;
  2038. procedure DoneSymtable;
  2039. begin
  2040. generrorsym.free;
  2041. generrortype.def.free;
  2042. {$ifdef UNITALIASES}
  2043. unitaliases.free;
  2044. {$endif}
  2045. end;
  2046. end.
  2047. {
  2048. $Log$
  2049. Revision 1.84 2002-12-06 17:51:11 peter
  2050. * merged cdecl and array fixes
  2051. Revision 1.83 2002/11/30 11:12:48 carl
  2052. + checking for symbols used with hint directives is done mostly in pexpr
  2053. only now
  2054. Revision 1.82 2002/11/29 22:31:20 carl
  2055. + unimplemented hint directive added
  2056. * hint directive parsing implemented
  2057. * warning on these directives
  2058. Revision 1.81 2002/11/27 20:04:09 peter
  2059. * tvarsym.get_push_size replaced by paramanager.push_size
  2060. Revision 1.80 2002/11/22 22:45:49 carl
  2061. + small optimization for speed
  2062. Revision 1.79 2002/11/19 16:26:33 pierre
  2063. * correct a stabs generation problem that lead to use errordef in stabs
  2064. Revision 1.78 2002/11/18 17:32:00 peter
  2065. * pass proccalloption to ret_in_xxx and push_xxx functions
  2066. Revision 1.77 2002/11/15 01:58:54 peter
  2067. * merged changes from 1.0.7 up to 04-11
  2068. - -V option for generating bug report tracing
  2069. - more tracing for option parsing
  2070. - errors for cdecl and high()
  2071. - win32 import stabs
  2072. - win32 records<=8 are returned in eax:edx (turned off by default)
  2073. - heaptrc update
  2074. - more info for temp management in .s file with EXTDEBUG
  2075. Revision 1.76 2002/11/09 15:29:28 carl
  2076. + bss / constant alignment fixes
  2077. * avoid incrementing address/datasize in local symtable for const's
  2078. Revision 1.75 2002/10/14 19:44:43 peter
  2079. * threadvars need 4 bytes extra for storing the threadvar index
  2080. Revision 1.74 2002/10/06 19:41:31 peter
  2081. * Add finalization of typed consts
  2082. * Finalization of globals in the main program
  2083. Revision 1.73 2002/10/05 12:43:29 carl
  2084. * fixes for Delphi 6 compilation
  2085. (warning : Some features do not work under Delphi)
  2086. Revision 1.72 2002/09/09 19:41:46 peter
  2087. * real fix internalerror for dup ids in union sym
  2088. Revision 1.71 2002/09/09 17:34:16 peter
  2089. * tdicationary.replace added to replace and item in a dictionary. This
  2090. is only allowed for the same name
  2091. * varsyms are inserted in symtable before the types are parsed. This
  2092. fixes the long standing "var longint : longint" bug
  2093. - consume_idlist and idstringlist removed. The loops are inserted
  2094. at the callers place and uses the symtable for duplicate id checking
  2095. Revision 1.70 2002/09/05 19:29:45 peter
  2096. * memdebug enhancements
  2097. Revision 1.69 2002/08/25 19:25:21 peter
  2098. * sym.insert_in_data removed
  2099. * symtable.insertvardata/insertconstdata added
  2100. * removed insert_in_data call from symtable.insert, it needs to be
  2101. called separatly. This allows to deref the address calculation
  2102. * procedures now calculate the parast addresses after the procedure
  2103. directives are parsed. This fixes the cdecl parast problem
  2104. * push_addr_param has an extra argument that specifies if cdecl is used
  2105. or not
  2106. Revision 1.68 2002/08/18 20:06:27 peter
  2107. * inlining is now also allowed in interface
  2108. * renamed write/load to ppuwrite/ppuload
  2109. * tnode storing in ppu
  2110. * nld,ncon,nbas are already updated for storing in ppu
  2111. Revision 1.67 2002/08/17 09:23:43 florian
  2112. * first part of procinfo rewrite
  2113. Revision 1.66 2002/08/11 13:24:15 peter
  2114. * saving of asmsymbols in ppu supported
  2115. * asmsymbollist global is removed and moved into a new class
  2116. tasmlibrarydata that will hold the info of a .a file which
  2117. corresponds with a single module. Added librarydata to tmodule
  2118. to keep the library info stored for the module. In the future the
  2119. objectfiles will also be stored to the tasmlibrarydata class
  2120. * all getlabel/newasmsymbol and friends are moved to the new class
  2121. Revision 1.65 2002/07/23 09:51:27 daniel
  2122. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2123. are worth comitting.
  2124. Revision 1.64 2002/07/16 15:34:21 florian
  2125. * exit is now a syssym instead of a keyword
  2126. Revision 1.63 2002/07/15 19:44:53 florian
  2127. * fixed crash with default parameters and stdcall calling convention
  2128. Revision 1.62 2002/07/01 18:46:28 peter
  2129. * internal linker
  2130. * reorganized aasm layer
  2131. Revision 1.61 2002/05/18 13:34:19 peter
  2132. * readded missing revisions
  2133. Revision 1.60 2002/05/16 19:46:45 carl
  2134. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2135. + try to fix temp allocation (still in ifdef)
  2136. + generic constructor calls
  2137. + start of tassembler / tmodulebase class cleanup
  2138. Revision 1.58 2002/05/12 16:53:15 peter
  2139. * moved entry and exitcode to ncgutil and cgobj
  2140. * foreach gets extra argument for passing local data to the
  2141. iterator function
  2142. * -CR checks also class typecasts at runtime by changing them
  2143. into as
  2144. * fixed compiler to cycle with the -CR option
  2145. * fixed stabs with elf writer, finally the global variables can
  2146. be watched
  2147. * removed a lot of routines from cga unit and replaced them by
  2148. calls to cgobj
  2149. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2150. u32bit then the other is typecasted also to u32bit without giving
  2151. a rangecheck warning/error.
  2152. * fixed pascal calling method with reversing also the high tree in
  2153. the parast, detected by tcalcst3 test
  2154. Revision 1.57 2002/04/04 19:06:05 peter
  2155. * removed unused units
  2156. * use tlocation.size in cg.a_*loc*() routines
  2157. Revision 1.56 2002/03/04 19:10:11 peter
  2158. * removed compiler warnings
  2159. Revision 1.55 2002/02/03 09:30:07 peter
  2160. * more fixes for protected handling
  2161. Revision 1.54 2002/01/29 21:30:25 peter
  2162. * allow also dup id in delphi mode in interfaces
  2163. Revision 1.53 2002/01/29 19:46:00 peter
  2164. * fixed recordsymtable.insert_in() for inserting variant record fields
  2165. to not used symtable.insert() because that also updates alignmentinfo
  2166. which was already set
  2167. Revision 1.52 2002/01/24 18:25:50 peter
  2168. * implicit result variable generation for assembler routines
  2169. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  2170. }