symtype.pas 41 KB

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