symtype.pas 31 KB

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