symtype.pas 40 KB

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