symtype.pas 40 KB

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