symtype.pas 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  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 getvardef: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 getderefdef: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. tpropaccesslist
  127. ************************************************}
  128. ppropaccesslistitem = ^tpropaccesslistitem;
  129. tpropaccesslistitem = record
  130. sltype : tsltype;
  131. next : ppropaccesslistitem;
  132. case byte of
  133. 0 : (sym : tsym; symderef : tderef);
  134. 1 : (value : TConstExprInt; valuedef: tdef; valuedefderef:tderef);
  135. 2 : (def: tdef; defderef:tderef);
  136. end;
  137. tpropaccesslist = class
  138. procdef : tdef;
  139. procdefderef : tderef;
  140. firstsym,
  141. lastsym : ppropaccesslistitem;
  142. constructor create;
  143. destructor destroy;override;
  144. function empty:boolean;
  145. procedure addsym(slt:tsltype;p:tsym);
  146. procedure addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  147. procedure addtype(slt:tsltype;d:tdef);
  148. procedure addsymderef(slt:tsltype;d:tderef);
  149. procedure addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  150. procedure addtypederef(slt:tsltype;d:tderef);
  151. procedure clear;
  152. procedure resolve;
  153. procedure buildderef;
  154. end;
  155. {************************************************
  156. Tcompilerppufile
  157. ************************************************}
  158. tcompilerppufile=class(tppufile)
  159. public
  160. procedure checkerror;
  161. procedure getguid(var g: tguid);
  162. function getexprint:tconstexprint;
  163. function getptruint:TConstPtrUInt;
  164. procedure getposinfo(var p:tfileposinfo);
  165. procedure getderef(var d:tderef);
  166. function getpropaccesslist:tpropaccesslist;
  167. function getasmsymbol:tasmsymbol;
  168. procedure putguid(const g: tguid);
  169. procedure putexprint(v:tconstexprint);
  170. procedure PutPtrUInt(v:TConstPtrUInt);
  171. procedure putposinfo(const p:tfileposinfo);
  172. procedure putderef(const d:tderef);
  173. procedure putpropaccesslist(p:tpropaccesslist);
  174. procedure putasmsymbol(s:tasmsymbol);
  175. end;
  176. {$ifdef MEMDEBUG}
  177. var
  178. membrowser,
  179. memrealnames,
  180. memmanglednames,
  181. memprocpara,
  182. memprocparast,
  183. memproclocalst,
  184. memprocnodetree : tmemdebug;
  185. {$endif MEMDEBUG}
  186. const
  187. current_object_option : tsymoptions = [sp_public];
  188. implementation
  189. uses
  190. verbose,
  191. fmodule,symtable
  192. ;
  193. {****************************************************************************
  194. Tdef
  195. ****************************************************************************}
  196. constructor tdef.create(dt:tdeftype);
  197. begin
  198. inherited create;
  199. deftype:=dt;
  200. owner := nil;
  201. typesym := nil;
  202. defoptions:=[];
  203. dbg_state:=dbg_state_unused;
  204. stab_number:=0;
  205. end;
  206. function tdef.typename:string;
  207. begin
  208. if assigned(typesym) and
  209. not(deftype in [procvardef,procdef]) and
  210. assigned(typesym._realname) and
  211. (typesym._realname^[1]<>'$') then
  212. typename:=typesym._realname^
  213. else
  214. typename:=GetTypeName;
  215. end;
  216. function tdef.GetTypeName : string;
  217. begin
  218. GetTypeName:='<unknown type>'
  219. end;
  220. function tdef.mangledparaname:string;
  221. begin
  222. if assigned(typesym) then
  223. mangledparaname:=typesym.name
  224. else
  225. mangledparaname:=getmangledparaname;
  226. end;
  227. function tdef.getmangledparaname:string;
  228. begin
  229. result:='<unknown type>';
  230. end;
  231. function tdef.getparentdef:tdef;
  232. begin
  233. result:=nil;
  234. end;
  235. function tdef.getsymtable(t:tgetsymtable):tsymtable;
  236. begin
  237. result:=nil;
  238. end;
  239. function tdef.is_related(def:tdef):boolean;
  240. begin
  241. result:=false;
  242. end;
  243. function tdef.packedbitsize:aint;
  244. begin
  245. result:=size * 8;
  246. end;
  247. {****************************************************************************
  248. TSYM (base for all symtypes)
  249. ****************************************************************************}
  250. constructor tsym.create(st:tsymtyp;const n : string);
  251. begin
  252. if n[1]='$' then
  253. inherited createname(copy(n,2,255))
  254. else
  255. inherited createname(upper(n));
  256. _realname:=stringdup(n);
  257. typ:=st;
  258. symoptions:=[];
  259. defref:=nil;
  260. refs:=0;
  261. lastwritten:=nil;
  262. refcount:=0;
  263. fileinfo:=current_tokenpos;
  264. if (cs_browser in current_settings.moduleswitches) and make_ref then
  265. begin
  266. defref:=tref.create(defref,@current_tokenpos);
  267. inc(refcount);
  268. end;
  269. lastref:=defref;
  270. isdbgwritten := false;
  271. symoptions:=current_object_option;
  272. end;
  273. destructor tsym.destroy;
  274. begin
  275. {$ifdef MEMDEBUG}
  276. memrealnames.start;
  277. {$endif MEMDEBUG}
  278. stringdispose(_realname);
  279. {$ifdef MEMDEBUG}
  280. memrealnames.stop;
  281. {$endif MEMDEBUG}
  282. inherited destroy;
  283. end;
  284. procedure Tsym.buildderef;
  285. begin
  286. end;
  287. procedure Tsym.deref;
  288. begin
  289. end;
  290. function tsym.realname : string;
  291. begin
  292. if assigned(_realname) then
  293. realname:=_realname^
  294. else
  295. realname:=name;
  296. end;
  297. function tsym.mangledname : string;
  298. begin
  299. internalerror(200204171);
  300. result:='';
  301. end;
  302. function tsym.getderefdef:tdef;
  303. begin
  304. getderefdef:=nil;
  305. end;
  306. procedure Tsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  307. var
  308. pos : tfileposinfo;
  309. move_last : boolean;
  310. begin
  311. move_last:=lastwritten=lastref;
  312. while (not ppufile.endofentry) do
  313. begin
  314. ppufile.getposinfo(pos);
  315. inc(refcount);
  316. lastref:=tref.create(lastref,@pos);
  317. lastref.is_written:=true;
  318. if refcount=1 then
  319. defref:=lastref;
  320. end;
  321. if move_last then
  322. lastwritten:=lastref;
  323. end;
  324. { big problem here :
  325. wrong refs were written because of
  326. interface parsing of other units PM
  327. moduleindex must be checked !! }
  328. function Tsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  329. var
  330. d : tderef;
  331. ref : tref;
  332. symref_written,move_last : boolean;
  333. begin
  334. write_references:=false;
  335. if lastwritten=lastref then
  336. exit;
  337. { should we update lastref }
  338. move_last:=true;
  339. symref_written:=false;
  340. { write symbol refs }
  341. d.reset;
  342. if assigned(lastwritten) then
  343. ref:=lastwritten
  344. else
  345. ref:=defref;
  346. while assigned(ref) do
  347. begin
  348. if ref.moduleindex=current_module.unit_index then
  349. begin
  350. { write address to this symbol }
  351. if not symref_written then
  352. begin
  353. d.build(self);
  354. ppufile.putderef(d);
  355. symref_written:=true;
  356. end;
  357. ppufile.putposinfo(ref.posinfo);
  358. ref.is_written:=true;
  359. if move_last then
  360. lastwritten:=ref;
  361. end
  362. else if not ref.is_written then
  363. move_last:=false
  364. else if move_last then
  365. lastwritten:=ref;
  366. ref:=ref.nextref;
  367. end;
  368. if symref_written then
  369. ppufile.writeentry(ibsymref);
  370. write_references:=symref_written;
  371. end;
  372. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  373. begin
  374. is_visible_for_object:=false;
  375. { private symbols are allowed when we are in the same
  376. module as they are defined }
  377. if (sp_private in symoptions) and
  378. assigned(owner.defowner) and
  379. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  380. (not owner.defowner.owner.iscurrentunit) then
  381. exit;
  382. if (sp_strictprivate in symoptions) then
  383. begin
  384. result:=assigned(currobjdef) and
  385. (context=tdef(owner.defowner));
  386. exit;
  387. end;
  388. if (sp_strictprotected in symoptions) then
  389. begin
  390. result:=assigned(context) and
  391. context.is_related(tdef(owner.defowner));
  392. exit;
  393. end;
  394. { protected symbols are visible in the module that defines them and
  395. also visible to related objects }
  396. if (sp_protected in symoptions) and
  397. (
  398. (
  399. assigned(owner.defowner) and
  400. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  401. (not owner.defowner.owner.iscurrentunit)
  402. ) and
  403. not(
  404. assigned(currobjdef) and
  405. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  406. (currobjdef.owner.iscurrentunit) and
  407. currobjdef.is_related(tdef(owner.defowner))
  408. )
  409. ) then
  410. exit;
  411. is_visible_for_object:=true;
  412. end;
  413. {****************************************************************************
  414. TRef
  415. ****************************************************************************}
  416. constructor tref.create(ref :tref;pos : pfileposinfo);
  417. begin
  418. nextref:=nil;
  419. if pos<>nil then
  420. posinfo:=pos^;
  421. if assigned(current_module) then
  422. moduleindex:=current_module.unit_index;
  423. if assigned(ref) then
  424. ref.nextref:=self;
  425. is_written:=false;
  426. end;
  427. procedure tref.freechain;
  428. var
  429. p,q : tref;
  430. begin
  431. p:=nextref;
  432. nextref:=nil;
  433. while assigned(p) do
  434. begin
  435. q:=p.nextref;
  436. p.free;
  437. p:=q;
  438. end;
  439. end;
  440. destructor tref.destroy;
  441. begin
  442. nextref:=nil;
  443. end;
  444. {****************************************************************************
  445. tpropaccesslist
  446. ****************************************************************************}
  447. constructor tpropaccesslist.create;
  448. begin
  449. procdef:=nil; { needed for procedures }
  450. firstsym:=nil;
  451. lastsym:=nil;
  452. end;
  453. destructor tpropaccesslist.destroy;
  454. begin
  455. clear;
  456. end;
  457. function tpropaccesslist.empty:boolean;
  458. begin
  459. empty:=(firstsym=nil);
  460. end;
  461. procedure tpropaccesslist.clear;
  462. var
  463. hp : ppropaccesslistitem;
  464. begin
  465. while assigned(firstsym) do
  466. begin
  467. hp:=firstsym;
  468. firstsym:=firstsym^.next;
  469. dispose(hp);
  470. end;
  471. firstsym:=nil;
  472. lastsym:=nil;
  473. procdef:=nil;
  474. end;
  475. procedure tpropaccesslist.addsym(slt:tsltype;p:tsym);
  476. var
  477. hp : ppropaccesslistitem;
  478. begin
  479. new(hp);
  480. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  481. hp^.sltype:=slt;
  482. hp^.sym:=p;
  483. hp^.symderef.reset;
  484. if assigned(lastsym) then
  485. lastsym^.next:=hp
  486. else
  487. firstsym:=hp;
  488. lastsym:=hp;
  489. end;
  490. procedure tpropaccesslist.addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  491. var
  492. hp : ppropaccesslistitem;
  493. begin
  494. new(hp);
  495. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  496. hp^.sltype:=slt;
  497. hp^.value:=v;
  498. hp^.valuedef:=d;
  499. hp^.valuedefderef.reset;
  500. if assigned(lastsym) then
  501. lastsym^.next:=hp
  502. else
  503. firstsym:=hp;
  504. lastsym:=hp;
  505. end;
  506. procedure tpropaccesslist.addtype(slt:tsltype;d:tdef);
  507. var
  508. hp : ppropaccesslistitem;
  509. begin
  510. new(hp);
  511. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  512. hp^.sltype:=slt;
  513. hp^.def:=d;
  514. hp^.defderef.reset;
  515. if assigned(lastsym) then
  516. lastsym^.next:=hp
  517. else
  518. firstsym:=hp;
  519. lastsym:=hp;
  520. end;
  521. procedure tpropaccesslist.addsymderef(slt:tsltype;d:tderef);
  522. begin
  523. addsym(slt,nil);
  524. lastsym^.symderef:=d;
  525. end;
  526. procedure tpropaccesslist.addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  527. begin
  528. addconst(slt,v,nil);
  529. lastsym^.valuedefderef:=d;
  530. end;
  531. procedure tpropaccesslist.addtypederef(slt:tsltype;d:tderef);
  532. begin
  533. addtype(slt,nil);
  534. lastsym^.defderef:=d;
  535. end;
  536. procedure tpropaccesslist.resolve;
  537. var
  538. hp : ppropaccesslistitem;
  539. begin
  540. procdef:=tdef(procdefderef.resolve);
  541. hp:=firstsym;
  542. while assigned(hp) do
  543. begin
  544. case hp^.sltype of
  545. sl_call,
  546. sl_load,
  547. sl_subscript :
  548. hp^.sym:=tsym(hp^.symderef.resolve);
  549. sl_absolutetype,
  550. sl_typeconv :
  551. hp^.def:=tdef(hp^.defderef.resolve);
  552. sl_vec:
  553. hp^.valuedef:=tdef(hp^.valuedefderef.resolve);
  554. else
  555. internalerror(200110205);
  556. end;
  557. hp:=hp^.next;
  558. end;
  559. end;
  560. procedure tpropaccesslist.buildderef;
  561. var
  562. hp : ppropaccesslistitem;
  563. begin
  564. procdefderef.build(procdef);
  565. hp:=firstsym;
  566. while assigned(hp) do
  567. begin
  568. case hp^.sltype of
  569. sl_call,
  570. sl_load,
  571. sl_subscript :
  572. hp^.symderef.build(hp^.sym);
  573. sl_absolutetype,
  574. sl_typeconv :
  575. hp^.defderef.build(hp^.def);
  576. sl_vec:
  577. hp^.valuedefderef.build(hp^.valuedef);
  578. else
  579. internalerror(200110205);
  580. end;
  581. hp:=hp^.next;
  582. end;
  583. end;
  584. {****************************************************************************
  585. Tderef
  586. ****************************************************************************}
  587. procedure tderef.reset;
  588. begin
  589. dataidx:=-1;
  590. end;
  591. procedure tderef.build(s:tsymtableentry);
  592. var
  593. len : byte;
  594. st : tsymtable;
  595. data : array[0..255] of byte;
  596. idx : word;
  597. begin
  598. { skip length byte }
  599. len:=1;
  600. if assigned(s) then
  601. begin
  602. st:=findunitsymtable(s.owner);
  603. if not st.iscurrentunit then
  604. begin
  605. { register that the unit is needed for resolving }
  606. data[len]:=ord(deref_unit);
  607. idx:=current_module.derefidx_unit(st.moduleid);
  608. data[len+1]:=idx shr 8 and $ff;
  609. data[len+2]:=idx and $ff;
  610. inc(len,3);
  611. end;
  612. if s is tsym then
  613. begin
  614. data[len]:=ord(deref_symid);
  615. data[len+1]:=tsym(s).symid shr 24 and $ff;
  616. data[len+2]:=tsym(s).symid shr 16 and $ff;
  617. data[len+3]:=tsym(s).symid shr 8 and $ff;
  618. data[len+4]:=tsym(s).symid and $ff;
  619. inc(len,5);
  620. end
  621. else
  622. begin
  623. data[len]:=ord(deref_defid);
  624. data[len+1]:=tdef(s).defid shr 24 and $ff;
  625. data[len+2]:=tdef(s).defid shr 16 and $ff;
  626. data[len+3]:=tdef(s).defid shr 8 and $ff;
  627. data[len+4]:=tdef(s).defid and $ff;
  628. inc(len,5);
  629. end;
  630. end
  631. else
  632. begin
  633. { nil pointer }
  634. data[len]:=ord(deref_nil);
  635. inc(len);
  636. end;
  637. { store data length in first byte }
  638. data[0]:=len-1;
  639. { store index and write to derefdata }
  640. dataidx:=current_module.derefdata.size;
  641. current_module.derefdata.write(data,len);
  642. end;
  643. function tderef.resolve:tsymtableentry;
  644. var
  645. pm : tmodule;
  646. typ : tdereftype;
  647. idx : word;
  648. i : aint;
  649. len : byte;
  650. data : array[0..255] of byte;
  651. begin
  652. result:=nil;
  653. { not initialized or error }
  654. if dataidx<0 then
  655. internalerror(200306067);
  656. { read data }
  657. current_module.derefdata.seek(dataidx);
  658. if current_module.derefdata.read(len,1)<>1 then
  659. internalerror(200310221);
  660. if len>0 then
  661. begin
  662. if current_module.derefdata.read(data,len)<>len then
  663. internalerror(200310222);
  664. end;
  665. { process data }
  666. pm:=current_module;
  667. i:=0;
  668. while (i<len) do
  669. begin
  670. typ:=tdereftype(data[i]);
  671. inc(i);
  672. case typ of
  673. deref_unit :
  674. begin
  675. idx:=(data[i] shl 8) or data[i+1];
  676. inc(i,2);
  677. pm:=current_module.resolve_unit(idx);
  678. end;
  679. deref_defid :
  680. begin
  681. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  682. inc(i,4);
  683. result:=tdef(pm.deflist[idx]);
  684. end;
  685. deref_symid :
  686. begin
  687. idx:=(data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3];
  688. inc(i,4);
  689. result:=tsym(pm.symlist[idx]);
  690. end;
  691. deref_nil :
  692. begin
  693. result:=nil;
  694. { Only allowed when no other deref is available }
  695. if len<>1 then
  696. internalerror(200306232);
  697. end;
  698. else
  699. internalerror(200212277);
  700. end;
  701. end;
  702. end;
  703. {*****************************************************************************
  704. TCompilerPPUFile
  705. *****************************************************************************}
  706. procedure tcompilerppufile.checkerror;
  707. begin
  708. if error then
  709. Message(unit_f_ppu_read_error);
  710. end;
  711. procedure tcompilerppufile.getguid(var g: tguid);
  712. begin
  713. getdata(g,sizeof(g));
  714. end;
  715. function tcompilerppufile.getexprint:tconstexprint;
  716. begin
  717. if sizeof(tconstexprint)=8 then
  718. result:=tconstexprint(getint64)
  719. else
  720. result:=tconstexprint(getlongint);
  721. end;
  722. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  723. begin
  724. if sizeof(TConstPtrUInt)=8 then
  725. result:=tconstptruint(getint64)
  726. else
  727. result:=TConstPtrUInt(getlongint);
  728. end;
  729. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  730. var
  731. info : byte;
  732. begin
  733. {
  734. info byte layout in bits:
  735. 0-1 - amount of bytes for fileindex
  736. 2-3 - amount of bytes for line
  737. 4-5 - amount of bytes for column
  738. }
  739. info:=getbyte;
  740. case (info and $03) of
  741. 0 : p.fileindex:=getbyte;
  742. 1 : p.fileindex:=getword;
  743. 2 : p.fileindex:=(getbyte shl 16) or getword;
  744. 3 : p.fileindex:=getlongint;
  745. end;
  746. case ((info shr 2) and $03) of
  747. 0 : p.line:=getbyte;
  748. 1 : p.line:=getword;
  749. 2 : p.line:=(getbyte shl 16) or getword;
  750. 3 : p.line:=getlongint;
  751. end;
  752. case ((info shr 4) and $03) of
  753. 0 : p.column:=getbyte;
  754. 1 : p.column:=getword;
  755. 2 : p.column:=(getbyte shl 16) or getword;
  756. 3 : p.column:=getlongint;
  757. end;
  758. p.moduleindex:=current_module.unit_index;
  759. end;
  760. procedure tcompilerppufile.getderef(var d:tderef);
  761. begin
  762. d.dataidx:=getlongint;
  763. end;
  764. function tcompilerppufile.getpropaccesslist:tpropaccesslist;
  765. var
  766. hderef : tderef;
  767. slt : tsltype;
  768. idx : longint;
  769. p : tpropaccesslist;
  770. begin
  771. p:=tpropaccesslist.create;
  772. getderef(p.procdefderef);
  773. repeat
  774. slt:=tsltype(getbyte);
  775. case slt of
  776. sl_none :
  777. break;
  778. sl_call,
  779. sl_load,
  780. sl_subscript :
  781. begin
  782. getderef(hderef);
  783. p.addsymderef(slt,hderef);
  784. end;
  785. sl_absolutetype,
  786. sl_typeconv :
  787. begin
  788. getderef(hderef);
  789. p.addtypederef(slt,hderef);
  790. end;
  791. sl_vec :
  792. begin
  793. idx:=getlongint;
  794. getderef(hderef);
  795. p.addconstderef(slt,idx,hderef);
  796. end;
  797. else
  798. internalerror(200110204);
  799. end;
  800. until false;
  801. getpropaccesslist:=tpropaccesslist(p);
  802. end;
  803. function tcompilerppufile.getasmsymbol:tasmsymbol;
  804. begin
  805. getlongint;
  806. getasmsymbol:=nil;
  807. end;
  808. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  809. var
  810. oldcrc : boolean;
  811. info : byte;
  812. begin
  813. { posinfo is not relevant for changes in PPU }
  814. oldcrc:=do_crc;
  815. do_crc:=false;
  816. {
  817. info byte layout in bits:
  818. 0-1 - amount of bytes for fileindex
  819. 2-3 - amount of bytes for line
  820. 4-5 - amount of bytes for column
  821. }
  822. info:=0;
  823. { calculate info byte }
  824. if (p.fileindex>$ff) then
  825. begin
  826. if (p.fileindex<=$ffff) then
  827. info:=info or $1
  828. else
  829. if (p.fileindex<=$ffffff) then
  830. info:=info or $2
  831. else
  832. info:=info or $3;
  833. end;
  834. if (p.line>$ff) then
  835. begin
  836. if (p.line<=$ffff) then
  837. info:=info or $4
  838. else
  839. if (p.line<=$ffffff) then
  840. info:=info or $8
  841. else
  842. info:=info or $c;
  843. end;
  844. if (p.column>$ff) then
  845. begin
  846. if (p.column<=$ffff) then
  847. info:=info or $10
  848. else
  849. if (p.column<=$ffffff) then
  850. info:=info or $20
  851. else
  852. info:=info or $30;
  853. end;
  854. { write data }
  855. putbyte(info);
  856. case (info and $03) of
  857. 0 : putbyte(p.fileindex);
  858. 1 : putword(p.fileindex);
  859. 2 : begin
  860. putbyte(p.fileindex shr 16);
  861. putword(p.fileindex and $ffff);
  862. end;
  863. 3 : putlongint(p.fileindex);
  864. end;
  865. case ((info shr 2) and $03) of
  866. 0 : putbyte(p.line);
  867. 1 : putword(p.line);
  868. 2 : begin
  869. putbyte(p.line shr 16);
  870. putword(p.line and $ffff);
  871. end;
  872. 3 : putlongint(p.line);
  873. end;
  874. case ((info shr 4) and $03) of
  875. 0 : putbyte(p.column);
  876. 1 : putword(p.column);
  877. 2 : begin
  878. putbyte(p.column shr 16);
  879. putword(p.column and $ffff);
  880. end;
  881. 3 : putlongint(p.column);
  882. end;
  883. do_crc:=oldcrc;
  884. end;
  885. procedure tcompilerppufile.putguid(const g: tguid);
  886. begin
  887. putdata(g,sizeof(g));
  888. end;
  889. procedure tcompilerppufile.putexprint(v:tconstexprint);
  890. begin
  891. if sizeof(TConstExprInt)=8 then
  892. putint64(int64(v))
  893. else if sizeof(TConstExprInt)=4 then
  894. putlongint(longint(v))
  895. else
  896. internalerror(2002082601);
  897. end;
  898. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  899. begin
  900. if sizeof(TConstPtrUInt)=8 then
  901. putint64(int64(v))
  902. else if sizeof(TConstPtrUInt)=4 then
  903. putlongint(longint(v))
  904. else
  905. internalerror(2002082601);
  906. end;
  907. procedure tcompilerppufile.putderef(const d:tderef);
  908. var
  909. oldcrc : boolean;
  910. begin
  911. oldcrc:=do_crc;
  912. do_crc:=false;
  913. putlongint(d.dataidx);
  914. do_crc:=oldcrc;
  915. end;
  916. procedure tcompilerppufile.putpropaccesslist(p:tpropaccesslist);
  917. var
  918. hp : ppropaccesslistitem;
  919. begin
  920. putderef(p.procdefderef);
  921. hp:=p.firstsym;
  922. while assigned(hp) do
  923. begin
  924. putbyte(byte(hp^.sltype));
  925. case hp^.sltype of
  926. sl_call,
  927. sl_load,
  928. sl_subscript :
  929. putderef(hp^.symderef);
  930. sl_absolutetype,
  931. sl_typeconv :
  932. putderef(hp^.defderef);
  933. sl_vec :
  934. begin
  935. putlongint(hp^.value);
  936. putderef(hp^.valuedefderef);
  937. end;
  938. else
  939. internalerror(200110205);
  940. end;
  941. hp:=hp^.next;
  942. end;
  943. putbyte(byte(sl_none));
  944. end;
  945. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  946. begin
  947. putlongint(0);
  948. end;
  949. {$ifdef MEMDEBUG}
  950. initialization
  951. membrowser:=TMemDebug.create('BrowserRefs');
  952. membrowser.stop;
  953. memrealnames:=TMemDebug.create('Realnames');
  954. memrealnames.stop;
  955. memmanglednames:=TMemDebug.create('Manglednames');
  956. memmanglednames.stop;
  957. memprocpara:=TMemDebug.create('ProcPara');
  958. memprocpara.stop;
  959. memprocparast:=TMemDebug.create('ProcParaSt');
  960. memprocparast.stop;
  961. memproclocalst:=TMemDebug.create('ProcLocalSt');
  962. memproclocalst.stop;
  963. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  964. memprocnodetree.stop;
  965. finalization
  966. membrowser.free;
  967. memrealnames.free;
  968. memmanglednames.free;
  969. memprocpara.free;
  970. memprocparast.free;
  971. memproclocalst.free;
  972. memprocnodetree.free;
  973. {$endif MEMDEBUG}
  974. end.