symtype.pas 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  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. cclasses,
  24. { global }
  25. globtype,globals,constexp,
  26. { symtable }
  27. symconst,symbase,
  28. { aasm }
  29. aasmbase,ppu,cpuinfo
  30. ;
  31. type
  32. {************************************************
  33. Required Forwards
  34. ************************************************}
  35. tsym = class;
  36. Tcompilerppufile=class;
  37. {************************************************
  38. TDef
  39. ************************************************}
  40. tgeTSymtable = (gs_none,gs_record,gs_local,gs_para);
  41. tdef = class(TDefEntry)
  42. typesym : tsym; { which type the definition was generated this def }
  43. { maybe it's useful to merge the dwarf and stabs debugging info with some hacking }
  44. { dwarf debugging }
  45. dwarf_lab : tasmsymbol;
  46. dwarf_ref_lab : tasmsymbol;
  47. { stabs debugging }
  48. stab_number : word;
  49. dbg_state : tdefdbgstatus;
  50. defoptions : tdefoptions;
  51. defstates : tdefstates;
  52. constructor create(dt:tdeftyp);
  53. procedure buildderef;virtual;abstract;
  54. procedure buildderefimpl;virtual;abstract;
  55. procedure deref;virtual;abstract;
  56. procedure derefimpl;virtual;abstract;
  57. function typename:string;
  58. function GetTypeName:string;virtual;
  59. function mangledparaname:string;
  60. function getmangledparaname:string;virtual;
  61. function rtti_mangledname(rt:trttitype):string;virtual;abstract;
  62. function size:aint;virtual;abstract;
  63. function packedbitsize:aint;virtual;
  64. function alignment:shortint;virtual;abstract;
  65. function getvardef:longint;virtual;abstract;
  66. function getparentdef:tdef;virtual;
  67. function geTSymtable(t:tgeTSymtable):TSymtable;virtual;
  68. function is_publishable:boolean;virtual;abstract;
  69. function needs_inittable:boolean;virtual;abstract;
  70. function is_related(def:tdef):boolean;virtual;
  71. procedure ChangeOwner(st:TSymtable);
  72. procedure register_created_object_type;virtual;
  73. end;
  74. {************************************************
  75. TSym
  76. ************************************************}
  77. { this object is the base for all symbol objects }
  78. { tsym }
  79. tsym = class(TSymEntry)
  80. protected
  81. public
  82. fileinfo : tfileposinfo;
  83. symoptions : tsymoptions;
  84. refs : longint;
  85. reflist : TLinkedList;
  86. isdbgwritten : boolean;
  87. constructor create(st:tsymtyp;const aname:string);
  88. destructor destroy;override;
  89. function mangledname:string; virtual;
  90. procedure buildderef;virtual;
  91. procedure deref;virtual;
  92. { currobjdef is the object def to assume, this is necessary for protected and
  93. private,
  94. context is the object def we're really in, this is for the strict stuff
  95. }
  96. function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
  97. procedure ChangeOwner(st:TSymtable);
  98. procedure IncRefCount;
  99. procedure IncRefCountBy(AValue : longint);
  100. procedure MaybeCreateRefList;
  101. procedure AddRef;
  102. end;
  103. tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
  104. psymarr = ^tsymarr;
  105. {************************************************
  106. TDeref
  107. ************************************************}
  108. tderef = object
  109. dataidx : longint;
  110. procedure reset;
  111. procedure build(s:TObject);
  112. function resolve:TObject;
  113. end;
  114. {************************************************
  115. tpropaccesslist
  116. ************************************************}
  117. ppropaccesslistitem = ^tpropaccesslistitem;
  118. tpropaccesslistitem = record
  119. sltype : tsltype;
  120. next : ppropaccesslistitem;
  121. case byte of
  122. 0 : (sym : tsym; symderef : tderef);
  123. 1 : (value : TConstExprInt; valuedef: tdef; valuedefderef:tderef);
  124. 2 : (def: tdef; defderef:tderef);
  125. end;
  126. tpropaccesslist = class
  127. procdef : tdef;
  128. procdefderef : tderef;
  129. firstsym,
  130. lastsym : ppropaccesslistitem;
  131. constructor create;
  132. destructor destroy;override;
  133. function empty:boolean;
  134. procedure addsym(slt:tsltype;p:tsym);
  135. procedure addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  136. procedure addtype(slt:tsltype;d:tdef);
  137. procedure addsymderef(slt:tsltype;d:tderef);
  138. procedure addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  139. procedure addtypederef(slt:tsltype;d:tderef);
  140. procedure clear;
  141. procedure resolve;
  142. procedure buildderef;
  143. end;
  144. {************************************************
  145. Tcompilerppufile
  146. ************************************************}
  147. tcompilerppufile=class(tppufile)
  148. public
  149. procedure checkerror;
  150. procedure getguid(var g: tguid);
  151. function getexprint:Tconstexprint;
  152. function getptruint:TConstPtrUInt;
  153. procedure getposinfo(var p:tfileposinfo);
  154. procedure getderef(var d:tderef);
  155. function getpropaccesslist:tpropaccesslist;
  156. function getasmsymbol:tasmsymbol;
  157. procedure putguid(const g: tguid);
  158. procedure putexprint(const v:tconstexprint);
  159. procedure PutPtrUInt(v:TConstPtrUInt);
  160. procedure putposinfo(const p:tfileposinfo);
  161. procedure putderef(const d:tderef);
  162. procedure putpropaccesslist(p:tpropaccesslist);
  163. procedure putasmsymbol(s:tasmsymbol);
  164. end;
  165. {$ifdef MEMDEBUG}
  166. var
  167. memmanglednames,
  168. memprocpara,
  169. memprocparast,
  170. memproclocalst,
  171. memprocnodetree : tmemdebug;
  172. {$endif MEMDEBUG}
  173. const
  174. current_object_option : tsymoptions = [sp_public];
  175. function FindUnitSymtable(st:TSymtable):TSymtable;
  176. implementation
  177. uses
  178. crefs,
  179. verbose,
  180. fmodule
  181. ;
  182. {****************************************************************************
  183. Utils
  184. ****************************************************************************}
  185. function FindUnitSymtable(st:TSymtable):TSymtable;
  186. begin
  187. result:=nil;
  188. repeat
  189. if not assigned(st) then
  190. internalerror(200602034);
  191. case st.symtabletype of
  192. localmacrosymtable,
  193. exportedmacrosymtable,
  194. staticsymtable,
  195. globalsymtable :
  196. begin
  197. result:=st;
  198. exit;
  199. end;
  200. recordsymtable,
  201. localsymtable,
  202. parasymtable,
  203. ObjectSymtable :
  204. st:=st.defowner.owner;
  205. else
  206. internalerror(200602035);
  207. end;
  208. until false;
  209. end;
  210. {****************************************************************************
  211. Tdef
  212. ****************************************************************************}
  213. constructor tdef.create(dt:tdeftyp);
  214. begin
  215. inherited create;
  216. typ:=dt;
  217. owner := nil;
  218. typesym := nil;
  219. defoptions:=[];
  220. dbg_state:=dbg_state_unused;
  221. stab_number:=0;
  222. end;
  223. function tdef.typename:string;
  224. begin
  225. if assigned(typesym) and
  226. not(typ in [procvardef,procdef]) and
  227. (typesym.realname[1]<>'$') then
  228. result:=typesym.realname
  229. else
  230. result:=GetTypeName;
  231. end;
  232. function tdef.GetTypeName : string;
  233. begin
  234. GetTypeName:='<unknown type>'
  235. end;
  236. function tdef.mangledparaname:string;
  237. begin
  238. if assigned(typesym) then
  239. mangledparaname:=typesym.name
  240. else
  241. mangledparaname:=getmangledparaname;
  242. end;
  243. function tdef.getmangledparaname:string;
  244. begin
  245. result:='<unknown type>';
  246. end;
  247. function tdef.getparentdef:tdef;
  248. begin
  249. result:=nil;
  250. end;
  251. function tdef.geTSymtable(t:tgeTSymtable):TSymtable;
  252. begin
  253. result:=nil;
  254. end;
  255. function tdef.is_related(def:tdef):boolean;
  256. begin
  257. result:=false;
  258. end;
  259. function tdef.packedbitsize:aint;
  260. begin
  261. result:=size * 8;
  262. end;
  263. procedure tdef.ChangeOwner(st:TSymtable);
  264. begin
  265. // if assigned(Owner) then
  266. // Owner.DefList.List[i]:=nil;
  267. Owner:=st;
  268. Owner.DefList.Add(self);
  269. end;
  270. procedure tdef.register_created_object_type;
  271. begin
  272. end;
  273. {****************************************************************************
  274. TSYM (base for all symtypes)
  275. ****************************************************************************}
  276. constructor tsym.create(st:tsymtyp;const aname:string);
  277. begin
  278. inherited CreateNotOwned;
  279. realname:=aname;
  280. typ:=st;
  281. RefList:=nil;
  282. symoptions:=[];
  283. fileinfo:=current_tokenpos;
  284. isdbgwritten := false;
  285. symoptions:=current_object_option;
  286. end;
  287. destructor Tsym.destroy;
  288. begin
  289. if assigned(RefList) then
  290. RefList.Free;
  291. inherited Destroy;
  292. end;
  293. procedure Tsym.IncRefCount;
  294. begin
  295. inc(refs);
  296. if cs_browser in current_settings.moduleswitches then
  297. begin
  298. MaybeCreateRefList;
  299. AddRef;
  300. end;
  301. end;
  302. procedure Tsym.IncRefCountBy(AValue : longint);
  303. begin
  304. inc(refs,AValue);
  305. end;
  306. procedure Tsym.MaybeCreateRefList;
  307. begin
  308. if not assigned(reflist) then
  309. reflist:=TRefLinkedList.create;
  310. end;
  311. procedure Tsym.AddRef;
  312. var
  313. RefItem: TRefItem;
  314. begin
  315. RefItem:=TRefItem.Create(current_tokenpos);
  316. RefList.Concat(RefItem);
  317. end;
  318. procedure Tsym.buildderef;
  319. begin
  320. end;
  321. procedure Tsym.deref;
  322. begin
  323. end;
  324. function tsym.mangledname : string;
  325. begin
  326. internalerror(200204171);
  327. result:='';
  328. end;
  329. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  330. begin
  331. is_visible_for_object:=false;
  332. { private symbols are allowed when we are in the same
  333. module as they are defined }
  334. if (sp_private in symoptions) and
  335. assigned(owner.defowner) and
  336. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  337. (not owner.defowner.owner.iscurrentunit) then
  338. exit;
  339. if (sp_strictprivate in symoptions) then
  340. begin
  341. result:=assigned(currobjdef) and
  342. (context=tdef(owner.defowner));
  343. exit;
  344. end;
  345. if (sp_strictprotected in symoptions) then
  346. begin
  347. result:=assigned(context) and
  348. context.is_related(tdef(owner.defowner));
  349. exit;
  350. end;
  351. { protected symbols are visible in the module that defines them and
  352. also visible to related objects }
  353. if (sp_protected in symoptions) and
  354. (
  355. (
  356. assigned(owner.defowner) and
  357. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  358. (not owner.defowner.owner.iscurrentunit)
  359. ) and
  360. not(
  361. assigned(currobjdef) and
  362. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  363. (currobjdef.owner.iscurrentunit) and
  364. currobjdef.is_related(tdef(owner.defowner))
  365. )
  366. ) then
  367. exit;
  368. is_visible_for_object:=true;
  369. end;
  370. procedure tsym.ChangeOwner(st:TSymtable);
  371. begin
  372. // if assigned(Owner) then
  373. // Owner.SymList.List.List^[i].Data:=nil;
  374. Owner:=st;
  375. inherited ChangeOwner(Owner.SymList);
  376. end;
  377. {****************************************************************************
  378. tpropaccesslist
  379. ****************************************************************************}
  380. constructor tpropaccesslist.create;
  381. begin
  382. procdef:=nil; { needed for procedures }
  383. firstsym:=nil;
  384. lastsym:=nil;
  385. end;
  386. destructor tpropaccesslist.destroy;
  387. begin
  388. clear;
  389. end;
  390. function tpropaccesslist.empty:boolean;
  391. begin
  392. empty:=(firstsym=nil);
  393. end;
  394. procedure tpropaccesslist.clear;
  395. var
  396. hp : ppropaccesslistitem;
  397. begin
  398. while assigned(firstsym) do
  399. begin
  400. hp:=firstsym;
  401. firstsym:=firstsym^.next;
  402. dispose(hp);
  403. end;
  404. firstsym:=nil;
  405. lastsym:=nil;
  406. procdef:=nil;
  407. end;
  408. procedure tpropaccesslist.addsym(slt:tsltype;p:tsym);
  409. var
  410. hp : ppropaccesslistitem;
  411. begin
  412. new(hp);
  413. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  414. hp^.sltype:=slt;
  415. hp^.sym:=p;
  416. hp^.symderef.reset;
  417. if assigned(lastsym) then
  418. lastsym^.next:=hp
  419. else
  420. firstsym:=hp;
  421. lastsym:=hp;
  422. end;
  423. procedure tpropaccesslist.addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  424. var
  425. hp : ppropaccesslistitem;
  426. begin
  427. new(hp);
  428. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  429. hp^.sltype:=slt;
  430. hp^.value:=v;
  431. hp^.valuedef:=d;
  432. hp^.valuedefderef.reset;
  433. if assigned(lastsym) then
  434. lastsym^.next:=hp
  435. else
  436. firstsym:=hp;
  437. lastsym:=hp;
  438. end;
  439. procedure tpropaccesslist.addtype(slt:tsltype;d:tdef);
  440. var
  441. hp : ppropaccesslistitem;
  442. begin
  443. new(hp);
  444. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  445. hp^.sltype:=slt;
  446. hp^.def:=d;
  447. hp^.defderef.reset;
  448. if assigned(lastsym) then
  449. lastsym^.next:=hp
  450. else
  451. firstsym:=hp;
  452. lastsym:=hp;
  453. end;
  454. procedure tpropaccesslist.addsymderef(slt:tsltype;d:tderef);
  455. begin
  456. addsym(slt,nil);
  457. lastsym^.symderef:=d;
  458. end;
  459. procedure tpropaccesslist.addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  460. begin
  461. addconst(slt,v,nil);
  462. lastsym^.valuedefderef:=d;
  463. end;
  464. procedure tpropaccesslist.addtypederef(slt:tsltype;d:tderef);
  465. begin
  466. addtype(slt,nil);
  467. lastsym^.defderef:=d;
  468. end;
  469. procedure tpropaccesslist.resolve;
  470. var
  471. hp : ppropaccesslistitem;
  472. begin
  473. procdef:=tdef(procdefderef.resolve);
  474. hp:=firstsym;
  475. while assigned(hp) do
  476. begin
  477. case hp^.sltype of
  478. sl_call,
  479. sl_load,
  480. sl_subscript :
  481. hp^.sym:=tsym(hp^.symderef.resolve);
  482. sl_absolutetype,
  483. sl_typeconv :
  484. hp^.def:=tdef(hp^.defderef.resolve);
  485. sl_vec:
  486. hp^.valuedef:=tdef(hp^.valuedefderef.resolve);
  487. else
  488. internalerror(200110205);
  489. end;
  490. hp:=hp^.next;
  491. end;
  492. end;
  493. procedure tpropaccesslist.buildderef;
  494. var
  495. hp : ppropaccesslistitem;
  496. begin
  497. procdefderef.build(procdef);
  498. hp:=firstsym;
  499. while assigned(hp) do
  500. begin
  501. case hp^.sltype of
  502. sl_call,
  503. sl_load,
  504. sl_subscript :
  505. hp^.symderef.build(hp^.sym);
  506. sl_absolutetype,
  507. sl_typeconv :
  508. hp^.defderef.build(hp^.def);
  509. sl_vec:
  510. hp^.valuedefderef.build(hp^.valuedef);
  511. else
  512. internalerror(200110205);
  513. end;
  514. hp:=hp^.next;
  515. end;
  516. end;
  517. {****************************************************************************
  518. Tderef
  519. ****************************************************************************}
  520. procedure tderef.reset;
  521. begin
  522. dataidx:=-1;
  523. end;
  524. procedure tderef.build(s:TObject);
  525. var
  526. len : byte;
  527. st : TSymtable;
  528. data : array[0..255] of byte;
  529. idx : word;
  530. begin
  531. { skip length byte }
  532. len:=1;
  533. if assigned(s) then
  534. begin
  535. { TODO: ugly hack}
  536. if s is tsym then
  537. st:=FindUnitSymtable(tsym(s).owner)
  538. else
  539. st:=FindUnitSymtable(tdef(s).owner);
  540. if not st.iscurrentunit then
  541. begin
  542. { register that the unit is needed for resolving }
  543. data[len]:=ord(deref_unit);
  544. idx:=current_module.derefidx_unit(st.moduleid);
  545. data[len+1]:=idx shr 8 and $ff;
  546. data[len+2]:=idx and $ff;
  547. inc(len,3);
  548. end;
  549. if s is tsym then
  550. begin
  551. data[len]:=ord(deref_symid);
  552. data[len+1]:=tsym(s).symid shr 24 and $ff;
  553. data[len+2]:=tsym(s).symid shr 16 and $ff;
  554. data[len+3]:=tsym(s).symid shr 8 and $ff;
  555. data[len+4]:=tsym(s).symid and $ff;
  556. inc(len,5);
  557. end
  558. else
  559. begin
  560. data[len]:=ord(deref_defid);
  561. data[len+1]:=tdef(s).defid shr 24 and $ff;
  562. data[len+2]:=tdef(s).defid shr 16 and $ff;
  563. data[len+3]:=tdef(s).defid shr 8 and $ff;
  564. data[len+4]:=tdef(s).defid and $ff;
  565. inc(len,5);
  566. end;
  567. end
  568. else
  569. begin
  570. { nil pointer }
  571. data[len]:=ord(deref_nil);
  572. inc(len);
  573. end;
  574. { store data length in first byte }
  575. data[0]:=len-1;
  576. { store index and write to derefdata }
  577. dataidx:=current_module.derefdata.size;
  578. current_module.derefdata.write(data,len);
  579. end;
  580. function tderef.resolve:TObject;
  581. var
  582. pm : tmodule;
  583. typ : tdereftype;
  584. idx : longint;
  585. i : aint;
  586. len : byte;
  587. data : array[0..255] of byte;
  588. begin
  589. result:=nil;
  590. { not initialized or error }
  591. if dataidx<0 then
  592. internalerror(200306067);
  593. { read data }
  594. current_module.derefdata.seek(dataidx);
  595. if current_module.derefdata.read(len,1)<>1 then
  596. internalerror(200310221);
  597. if len>0 then
  598. begin
  599. if current_module.derefdata.read(data,len)<>len then
  600. internalerror(200310222);
  601. end;
  602. { process data }
  603. pm:=current_module;
  604. i:=0;
  605. while (i<len) do
  606. begin
  607. typ:=tdereftype(data[i]);
  608. inc(i);
  609. case typ of
  610. deref_unit :
  611. begin
  612. idx:=(data[i] shl 8) or data[i+1];
  613. inc(i,2);
  614. pm:=current_module.resolve_unit(idx);
  615. end;
  616. deref_defid :
  617. begin
  618. idx:=longint((data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3]);
  619. inc(i,4);
  620. result:=tdef(pm.deflist[idx]);
  621. end;
  622. deref_symid :
  623. begin
  624. idx:=longint((data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3]);
  625. inc(i,4);
  626. result:=tsym(pm.symlist[idx]);
  627. end;
  628. deref_nil :
  629. begin
  630. result:=nil;
  631. { Only allowed when no other deref is available }
  632. if len<>1 then
  633. internalerror(200306232);
  634. end;
  635. else
  636. internalerror(200212277);
  637. end;
  638. end;
  639. end;
  640. {*****************************************************************************
  641. TCompilerPPUFile
  642. *****************************************************************************}
  643. procedure tcompilerppufile.checkerror;
  644. begin
  645. if error then
  646. Message(unit_f_ppu_read_error);
  647. end;
  648. procedure tcompilerppufile.getguid(var g: tguid);
  649. begin
  650. longint(g.d1):=getlongint;
  651. g.d2:=getword;
  652. g.d3:=getword;
  653. getdata(g.d4,sizeof(g.d4));
  654. end;
  655. function tcompilerppufile.getexprint:Tconstexprint;
  656. begin
  657. getexprint.overflow:=false;
  658. getexprint.signed:=boolean(getbyte);
  659. getexprint.svalue:=getint64;
  660. end;
  661. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  662. begin
  663. {$if sizeof(TConstPtrUInt)=8}
  664. result:=tconstptruint(getint64);
  665. {$else}
  666. result:=TConstPtrUInt(getlongint);
  667. {$endif}
  668. end;
  669. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  670. var
  671. info : byte;
  672. begin
  673. {
  674. info byte layout in bits:
  675. 0-1 - amount of bytes for fileindex
  676. 2-3 - amount of bytes for line
  677. 4-5 - amount of bytes for column
  678. }
  679. info:=getbyte;
  680. case (info and $03) of
  681. 0 : p.fileindex:=getbyte;
  682. 1 : p.fileindex:=getword;
  683. 2 : p.fileindex:=(getbyte shl 16) or getword;
  684. 3 : p.fileindex:=getlongint;
  685. end;
  686. case ((info shr 2) and $03) of
  687. 0 : p.line:=getbyte;
  688. 1 : p.line:=getword;
  689. 2 : p.line:=(getbyte shl 16) or getword;
  690. 3 : p.line:=getlongint;
  691. end;
  692. case ((info shr 4) and $03) of
  693. 0 : p.column:=getbyte;
  694. 1 : p.column:=getword;
  695. 2 : p.column:=(getbyte shl 16) or getword;
  696. 3 : p.column:=getlongint;
  697. end;
  698. p.moduleindex:=current_module.unit_index;
  699. end;
  700. procedure tcompilerppufile.getderef(var d:tderef);
  701. begin
  702. d.dataidx:=getlongint;
  703. end;
  704. function tcompilerppufile.getpropaccesslist:tpropaccesslist;
  705. var
  706. hderef : tderef;
  707. slt : tsltype;
  708. idx : longint;
  709. p : tpropaccesslist;
  710. begin
  711. p:=tpropaccesslist.create;
  712. getderef(p.procdefderef);
  713. repeat
  714. slt:=tsltype(getbyte);
  715. case slt of
  716. sl_none :
  717. break;
  718. sl_call,
  719. sl_load,
  720. sl_subscript :
  721. begin
  722. getderef(hderef);
  723. p.addsymderef(slt,hderef);
  724. end;
  725. sl_absolutetype,
  726. sl_typeconv :
  727. begin
  728. getderef(hderef);
  729. p.addtypederef(slt,hderef);
  730. end;
  731. sl_vec :
  732. begin
  733. idx:=getlongint;
  734. getderef(hderef);
  735. p.addconstderef(slt,idx,hderef);
  736. end;
  737. else
  738. internalerror(200110204);
  739. end;
  740. until false;
  741. getpropaccesslist:=tpropaccesslist(p);
  742. end;
  743. function tcompilerppufile.getasmsymbol:tasmsymbol;
  744. begin
  745. getlongint;
  746. getasmsymbol:=nil;
  747. end;
  748. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  749. var
  750. oldcrc : boolean;
  751. info : byte;
  752. begin
  753. { posinfo is not relevant for changes in PPU }
  754. oldcrc:=do_crc;
  755. do_crc:=false;
  756. {
  757. info byte layout in bits:
  758. 0-1 - amount of bytes for fileindex
  759. 2-3 - amount of bytes for line
  760. 4-5 - amount of bytes for column
  761. }
  762. info:=0;
  763. { calculate info byte }
  764. if (p.fileindex>$ff) then
  765. begin
  766. info:=info or $1;
  767. { uncomment this code if tfileposinfo.fileindex type was changed
  768. if (p.fileindex<=$ffff) then
  769. info:=info or $1
  770. else
  771. if (p.fileindex<=$ffffff) then
  772. info:=info or $2
  773. else
  774. info:=info or $3;
  775. }
  776. end;
  777. if (p.line>$ff) then
  778. begin
  779. if (p.line<=$ffff) then
  780. info:=info or $4
  781. else
  782. if (p.line<=$ffffff) then
  783. info:=info or $8
  784. else
  785. info:=info or $c;
  786. end;
  787. if (p.column>$ff) then
  788. begin
  789. info:=info or $10;
  790. { uncomment this code if tfileposinfo.column type was changed
  791. if (p.column<=$ffff) then
  792. info:=info or $10
  793. else
  794. if (p.column<=$ffffff) then
  795. info:=info or $20
  796. else
  797. info:=info or $30;
  798. }
  799. end;
  800. { write data }
  801. putbyte(info);
  802. case (info and $03) of
  803. 0 : putbyte(p.fileindex);
  804. 1 : putword(p.fileindex);
  805. 2 : begin
  806. putbyte(p.fileindex shr 16);
  807. putword(p.fileindex and $ffff);
  808. end;
  809. 3 : putlongint(p.fileindex);
  810. end;
  811. case ((info shr 2) and $03) of
  812. 0 : putbyte(p.line);
  813. 1 : putword(p.line);
  814. 2 : begin
  815. putbyte(p.line shr 16);
  816. putword(p.line and $ffff);
  817. end;
  818. 3 : putlongint(p.line);
  819. end;
  820. case ((info shr 4) and $03) of
  821. 0 : putbyte(p.column);
  822. 1 : putword(p.column);
  823. 2 : begin
  824. putbyte(p.column shr 16);
  825. putword(p.column and $ffff);
  826. end;
  827. 3 : putlongint(p.column);
  828. end;
  829. do_crc:=oldcrc;
  830. end;
  831. procedure tcompilerppufile.putguid(const g: tguid);
  832. begin
  833. putlongint(longint(g.d1));
  834. putword(g.d2);
  835. putword(g.d3);
  836. putdata(g.d4,sizeof(g.d4));
  837. end;
  838. procedure Tcompilerppufile.putexprint(const v:Tconstexprint);
  839. begin
  840. if v.overflow then
  841. internalerror(200706102);
  842. putbyte(byte(v.signed));
  843. putint64(v.svalue);
  844. end;
  845. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  846. begin
  847. {$if sizeof(TConstPtrUInt)=8}
  848. putint64(int64(v));
  849. {$else}
  850. {$if sizeof(TConstPtrUInt)=4}
  851. putlongint(longint(v));
  852. {$else}
  853. internalerror(2002082601);
  854. {$endif} {$endif}
  855. end;
  856. procedure tcompilerppufile.putderef(const d:tderef);
  857. var
  858. oldcrc : boolean;
  859. begin
  860. oldcrc:=do_crc;
  861. do_crc:=false;
  862. putlongint(d.dataidx);
  863. do_crc:=oldcrc;
  864. end;
  865. procedure tcompilerppufile.putpropaccesslist(p:tpropaccesslist);
  866. var
  867. hp : ppropaccesslistitem;
  868. begin
  869. putderef(p.procdefderef);
  870. hp:=p.firstsym;
  871. while assigned(hp) do
  872. begin
  873. putbyte(byte(hp^.sltype));
  874. case hp^.sltype of
  875. sl_call,
  876. sl_load,
  877. sl_subscript :
  878. putderef(hp^.symderef);
  879. sl_absolutetype,
  880. sl_typeconv :
  881. putderef(hp^.defderef);
  882. sl_vec :
  883. begin
  884. putlongint(int64(hp^.value));
  885. putderef(hp^.valuedefderef);
  886. end;
  887. else
  888. internalerror(200110205);
  889. end;
  890. hp:=hp^.next;
  891. end;
  892. putbyte(byte(sl_none));
  893. end;
  894. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  895. begin
  896. putlongint(0);
  897. end;
  898. {$ifdef MEMDEBUG}
  899. initialization
  900. memmanglednames:=TMemDebug.create('Manglednames');
  901. memmanglednames.stop;
  902. memprocpara:=TMemDebug.create('ProcPara');
  903. memprocpara.stop;
  904. memprocparast:=TMemDebug.create('ProcParaSt');
  905. memprocparast.stop;
  906. memproclocalst:=TMemDebug.create('ProcLocalSt');
  907. memproclocalst.stop;
  908. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  909. memprocnodetree.stop;
  910. finalization
  911. memmanglednames.free;
  912. memprocpara.free;
  913. memprocparast.free;
  914. memproclocalst.free;
  915. memprocnodetree.free;
  916. {$endif MEMDEBUG}
  917. end.