2
0

symtype.pas 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  3. This unit handles the symbol tables
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit symtype;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,
  23. {$ifdef MEMDEBUG}
  24. cclasses,
  25. {$endif MEMDEBUG}
  26. { global }
  27. globtype,globals,
  28. { symtable }
  29. symconst,symbase,
  30. { aasm }
  31. aasmbase,ppu,cpuinfo
  32. ;
  33. type
  34. {************************************************
  35. Required Forwards
  36. ************************************************}
  37. tsym = class;
  38. Tcompilerppufile=class;
  39. {************************************************
  40. TRef
  41. ************************************************}
  42. tref = class
  43. nextref : tref;
  44. posinfo : tfileposinfo;
  45. moduleindex : longint;
  46. is_written : boolean;
  47. constructor create(ref:tref;pos:pfileposinfo);
  48. procedure freechain;
  49. destructor destroy;override;
  50. end;
  51. {************************************************
  52. TDef
  53. ************************************************}
  54. tgetsymtable = (gs_none,gs_record,gs_local,gs_para);
  55. tdef = class(tdefentry)
  56. typesym : tsym; { which type the definition was generated this def }
  57. { maybe it's useful to merge the dwarf and stabs debugging info with some hacking }
  58. { dwarf debugging }
  59. dwarf_lab : tasmlabel;
  60. { stabs debugging }
  61. stab_number : word;
  62. dbg_state : tdefdbgstatus;
  63. defoptions : tdefoptions;
  64. constructor create(dt:tdeftype);
  65. procedure buildderef;virtual;abstract;
  66. procedure buildderefimpl;virtual;abstract;
  67. procedure deref;virtual;abstract;
  68. procedure derefimpl;virtual;abstract;
  69. function typename:string;
  70. function gettypename:string;virtual;
  71. function mangledparaname:string;
  72. function getmangledparaname:string;virtual;
  73. function size:aint;virtual;abstract;
  74. function packedbitsize:aint;virtual;
  75. function alignment:shortint;virtual;abstract;
  76. function getvartype:longint;virtual;abstract;
  77. function getparentdef:tdef;virtual;
  78. function getsymtable(t:tgetsymtable):tsymtable;virtual;
  79. function is_publishable:boolean;virtual;abstract;
  80. function needs_inittable:boolean;virtual;abstract;
  81. function is_related(def:tdef):boolean;virtual;
  82. end;
  83. {************************************************
  84. TSym
  85. ************************************************}
  86. { this object is the base for all symbol objects }
  87. tsym = class(tsymentry)
  88. protected
  89. public
  90. _realname : pstring;
  91. fileinfo : tfileposinfo;
  92. symoptions : tsymoptions;
  93. refs : longint;
  94. lastref,
  95. defref,
  96. lastwritten : tref;
  97. refcount : longint;
  98. isstabwritten : boolean;
  99. constructor create(st:tsymtyp;const n : string);
  100. destructor destroy;override;
  101. function realname:string;
  102. function mangledname:string; virtual;
  103. procedure buildderef;virtual;
  104. procedure deref;virtual;
  105. procedure derefimpl; virtual;
  106. function gettypedef:tdef;virtual;
  107. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  108. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  109. { currobjdef is the object def to assume, this is necessary for protected and
  110. private,
  111. context is the object def we're really in, this is for the strict stuff
  112. }
  113. function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
  114. end;
  115. tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
  116. psymarr = ^tsymarr;
  117. {************************************************
  118. TDeref
  119. ************************************************}
  120. tderef = object
  121. dataidx : longint;
  122. procedure reset;
  123. procedure build(s:tsymtableentry);
  124. function resolve:tsymtableentry;
  125. end;
  126. {************************************************
  127. TType
  128. ************************************************}
  129. ttype = object
  130. def : tdef;
  131. sym : tsym;
  132. deref : tderef;
  133. procedure reset;
  134. procedure setdef(p:tdef);
  135. procedure setsym(p:tsym);
  136. procedure resolve;
  137. procedure buildderef;
  138. end;
  139. {************************************************
  140. TSymList
  141. ************************************************}
  142. psymlistitem = ^tsymlistitem;
  143. tsymlistitem = record
  144. sltype : tsltype;
  145. next : psymlistitem;
  146. case byte of
  147. 0 : (sym : tsym; symderef : tderef);
  148. 1 : (value : TConstExprInt; valuett: ttype);
  149. 2 : (tt : ttype);
  150. end;
  151. tsymlist = class
  152. procdef : tdef;
  153. procdefderef : tderef;
  154. firstsym,
  155. lastsym : psymlistitem;
  156. constructor create;
  157. destructor destroy;override;
  158. function empty:boolean;
  159. procedure addsym(slt:tsltype;p:tsym);
  160. procedure addsymderef(slt:tsltype;const d:tderef);
  161. procedure addconst(slt:tsltype;v:TConstExprInt;const tt:ttype);
  162. procedure addtype(slt:tsltype;const tt:ttype);
  163. procedure clear;
  164. function getcopy:tsymlist;
  165. procedure resolve;
  166. procedure buildderef;
  167. end;
  168. {************************************************
  169. Tcompilerppufile
  170. ************************************************}
  171. tcompilerppufile=class(tppufile)
  172. public
  173. procedure checkerror;
  174. procedure getguid(var g: tguid);
  175. function getexprint:tconstexprint;
  176. function getptruint:TConstPtrUInt;
  177. procedure getposinfo(var p:tfileposinfo);
  178. procedure getderef(var d:tderef);
  179. function getsymlist:tsymlist;
  180. procedure gettype(var t:ttype);
  181. function getasmsymbol:tasmsymbol;
  182. procedure putguid(const g: tguid);
  183. procedure putexprint(v:tconstexprint);
  184. procedure PutPtrUInt(v:TConstPtrUInt);
  185. procedure putposinfo(const p:tfileposinfo);
  186. procedure putderef(const d:tderef);
  187. procedure putsymlist(p:tsymlist);
  188. procedure puttype(const t:ttype);
  189. procedure putasmsymbol(s:tasmsymbol);
  190. end;
  191. {$ifdef MEMDEBUG}
  192. var
  193. membrowser,
  194. memrealnames,
  195. memmanglednames,
  196. memprocpara,
  197. memprocparast,
  198. memproclocalst,
  199. memprocnodetree : tmemdebug;
  200. {$endif MEMDEBUG}
  201. const
  202. current_object_option : tsymoptions = [sp_public];
  203. implementation
  204. uses
  205. verbose,
  206. fmodule
  207. ;
  208. {****************************************************************************
  209. Tdef
  210. ****************************************************************************}
  211. constructor tdef.create(dt:tdeftype);
  212. begin
  213. inherited create;
  214. deftype:=dt;
  215. owner := nil;
  216. typesym := nil;
  217. defoptions:=[];
  218. dbg_state:=dbg_state_unused;
  219. stab_number:=0;
  220. end;
  221. function tdef.typename:string;
  222. begin
  223. if assigned(typesym) and
  224. not(deftype in [procvardef,procdef]) and
  225. assigned(typesym._realname) and
  226. (typesym._realname^[1]<>'$') then
  227. typename:=typesym._realname^
  228. else
  229. typename:=gettypename;
  230. end;
  231. function tdef.gettypename : string;
  232. begin
  233. gettypename:='<unknown type>'
  234. end;
  235. function tdef.mangledparaname:string;
  236. begin
  237. if assigned(typesym) then
  238. mangledparaname:=typesym.name
  239. else
  240. mangledparaname:=getmangledparaname;
  241. end;
  242. function tdef.getmangledparaname:string;
  243. begin
  244. result:='<unknown type>';
  245. end;
  246. function tdef.getparentdef:tdef;
  247. begin
  248. result:=nil;
  249. end;
  250. function tdef.getsymtable(t:tgetsymtable):tsymtable;
  251. begin
  252. result:=nil;
  253. end;
  254. function tdef.is_related(def:tdef):boolean;
  255. begin
  256. result:=false;
  257. end;
  258. function tdef.packedbitsize:aint;
  259. begin
  260. result:=size * 8;
  261. end;
  262. {****************************************************************************
  263. TSYM (base for all symtypes)
  264. ****************************************************************************}
  265. constructor tsym.create(st:tsymtyp;const n : string);
  266. begin
  267. if n[1]='$' then
  268. inherited createname(copy(n,2,255))
  269. else
  270. inherited createname(upper(n));
  271. _realname:=stringdup(n);
  272. typ:=st;
  273. symoptions:=[];
  274. defref:=nil;
  275. refs:=0;
  276. lastwritten:=nil;
  277. refcount:=0;
  278. fileinfo:=akttokenpos;
  279. if (cs_browser in aktmoduleswitches) and make_ref then
  280. begin
  281. defref:=tref.create(defref,@akttokenpos);
  282. inc(refcount);
  283. end;
  284. lastref:=defref;
  285. isstabwritten := false;
  286. symoptions:=current_object_option;
  287. end;
  288. destructor tsym.destroy;
  289. begin
  290. {$ifdef MEMDEBUG}
  291. memrealnames.start;
  292. {$endif MEMDEBUG}
  293. stringdispose(_realname);
  294. {$ifdef MEMDEBUG}
  295. memrealnames.stop;
  296. {$endif MEMDEBUG}
  297. inherited destroy;
  298. end;
  299. procedure Tsym.buildderef;
  300. begin
  301. end;
  302. procedure Tsym.deref;
  303. begin
  304. end;
  305. procedure Tsym.derefimpl;
  306. begin
  307. end;
  308. function tsym.realname : string;
  309. begin
  310. if assigned(_realname) then
  311. realname:=_realname^
  312. else
  313. realname:=name;
  314. end;
  315. function tsym.mangledname : string;
  316. begin
  317. internalerror(200204171);
  318. end;
  319. function tsym.gettypedef:tdef;
  320. begin
  321. gettypedef:=nil;
  322. end;
  323. procedure Tsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  324. var
  325. pos : tfileposinfo;
  326. move_last : boolean;
  327. begin
  328. move_last:=lastwritten=lastref;
  329. while (not ppufile.endofentry) do
  330. begin
  331. ppufile.getposinfo(pos);
  332. inc(refcount);
  333. lastref:=tref.create(lastref,@pos);
  334. lastref.is_written:=true;
  335. if refcount=1 then
  336. defref:=lastref;
  337. end;
  338. if move_last then
  339. lastwritten:=lastref;
  340. end;
  341. { big problem here :
  342. wrong refs were written because of
  343. interface parsing of other units PM
  344. moduleindex must be checked !! }
  345. function Tsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  346. var
  347. d : tderef;
  348. ref : tref;
  349. symref_written,move_last : boolean;
  350. begin
  351. write_references:=false;
  352. if lastwritten=lastref then
  353. exit;
  354. { should we update lastref }
  355. move_last:=true;
  356. symref_written:=false;
  357. { write symbol refs }
  358. d.reset;
  359. if assigned(lastwritten) then
  360. ref:=lastwritten
  361. else
  362. ref:=defref;
  363. while assigned(ref) do
  364. begin
  365. if ref.moduleindex=current_module.unit_index then
  366. begin
  367. { write address to this symbol }
  368. if not symref_written then
  369. begin
  370. d.build(self);
  371. ppufile.putderef(d);
  372. symref_written:=true;
  373. end;
  374. ppufile.putposinfo(ref.posinfo);
  375. ref.is_written:=true;
  376. if move_last then
  377. lastwritten:=ref;
  378. end
  379. else if not ref.is_written then
  380. move_last:=false
  381. else if move_last then
  382. lastwritten:=ref;
  383. ref:=ref.nextref;
  384. end;
  385. if symref_written then
  386. ppufile.writeentry(ibsymref);
  387. write_references:=symref_written;
  388. end;
  389. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  390. begin
  391. is_visible_for_object:=false;
  392. { private symbols are allowed when we are in the same
  393. module as they are defined }
  394. if (sp_private in symoptions) and
  395. assigned(owner.defowner) and
  396. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  397. (not owner.defowner.owner.iscurrentunit) then
  398. exit;
  399. if (sp_strictprivate in symoptions) then
  400. begin
  401. result:=assigned(currobjdef) and
  402. (context=tdef(owner.defowner));
  403. exit;
  404. end;
  405. if (sp_strictprotected in symoptions) then
  406. begin
  407. result:=assigned(context) and
  408. context.is_related(tdef(owner.defowner));
  409. exit;
  410. end;
  411. { protected symbols are visible in the module that defines them and
  412. also visible to related objects }
  413. if (sp_protected in symoptions) and
  414. (
  415. (
  416. assigned(owner.defowner) and
  417. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  418. (not owner.defowner.owner.iscurrentunit)
  419. ) and
  420. not(
  421. assigned(currobjdef) and
  422. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  423. (currobjdef.owner.iscurrentunit) and
  424. currobjdef.is_related(tdef(owner.defowner))
  425. )
  426. ) then
  427. exit;
  428. is_visible_for_object:=true;
  429. end;
  430. {****************************************************************************
  431. TRef
  432. ****************************************************************************}
  433. constructor tref.create(ref :tref;pos : pfileposinfo);
  434. begin
  435. nextref:=nil;
  436. if pos<>nil then
  437. posinfo:=pos^;
  438. if assigned(current_module) then
  439. moduleindex:=current_module.unit_index;
  440. if assigned(ref) then
  441. ref.nextref:=self;
  442. is_written:=false;
  443. end;
  444. procedure tref.freechain;
  445. var
  446. p,q : tref;
  447. begin
  448. p:=nextref;
  449. nextref:=nil;
  450. while assigned(p) do
  451. begin
  452. q:=p.nextref;
  453. p.free;
  454. p:=q;
  455. end;
  456. end;
  457. destructor tref.destroy;
  458. begin
  459. nextref:=nil;
  460. end;
  461. {****************************************************************************
  462. TType
  463. ****************************************************************************}
  464. procedure ttype.reset;
  465. begin
  466. def:=nil;
  467. sym:=nil;
  468. end;
  469. procedure ttype.setdef(p:tdef);
  470. begin
  471. def:=p;
  472. sym:=nil;
  473. end;
  474. procedure ttype.setsym(p:tsym);
  475. begin
  476. sym:=p;
  477. def:=p.gettypedef;
  478. if not assigned(def) then
  479. internalerror(1234005);
  480. end;
  481. procedure ttype.resolve;
  482. var
  483. p : tsymtableentry;
  484. begin
  485. p:=deref.resolve;
  486. if assigned(p) then
  487. begin
  488. if p is tsym then
  489. begin
  490. setsym(tsym(p));
  491. if not assigned(def) then
  492. internalerror(200212272);
  493. end
  494. else
  495. begin
  496. setdef(tdef(p));
  497. end;
  498. end
  499. else
  500. reset;
  501. end;
  502. procedure ttype.buildderef;
  503. begin
  504. { Write symbol references when the symbol is a redefine,
  505. but don't write symbol references for the current unit
  506. and for the system unit }
  507. if assigned(sym) and
  508. (
  509. (sym<>def.typesym) or
  510. (
  511. not((sym.owner.symtabletype in [globalsymtable,staticsymtable]) and
  512. sym.owner.iscurrentunit)
  513. )
  514. ) then
  515. deref.build(sym)
  516. else
  517. deref.build(def);
  518. end;
  519. {****************************************************************************
  520. TSymList
  521. ****************************************************************************}
  522. constructor tsymlist.create;
  523. begin
  524. procdef:=nil; { needed for procedures }
  525. firstsym:=nil;
  526. lastsym:=nil;
  527. end;
  528. destructor tsymlist.destroy;
  529. begin
  530. clear;
  531. end;
  532. function tsymlist.empty:boolean;
  533. begin
  534. empty:=(firstsym=nil);
  535. end;
  536. procedure tsymlist.clear;
  537. var
  538. hp : psymlistitem;
  539. begin
  540. while assigned(firstsym) do
  541. begin
  542. hp:=firstsym;
  543. firstsym:=firstsym^.next;
  544. dispose(hp);
  545. end;
  546. firstsym:=nil;
  547. lastsym:=nil;
  548. procdef:=nil;
  549. end;
  550. procedure tsymlist.addsym(slt:tsltype;p:tsym);
  551. var
  552. hp : psymlistitem;
  553. begin
  554. if not assigned(p) then
  555. internalerror(200110203);
  556. new(hp);
  557. fillchar(hp^,sizeof(tsymlistitem),0);
  558. hp^.sltype:=slt;
  559. hp^.sym:=p;
  560. hp^.symderef.reset;
  561. if assigned(lastsym) then
  562. lastsym^.next:=hp
  563. else
  564. firstsym:=hp;
  565. lastsym:=hp;
  566. end;
  567. procedure tsymlist.addsymderef(slt:tsltype;const d:tderef);
  568. var
  569. hp : psymlistitem;
  570. begin
  571. new(hp);
  572. fillchar(hp^,sizeof(tsymlistitem),0);
  573. hp^.sltype:=slt;
  574. hp^.symderef:=d;
  575. if assigned(lastsym) then
  576. lastsym^.next:=hp
  577. else
  578. firstsym:=hp;
  579. lastsym:=hp;
  580. end;
  581. procedure tsymlist.addconst(slt:tsltype;v:TConstExprInt;const tt:ttype);
  582. var
  583. hp : psymlistitem;
  584. begin
  585. new(hp);
  586. fillchar(hp^,sizeof(tsymlistitem),0);
  587. hp^.sltype:=slt;
  588. hp^.value:=v;
  589. hp^.valuett:=tt;
  590. if assigned(lastsym) then
  591. lastsym^.next:=hp
  592. else
  593. firstsym:=hp;
  594. lastsym:=hp;
  595. end;
  596. procedure tsymlist.addtype(slt:tsltype;const tt:ttype);
  597. var
  598. hp : psymlistitem;
  599. begin
  600. new(hp);
  601. fillchar(hp^,sizeof(tsymlistitem),0);
  602. hp^.sltype:=slt;
  603. hp^.tt:=tt;
  604. if assigned(lastsym) then
  605. lastsym^.next:=hp
  606. else
  607. firstsym:=hp;
  608. lastsym:=hp;
  609. end;
  610. function tsymlist.getcopy:tsymlist;
  611. var
  612. hp : tsymlist;
  613. hp2 : psymlistitem;
  614. hpn : psymlistitem;
  615. begin
  616. hp:=tsymlist.create;
  617. hp.procdef:=procdef;
  618. hp2:=firstsym;
  619. while assigned(hp2) do
  620. begin
  621. new(hpn);
  622. hpn^:=hp2^;
  623. hpn^.next:=nil;
  624. if assigned(hp.lastsym) then
  625. hp.lastsym^.next:=hpn
  626. else
  627. hp.firstsym:=hpn;
  628. hp.lastsym:=hpn;
  629. hp2:=hp2^.next;
  630. end;
  631. getcopy:=hp;
  632. end;
  633. procedure tsymlist.resolve;
  634. var
  635. hp : psymlistitem;
  636. begin
  637. procdef:=tdef(procdefderef.resolve);
  638. hp:=firstsym;
  639. while assigned(hp) do
  640. begin
  641. case hp^.sltype of
  642. sl_call,
  643. sl_load,
  644. sl_subscript :
  645. hp^.sym:=tsym(hp^.symderef.resolve);
  646. sl_absolutetype,
  647. sl_typeconv :
  648. hp^.tt.resolve;
  649. sl_vec:
  650. hp^.valuett.resolve;
  651. else
  652. internalerror(200110205);
  653. end;
  654. hp:=hp^.next;
  655. end;
  656. end;
  657. procedure tsymlist.buildderef;
  658. var
  659. hp : psymlistitem;
  660. begin
  661. procdefderef.build(procdef);
  662. hp:=firstsym;
  663. while assigned(hp) do
  664. begin
  665. case hp^.sltype of
  666. sl_call,
  667. sl_load,
  668. sl_subscript :
  669. hp^.symderef.build(hp^.sym);
  670. sl_absolutetype,
  671. sl_typeconv :
  672. hp^.tt.buildderef;
  673. sl_vec:
  674. hp^.valuett.buildderef;
  675. else
  676. internalerror(200110205);
  677. end;
  678. hp:=hp^.next;
  679. end;
  680. end;
  681. {****************************************************************************
  682. Tderef
  683. ****************************************************************************}
  684. procedure tderef.reset;
  685. begin
  686. dataidx:=-1;
  687. end;
  688. procedure tderef.build(s:tsymtableentry);
  689. var
  690. len : byte;
  691. data : array[0..255] of byte;
  692. function is_child(currdef,ownerdef:tdef):boolean;
  693. begin
  694. while assigned(currdef) and
  695. (currdef<>ownerdef) do
  696. currdef:=currdef.getparentdef;
  697. result:=assigned(currdef);
  698. end;
  699. procedure addowner(s:tsymtableentry);
  700. var
  701. idx : longint;
  702. begin
  703. if not assigned(s.owner) then
  704. internalerror(200306063);
  705. case s.owner.symtabletype of
  706. globalsymtable :
  707. begin
  708. if s.owner.iscurrentunit then
  709. begin
  710. data[len]:=ord(deref_aktglobal);
  711. inc(len);
  712. end
  713. else
  714. begin
  715. { register that the unit is needed for resolving }
  716. idx:=current_module.derefidx_unit(s.owner.moduleid);
  717. data[len]:=ord(deref_unit);
  718. data[len+1]:=idx shr 8;
  719. data[len+2]:=idx and $ff;
  720. inc(len,3);
  721. end;
  722. end;
  723. staticsymtable :
  724. begin
  725. { only references to the current static symtable are allowed }
  726. if not s.owner.iscurrentunit then
  727. internalerror(200306233);
  728. data[len]:=ord(deref_aktstatic);
  729. inc(len);
  730. end;
  731. localsymtable :
  732. begin
  733. addowner(s.owner.defowner);
  734. data[len]:=ord(deref_def);
  735. data[len+1]:=s.owner.defowner.indexnr shr 8;
  736. data[len+2]:=s.owner.defowner.indexnr and $ff;
  737. data[len+3]:=ord(deref_local);
  738. inc(len,4);
  739. end;
  740. parasymtable :
  741. begin
  742. addowner(s.owner.defowner);
  743. data[len]:=ord(deref_def);
  744. data[len+1]:=s.owner.defowner.indexnr shr 8;
  745. data[len+2]:=s.owner.defowner.indexnr and $ff;
  746. data[len+3]:=ord(deref_para);
  747. inc(len,4);
  748. end;
  749. objectsymtable,
  750. recordsymtable :
  751. begin
  752. addowner(s.owner.defowner);
  753. data[len]:=ord(deref_def);
  754. data[len+1]:=s.owner.defowner.indexnr shr 8;
  755. data[len+2]:=s.owner.defowner.indexnr and $ff;
  756. data[len+3]:=ord(deref_record);
  757. inc(len,4);
  758. end;
  759. else
  760. internalerror(200306065);
  761. end;
  762. if len>252 then
  763. internalerror(200306062);
  764. end;
  765. procedure addparentobject(currdef,ownerdef:tdef);
  766. var
  767. nextdef : tdef;
  768. begin
  769. if not assigned(currdef) then
  770. internalerror(200306185);
  771. { Already handled by derefaktrecordindex }
  772. if currdef=ownerdef then
  773. internalerror(200306188);
  774. { Generate a direct reference to the top parent
  775. class available in the current unit, this is required because
  776. the parent class is maybe not resolved yet and therefor
  777. has the childof value not available yet }
  778. while (currdef<>ownerdef) do
  779. begin
  780. nextdef:=currdef.getparentdef;
  781. { objects are only allowed in globalsymtable,staticsymtable }
  782. if not(nextdef.owner.symtabletype in [globalsymtable,staticsymtable]) then
  783. internalerror(200306187);
  784. { Next parent is in a different unit, then stop }
  785. if not(nextdef.owner.iscurrentunit) then
  786. break;
  787. currdef:=nextdef;
  788. end;
  789. { Add reference where to start the parent lookup }
  790. if currdef=aktrecordsymtable.defowner then
  791. begin
  792. data[len]:=ord(deref_aktrecord);
  793. inc(len);
  794. end
  795. else
  796. begin
  797. if currdef.owner.symtabletype=globalsymtable then
  798. data[len]:=ord(deref_aktglobal)
  799. else
  800. data[len]:=ord(deref_aktstatic);
  801. data[len+1]:=ord(deref_def);
  802. data[len+2]:=currdef.indexnr shr 8;
  803. data[len+3]:=currdef.indexnr and $ff;
  804. data[len+4]:=ord(deref_record);
  805. inc(len,5);
  806. end;
  807. { When the current found parent in this module is not the owner we
  808. add derefs for the parent classes not available in this unit }
  809. while (currdef<>ownerdef) do
  810. begin
  811. data[len]:=ord(deref_parent_object);
  812. inc(len);
  813. currdef:=currdef.getparentdef;
  814. { It should be valid as it is checked by is_child }
  815. if not assigned(currdef) then
  816. internalerror(200306186);
  817. end;
  818. end;
  819. begin
  820. { skip length byte }
  821. len:=1;
  822. if assigned(s) then
  823. begin
  824. { Static symtable of current unit ? }
  825. if (s.owner.symtabletype=staticsymtable) and
  826. s.owner.iscurrentunit then
  827. begin
  828. data[len]:=ord(deref_aktstatic);
  829. inc(len);
  830. end
  831. { Global symtable of current unit ? }
  832. else if (s.owner.symtabletype=globalsymtable) and
  833. s.owner.iscurrentunit then
  834. begin
  835. data[len]:=ord(deref_aktglobal);
  836. inc(len);
  837. end
  838. { Current record/object symtable ? }
  839. else if (s.owner=aktrecordsymtable) then
  840. begin
  841. data[len]:=ord(deref_aktrecord);
  842. inc(len);
  843. end
  844. { Current local symtable ? }
  845. else if (s.owner=aktlocalsymtable) then
  846. begin
  847. data[len]:=ord(deref_aktlocal);
  848. inc(len);
  849. end
  850. { Current para symtable ? }
  851. else if (s.owner=aktparasymtable) then
  852. begin
  853. data[len]:=ord(deref_aktpara);
  854. inc(len);
  855. end
  856. { Parent class? }
  857. else if assigned(aktrecordsymtable) and
  858. (aktrecordsymtable.symtabletype=objectsymtable) and
  859. (s.owner.symtabletype=objectsymtable) and
  860. is_child(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner)) then
  861. begin
  862. addparentobject(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner));
  863. end
  864. else
  865. { Default, start by building from unit symtable }
  866. begin
  867. addowner(s);
  868. end;
  869. { Add index of the symbol/def }
  870. if s is tsym then
  871. data[len]:=ord(deref_sym)
  872. else
  873. data[len]:=ord(deref_def);
  874. data[len+1]:=s.indexnr shr 8;
  875. data[len+2]:=s.indexnr and $ff;
  876. inc(len,3);
  877. end
  878. else
  879. begin
  880. { nil pointer }
  881. data[len]:=0;
  882. inc(len);
  883. end;
  884. { store data length in first byte }
  885. data[0]:=len-1;
  886. { store index and write to derefdata }
  887. dataidx:=current_module.derefdata.size;
  888. current_module.derefdata.write(data,len);
  889. end;
  890. function tderef.resolve:tsymtableentry;
  891. var
  892. pd : tdef;
  893. pm : tmodule;
  894. typ : tdereftype;
  895. st : tsymtable;
  896. idx : word;
  897. i : aint;
  898. len : byte;
  899. data : array[0..255] of byte;
  900. begin
  901. result:=nil;
  902. { not initialized or error }
  903. if dataidx<0 then
  904. internalerror(200306067);
  905. { read data }
  906. current_module.derefdata.seek(dataidx);
  907. if current_module.derefdata.read(len,1)<>1 then
  908. internalerror(200310221);
  909. if len>0 then
  910. begin
  911. if current_module.derefdata.read(data,len)<>len then
  912. internalerror(200310222);
  913. end;
  914. { process data }
  915. st:=nil;
  916. i:=0;
  917. while (i<len) do
  918. begin
  919. typ:=tdereftype(data[i]);
  920. inc(i);
  921. case typ of
  922. deref_nil :
  923. begin
  924. result:=nil;
  925. { Only allowed when no other deref is available }
  926. if len<>1 then
  927. internalerror(200306232);
  928. end;
  929. deref_sym :
  930. begin
  931. if not assigned(st) then
  932. internalerror(200309141);
  933. idx:=(data[i] shl 8) or data[i+1];
  934. inc(i,2);
  935. result:=st.getsymnr(idx);
  936. end;
  937. deref_def :
  938. begin
  939. if not assigned(st) then
  940. internalerror(200309142);
  941. idx:=(data[i] shl 8) or data[i+1];
  942. inc(i,2);
  943. result:=st.getdefnr(idx);
  944. end;
  945. deref_aktrecord :
  946. st:=aktrecordsymtable;
  947. deref_aktstatic :
  948. st:=current_module.localsymtable;
  949. deref_aktglobal :
  950. st:=current_module.globalsymtable;
  951. deref_aktlocal :
  952. st:=aktlocalsymtable;
  953. deref_aktpara :
  954. st:=aktparasymtable;
  955. deref_unit :
  956. begin
  957. idx:=(data[i] shl 8) or data[i+1];
  958. inc(i,2);
  959. pm:=current_module.resolve_unit(idx);
  960. st:=pm.globalsymtable;
  961. end;
  962. deref_local :
  963. begin
  964. if not assigned(result) then
  965. internalerror(200306069);
  966. st:=tdef(result).getsymtable(gs_local);
  967. result:=nil;
  968. if not assigned(st) then
  969. internalerror(200212275);
  970. end;
  971. deref_para :
  972. begin
  973. if not assigned(result) then
  974. internalerror(2003060610);
  975. st:=tdef(result).getsymtable(gs_para);
  976. result:=nil;
  977. if not assigned(st) then
  978. internalerror(200212276);
  979. end;
  980. deref_record :
  981. begin
  982. if not assigned(result) then
  983. internalerror(200306068);
  984. st:=tdef(result).getsymtable(gs_record);
  985. result:=nil;
  986. if not assigned(st) then
  987. internalerror(200212274);
  988. end;
  989. deref_parent_object :
  990. begin
  991. { load current object symtable if no
  992. symtable is available yet }
  993. if st=nil then
  994. begin
  995. st:=aktrecordsymtable;
  996. if not assigned(st) then
  997. internalerror(200306068);
  998. end;
  999. if st.symtabletype<>objectsymtable then
  1000. internalerror(200306189);
  1001. pd:=tdef(st.defowner).getparentdef;
  1002. if not assigned(pd) then
  1003. internalerror(200306184);
  1004. st:=pd.getsymtable(gs_record);
  1005. if not assigned(st) then
  1006. internalerror(200212274);
  1007. end;
  1008. else
  1009. internalerror(200212277);
  1010. end;
  1011. end;
  1012. end;
  1013. {*****************************************************************************
  1014. TCompilerPPUFile
  1015. *****************************************************************************}
  1016. procedure tcompilerppufile.checkerror;
  1017. begin
  1018. if error then
  1019. Message(unit_f_ppu_read_error);
  1020. end;
  1021. procedure tcompilerppufile.getguid(var g: tguid);
  1022. begin
  1023. getdata(g,sizeof(g));
  1024. end;
  1025. function tcompilerppufile.getexprint:tconstexprint;
  1026. begin
  1027. if sizeof(tconstexprint)=8 then
  1028. result:=tconstexprint(getint64)
  1029. else
  1030. result:=tconstexprint(getlongint);
  1031. end;
  1032. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  1033. begin
  1034. if sizeof(TConstPtrUInt)=8 then
  1035. result:=tconstptruint(getint64)
  1036. else
  1037. result:=TConstPtrUInt(getlongint);
  1038. end;
  1039. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  1040. var
  1041. info : byte;
  1042. begin
  1043. {
  1044. info byte layout in bits:
  1045. 0-1 - amount of bytes for fileindex
  1046. 2-3 - amount of bytes for line
  1047. 4-5 - amount of bytes for column
  1048. }
  1049. info:=getbyte;
  1050. case (info and $03) of
  1051. 0 : p.fileindex:=getbyte;
  1052. 1 : p.fileindex:=getword;
  1053. 2 : p.fileindex:=(getbyte shl 16) or getword;
  1054. 3 : p.fileindex:=getlongint;
  1055. end;
  1056. case ((info shr 2) and $03) of
  1057. 0 : p.line:=getbyte;
  1058. 1 : p.line:=getword;
  1059. 2 : p.line:=(getbyte shl 16) or getword;
  1060. 3 : p.line:=getlongint;
  1061. end;
  1062. case ((info shr 4) and $03) of
  1063. 0 : p.column:=getbyte;
  1064. 1 : p.column:=getword;
  1065. 2 : p.column:=(getbyte shl 16) or getword;
  1066. 3 : p.column:=getlongint;
  1067. end;
  1068. end;
  1069. procedure tcompilerppufile.getderef(var d:tderef);
  1070. begin
  1071. d.dataidx:=getlongint;
  1072. end;
  1073. function tcompilerppufile.getsymlist:tsymlist;
  1074. var
  1075. symderef : tderef;
  1076. tt : ttype;
  1077. slt : tsltype;
  1078. idx : longint;
  1079. p : tsymlist;
  1080. begin
  1081. p:=tsymlist.create;
  1082. getderef(p.procdefderef);
  1083. repeat
  1084. slt:=tsltype(getbyte);
  1085. case slt of
  1086. sl_none :
  1087. break;
  1088. sl_call,
  1089. sl_load,
  1090. sl_subscript :
  1091. begin
  1092. getderef(symderef);
  1093. p.addsymderef(slt,symderef);
  1094. end;
  1095. sl_absolutetype,
  1096. sl_typeconv :
  1097. begin
  1098. gettype(tt);
  1099. p.addtype(slt,tt);
  1100. end;
  1101. sl_vec :
  1102. begin
  1103. idx:=getlongint;
  1104. gettype(tt);
  1105. p.addconst(slt,idx,tt);
  1106. end;
  1107. else
  1108. internalerror(200110204);
  1109. end;
  1110. until false;
  1111. getsymlist:=tsymlist(p);
  1112. end;
  1113. procedure tcompilerppufile.gettype(var t:ttype);
  1114. begin
  1115. getderef(t.deref);
  1116. t.def:=nil;
  1117. t.sym:=nil;
  1118. end;
  1119. function tcompilerppufile.getasmsymbol:tasmsymbol;
  1120. begin
  1121. getlongint;
  1122. getasmsymbol:=nil;
  1123. end;
  1124. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  1125. var
  1126. oldcrc : boolean;
  1127. info : byte;
  1128. begin
  1129. { posinfo is not relevant for changes in PPU }
  1130. oldcrc:=do_crc;
  1131. do_crc:=false;
  1132. {
  1133. info byte layout in bits:
  1134. 0-1 - amount of bytes for fileindex
  1135. 2-3 - amount of bytes for line
  1136. 4-5 - amount of bytes for column
  1137. }
  1138. info:=0;
  1139. { calculate info byte }
  1140. if (p.fileindex>$ff) then
  1141. begin
  1142. if (p.fileindex<=$ffff) then
  1143. info:=info or $1
  1144. else
  1145. if (p.fileindex<=$ffffff) then
  1146. info:=info or $2
  1147. else
  1148. info:=info or $3;
  1149. end;
  1150. if (p.line>$ff) then
  1151. begin
  1152. if (p.line<=$ffff) then
  1153. info:=info or $4
  1154. else
  1155. if (p.line<=$ffffff) then
  1156. info:=info or $8
  1157. else
  1158. info:=info or $c;
  1159. end;
  1160. if (p.column>$ff) then
  1161. begin
  1162. if (p.column<=$ffff) then
  1163. info:=info or $10
  1164. else
  1165. if (p.column<=$ffffff) then
  1166. info:=info or $20
  1167. else
  1168. info:=info or $30;
  1169. end;
  1170. { write data }
  1171. putbyte(info);
  1172. case (info and $03) of
  1173. 0 : putbyte(p.fileindex);
  1174. 1 : putword(p.fileindex);
  1175. 2 : begin
  1176. putbyte(p.fileindex shr 16);
  1177. putword(p.fileindex and $ffff);
  1178. end;
  1179. 3 : putlongint(p.fileindex);
  1180. end;
  1181. case ((info shr 2) and $03) of
  1182. 0 : putbyte(p.line);
  1183. 1 : putword(p.line);
  1184. 2 : begin
  1185. putbyte(p.line shr 16);
  1186. putword(p.line and $ffff);
  1187. end;
  1188. 3 : putlongint(p.line);
  1189. end;
  1190. case ((info shr 4) and $03) of
  1191. 0 : putbyte(p.column);
  1192. 1 : putword(p.column);
  1193. 2 : begin
  1194. putbyte(p.column shr 16);
  1195. putword(p.column and $ffff);
  1196. end;
  1197. 3 : putlongint(p.column);
  1198. end;
  1199. do_crc:=oldcrc;
  1200. end;
  1201. procedure tcompilerppufile.putguid(const g: tguid);
  1202. begin
  1203. putdata(g,sizeof(g));
  1204. end;
  1205. procedure tcompilerppufile.putexprint(v:tconstexprint);
  1206. begin
  1207. if sizeof(TConstExprInt)=8 then
  1208. putint64(int64(v))
  1209. else if sizeof(TConstExprInt)=4 then
  1210. putlongint(longint(v))
  1211. else
  1212. internalerror(2002082601);
  1213. end;
  1214. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  1215. begin
  1216. if sizeof(TConstPtrUInt)=8 then
  1217. putint64(int64(v))
  1218. else if sizeof(TConstPtrUInt)=4 then
  1219. putlongint(longint(v))
  1220. else
  1221. internalerror(2002082601);
  1222. end;
  1223. procedure tcompilerppufile.putderef(const d:tderef);
  1224. var
  1225. oldcrc : boolean;
  1226. begin
  1227. oldcrc:=do_crc;
  1228. do_crc:=false;
  1229. putlongint(d.dataidx);
  1230. do_crc:=oldcrc;
  1231. end;
  1232. procedure tcompilerppufile.putsymlist(p:tsymlist);
  1233. var
  1234. hp : psymlistitem;
  1235. begin
  1236. putderef(p.procdefderef);
  1237. hp:=p.firstsym;
  1238. while assigned(hp) do
  1239. begin
  1240. putbyte(byte(hp^.sltype));
  1241. case hp^.sltype of
  1242. sl_call,
  1243. sl_load,
  1244. sl_subscript :
  1245. putderef(hp^.symderef);
  1246. sl_absolutetype,
  1247. sl_typeconv :
  1248. puttype(hp^.tt);
  1249. sl_vec :
  1250. begin
  1251. putlongint(hp^.value);
  1252. puttype(hp^.valuett);
  1253. end;
  1254. else
  1255. internalerror(200110205);
  1256. end;
  1257. hp:=hp^.next;
  1258. end;
  1259. putbyte(byte(sl_none));
  1260. end;
  1261. procedure tcompilerppufile.puttype(const t:ttype);
  1262. begin
  1263. putderef(t.deref);
  1264. end;
  1265. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  1266. begin
  1267. putlongint(0);
  1268. end;
  1269. {$ifdef MEMDEBUG}
  1270. initialization
  1271. membrowser:=TMemDebug.create('BrowserRefs');
  1272. membrowser.stop;
  1273. memrealnames:=TMemDebug.create('Realnames');
  1274. memrealnames.stop;
  1275. memmanglednames:=TMemDebug.create('Manglednames');
  1276. memmanglednames.stop;
  1277. memprocpara:=TMemDebug.create('ProcPara');
  1278. memprocpara.stop;
  1279. memprocparast:=TMemDebug.create('ProcParaSt');
  1280. memprocparast.stop;
  1281. memproclocalst:=TMemDebug.create('ProcLocalSt');
  1282. memproclocalst.stop;
  1283. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  1284. memprocnodetree.stop;
  1285. finalization
  1286. membrowser.free;
  1287. memrealnames.free;
  1288. memmanglednames.free;
  1289. memprocpara.free;
  1290. memprocparast.free;
  1291. memproclocalst.free;
  1292. memprocnodetree.free;
  1293. {$endif MEMDEBUG}
  1294. end.