symtype.pas 28 KB

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