2
0

symtype.pas 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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 : tasmsymbol;
  60. { stabs debugging }
  61. stab_number : word;
  62. dbg_state : tdefdbgstatus;
  63. defoptions : tdefoptions;
  64. constructor create(dt:tdeftype);
  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 packedbitsize:aint;virtual;
  75. function alignment:shortint;virtual;abstract;
  76. function getvartype:longint;virtual;abstract;
  77. function getparentdef:tdef;virtual;
  78. function getsymtable(t:tgetsymtable):tsymtable;virtual;
  79. function is_publishable:boolean;virtual;abstract;
  80. function needs_inittable:boolean;virtual;abstract;
  81. function is_related(def:tdef):boolean;virtual;
  82. end;
  83. {************************************************
  84. TSym
  85. ************************************************}
  86. { this object is the base for all symbol objects }
  87. tsym = class(tsymentry)
  88. protected
  89. public
  90. _realname : pstring;
  91. fileinfo : tfileposinfo;
  92. symoptions : tsymoptions;
  93. refs : longint;
  94. lastref,
  95. defref,
  96. lastwritten : tref;
  97. refcount : longint;
  98. isdbgwritten : boolean;
  99. constructor create(st:tsymtyp;const n : string);
  100. destructor destroy;override;
  101. function realname:string;
  102. function mangledname:string; virtual;
  103. procedure buildderef;virtual;
  104. procedure deref;virtual;
  105. function gettypedef:tdef;virtual;
  106. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  107. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  108. { currobjdef is the object def to assume, this is necessary for protected and
  109. private,
  110. context is the object def we're really in, this is for the strict stuff
  111. }
  112. function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
  113. end;
  114. tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
  115. psymarr = ^tsymarr;
  116. {************************************************
  117. TDeref
  118. ************************************************}
  119. tderef = object
  120. dataidx : longint;
  121. procedure reset;
  122. procedure build(s:tsymtableentry);
  123. function resolve:tsymtableentry;
  124. end;
  125. {************************************************
  126. TType
  127. ************************************************}
  128. ttype = object
  129. def : tdef;
  130. sym : tsym;
  131. deref : tderef;
  132. procedure reset;
  133. procedure setdef(p:tdef);
  134. procedure setsym(p:tsym);
  135. procedure resolve;
  136. procedure buildderef;
  137. end;
  138. {************************************************
  139. tpropaccesslist
  140. ************************************************}
  141. ppropaccesslistitem = ^tpropaccesslistitem;
  142. tpropaccesslistitem = record
  143. sltype : tsltype;
  144. next : ppropaccesslistitem;
  145. case byte of
  146. 0 : (sym : tsym; symderef : tderef);
  147. 1 : (value : TConstExprInt; valuett: ttype);
  148. 2 : (tt : ttype);
  149. end;
  150. tpropaccesslist = class
  151. procdef : tdef;
  152. procdefderef : tderef;
  153. firstsym,
  154. lastsym : ppropaccesslistitem;
  155. constructor create;
  156. destructor destroy;override;
  157. function empty:boolean;
  158. procedure addsym(slt:tsltype;p:tsym);
  159. procedure addsymderef(slt:tsltype;const d:tderef);
  160. procedure addconst(slt:tsltype;v:TConstExprInt;const tt:ttype);
  161. procedure addtype(slt:tsltype;const tt:ttype);
  162. procedure clear;
  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 getpropaccesslist:tpropaccesslist;
  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 putpropaccesslist(p:tpropaccesslist);
  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,symtable
  205. ;
  206. {****************************************************************************
  207. Tdef
  208. ****************************************************************************}
  209. constructor tdef.create(dt:tdeftype);
  210. begin
  211. inherited create;
  212. deftype:=dt;
  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. function tdef.packedbitsize:aint;
  257. begin
  258. result:=size * 8;
  259. end;
  260. {****************************************************************************
  261. TSYM (base for all symtypes)
  262. ****************************************************************************}
  263. constructor tsym.create(st:tsymtyp;const n : string);
  264. begin
  265. if n[1]='$' then
  266. inherited createname(copy(n,2,255))
  267. else
  268. inherited createname(upper(n));
  269. _realname:=stringdup(n);
  270. typ:=st;
  271. symoptions:=[];
  272. defref:=nil;
  273. refs:=0;
  274. lastwritten:=nil;
  275. refcount:=0;
  276. fileinfo:=akttokenpos;
  277. if (cs_browser in aktmoduleswitches) and make_ref then
  278. begin
  279. defref:=tref.create(defref,@akttokenpos);
  280. inc(refcount);
  281. end;
  282. lastref:=defref;
  283. isdbgwritten := false;
  284. symoptions:=current_object_option;
  285. end;
  286. destructor tsym.destroy;
  287. begin
  288. {$ifdef MEMDEBUG}
  289. memrealnames.start;
  290. {$endif MEMDEBUG}
  291. stringdispose(_realname);
  292. {$ifdef MEMDEBUG}
  293. memrealnames.stop;
  294. {$endif MEMDEBUG}
  295. inherited destroy;
  296. end;
  297. procedure Tsym.buildderef;
  298. begin
  299. end;
  300. procedure Tsym.deref;
  301. begin
  302. end;
  303. function tsym.realname : string;
  304. begin
  305. if assigned(_realname) then
  306. realname:=_realname^
  307. else
  308. realname:=name;
  309. end;
  310. function tsym.mangledname : string;
  311. begin
  312. internalerror(200204171);
  313. result:='';
  314. end;
  315. function tsym.gettypedef:tdef;
  316. begin
  317. gettypedef:=nil;
  318. end;
  319. procedure Tsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  320. var
  321. pos : tfileposinfo;
  322. move_last : boolean;
  323. begin
  324. move_last:=lastwritten=lastref;
  325. while (not ppufile.endofentry) do
  326. begin
  327. ppufile.getposinfo(pos);
  328. inc(refcount);
  329. lastref:=tref.create(lastref,@pos);
  330. lastref.is_written:=true;
  331. if refcount=1 then
  332. defref:=lastref;
  333. end;
  334. if move_last then
  335. lastwritten:=lastref;
  336. end;
  337. { big problem here :
  338. wrong refs were written because of
  339. interface parsing of other units PM
  340. moduleindex must be checked !! }
  341. function Tsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  342. var
  343. d : tderef;
  344. ref : tref;
  345. symref_written,move_last : boolean;
  346. begin
  347. write_references:=false;
  348. if lastwritten=lastref then
  349. exit;
  350. { should we update lastref }
  351. move_last:=true;
  352. symref_written:=false;
  353. { write symbol refs }
  354. d.reset;
  355. if assigned(lastwritten) then
  356. ref:=lastwritten
  357. else
  358. ref:=defref;
  359. while assigned(ref) do
  360. begin
  361. if ref.moduleindex=current_module.unit_index then
  362. begin
  363. { write address to this symbol }
  364. if not symref_written then
  365. begin
  366. d.build(self);
  367. ppufile.putderef(d);
  368. symref_written:=true;
  369. end;
  370. ppufile.putposinfo(ref.posinfo);
  371. ref.is_written:=true;
  372. if move_last then
  373. lastwritten:=ref;
  374. end
  375. else if not ref.is_written then
  376. move_last:=false
  377. else if move_last then
  378. lastwritten:=ref;
  379. ref:=ref.nextref;
  380. end;
  381. if symref_written then
  382. ppufile.writeentry(ibsymref);
  383. write_references:=symref_written;
  384. end;
  385. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  386. begin
  387. is_visible_for_object:=false;
  388. { private symbols are allowed when we are in the same
  389. module as they are defined }
  390. if (sp_private in symoptions) and
  391. assigned(owner.defowner) and
  392. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  393. (not owner.defowner.owner.iscurrentunit) then
  394. exit;
  395. if (sp_strictprivate in symoptions) then
  396. begin
  397. result:=assigned(currobjdef) and
  398. (context=tdef(owner.defowner));
  399. exit;
  400. end;
  401. if (sp_strictprotected in symoptions) then
  402. begin
  403. result:=assigned(context) and
  404. context.is_related(tdef(owner.defowner));
  405. exit;
  406. end;
  407. { protected symbols are visible in the module that defines them and
  408. also visible to related objects }
  409. if (sp_protected in symoptions) and
  410. (
  411. (
  412. assigned(owner.defowner) and
  413. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  414. (not owner.defowner.owner.iscurrentunit)
  415. ) and
  416. not(
  417. assigned(currobjdef) and
  418. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  419. (currobjdef.owner.iscurrentunit) and
  420. currobjdef.is_related(tdef(owner.defowner))
  421. )
  422. ) then
  423. exit;
  424. is_visible_for_object:=true;
  425. end;
  426. {****************************************************************************
  427. TRef
  428. ****************************************************************************}
  429. constructor tref.create(ref :tref;pos : pfileposinfo);
  430. begin
  431. nextref:=nil;
  432. if pos<>nil then
  433. posinfo:=pos^;
  434. if assigned(current_module) then
  435. moduleindex:=current_module.unit_index;
  436. if assigned(ref) then
  437. ref.nextref:=self;
  438. is_written:=false;
  439. end;
  440. procedure tref.freechain;
  441. var
  442. p,q : tref;
  443. begin
  444. p:=nextref;
  445. nextref:=nil;
  446. while assigned(p) do
  447. begin
  448. q:=p.nextref;
  449. p.free;
  450. p:=q;
  451. end;
  452. end;
  453. destructor tref.destroy;
  454. begin
  455. nextref:=nil;
  456. end;
  457. {****************************************************************************
  458. TType
  459. ****************************************************************************}
  460. procedure ttype.reset;
  461. begin
  462. def:=nil;
  463. sym:=nil;
  464. end;
  465. procedure ttype.setdef(p:tdef);
  466. begin
  467. def:=p;
  468. sym:=nil;
  469. end;
  470. procedure ttype.setsym(p:tsym);
  471. begin
  472. sym:=p;
  473. def:=p.gettypedef;
  474. if not assigned(def) then
  475. internalerror(1234005);
  476. end;
  477. procedure ttype.resolve;
  478. var
  479. p : tsymtableentry;
  480. begin
  481. p:=deref.resolve;
  482. if assigned(p) then
  483. begin
  484. if p is tsym then
  485. begin
  486. setsym(tsym(p));
  487. if not assigned(def) then
  488. internalerror(200212272);
  489. end
  490. else
  491. begin
  492. setdef(tdef(p));
  493. end;
  494. end
  495. else
  496. reset;
  497. end;
  498. procedure ttype.buildderef;
  499. begin
  500. { Write symbol references when the symbol is a redefine,
  501. but don't write symbol references for the current unit
  502. and for the system unit }
  503. if assigned(sym) and
  504. (
  505. (sym<>def.typesym) or
  506. (
  507. not((sym.owner.symtabletype in [globalsymtable,staticsymtable]) and
  508. sym.owner.iscurrentunit)
  509. )
  510. ) then
  511. deref.build(sym)
  512. else
  513. deref.build(def);
  514. end;
  515. {****************************************************************************
  516. tpropaccesslist
  517. ****************************************************************************}
  518. constructor tpropaccesslist.create;
  519. begin
  520. procdef:=nil; { needed for procedures }
  521. firstsym:=nil;
  522. lastsym:=nil;
  523. end;
  524. destructor tpropaccesslist.destroy;
  525. begin
  526. clear;
  527. end;
  528. function tpropaccesslist.empty:boolean;
  529. begin
  530. empty:=(firstsym=nil);
  531. end;
  532. procedure tpropaccesslist.clear;
  533. var
  534. hp : ppropaccesslistitem;
  535. begin
  536. while assigned(firstsym) do
  537. begin
  538. hp:=firstsym;
  539. firstsym:=firstsym^.next;
  540. dispose(hp);
  541. end;
  542. firstsym:=nil;
  543. lastsym:=nil;
  544. procdef:=nil;
  545. end;
  546. procedure tpropaccesslist.addsym(slt:tsltype;p:tsym);
  547. var
  548. hp : ppropaccesslistitem;
  549. begin
  550. if not assigned(p) then
  551. internalerror(200110203);
  552. new(hp);
  553. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  554. hp^.sltype:=slt;
  555. hp^.sym:=p;
  556. hp^.symderef.reset;
  557. if assigned(lastsym) then
  558. lastsym^.next:=hp
  559. else
  560. firstsym:=hp;
  561. lastsym:=hp;
  562. end;
  563. procedure tpropaccesslist.addsymderef(slt:tsltype;const d:tderef);
  564. var
  565. hp : ppropaccesslistitem;
  566. begin
  567. new(hp);
  568. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  569. hp^.sltype:=slt;
  570. hp^.symderef:=d;
  571. if assigned(lastsym) then
  572. lastsym^.next:=hp
  573. else
  574. firstsym:=hp;
  575. lastsym:=hp;
  576. end;
  577. procedure tpropaccesslist.addconst(slt:tsltype;v:TConstExprInt;const tt:ttype);
  578. var
  579. hp : ppropaccesslistitem;
  580. begin
  581. new(hp);
  582. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  583. hp^.sltype:=slt;
  584. hp^.value:=v;
  585. hp^.valuett:=tt;
  586. if assigned(lastsym) then
  587. lastsym^.next:=hp
  588. else
  589. firstsym:=hp;
  590. lastsym:=hp;
  591. end;
  592. procedure tpropaccesslist.addtype(slt:tsltype;const tt:ttype);
  593. var
  594. hp : ppropaccesslistitem;
  595. begin
  596. new(hp);
  597. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  598. hp^.sltype:=slt;
  599. hp^.tt:=tt;
  600. if assigned(lastsym) then
  601. lastsym^.next:=hp
  602. else
  603. firstsym:=hp;
  604. lastsym:=hp;
  605. end;
  606. procedure tpropaccesslist.resolve;
  607. var
  608. hp : ppropaccesslistitem;
  609. begin
  610. procdef:=tdef(procdefderef.resolve);
  611. hp:=firstsym;
  612. while assigned(hp) do
  613. begin
  614. case hp^.sltype of
  615. sl_call,
  616. sl_load,
  617. sl_subscript :
  618. hp^.sym:=tsym(hp^.symderef.resolve);
  619. sl_absolutetype,
  620. sl_typeconv :
  621. hp^.tt.resolve;
  622. sl_vec:
  623. hp^.valuett.resolve;
  624. else
  625. internalerror(200110205);
  626. end;
  627. hp:=hp^.next;
  628. end;
  629. end;
  630. procedure tpropaccesslist.buildderef;
  631. var
  632. hp : ppropaccesslistitem;
  633. begin
  634. procdefderef.build(procdef);
  635. hp:=firstsym;
  636. while assigned(hp) do
  637. begin
  638. case hp^.sltype of
  639. sl_call,
  640. sl_load,
  641. sl_subscript :
  642. hp^.symderef.build(hp^.sym);
  643. sl_absolutetype,
  644. sl_typeconv :
  645. hp^.tt.buildderef;
  646. sl_vec:
  647. hp^.valuett.buildderef;
  648. else
  649. internalerror(200110205);
  650. end;
  651. hp:=hp^.next;
  652. end;
  653. end;
  654. {****************************************************************************
  655. Tderef
  656. ****************************************************************************}
  657. procedure tderef.reset;
  658. begin
  659. dataidx:=-1;
  660. end;
  661. procedure tderef.build(s:tsymtableentry);
  662. var
  663. len : byte;
  664. st : tsymtable;
  665. data : array[0..255] of byte;
  666. idx : word;
  667. begin
  668. { skip length byte }
  669. len:=1;
  670. if assigned(s) then
  671. begin
  672. st:=findunitsymtable(s.owner);
  673. if not st.iscurrentunit then
  674. begin
  675. { register that the unit is needed for resolving }
  676. data[len]:=ord(deref_unit);
  677. idx:=current_module.derefidx_unit(st.moduleid);
  678. data[len+1]:=idx shr 8 and $ff;
  679. data[len+2]:=idx and $ff;
  680. inc(len,3);
  681. end;
  682. if s is tsym then
  683. begin
  684. data[len]:=ord(deref_symid);
  685. data[len+1]:=tsym(s).symid shr 24 and $ff;
  686. data[len+2]:=tsym(s).symid shr 16 and $ff;
  687. data[len+3]:=tsym(s).symid shr 8 and $ff;
  688. data[len+4]:=tsym(s).symid and $ff;
  689. inc(len,5);
  690. end
  691. else
  692. begin
  693. data[len]:=ord(deref_defid);
  694. data[len+1]:=tdef(s).defid shr 24 and $ff;
  695. data[len+2]:=tdef(s).defid shr 16 and $ff;
  696. data[len+3]:=tdef(s).defid shr 8 and $ff;
  697. data[len+4]:=tdef(s).defid and $ff;
  698. inc(len,5);
  699. end;
  700. end
  701. else
  702. begin
  703. { nil pointer }
  704. data[len]:=ord(deref_nil);
  705. inc(len);
  706. end;
  707. { store data length in first byte }
  708. data[0]:=len-1;
  709. { store index and write to derefdata }
  710. dataidx:=current_module.derefdata.size;
  711. current_module.derefdata.write(data,len);
  712. end;
  713. function tderef.resolve:tsymtableentry;
  714. var
  715. pm : tmodule;
  716. typ : tdereftype;
  717. idx : word;
  718. i : aint;
  719. len : byte;
  720. data : array[0..255] of byte;
  721. begin
  722. result:=nil;
  723. { not initialized or error }
  724. if dataidx<0 then
  725. internalerror(200306067);
  726. { read data }
  727. current_module.derefdata.seek(dataidx);
  728. if current_module.derefdata.read(len,1)<>1 then
  729. internalerror(200310221);
  730. if len>0 then
  731. begin
  732. if current_module.derefdata.read(data,len)<>len then
  733. internalerror(200310222);
  734. end;
  735. { process data }
  736. pm:=current_module;
  737. i:=0;
  738. while (i<len) do
  739. begin
  740. typ:=tdereftype(data[i]);
  741. inc(i);
  742. case typ of
  743. deref_unit :
  744. begin
  745. idx:=(data[i] shl 8) or data[i+1];
  746. inc(i,2);
  747. pm:=current_module.resolve_unit(idx);
  748. end;
  749. deref_defid :
  750. begin
  751. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  752. inc(i,4);
  753. result:=tdef(pm.deflist[idx]);
  754. end;
  755. deref_symid :
  756. begin
  757. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  758. inc(i,4);
  759. result:=tsym(pm.symlist[idx]);
  760. end;
  761. deref_nil :
  762. begin
  763. result:=nil;
  764. { Only allowed when no other deref is available }
  765. if len<>1 then
  766. internalerror(200306232);
  767. end;
  768. else
  769. internalerror(200212277);
  770. end;
  771. end;
  772. end;
  773. {*****************************************************************************
  774. TCompilerPPUFile
  775. *****************************************************************************}
  776. procedure tcompilerppufile.checkerror;
  777. begin
  778. if error then
  779. Message(unit_f_ppu_read_error);
  780. end;
  781. procedure tcompilerppufile.getguid(var g: tguid);
  782. begin
  783. getdata(g,sizeof(g));
  784. end;
  785. function tcompilerppufile.getexprint:tconstexprint;
  786. begin
  787. if sizeof(tconstexprint)=8 then
  788. result:=tconstexprint(getint64)
  789. else
  790. result:=tconstexprint(getlongint);
  791. end;
  792. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  793. begin
  794. if sizeof(TConstPtrUInt)=8 then
  795. result:=tconstptruint(getint64)
  796. else
  797. result:=TConstPtrUInt(getlongint);
  798. end;
  799. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  800. var
  801. info : byte;
  802. begin
  803. {
  804. info byte layout in bits:
  805. 0-1 - amount of bytes for fileindex
  806. 2-3 - amount of bytes for line
  807. 4-5 - amount of bytes for column
  808. }
  809. info:=getbyte;
  810. case (info and $03) of
  811. 0 : p.fileindex:=getbyte;
  812. 1 : p.fileindex:=getword;
  813. 2 : p.fileindex:=(getbyte shl 16) or getword;
  814. 3 : p.fileindex:=getlongint;
  815. end;
  816. case ((info shr 2) and $03) of
  817. 0 : p.line:=getbyte;
  818. 1 : p.line:=getword;
  819. 2 : p.line:=(getbyte shl 16) or getword;
  820. 3 : p.line:=getlongint;
  821. end;
  822. case ((info shr 4) and $03) of
  823. 0 : p.column:=getbyte;
  824. 1 : p.column:=getword;
  825. 2 : p.column:=(getbyte shl 16) or getword;
  826. 3 : p.column:=getlongint;
  827. end;
  828. end;
  829. procedure tcompilerppufile.getderef(var d:tderef);
  830. begin
  831. d.dataidx:=getlongint;
  832. end;
  833. function tcompilerppufile.getpropaccesslist:tpropaccesslist;
  834. var
  835. symderef : tderef;
  836. tt : ttype;
  837. slt : tsltype;
  838. idx : longint;
  839. p : tpropaccesslist;
  840. begin
  841. p:=tpropaccesslist.create;
  842. getderef(p.procdefderef);
  843. repeat
  844. slt:=tsltype(getbyte);
  845. case slt of
  846. sl_none :
  847. break;
  848. sl_call,
  849. sl_load,
  850. sl_subscript :
  851. begin
  852. getderef(symderef);
  853. p.addsymderef(slt,symderef);
  854. end;
  855. sl_absolutetype,
  856. sl_typeconv :
  857. begin
  858. gettype(tt);
  859. p.addtype(slt,tt);
  860. end;
  861. sl_vec :
  862. begin
  863. idx:=getlongint;
  864. gettype(tt);
  865. p.addconst(slt,idx,tt);
  866. end;
  867. else
  868. internalerror(200110204);
  869. end;
  870. until false;
  871. getpropaccesslist:=tpropaccesslist(p);
  872. end;
  873. procedure tcompilerppufile.gettype(var t:ttype);
  874. begin
  875. getderef(t.deref);
  876. t.def:=nil;
  877. t.sym:=nil;
  878. end;
  879. function tcompilerppufile.getasmsymbol:tasmsymbol;
  880. begin
  881. getlongint;
  882. getasmsymbol:=nil;
  883. end;
  884. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  885. var
  886. oldcrc : boolean;
  887. info : byte;
  888. begin
  889. { posinfo is not relevant for changes in PPU }
  890. oldcrc:=do_crc;
  891. do_crc:=false;
  892. {
  893. info byte layout in bits:
  894. 0-1 - amount of bytes for fileindex
  895. 2-3 - amount of bytes for line
  896. 4-5 - amount of bytes for column
  897. }
  898. info:=0;
  899. { calculate info byte }
  900. if (p.fileindex>$ff) then
  901. begin
  902. if (p.fileindex<=$ffff) then
  903. info:=info or $1
  904. else
  905. if (p.fileindex<=$ffffff) then
  906. info:=info or $2
  907. else
  908. info:=info or $3;
  909. end;
  910. if (p.line>$ff) then
  911. begin
  912. if (p.line<=$ffff) then
  913. info:=info or $4
  914. else
  915. if (p.line<=$ffffff) then
  916. info:=info or $8
  917. else
  918. info:=info or $c;
  919. end;
  920. if (p.column>$ff) then
  921. begin
  922. if (p.column<=$ffff) then
  923. info:=info or $10
  924. else
  925. if (p.column<=$ffffff) then
  926. info:=info or $20
  927. else
  928. info:=info or $30;
  929. end;
  930. { write data }
  931. putbyte(info);
  932. case (info and $03) of
  933. 0 : putbyte(p.fileindex);
  934. 1 : putword(p.fileindex);
  935. 2 : begin
  936. putbyte(p.fileindex shr 16);
  937. putword(p.fileindex and $ffff);
  938. end;
  939. 3 : putlongint(p.fileindex);
  940. end;
  941. case ((info shr 2) and $03) of
  942. 0 : putbyte(p.line);
  943. 1 : putword(p.line);
  944. 2 : begin
  945. putbyte(p.line shr 16);
  946. putword(p.line and $ffff);
  947. end;
  948. 3 : putlongint(p.line);
  949. end;
  950. case ((info shr 4) and $03) of
  951. 0 : putbyte(p.column);
  952. 1 : putword(p.column);
  953. 2 : begin
  954. putbyte(p.column shr 16);
  955. putword(p.column and $ffff);
  956. end;
  957. 3 : putlongint(p.column);
  958. end;
  959. do_crc:=oldcrc;
  960. end;
  961. procedure tcompilerppufile.putguid(const g: tguid);
  962. begin
  963. putdata(g,sizeof(g));
  964. end;
  965. procedure tcompilerppufile.putexprint(v:tconstexprint);
  966. begin
  967. if sizeof(TConstExprInt)=8 then
  968. putint64(int64(v))
  969. else if sizeof(TConstExprInt)=4 then
  970. putlongint(longint(v))
  971. else
  972. internalerror(2002082601);
  973. end;
  974. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  975. begin
  976. if sizeof(TConstPtrUInt)=8 then
  977. putint64(int64(v))
  978. else if sizeof(TConstPtrUInt)=4 then
  979. putlongint(longint(v))
  980. else
  981. internalerror(2002082601);
  982. end;
  983. procedure tcompilerppufile.putderef(const d:tderef);
  984. var
  985. oldcrc : boolean;
  986. begin
  987. oldcrc:=do_crc;
  988. do_crc:=false;
  989. putlongint(d.dataidx);
  990. do_crc:=oldcrc;
  991. end;
  992. procedure tcompilerppufile.putpropaccesslist(p:tpropaccesslist);
  993. var
  994. hp : ppropaccesslistitem;
  995. begin
  996. putderef(p.procdefderef);
  997. hp:=p.firstsym;
  998. while assigned(hp) do
  999. begin
  1000. putbyte(byte(hp^.sltype));
  1001. case hp^.sltype of
  1002. sl_call,
  1003. sl_load,
  1004. sl_subscript :
  1005. putderef(hp^.symderef);
  1006. sl_absolutetype,
  1007. sl_typeconv :
  1008. puttype(hp^.tt);
  1009. sl_vec :
  1010. begin
  1011. putlongint(hp^.value);
  1012. puttype(hp^.valuett);
  1013. end;
  1014. else
  1015. internalerror(200110205);
  1016. end;
  1017. hp:=hp^.next;
  1018. end;
  1019. putbyte(byte(sl_none));
  1020. end;
  1021. procedure tcompilerppufile.puttype(const t:ttype);
  1022. begin
  1023. putderef(t.deref);
  1024. end;
  1025. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  1026. begin
  1027. putlongint(0);
  1028. end;
  1029. {$ifdef MEMDEBUG}
  1030. initialization
  1031. membrowser:=TMemDebug.create('BrowserRefs');
  1032. membrowser.stop;
  1033. memrealnames:=TMemDebug.create('Realnames');
  1034. memrealnames.stop;
  1035. memmanglednames:=TMemDebug.create('Manglednames');
  1036. memmanglednames.stop;
  1037. memprocpara:=TMemDebug.create('ProcPara');
  1038. memprocpara.stop;
  1039. memprocparast:=TMemDebug.create('ProcParaSt');
  1040. memprocparast.stop;
  1041. memproclocalst:=TMemDebug.create('ProcLocalSt');
  1042. memproclocalst.stop;
  1043. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  1044. memprocnodetree.stop;
  1045. finalization
  1046. membrowser.free;
  1047. memrealnames.free;
  1048. memmanglednames.free;
  1049. memprocpara.free;
  1050. memprocparast.free;
  1051. memproclocalst.free;
  1052. memprocnodetree.free;
  1053. {$endif MEMDEBUG}
  1054. end.