symtype.pas 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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 : tasmsymbol;
  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 getvardef: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. isdbgwritten : 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. function getderefdef:tdef;virtual;
  106. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  107. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  108. { currobjdef is the object def to assume, this is necessary for protected and
  109. private,
  110. context is the object def we're really in, this is for the strict stuff
  111. }
  112. function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
  113. end;
  114. tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
  115. psymarr = ^tsymarr;
  116. {************************************************
  117. TDeref
  118. ************************************************}
  119. tderef = object
  120. dataidx : longint;
  121. procedure reset;
  122. procedure build(s:tsymtableentry);
  123. function resolve:tsymtableentry;
  124. end;
  125. {************************************************
  126. tpropaccesslist
  127. ************************************************}
  128. ppropaccesslistitem = ^tpropaccesslistitem;
  129. tpropaccesslistitem = record
  130. sltype : tsltype;
  131. next : ppropaccesslistitem;
  132. case byte of
  133. 0 : (sym : tsym; symderef : tderef);
  134. 1 : (value : TConstExprInt; valuedef: tdef; valuedefderef:tderef);
  135. 2 : (def: tdef; defderef:tderef);
  136. end;
  137. tpropaccesslist = class
  138. procdef : tdef;
  139. procdefderef : tderef;
  140. firstsym,
  141. lastsym : ppropaccesslistitem;
  142. constructor create;
  143. destructor destroy;override;
  144. function empty:boolean;
  145. procedure addsym(slt:tsltype;p:tsym);
  146. procedure addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  147. procedure addtype(slt:tsltype;d:tdef);
  148. procedure addsymderef(slt:tsltype;d:tderef);
  149. procedure addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  150. procedure addtypederef(slt:tsltype;d:tderef);
  151. procedure clear;
  152. procedure resolve;
  153. procedure buildderef;
  154. end;
  155. {************************************************
  156. Tcompilerppufile
  157. ************************************************}
  158. tcompilerppufile=class(tppufile)
  159. public
  160. procedure checkerror;
  161. procedure getguid(var g: tguid);
  162. function getexprint:tconstexprint;
  163. function getptruint:TConstPtrUInt;
  164. procedure getposinfo(var p:tfileposinfo);
  165. procedure getderef(var d:tderef);
  166. function getpropaccesslist:tpropaccesslist;
  167. function getasmsymbol:tasmsymbol;
  168. procedure putguid(const g: tguid);
  169. procedure putexprint(v:tconstexprint);
  170. procedure PutPtrUInt(v:TConstPtrUInt);
  171. procedure putposinfo(const p:tfileposinfo);
  172. procedure putderef(const d:tderef);
  173. procedure putpropaccesslist(p:tpropaccesslist);
  174. procedure putasmsymbol(s:tasmsymbol);
  175. end;
  176. {$ifdef MEMDEBUG}
  177. var
  178. membrowser,
  179. memrealnames,
  180. memmanglednames,
  181. memprocpara,
  182. memprocparast,
  183. memproclocalst,
  184. memprocnodetree : tmemdebug;
  185. {$endif MEMDEBUG}
  186. const
  187. current_object_option : tsymoptions = [sp_public];
  188. implementation
  189. uses
  190. verbose,
  191. fmodule,symtable
  192. ;
  193. {****************************************************************************
  194. Tdef
  195. ****************************************************************************}
  196. constructor tdef.create(dt:tdeftype);
  197. begin
  198. inherited create;
  199. deftype:=dt;
  200. owner := nil;
  201. typesym := nil;
  202. defoptions:=[];
  203. dbg_state:=dbg_state_unused;
  204. stab_number:=0;
  205. end;
  206. function tdef.typename:string;
  207. begin
  208. if assigned(typesym) and
  209. not(deftype in [procvardef,procdef]) and
  210. assigned(typesym._realname) and
  211. (typesym._realname^[1]<>'$') then
  212. typename:=typesym._realname^
  213. else
  214. typename:=GetTypeName;
  215. end;
  216. function tdef.GetTypeName : string;
  217. begin
  218. GetTypeName:='<unknown type>'
  219. end;
  220. function tdef.mangledparaname:string;
  221. begin
  222. if assigned(typesym) then
  223. mangledparaname:=typesym.name
  224. else
  225. mangledparaname:=getmangledparaname;
  226. end;
  227. function tdef.getmangledparaname:string;
  228. begin
  229. result:='<unknown type>';
  230. end;
  231. function tdef.getparentdef:tdef;
  232. begin
  233. result:=nil;
  234. end;
  235. function tdef.getsymtable(t:tgetsymtable):tsymtable;
  236. begin
  237. result:=nil;
  238. end;
  239. function tdef.is_related(def:tdef):boolean;
  240. begin
  241. result:=false;
  242. end;
  243. function tdef.packedbitsize:aint;
  244. begin
  245. result:=size * 8;
  246. end;
  247. {****************************************************************************
  248. TSYM (base for all symtypes)
  249. ****************************************************************************}
  250. constructor tsym.create(st:tsymtyp;const n : string);
  251. begin
  252. if n[1]='$' then
  253. inherited createname(copy(n,2,255))
  254. else
  255. inherited createname(upper(n));
  256. _realname:=stringdup(n);
  257. typ:=st;
  258. symoptions:=[];
  259. defref:=nil;
  260. refs:=0;
  261. lastwritten:=nil;
  262. refcount:=0;
  263. fileinfo:=akttokenpos;
  264. if (cs_browser in aktmoduleswitches) and make_ref then
  265. begin
  266. defref:=tref.create(defref,@akttokenpos);
  267. inc(refcount);
  268. end;
  269. lastref:=defref;
  270. isdbgwritten := false;
  271. symoptions:=current_object_option;
  272. end;
  273. destructor tsym.destroy;
  274. begin
  275. {$ifdef MEMDEBUG}
  276. memrealnames.start;
  277. {$endif MEMDEBUG}
  278. stringdispose(_realname);
  279. {$ifdef MEMDEBUG}
  280. memrealnames.stop;
  281. {$endif MEMDEBUG}
  282. inherited destroy;
  283. end;
  284. procedure Tsym.buildderef;
  285. begin
  286. end;
  287. procedure Tsym.deref;
  288. begin
  289. end;
  290. function tsym.realname : string;
  291. begin
  292. if assigned(_realname) then
  293. realname:=_realname^
  294. else
  295. realname:=name;
  296. end;
  297. function tsym.mangledname : string;
  298. begin
  299. internalerror(200204171);
  300. result:='';
  301. end;
  302. function tsym.getderefdef:tdef;
  303. begin
  304. getderefdef:=nil;
  305. end;
  306. procedure Tsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  307. var
  308. pos : tfileposinfo;
  309. move_last : boolean;
  310. begin
  311. move_last:=lastwritten=lastref;
  312. while (not ppufile.endofentry) do
  313. begin
  314. ppufile.getposinfo(pos);
  315. inc(refcount);
  316. lastref:=tref.create(lastref,@pos);
  317. lastref.is_written:=true;
  318. if refcount=1 then
  319. defref:=lastref;
  320. end;
  321. if move_last then
  322. lastwritten:=lastref;
  323. end;
  324. { big problem here :
  325. wrong refs were written because of
  326. interface parsing of other units PM
  327. moduleindex must be checked !! }
  328. function Tsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  329. var
  330. d : tderef;
  331. ref : tref;
  332. symref_written,move_last : boolean;
  333. begin
  334. write_references:=false;
  335. if lastwritten=lastref then
  336. exit;
  337. { should we update lastref }
  338. move_last:=true;
  339. symref_written:=false;
  340. { write symbol refs }
  341. d.reset;
  342. if assigned(lastwritten) then
  343. ref:=lastwritten
  344. else
  345. ref:=defref;
  346. while assigned(ref) do
  347. begin
  348. if ref.moduleindex=current_module.unit_index then
  349. begin
  350. { write address to this symbol }
  351. if not symref_written then
  352. begin
  353. d.build(self);
  354. ppufile.putderef(d);
  355. symref_written:=true;
  356. end;
  357. ppufile.putposinfo(ref.posinfo);
  358. ref.is_written:=true;
  359. if move_last then
  360. lastwritten:=ref;
  361. end
  362. else if not ref.is_written then
  363. move_last:=false
  364. else if move_last then
  365. lastwritten:=ref;
  366. ref:=ref.nextref;
  367. end;
  368. if symref_written then
  369. ppufile.writeentry(ibsymref);
  370. write_references:=symref_written;
  371. end;
  372. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  373. begin
  374. is_visible_for_object:=false;
  375. { private symbols are allowed when we are in the same
  376. module as they are defined }
  377. if (sp_private in symoptions) and
  378. assigned(owner.defowner) and
  379. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  380. (not owner.defowner.owner.iscurrentunit) then
  381. exit;
  382. if (sp_strictprivate in symoptions) then
  383. begin
  384. result:=assigned(currobjdef) and
  385. (context=tdef(owner.defowner));
  386. exit;
  387. end;
  388. if (sp_strictprotected in symoptions) then
  389. begin
  390. result:=assigned(context) and
  391. context.is_related(tdef(owner.defowner));
  392. exit;
  393. end;
  394. { protected symbols are visible in the module that defines them and
  395. also visible to related objects }
  396. if (sp_protected in symoptions) and
  397. (
  398. (
  399. assigned(owner.defowner) and
  400. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  401. (not owner.defowner.owner.iscurrentunit)
  402. ) and
  403. not(
  404. assigned(currobjdef) and
  405. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  406. (currobjdef.owner.iscurrentunit) and
  407. currobjdef.is_related(tdef(owner.defowner))
  408. )
  409. ) then
  410. exit;
  411. is_visible_for_object:=true;
  412. end;
  413. {****************************************************************************
  414. TRef
  415. ****************************************************************************}
  416. constructor tref.create(ref :tref;pos : pfileposinfo);
  417. begin
  418. nextref:=nil;
  419. if pos<>nil then
  420. posinfo:=pos^;
  421. if assigned(current_module) then
  422. moduleindex:=current_module.unit_index;
  423. if assigned(ref) then
  424. ref.nextref:=self;
  425. is_written:=false;
  426. end;
  427. procedure tref.freechain;
  428. var
  429. p,q : tref;
  430. begin
  431. p:=nextref;
  432. nextref:=nil;
  433. while assigned(p) do
  434. begin
  435. q:=p.nextref;
  436. p.free;
  437. p:=q;
  438. end;
  439. end;
  440. destructor tref.destroy;
  441. begin
  442. nextref:=nil;
  443. end;
  444. {****************************************************************************
  445. tpropaccesslist
  446. ****************************************************************************}
  447. constructor tpropaccesslist.create;
  448. begin
  449. procdef:=nil; { needed for procedures }
  450. firstsym:=nil;
  451. lastsym:=nil;
  452. end;
  453. destructor tpropaccesslist.destroy;
  454. begin
  455. clear;
  456. end;
  457. function tpropaccesslist.empty:boolean;
  458. begin
  459. empty:=(firstsym=nil);
  460. end;
  461. procedure tpropaccesslist.clear;
  462. var
  463. hp : ppropaccesslistitem;
  464. begin
  465. while assigned(firstsym) do
  466. begin
  467. hp:=firstsym;
  468. firstsym:=firstsym^.next;
  469. dispose(hp);
  470. end;
  471. firstsym:=nil;
  472. lastsym:=nil;
  473. procdef:=nil;
  474. end;
  475. procedure tpropaccesslist.addsym(slt:tsltype;p:tsym);
  476. var
  477. hp : ppropaccesslistitem;
  478. begin
  479. new(hp);
  480. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  481. hp^.sltype:=slt;
  482. hp^.sym:=p;
  483. hp^.symderef.reset;
  484. if assigned(lastsym) then
  485. lastsym^.next:=hp
  486. else
  487. firstsym:=hp;
  488. lastsym:=hp;
  489. end;
  490. procedure tpropaccesslist.addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  491. var
  492. hp : ppropaccesslistitem;
  493. begin
  494. new(hp);
  495. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  496. hp^.sltype:=slt;
  497. hp^.value:=v;
  498. hp^.valuedef:=d;
  499. hp^.valuedefderef.reset;
  500. if assigned(lastsym) then
  501. lastsym^.next:=hp
  502. else
  503. firstsym:=hp;
  504. lastsym:=hp;
  505. end;
  506. procedure tpropaccesslist.addtype(slt:tsltype;d:tdef);
  507. var
  508. hp : ppropaccesslistitem;
  509. begin
  510. new(hp);
  511. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  512. hp^.sltype:=slt;
  513. hp^.def:=d;
  514. hp^.defderef.reset;
  515. if assigned(lastsym) then
  516. lastsym^.next:=hp
  517. else
  518. firstsym:=hp;
  519. lastsym:=hp;
  520. end;
  521. procedure tpropaccesslist.addsymderef(slt:tsltype;d:tderef);
  522. begin
  523. addsym(slt,nil);
  524. lastsym^.symderef:=d;
  525. end;
  526. procedure tpropaccesslist.addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  527. begin
  528. addconst(slt,v,nil);
  529. lastsym^.valuedefderef:=d;
  530. end;
  531. procedure tpropaccesslist.addtypederef(slt:tsltype;d:tderef);
  532. begin
  533. addtype(slt,nil);
  534. lastsym^.defderef:=d;
  535. end;
  536. procedure tpropaccesslist.resolve;
  537. var
  538. hp : ppropaccesslistitem;
  539. begin
  540. procdef:=tdef(procdefderef.resolve);
  541. hp:=firstsym;
  542. while assigned(hp) do
  543. begin
  544. case hp^.sltype of
  545. sl_call,
  546. sl_load,
  547. sl_subscript :
  548. hp^.sym:=tsym(hp^.symderef.resolve);
  549. sl_absolutetype,
  550. sl_typeconv :
  551. hp^.def:=tdef(hp^.defderef.resolve);
  552. sl_vec:
  553. hp^.valuedef:=tdef(hp^.valuedefderef.resolve);
  554. else
  555. internalerror(200110205);
  556. end;
  557. hp:=hp^.next;
  558. end;
  559. end;
  560. procedure tpropaccesslist.buildderef;
  561. var
  562. hp : ppropaccesslistitem;
  563. begin
  564. procdefderef.build(procdef);
  565. hp:=firstsym;
  566. while assigned(hp) do
  567. begin
  568. case hp^.sltype of
  569. sl_call,
  570. sl_load,
  571. sl_subscript :
  572. hp^.symderef.build(hp^.sym);
  573. sl_absolutetype,
  574. sl_typeconv :
  575. hp^.defderef.build(hp^.def);
  576. sl_vec:
  577. hp^.valuedefderef.build(hp^.valuedef);
  578. else
  579. internalerror(200110205);
  580. end;
  581. hp:=hp^.next;
  582. end;
  583. end;
  584. {****************************************************************************
  585. Tderef
  586. ****************************************************************************}
  587. procedure tderef.reset;
  588. begin
  589. dataidx:=-1;
  590. end;
  591. procedure tderef.build(s:tsymtableentry);
  592. var
  593. len : byte;
  594. st : tsymtable;
  595. data : array[0..255] of byte;
  596. idx : word;
  597. begin
  598. { skip length byte }
  599. len:=1;
  600. if assigned(s) then
  601. begin
  602. st:=findunitsymtable(s.owner);
  603. if not st.iscurrentunit then
  604. begin
  605. { register that the unit is needed for resolving }
  606. data[len]:=ord(deref_unit);
  607. idx:=current_module.derefidx_unit(st.moduleid);
  608. data[len+1]:=idx shr 8 and $ff;
  609. data[len+2]:=idx and $ff;
  610. inc(len,3);
  611. end;
  612. if s is tsym then
  613. begin
  614. data[len]:=ord(deref_symid);
  615. data[len+1]:=tsym(s).symid shr 24 and $ff;
  616. data[len+2]:=tsym(s).symid shr 16 and $ff;
  617. data[len+3]:=tsym(s).symid shr 8 and $ff;
  618. data[len+4]:=tsym(s).symid and $ff;
  619. inc(len,5);
  620. end
  621. else
  622. begin
  623. data[len]:=ord(deref_defid);
  624. data[len+1]:=tdef(s).defid shr 24 and $ff;
  625. data[len+2]:=tdef(s).defid shr 16 and $ff;
  626. data[len+3]:=tdef(s).defid shr 8 and $ff;
  627. data[len+4]:=tdef(s).defid and $ff;
  628. inc(len,5);
  629. end;
  630. end
  631. else
  632. begin
  633. { nil pointer }
  634. data[len]:=ord(deref_nil);
  635. inc(len);
  636. end;
  637. { store data length in first byte }
  638. data[0]:=len-1;
  639. { store index and write to derefdata }
  640. dataidx:=current_module.derefdata.size;
  641. current_module.derefdata.write(data,len);
  642. end;
  643. function tderef.resolve:tsymtableentry;
  644. var
  645. pm : tmodule;
  646. typ : tdereftype;
  647. idx : word;
  648. i : aint;
  649. len : byte;
  650. data : array[0..255] of byte;
  651. begin
  652. result:=nil;
  653. { not initialized or error }
  654. if dataidx<0 then
  655. internalerror(200306067);
  656. { read data }
  657. current_module.derefdata.seek(dataidx);
  658. if current_module.derefdata.read(len,1)<>1 then
  659. internalerror(200310221);
  660. if len>0 then
  661. begin
  662. if current_module.derefdata.read(data,len)<>len then
  663. internalerror(200310222);
  664. end;
  665. { process data }
  666. pm:=current_module;
  667. i:=0;
  668. while (i<len) do
  669. begin
  670. typ:=tdereftype(data[i]);
  671. inc(i);
  672. case typ of
  673. deref_unit :
  674. begin
  675. idx:=(data[i] shl 8) or data[i+1];
  676. inc(i,2);
  677. pm:=current_module.resolve_unit(idx);
  678. end;
  679. deref_defid :
  680. begin
  681. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  682. inc(i,4);
  683. result:=tdef(pm.deflist[idx]);
  684. end;
  685. deref_symid :
  686. begin
  687. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  688. inc(i,4);
  689. result:=tsym(pm.symlist[idx]);
  690. end;
  691. deref_nil :
  692. begin
  693. result:=nil;
  694. { Only allowed when no other deref is available }
  695. if len<>1 then
  696. internalerror(200306232);
  697. end;
  698. else
  699. internalerror(200212277);
  700. end;
  701. end;
  702. end;
  703. {*****************************************************************************
  704. TCompilerPPUFile
  705. *****************************************************************************}
  706. procedure tcompilerppufile.checkerror;
  707. begin
  708. if error then
  709. Message(unit_f_ppu_read_error);
  710. end;
  711. procedure tcompilerppufile.getguid(var g: tguid);
  712. begin
  713. getdata(g,sizeof(g));
  714. end;
  715. function tcompilerppufile.getexprint:tconstexprint;
  716. begin
  717. if sizeof(tconstexprint)=8 then
  718. result:=tconstexprint(getint64)
  719. else
  720. result:=tconstexprint(getlongint);
  721. end;
  722. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  723. begin
  724. if sizeof(TConstPtrUInt)=8 then
  725. result:=tconstptruint(getint64)
  726. else
  727. result:=TConstPtrUInt(getlongint);
  728. end;
  729. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  730. var
  731. info : byte;
  732. begin
  733. {
  734. info byte layout in bits:
  735. 0-1 - amount of bytes for fileindex
  736. 2-3 - amount of bytes for line
  737. 4-5 - amount of bytes for column
  738. }
  739. info:=getbyte;
  740. case (info and $03) of
  741. 0 : p.fileindex:=getbyte;
  742. 1 : p.fileindex:=getword;
  743. 2 : p.fileindex:=(getbyte shl 16) or getword;
  744. 3 : p.fileindex:=getlongint;
  745. end;
  746. case ((info shr 2) and $03) of
  747. 0 : p.line:=getbyte;
  748. 1 : p.line:=getword;
  749. 2 : p.line:=(getbyte shl 16) or getword;
  750. 3 : p.line:=getlongint;
  751. end;
  752. case ((info shr 4) and $03) of
  753. 0 : p.column:=getbyte;
  754. 1 : p.column:=getword;
  755. 2 : p.column:=(getbyte shl 16) or getword;
  756. 3 : p.column:=getlongint;
  757. end;
  758. end;
  759. procedure tcompilerppufile.getderef(var d:tderef);
  760. begin
  761. d.dataidx:=getlongint;
  762. end;
  763. function tcompilerppufile.getpropaccesslist:tpropaccesslist;
  764. var
  765. hderef : tderef;
  766. slt : tsltype;
  767. idx : longint;
  768. p : tpropaccesslist;
  769. begin
  770. p:=tpropaccesslist.create;
  771. getderef(p.procdefderef);
  772. repeat
  773. slt:=tsltype(getbyte);
  774. case slt of
  775. sl_none :
  776. break;
  777. sl_call,
  778. sl_load,
  779. sl_subscript :
  780. begin
  781. getderef(hderef);
  782. p.addsymderef(slt,hderef);
  783. end;
  784. sl_absolutetype,
  785. sl_typeconv :
  786. begin
  787. getderef(hderef);
  788. p.addtypederef(slt,hderef);
  789. end;
  790. sl_vec :
  791. begin
  792. idx:=getlongint;
  793. getderef(hderef);
  794. p.addconstderef(slt,idx,hderef);
  795. end;
  796. else
  797. internalerror(200110204);
  798. end;
  799. until false;
  800. getpropaccesslist:=tpropaccesslist(p);
  801. end;
  802. function tcompilerppufile.getasmsymbol:tasmsymbol;
  803. begin
  804. getlongint;
  805. getasmsymbol:=nil;
  806. end;
  807. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  808. var
  809. oldcrc : boolean;
  810. info : byte;
  811. begin
  812. { posinfo is not relevant for changes in PPU }
  813. oldcrc:=do_crc;
  814. do_crc:=false;
  815. {
  816. info byte layout in bits:
  817. 0-1 - amount of bytes for fileindex
  818. 2-3 - amount of bytes for line
  819. 4-5 - amount of bytes for column
  820. }
  821. info:=0;
  822. { calculate info byte }
  823. if (p.fileindex>$ff) then
  824. begin
  825. if (p.fileindex<=$ffff) then
  826. info:=info or $1
  827. else
  828. if (p.fileindex<=$ffffff) then
  829. info:=info or $2
  830. else
  831. info:=info or $3;
  832. end;
  833. if (p.line>$ff) then
  834. begin
  835. if (p.line<=$ffff) then
  836. info:=info or $4
  837. else
  838. if (p.line<=$ffffff) then
  839. info:=info or $8
  840. else
  841. info:=info or $c;
  842. end;
  843. if (p.column>$ff) then
  844. begin
  845. if (p.column<=$ffff) then
  846. info:=info or $10
  847. else
  848. if (p.column<=$ffffff) then
  849. info:=info or $20
  850. else
  851. info:=info or $30;
  852. end;
  853. { write data }
  854. putbyte(info);
  855. case (info and $03) of
  856. 0 : putbyte(p.fileindex);
  857. 1 : putword(p.fileindex);
  858. 2 : begin
  859. putbyte(p.fileindex shr 16);
  860. putword(p.fileindex and $ffff);
  861. end;
  862. 3 : putlongint(p.fileindex);
  863. end;
  864. case ((info shr 2) and $03) of
  865. 0 : putbyte(p.line);
  866. 1 : putword(p.line);
  867. 2 : begin
  868. putbyte(p.line shr 16);
  869. putword(p.line and $ffff);
  870. end;
  871. 3 : putlongint(p.line);
  872. end;
  873. case ((info shr 4) and $03) of
  874. 0 : putbyte(p.column);
  875. 1 : putword(p.column);
  876. 2 : begin
  877. putbyte(p.column shr 16);
  878. putword(p.column and $ffff);
  879. end;
  880. 3 : putlongint(p.column);
  881. end;
  882. do_crc:=oldcrc;
  883. end;
  884. procedure tcompilerppufile.putguid(const g: tguid);
  885. begin
  886. putdata(g,sizeof(g));
  887. end;
  888. procedure tcompilerppufile.putexprint(v:tconstexprint);
  889. begin
  890. if sizeof(TConstExprInt)=8 then
  891. putint64(int64(v))
  892. else if sizeof(TConstExprInt)=4 then
  893. putlongint(longint(v))
  894. else
  895. internalerror(2002082601);
  896. end;
  897. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  898. begin
  899. if sizeof(TConstPtrUInt)=8 then
  900. putint64(int64(v))
  901. else if sizeof(TConstPtrUInt)=4 then
  902. putlongint(longint(v))
  903. else
  904. internalerror(2002082601);
  905. end;
  906. procedure tcompilerppufile.putderef(const d:tderef);
  907. var
  908. oldcrc : boolean;
  909. begin
  910. oldcrc:=do_crc;
  911. do_crc:=false;
  912. putlongint(d.dataidx);
  913. do_crc:=oldcrc;
  914. end;
  915. procedure tcompilerppufile.putpropaccesslist(p:tpropaccesslist);
  916. var
  917. hp : ppropaccesslistitem;
  918. begin
  919. putderef(p.procdefderef);
  920. hp:=p.firstsym;
  921. while assigned(hp) do
  922. begin
  923. putbyte(byte(hp^.sltype));
  924. case hp^.sltype of
  925. sl_call,
  926. sl_load,
  927. sl_subscript :
  928. putderef(hp^.symderef);
  929. sl_absolutetype,
  930. sl_typeconv :
  931. putderef(hp^.defderef);
  932. sl_vec :
  933. begin
  934. putlongint(hp^.value);
  935. putderef(hp^.valuedefderef);
  936. end;
  937. else
  938. internalerror(200110205);
  939. end;
  940. hp:=hp^.next;
  941. end;
  942. putbyte(byte(sl_none));
  943. end;
  944. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  945. begin
  946. putlongint(0);
  947. end;
  948. {$ifdef MEMDEBUG}
  949. initialization
  950. membrowser:=TMemDebug.create('BrowserRefs');
  951. membrowser.stop;
  952. memrealnames:=TMemDebug.create('Realnames');
  953. memrealnames.stop;
  954. memmanglednames:=TMemDebug.create('Manglednames');
  955. memmanglednames.stop;
  956. memprocpara:=TMemDebug.create('ProcPara');
  957. memprocpara.stop;
  958. memprocparast:=TMemDebug.create('ProcParaSt');
  959. memprocparast.stop;
  960. memproclocalst:=TMemDebug.create('ProcLocalSt');
  961. memproclocalst.stop;
  962. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  963. memprocnodetree.stop;
  964. finalization
  965. membrowser.free;
  966. memrealnames.free;
  967. memmanglednames.free;
  968. memprocpara.free;
  969. memprocparast.free;
  970. memproclocalst.free;
  971. memprocnodetree.free;
  972. {$endif MEMDEBUG}
  973. end.