symtype.pas 41 KB

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