symtype.pas 40 KB

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