symtype.pas 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453
  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;
  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(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;
  210. begin
  211. inherited create;
  212. deftype:=abstractdef;
  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(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:=abstractsym;
  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_vec,
  638. sl_absolutetype,
  639. sl_typeconv :
  640. hp^.tt.resolve;
  641. else
  642. internalerror(200110205);
  643. end;
  644. hp:=hp^.next;
  645. end;
  646. end;
  647. procedure tsymlist.buildderef;
  648. var
  649. hp : psymlistitem;
  650. begin
  651. procdefderef.build(procdef);
  652. hp:=firstsym;
  653. while assigned(hp) do
  654. begin
  655. case hp^.sltype of
  656. sl_call,
  657. sl_load,
  658. sl_subscript :
  659. hp^.symderef.build(hp^.sym);
  660. sl_vec,
  661. sl_absolutetype,
  662. sl_typeconv :
  663. hp^.tt.buildderef;
  664. else
  665. internalerror(200110205);
  666. end;
  667. hp:=hp^.next;
  668. end;
  669. end;
  670. {****************************************************************************
  671. Tderef
  672. ****************************************************************************}
  673. procedure tderef.reset;
  674. begin
  675. dataidx:=-1;
  676. end;
  677. procedure tderef.build(s:tsymtableentry);
  678. var
  679. len : byte;
  680. data : array[0..255] of byte;
  681. function is_child(currdef,ownerdef:tdef):boolean;
  682. begin
  683. while assigned(currdef) and
  684. (currdef<>ownerdef) do
  685. currdef:=currdef.getparentdef;
  686. result:=assigned(currdef);
  687. end;
  688. procedure addowner(s:tsymtableentry);
  689. var
  690. idx : longint;
  691. begin
  692. if not assigned(s.owner) then
  693. internalerror(200306063);
  694. case s.owner.symtabletype of
  695. globalsymtable :
  696. begin
  697. if s.owner.iscurrentunit then
  698. begin
  699. data[len]:=ord(deref_aktglobal);
  700. inc(len);
  701. end
  702. else
  703. begin
  704. { register that the unit is needed for resolving }
  705. idx:=current_module.derefidx_unit(s.owner.moduleid);
  706. data[len]:=ord(deref_unit);
  707. data[len+1]:=idx shr 8;
  708. data[len+2]:=idx and $ff;
  709. inc(len,3);
  710. end;
  711. end;
  712. staticsymtable :
  713. begin
  714. { only references to the current static symtable are allowed }
  715. if not s.owner.iscurrentunit then
  716. internalerror(200306233);
  717. data[len]:=ord(deref_aktstatic);
  718. inc(len);
  719. end;
  720. localsymtable :
  721. begin
  722. addowner(s.owner.defowner);
  723. data[len]:=ord(deref_def);
  724. data[len+1]:=s.owner.defowner.indexnr shr 8;
  725. data[len+2]:=s.owner.defowner.indexnr and $ff;
  726. data[len+3]:=ord(deref_local);
  727. inc(len,4);
  728. end;
  729. parasymtable :
  730. begin
  731. addowner(s.owner.defowner);
  732. data[len]:=ord(deref_def);
  733. data[len+1]:=s.owner.defowner.indexnr shr 8;
  734. data[len+2]:=s.owner.defowner.indexnr and $ff;
  735. data[len+3]:=ord(deref_para);
  736. inc(len,4);
  737. end;
  738. objectsymtable,
  739. recordsymtable :
  740. begin
  741. addowner(s.owner.defowner);
  742. data[len]:=ord(deref_def);
  743. data[len+1]:=s.owner.defowner.indexnr shr 8;
  744. data[len+2]:=s.owner.defowner.indexnr and $ff;
  745. data[len+3]:=ord(deref_record);
  746. inc(len,4);
  747. end;
  748. else
  749. internalerror(200306065);
  750. end;
  751. if len>252 then
  752. internalerror(200306062);
  753. end;
  754. procedure addparentobject(currdef,ownerdef:tdef);
  755. var
  756. nextdef : tdef;
  757. begin
  758. if not assigned(currdef) then
  759. internalerror(200306185);
  760. { Already handled by derefaktrecordindex }
  761. if currdef=ownerdef then
  762. internalerror(200306188);
  763. { Generate a direct reference to the top parent
  764. class available in the current unit, this is required because
  765. the parent class is maybe not resolved yet and therefor
  766. has the childof value not available yet }
  767. while (currdef<>ownerdef) do
  768. begin
  769. nextdef:=currdef.getparentdef;
  770. { objects are only allowed in globalsymtable,staticsymtable }
  771. if not(nextdef.owner.symtabletype in [globalsymtable,staticsymtable]) then
  772. internalerror(200306187);
  773. { Next parent is in a different unit, then stop }
  774. if not(nextdef.owner.iscurrentunit) then
  775. break;
  776. currdef:=nextdef;
  777. end;
  778. { Add reference where to start the parent lookup }
  779. if currdef=aktrecordsymtable.defowner then
  780. begin
  781. data[len]:=ord(deref_aktrecord);
  782. inc(len);
  783. end
  784. else
  785. begin
  786. if currdef.owner.symtabletype=globalsymtable then
  787. data[len]:=ord(deref_aktglobal)
  788. else
  789. data[len]:=ord(deref_aktstatic);
  790. data[len+1]:=ord(deref_def);
  791. data[len+2]:=currdef.indexnr shr 8;
  792. data[len+3]:=currdef.indexnr and $ff;
  793. data[len+4]:=ord(deref_record);
  794. inc(len,5);
  795. end;
  796. { When the current found parent in this module is not the owner we
  797. add derefs for the parent classes not available in this unit }
  798. while (currdef<>ownerdef) do
  799. begin
  800. data[len]:=ord(deref_parent_object);
  801. inc(len);
  802. currdef:=currdef.getparentdef;
  803. { It should be valid as it is checked by is_child }
  804. if not assigned(currdef) then
  805. internalerror(200306186);
  806. end;
  807. end;
  808. begin
  809. { skip length byte }
  810. len:=1;
  811. if assigned(s) then
  812. begin
  813. { Static symtable of current unit ? }
  814. if (s.owner.symtabletype=staticsymtable) and
  815. s.owner.iscurrentunit then
  816. begin
  817. data[len]:=ord(deref_aktstatic);
  818. inc(len);
  819. end
  820. { Global symtable of current unit ? }
  821. else if (s.owner.symtabletype=globalsymtable) and
  822. s.owner.iscurrentunit then
  823. begin
  824. data[len]:=ord(deref_aktglobal);
  825. inc(len);
  826. end
  827. { Current record/object symtable ? }
  828. else if (s.owner=aktrecordsymtable) then
  829. begin
  830. data[len]:=ord(deref_aktrecord);
  831. inc(len);
  832. end
  833. { Current local symtable ? }
  834. else if (s.owner=aktlocalsymtable) then
  835. begin
  836. data[len]:=ord(deref_aktlocal);
  837. inc(len);
  838. end
  839. { Current para symtable ? }
  840. else if (s.owner=aktparasymtable) then
  841. begin
  842. data[len]:=ord(deref_aktpara);
  843. inc(len);
  844. end
  845. { Parent class? }
  846. else if assigned(aktrecordsymtable) and
  847. (aktrecordsymtable.symtabletype=objectsymtable) and
  848. (s.owner.symtabletype=objectsymtable) and
  849. is_child(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner)) then
  850. begin
  851. addparentobject(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner));
  852. end
  853. else
  854. { Default, start by building from unit symtable }
  855. begin
  856. addowner(s);
  857. end;
  858. { Add index of the symbol/def }
  859. if s is tsym then
  860. data[len]:=ord(deref_sym)
  861. else
  862. data[len]:=ord(deref_def);
  863. data[len+1]:=s.indexnr shr 8;
  864. data[len+2]:=s.indexnr and $ff;
  865. inc(len,3);
  866. end
  867. else
  868. begin
  869. { nil pointer }
  870. data[len]:=0;
  871. inc(len);
  872. end;
  873. { store data length in first byte }
  874. data[0]:=len-1;
  875. { store index and write to derefdata }
  876. dataidx:=current_module.derefdata.size;
  877. current_module.derefdata.write(data,len);
  878. end;
  879. function tderef.resolve:tsymtableentry;
  880. var
  881. pd : tdef;
  882. pm : tmodule;
  883. typ : tdereftype;
  884. st : tsymtable;
  885. idx : word;
  886. i : aint;
  887. len : byte;
  888. data : array[0..255] of byte;
  889. begin
  890. result:=nil;
  891. { not initialized or error }
  892. if dataidx<0 then
  893. internalerror(200306067);
  894. { read data }
  895. current_module.derefdata.seek(dataidx);
  896. if current_module.derefdata.read(len,1)<>1 then
  897. internalerror(200310221);
  898. if len>0 then
  899. begin
  900. if current_module.derefdata.read(data,len)<>len then
  901. internalerror(200310222);
  902. end;
  903. { process data }
  904. st:=nil;
  905. i:=0;
  906. while (i<len) do
  907. begin
  908. typ:=tdereftype(data[i]);
  909. inc(i);
  910. case typ of
  911. deref_nil :
  912. begin
  913. result:=nil;
  914. { Only allowed when no other deref is available }
  915. if len<>1 then
  916. internalerror(200306232);
  917. end;
  918. deref_sym :
  919. begin
  920. if not assigned(st) then
  921. internalerror(200309141);
  922. idx:=(data[i] shl 8) or data[i+1];
  923. inc(i,2);
  924. result:=st.getsymnr(idx);
  925. end;
  926. deref_def :
  927. begin
  928. if not assigned(st) then
  929. internalerror(200309142);
  930. idx:=(data[i] shl 8) or data[i+1];
  931. inc(i,2);
  932. result:=st.getdefnr(idx);
  933. end;
  934. deref_aktrecord :
  935. st:=aktrecordsymtable;
  936. deref_aktstatic :
  937. st:=current_module.localsymtable;
  938. deref_aktglobal :
  939. st:=current_module.globalsymtable;
  940. deref_aktlocal :
  941. st:=aktlocalsymtable;
  942. deref_aktpara :
  943. st:=aktparasymtable;
  944. deref_unit :
  945. begin
  946. idx:=(data[i] shl 8) or data[i+1];
  947. inc(i,2);
  948. pm:=current_module.resolve_unit(idx);
  949. st:=pm.globalsymtable;
  950. end;
  951. deref_local :
  952. begin
  953. if not assigned(result) then
  954. internalerror(200306069);
  955. st:=tdef(result).getsymtable(gs_local);
  956. result:=nil;
  957. if not assigned(st) then
  958. internalerror(200212275);
  959. end;
  960. deref_para :
  961. begin
  962. if not assigned(result) then
  963. internalerror(2003060610);
  964. st:=tdef(result).getsymtable(gs_para);
  965. result:=nil;
  966. if not assigned(st) then
  967. internalerror(200212276);
  968. end;
  969. deref_record :
  970. begin
  971. if not assigned(result) then
  972. internalerror(200306068);
  973. st:=tdef(result).getsymtable(gs_record);
  974. result:=nil;
  975. if not assigned(st) then
  976. internalerror(200212274);
  977. end;
  978. deref_parent_object :
  979. begin
  980. { load current object symtable if no
  981. symtable is available yet }
  982. if st=nil then
  983. begin
  984. st:=aktrecordsymtable;
  985. if not assigned(st) then
  986. internalerror(200306068);
  987. end;
  988. if st.symtabletype<>objectsymtable then
  989. internalerror(200306189);
  990. pd:=tdef(st.defowner).getparentdef;
  991. if not assigned(pd) then
  992. internalerror(200306184);
  993. st:=pd.getsymtable(gs_record);
  994. if not assigned(st) then
  995. internalerror(200212274);
  996. end;
  997. else
  998. internalerror(200212277);
  999. end;
  1000. end;
  1001. end;
  1002. {*****************************************************************************
  1003. TCompilerPPUFile
  1004. *****************************************************************************}
  1005. procedure tcompilerppufile.checkerror;
  1006. begin
  1007. if error then
  1008. Message(unit_f_ppu_read_error);
  1009. end;
  1010. procedure tcompilerppufile.getguid(var g: tguid);
  1011. begin
  1012. getdata(g,sizeof(g));
  1013. end;
  1014. function tcompilerppufile.getexprint:tconstexprint;
  1015. begin
  1016. if sizeof(tconstexprint)=8 then
  1017. result:=tconstexprint(getint64)
  1018. else
  1019. result:=tconstexprint(getlongint);
  1020. end;
  1021. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  1022. begin
  1023. if sizeof(TConstPtrUInt)=8 then
  1024. result:=tconstptruint(getint64)
  1025. else
  1026. result:=TConstPtrUInt(getlongint);
  1027. end;
  1028. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  1029. var
  1030. info : byte;
  1031. begin
  1032. {
  1033. info byte layout in bits:
  1034. 0-1 - amount of bytes for fileindex
  1035. 2-3 - amount of bytes for line
  1036. 4-5 - amount of bytes for column
  1037. }
  1038. info:=getbyte;
  1039. case (info and $03) of
  1040. 0 : p.fileindex:=getbyte;
  1041. 1 : p.fileindex:=getword;
  1042. 2 : p.fileindex:=(getbyte shl 16) or getword;
  1043. 3 : p.fileindex:=getlongint;
  1044. end;
  1045. case ((info shr 2) and $03) of
  1046. 0 : p.line:=getbyte;
  1047. 1 : p.line:=getword;
  1048. 2 : p.line:=(getbyte shl 16) or getword;
  1049. 3 : p.line:=getlongint;
  1050. end;
  1051. case ((info shr 4) and $03) of
  1052. 0 : p.column:=getbyte;
  1053. 1 : p.column:=getword;
  1054. 2 : p.column:=(getbyte shl 16) or getword;
  1055. 3 : p.column:=getlongint;
  1056. end;
  1057. end;
  1058. procedure tcompilerppufile.getderef(var d:tderef);
  1059. begin
  1060. d.dataidx:=getlongint;
  1061. end;
  1062. function tcompilerppufile.getsymlist:tsymlist;
  1063. var
  1064. symderef : tderef;
  1065. tt : ttype;
  1066. slt : tsltype;
  1067. idx : longint;
  1068. p : tsymlist;
  1069. begin
  1070. p:=tsymlist.create;
  1071. getderef(p.procdefderef);
  1072. repeat
  1073. slt:=tsltype(getbyte);
  1074. case slt of
  1075. sl_none :
  1076. break;
  1077. sl_call,
  1078. sl_load,
  1079. sl_subscript :
  1080. begin
  1081. getderef(symderef);
  1082. p.addsymderef(slt,symderef);
  1083. end;
  1084. sl_absolutetype,
  1085. sl_typeconv :
  1086. begin
  1087. gettype(tt);
  1088. p.addtype(slt,tt);
  1089. end;
  1090. sl_vec :
  1091. begin
  1092. idx:=getlongint;
  1093. gettype(tt);
  1094. p.addconst(slt,idx,tt);
  1095. end;
  1096. else
  1097. internalerror(200110204);
  1098. end;
  1099. until false;
  1100. getsymlist:=tsymlist(p);
  1101. end;
  1102. procedure tcompilerppufile.gettype(var t:ttype);
  1103. begin
  1104. getderef(t.deref);
  1105. t.def:=nil;
  1106. t.sym:=nil;
  1107. end;
  1108. function tcompilerppufile.getasmsymbol:tasmsymbol;
  1109. begin
  1110. getasmsymbol:=tasmsymbol(pointer(ptrint(getlongint)));
  1111. end;
  1112. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  1113. var
  1114. oldcrc : boolean;
  1115. info : byte;
  1116. begin
  1117. { posinfo is not relevant for changes in PPU }
  1118. oldcrc:=do_crc;
  1119. do_crc:=false;
  1120. {
  1121. info byte layout in bits:
  1122. 0-1 - amount of bytes for fileindex
  1123. 2-3 - amount of bytes for line
  1124. 4-5 - amount of bytes for column
  1125. }
  1126. info:=0;
  1127. { calculate info byte }
  1128. if (p.fileindex>$ff) then
  1129. begin
  1130. if (p.fileindex<=$ffff) then
  1131. info:=info or $1
  1132. else
  1133. if (p.fileindex<=$ffffff) then
  1134. info:=info or $2
  1135. else
  1136. info:=info or $3;
  1137. end;
  1138. if (p.line>$ff) then
  1139. begin
  1140. if (p.line<=$ffff) then
  1141. info:=info or $4
  1142. else
  1143. if (p.line<=$ffffff) then
  1144. info:=info or $8
  1145. else
  1146. info:=info or $c;
  1147. end;
  1148. if (p.column>$ff) then
  1149. begin
  1150. if (p.column<=$ffff) then
  1151. info:=info or $10
  1152. else
  1153. if (p.column<=$ffffff) then
  1154. info:=info or $20
  1155. else
  1156. info:=info or $30;
  1157. end;
  1158. { write data }
  1159. putbyte(info);
  1160. case (info and $03) of
  1161. 0 : putbyte(p.fileindex);
  1162. 1 : putword(p.fileindex);
  1163. 2 : begin
  1164. putbyte(p.fileindex shr 16);
  1165. putword(p.fileindex and $ffff);
  1166. end;
  1167. 3 : putlongint(p.fileindex);
  1168. end;
  1169. case ((info shr 2) and $03) of
  1170. 0 : putbyte(p.line);
  1171. 1 : putword(p.line);
  1172. 2 : begin
  1173. putbyte(p.line shr 16);
  1174. putword(p.line and $ffff);
  1175. end;
  1176. 3 : putlongint(p.line);
  1177. end;
  1178. case ((info shr 4) and $03) of
  1179. 0 : putbyte(p.column);
  1180. 1 : putword(p.column);
  1181. 2 : begin
  1182. putbyte(p.column shr 16);
  1183. putword(p.column and $ffff);
  1184. end;
  1185. 3 : putlongint(p.column);
  1186. end;
  1187. do_crc:=oldcrc;
  1188. end;
  1189. procedure tcompilerppufile.putguid(const g: tguid);
  1190. begin
  1191. putdata(g,sizeof(g));
  1192. end;
  1193. procedure tcompilerppufile.putexprint(v:tconstexprint);
  1194. begin
  1195. if sizeof(TConstExprInt)=8 then
  1196. putint64(int64(v))
  1197. else if sizeof(TConstExprInt)=4 then
  1198. putlongint(longint(v))
  1199. else
  1200. internalerror(2002082601);
  1201. end;
  1202. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  1203. begin
  1204. if sizeof(TConstPtrUInt)=8 then
  1205. putint64(int64(v))
  1206. else if sizeof(TConstPtrUInt)=4 then
  1207. putlongint(longint(v))
  1208. else
  1209. internalerror(2002082601);
  1210. end;
  1211. procedure tcompilerppufile.putderef(const d:tderef);
  1212. var
  1213. oldcrc : boolean;
  1214. begin
  1215. oldcrc:=do_crc;
  1216. do_crc:=false;
  1217. putlongint(d.dataidx);
  1218. do_crc:=oldcrc;
  1219. end;
  1220. procedure tcompilerppufile.putsymlist(p:tsymlist);
  1221. var
  1222. hp : psymlistitem;
  1223. begin
  1224. putderef(p.procdefderef);
  1225. hp:=p.firstsym;
  1226. while assigned(hp) do
  1227. begin
  1228. putbyte(byte(hp^.sltype));
  1229. case hp^.sltype of
  1230. sl_call,
  1231. sl_load,
  1232. sl_subscript :
  1233. putderef(hp^.symderef);
  1234. sl_absolutetype,
  1235. sl_typeconv :
  1236. puttype(hp^.tt);
  1237. sl_vec :
  1238. begin
  1239. putlongint(hp^.value);
  1240. puttype(hp^.valuett);
  1241. end;
  1242. else
  1243. internalerror(200110205);
  1244. end;
  1245. hp:=hp^.next;
  1246. end;
  1247. putbyte(byte(sl_none));
  1248. end;
  1249. procedure tcompilerppufile.puttype(const t:ttype);
  1250. begin
  1251. putderef(t.deref);
  1252. end;
  1253. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  1254. begin
  1255. if assigned(s) then
  1256. begin
  1257. if s.ppuidx=-1 then
  1258. begin
  1259. inc(objectlibrary.asmsymbolppuidx);
  1260. s.ppuidx:=objectlibrary.asmsymbolppuidx;
  1261. end;
  1262. putlongint(s.ppuidx);
  1263. end
  1264. else
  1265. putlongint(0);
  1266. end;
  1267. {$ifdef MEMDEBUG}
  1268. initialization
  1269. membrowser:=TMemDebug.create('BrowserRefs');
  1270. membrowser.stop;
  1271. memrealnames:=TMemDebug.create('Realnames');
  1272. memrealnames.stop;
  1273. memmanglednames:=TMemDebug.create('Manglednames');
  1274. memmanglednames.stop;
  1275. memprocpara:=TMemDebug.create('ProcPara');
  1276. memprocpara.stop;
  1277. memprocparast:=TMemDebug.create('ProcParaSt');
  1278. memprocparast.stop;
  1279. memproclocalst:=TMemDebug.create('ProcLocalSt');
  1280. memproclocalst.stop;
  1281. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  1282. memprocnodetree.stop;
  1283. finalization
  1284. membrowser.free;
  1285. memrealnames.free;
  1286. memmanglednames.free;
  1287. memprocpara.free;
  1288. memprocparast.free;
  1289. memproclocalst.free;
  1290. memprocnodetree.free;
  1291. {$endif MEMDEBUG}
  1292. end.