symtype.pas 40 KB

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