symtype.pas 40 KB

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