symtype.pas 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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. cclasses,
  24. { global }
  25. globtype,globals,constexp,
  26. { symtable }
  27. symconst,symbase,
  28. { aasm }
  29. aasmbase,ppu,cpuinfo
  30. ;
  31. type
  32. {************************************************
  33. Required Forwards
  34. ************************************************}
  35. tsym = class;
  36. Tcompilerppufile=class;
  37. {************************************************
  38. TDef
  39. ************************************************}
  40. tgeTSymtable = (gs_none,gs_record,gs_local,gs_para);
  41. tdef = class(TDefEntry)
  42. typesym : tsym; { which type the definition was generated this def }
  43. { maybe it's useful to merge the dwarf and stabs debugging info with some hacking }
  44. { dwarf debugging }
  45. dwarf_lab : tasmsymbol;
  46. dwarf_ref_lab : tasmsymbol;
  47. { stabs debugging }
  48. stab_number : word;
  49. dbg_state : tdefdbgstatus;
  50. defoptions : tdefoptions;
  51. defstates : tdefstates;
  52. {$ifdef support_llvm}
  53. protected
  54. fllvm_name_sym,
  55. { so we don't have to create pointerdefs all the time }
  56. fllvm_pointer_name_sym: tasmsymbol;
  57. public
  58. {$endif support_llvm}
  59. constructor create(dt:tdeftyp);
  60. procedure buildderef;virtual;abstract;
  61. procedure buildderefimpl;virtual;abstract;
  62. procedure deref;virtual;abstract;
  63. procedure derefimpl;virtual;abstract;
  64. function typename:string;
  65. function GetTypeName:string;virtual;
  66. function mangledparaname:string;
  67. function getmangledparaname:string;virtual;
  68. function rtti_mangledname(rt:trttitype):string;virtual;abstract;
  69. {$ifdef support_llvm}
  70. function llvm_mangledname:string;virtual;abstract;
  71. {$endif support_llvm}
  72. function size:aint;virtual;abstract;
  73. function packedbitsize:aint;virtual;
  74. function alignment:shortint;virtual;abstract;
  75. function getvardef:longint;virtual;abstract;
  76. function getparentdef:tdef;virtual;
  77. function geTSymtable(t:tgeTSymtable):TSymtable;virtual;
  78. function is_publishable:boolean;virtual;abstract;
  79. function needs_inittable:boolean;virtual;abstract;
  80. function is_related(def:tdef):boolean;virtual;
  81. procedure ChangeOwner(st:TSymtable);
  82. {$ifdef support_llvm}
  83. protected
  84. function get_llvm_name_sym: tasmsymbol;virtual;abstract;
  85. function get_llvm_pointer_name_sym: tasmsymbol;virtual;abstract;
  86. public
  87. property llvm_name_sym: tasmsymbol read get_llvm_name_sym;
  88. property llvm_pointername_sym: tasmsymbol read get_llvm_pointer_name_sym;
  89. {$endif support_llvm}
  90. end;
  91. {************************************************
  92. TSym
  93. ************************************************}
  94. { this object is the base for all symbol objects }
  95. { tsym }
  96. tsym = class(TSymEntry)
  97. protected
  98. public
  99. fileinfo : tfileposinfo;
  100. symoptions : tsymoptions;
  101. refs : longint;
  102. reflist : TLinkedList;
  103. isdbgwritten : boolean;
  104. constructor create(st:tsymtyp;const aname:string);
  105. destructor destroy;override;
  106. function mangledname:string; virtual;
  107. procedure buildderef;virtual;
  108. procedure deref;virtual;
  109. { currobjdef is the object def to assume, this is necessary for protected and
  110. private,
  111. context is the object def we're really in, this is for the strict stuff
  112. }
  113. function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
  114. procedure ChangeOwner(st:TSymtable);
  115. procedure IncRefCount;
  116. procedure IncRefCountBy(AValue : longint);
  117. procedure MaybeCreateRefList;
  118. procedure AddRef;
  119. end;
  120. tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
  121. psymarr = ^tsymarr;
  122. {************************************************
  123. TDeref
  124. ************************************************}
  125. tderef = object
  126. dataidx : longint;
  127. procedure reset;
  128. procedure build(s:TObject);
  129. function resolve:TObject;
  130. end;
  131. {************************************************
  132. tpropaccesslist
  133. ************************************************}
  134. ppropaccesslistitem = ^tpropaccesslistitem;
  135. tpropaccesslistitem = record
  136. sltype : tsltype;
  137. next : ppropaccesslistitem;
  138. case byte of
  139. 0 : (sym : tsym; symderef : tderef);
  140. 1 : (value : TConstExprInt; valuedef: tdef; valuedefderef:tderef);
  141. 2 : (def: tdef; defderef:tderef);
  142. end;
  143. tpropaccesslist = class
  144. procdef : tdef;
  145. procdefderef : tderef;
  146. firstsym,
  147. lastsym : ppropaccesslistitem;
  148. constructor create;
  149. destructor destroy;override;
  150. function empty:boolean;
  151. procedure addsym(slt:tsltype;p:tsym);
  152. procedure addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  153. procedure addtype(slt:tsltype;d:tdef);
  154. procedure addsymderef(slt:tsltype;d:tderef);
  155. procedure addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  156. procedure addtypederef(slt:tsltype;d:tderef);
  157. procedure clear;
  158. procedure resolve;
  159. procedure buildderef;
  160. end;
  161. {************************************************
  162. Tcompilerppufile
  163. ************************************************}
  164. tcompilerppufile=class(tppufile)
  165. public
  166. procedure checkerror;
  167. procedure getguid(var g: tguid);
  168. function getexprint:Tconstexprint;
  169. function getptruint:TConstPtrUInt;
  170. procedure getposinfo(var p:tfileposinfo);
  171. procedure getderef(var d:tderef);
  172. function getpropaccesslist:tpropaccesslist;
  173. function getasmsymbol:tasmsymbol;
  174. procedure putguid(const g: tguid);
  175. procedure putexprint(const v:tconstexprint);
  176. procedure PutPtrUInt(v:TConstPtrUInt);
  177. procedure putposinfo(const p:tfileposinfo);
  178. procedure putderef(const d:tderef);
  179. procedure putpropaccesslist(p:tpropaccesslist);
  180. procedure putasmsymbol(s:tasmsymbol);
  181. end;
  182. {$ifdef MEMDEBUG}
  183. var
  184. memmanglednames,
  185. memprocpara,
  186. memprocparast,
  187. memproclocalst,
  188. memprocnodetree : tmemdebug;
  189. {$endif MEMDEBUG}
  190. const
  191. current_object_option : tsymoptions = [sp_public];
  192. function FindUnitSymtable(st:TSymtable):TSymtable;
  193. implementation
  194. uses
  195. crefs,
  196. verbose,
  197. fmodule
  198. ;
  199. {****************************************************************************
  200. Utils
  201. ****************************************************************************}
  202. function FindUnitSymtable(st:TSymtable):TSymtable;
  203. begin
  204. result:=nil;
  205. repeat
  206. if not assigned(st) then
  207. internalerror(200602034);
  208. case st.symtabletype of
  209. localmacrosymtable,
  210. exportedmacrosymtable,
  211. staticsymtable,
  212. globalsymtable :
  213. begin
  214. result:=st;
  215. exit;
  216. end;
  217. recordsymtable,
  218. localsymtable,
  219. parasymtable,
  220. ObjectSymtable :
  221. st:=st.defowner.owner;
  222. else
  223. internalerror(200602035);
  224. end;
  225. until false;
  226. end;
  227. {****************************************************************************
  228. Tdef
  229. ****************************************************************************}
  230. constructor tdef.create(dt:tdeftyp);
  231. begin
  232. inherited create;
  233. typ:=dt;
  234. owner := nil;
  235. typesym := nil;
  236. defoptions:=[];
  237. dbg_state:=dbg_state_unused;
  238. stab_number:=0;
  239. end;
  240. function tdef.typename:string;
  241. begin
  242. if assigned(typesym) and
  243. not(typ in [procvardef,procdef]) and
  244. (typesym.realname[1]<>'$') then
  245. result:=typesym.realname
  246. else
  247. result:=GetTypeName;
  248. end;
  249. function tdef.GetTypeName : string;
  250. begin
  251. GetTypeName:='<unknown type>'
  252. end;
  253. function tdef.mangledparaname:string;
  254. begin
  255. if assigned(typesym) then
  256. mangledparaname:=typesym.name
  257. else
  258. mangledparaname:=getmangledparaname;
  259. end;
  260. function tdef.getmangledparaname:string;
  261. begin
  262. result:='<unknown type>';
  263. end;
  264. function tdef.getparentdef:tdef;
  265. begin
  266. result:=nil;
  267. end;
  268. function tdef.geTSymtable(t:tgeTSymtable):TSymtable;
  269. begin
  270. result:=nil;
  271. end;
  272. function tdef.is_related(def:tdef):boolean;
  273. begin
  274. result:=false;
  275. end;
  276. function tdef.packedbitsize:aint;
  277. begin
  278. result:=size * 8;
  279. end;
  280. procedure tdef.ChangeOwner(st:TSymtable);
  281. begin
  282. // if assigned(Owner) then
  283. // Owner.DefList.List[i]:=nil;
  284. Owner:=st;
  285. Owner.DefList.Add(self);
  286. end;
  287. {****************************************************************************
  288. TSYM (base for all symtypes)
  289. ****************************************************************************}
  290. constructor tsym.create(st:tsymtyp;const aname:string);
  291. begin
  292. inherited CreateNotOwned;
  293. realname:=aname;
  294. typ:=st;
  295. RefList:=nil;
  296. symoptions:=[];
  297. fileinfo:=current_tokenpos;
  298. isdbgwritten := false;
  299. symoptions:=current_object_option;
  300. end;
  301. destructor Tsym.destroy;
  302. begin
  303. if assigned(RefList) then
  304. RefList.Free;
  305. inherited Destroy;
  306. end;
  307. procedure Tsym.IncRefCount;
  308. begin
  309. inc(refs);
  310. if cs_browser in current_settings.moduleswitches then
  311. begin
  312. MaybeCreateRefList;
  313. AddRef;
  314. end;
  315. end;
  316. procedure Tsym.IncRefCountBy(AValue : longint);
  317. begin
  318. inc(refs,AValue);
  319. end;
  320. procedure Tsym.MaybeCreateRefList;
  321. begin
  322. if not assigned(reflist) then
  323. reflist:=TRefLinkedList.create;
  324. end;
  325. procedure Tsym.AddRef;
  326. var
  327. RefItem: TRefItem;
  328. begin
  329. RefItem:=TRefItem.Create(current_tokenpos);
  330. RefList.Concat(RefItem);
  331. end;
  332. procedure Tsym.buildderef;
  333. begin
  334. end;
  335. procedure Tsym.deref;
  336. begin
  337. end;
  338. function tsym.mangledname : string;
  339. begin
  340. internalerror(200204171);
  341. result:='';
  342. end;
  343. function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
  344. begin
  345. is_visible_for_object:=false;
  346. { private symbols are allowed when we are in the same
  347. module as they are defined }
  348. if (sp_private in symoptions) and
  349. assigned(owner.defowner) and
  350. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  351. (not owner.defowner.owner.iscurrentunit) then
  352. exit;
  353. if (sp_strictprivate in symoptions) then
  354. begin
  355. result:=assigned(currobjdef) and
  356. (context=tdef(owner.defowner));
  357. exit;
  358. end;
  359. if (sp_strictprotected in symoptions) then
  360. begin
  361. result:=assigned(context) and
  362. context.is_related(tdef(owner.defowner));
  363. exit;
  364. end;
  365. { protected symbols are visible in the module that defines them and
  366. also visible to related objects }
  367. if (sp_protected in symoptions) and
  368. (
  369. (
  370. assigned(owner.defowner) and
  371. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  372. (not owner.defowner.owner.iscurrentunit)
  373. ) and
  374. not(
  375. assigned(currobjdef) and
  376. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  377. (currobjdef.owner.iscurrentunit) and
  378. currobjdef.is_related(tdef(owner.defowner))
  379. )
  380. ) then
  381. exit;
  382. is_visible_for_object:=true;
  383. end;
  384. procedure tsym.ChangeOwner(st:TSymtable);
  385. begin
  386. // if assigned(Owner) then
  387. // Owner.SymList.List.List^[i].Data:=nil;
  388. Owner:=st;
  389. inherited ChangeOwner(Owner.SymList);
  390. end;
  391. {****************************************************************************
  392. tpropaccesslist
  393. ****************************************************************************}
  394. constructor tpropaccesslist.create;
  395. begin
  396. procdef:=nil; { needed for procedures }
  397. firstsym:=nil;
  398. lastsym:=nil;
  399. end;
  400. destructor tpropaccesslist.destroy;
  401. begin
  402. clear;
  403. end;
  404. function tpropaccesslist.empty:boolean;
  405. begin
  406. empty:=(firstsym=nil);
  407. end;
  408. procedure tpropaccesslist.clear;
  409. var
  410. hp : ppropaccesslistitem;
  411. begin
  412. while assigned(firstsym) do
  413. begin
  414. hp:=firstsym;
  415. firstsym:=firstsym^.next;
  416. dispose(hp);
  417. end;
  418. firstsym:=nil;
  419. lastsym:=nil;
  420. procdef:=nil;
  421. end;
  422. procedure tpropaccesslist.addsym(slt:tsltype;p:tsym);
  423. var
  424. hp : ppropaccesslistitem;
  425. begin
  426. new(hp);
  427. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  428. hp^.sltype:=slt;
  429. hp^.sym:=p;
  430. hp^.symderef.reset;
  431. if assigned(lastsym) then
  432. lastsym^.next:=hp
  433. else
  434. firstsym:=hp;
  435. lastsym:=hp;
  436. end;
  437. procedure tpropaccesslist.addconst(slt:tsltype;v:TConstExprInt;d:tdef);
  438. var
  439. hp : ppropaccesslistitem;
  440. begin
  441. new(hp);
  442. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  443. hp^.sltype:=slt;
  444. hp^.value:=v;
  445. hp^.valuedef:=d;
  446. hp^.valuedefderef.reset;
  447. if assigned(lastsym) then
  448. lastsym^.next:=hp
  449. else
  450. firstsym:=hp;
  451. lastsym:=hp;
  452. end;
  453. procedure tpropaccesslist.addtype(slt:tsltype;d:tdef);
  454. var
  455. hp : ppropaccesslistitem;
  456. begin
  457. new(hp);
  458. fillchar(hp^,sizeof(tpropaccesslistitem),0);
  459. hp^.sltype:=slt;
  460. hp^.def:=d;
  461. hp^.defderef.reset;
  462. if assigned(lastsym) then
  463. lastsym^.next:=hp
  464. else
  465. firstsym:=hp;
  466. lastsym:=hp;
  467. end;
  468. procedure tpropaccesslist.addsymderef(slt:tsltype;d:tderef);
  469. begin
  470. addsym(slt,nil);
  471. lastsym^.symderef:=d;
  472. end;
  473. procedure tpropaccesslist.addconstderef(slt:tsltype;v:TConstExprInt;d:tderef);
  474. begin
  475. addconst(slt,v,nil);
  476. lastsym^.valuedefderef:=d;
  477. end;
  478. procedure tpropaccesslist.addtypederef(slt:tsltype;d:tderef);
  479. begin
  480. addtype(slt,nil);
  481. lastsym^.defderef:=d;
  482. end;
  483. procedure tpropaccesslist.resolve;
  484. var
  485. hp : ppropaccesslistitem;
  486. begin
  487. procdef:=tdef(procdefderef.resolve);
  488. hp:=firstsym;
  489. while assigned(hp) do
  490. begin
  491. case hp^.sltype of
  492. sl_call,
  493. sl_load,
  494. sl_subscript :
  495. hp^.sym:=tsym(hp^.symderef.resolve);
  496. sl_absolutetype,
  497. sl_typeconv :
  498. hp^.def:=tdef(hp^.defderef.resolve);
  499. sl_vec:
  500. hp^.valuedef:=tdef(hp^.valuedefderef.resolve);
  501. else
  502. internalerror(200110205);
  503. end;
  504. hp:=hp^.next;
  505. end;
  506. end;
  507. procedure tpropaccesslist.buildderef;
  508. var
  509. hp : ppropaccesslistitem;
  510. begin
  511. procdefderef.build(procdef);
  512. hp:=firstsym;
  513. while assigned(hp) do
  514. begin
  515. case hp^.sltype of
  516. sl_call,
  517. sl_load,
  518. sl_subscript :
  519. hp^.symderef.build(hp^.sym);
  520. sl_absolutetype,
  521. sl_typeconv :
  522. hp^.defderef.build(hp^.def);
  523. sl_vec:
  524. hp^.valuedefderef.build(hp^.valuedef);
  525. else
  526. internalerror(200110205);
  527. end;
  528. hp:=hp^.next;
  529. end;
  530. end;
  531. {****************************************************************************
  532. Tderef
  533. ****************************************************************************}
  534. procedure tderef.reset;
  535. begin
  536. dataidx:=-1;
  537. end;
  538. procedure tderef.build(s:TObject);
  539. var
  540. len : byte;
  541. st : TSymtable;
  542. data : array[0..255] of byte;
  543. idx : word;
  544. begin
  545. { skip length byte }
  546. len:=1;
  547. if assigned(s) then
  548. begin
  549. {$warning TODO ugly hack}
  550. if s is tsym then
  551. st:=FindUnitSymtable(tsym(s).owner)
  552. else
  553. st:=FindUnitSymtable(tdef(s).owner);
  554. if not st.iscurrentunit then
  555. begin
  556. { register that the unit is needed for resolving }
  557. data[len]:=ord(deref_unit);
  558. idx:=current_module.derefidx_unit(st.moduleid);
  559. data[len+1]:=idx shr 8 and $ff;
  560. data[len+2]:=idx and $ff;
  561. inc(len,3);
  562. end;
  563. if s is tsym then
  564. begin
  565. data[len]:=ord(deref_symid);
  566. data[len+1]:=tsym(s).symid shr 24 and $ff;
  567. data[len+2]:=tsym(s).symid shr 16 and $ff;
  568. data[len+3]:=tsym(s).symid shr 8 and $ff;
  569. data[len+4]:=tsym(s).symid and $ff;
  570. inc(len,5);
  571. end
  572. else
  573. begin
  574. data[len]:=ord(deref_defid);
  575. data[len+1]:=tdef(s).defid shr 24 and $ff;
  576. data[len+2]:=tdef(s).defid shr 16 and $ff;
  577. data[len+3]:=tdef(s).defid shr 8 and $ff;
  578. data[len+4]:=tdef(s).defid and $ff;
  579. inc(len,5);
  580. end;
  581. end
  582. else
  583. begin
  584. { nil pointer }
  585. data[len]:=ord(deref_nil);
  586. inc(len);
  587. end;
  588. { store data length in first byte }
  589. data[0]:=len-1;
  590. { store index and write to derefdata }
  591. dataidx:=current_module.derefdata.size;
  592. current_module.derefdata.write(data,len);
  593. end;
  594. function tderef.resolve:TObject;
  595. var
  596. pm : tmodule;
  597. typ : tdereftype;
  598. idx : longint;
  599. i : aint;
  600. len : byte;
  601. data : array[0..255] of byte;
  602. begin
  603. result:=nil;
  604. { not initialized or error }
  605. if dataidx<0 then
  606. internalerror(200306067);
  607. { read data }
  608. current_module.derefdata.seek(dataidx);
  609. if current_module.derefdata.read(len,1)<>1 then
  610. internalerror(200310221);
  611. if len>0 then
  612. begin
  613. if current_module.derefdata.read(data,len)<>len then
  614. internalerror(200310222);
  615. end;
  616. { process data }
  617. pm:=current_module;
  618. i:=0;
  619. while (i<len) do
  620. begin
  621. typ:=tdereftype(data[i]);
  622. inc(i);
  623. case typ of
  624. deref_unit :
  625. begin
  626. idx:=(data[i] shl 8) or data[i+1];
  627. inc(i,2);
  628. pm:=current_module.resolve_unit(idx);
  629. end;
  630. deref_defid :
  631. begin
  632. idx:=longint((data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3]);
  633. inc(i,4);
  634. result:=tdef(pm.deflist[idx]);
  635. end;
  636. deref_symid :
  637. begin
  638. idx:=longint((data[i] shl 24) or (data[i+1] shl 16) or (data[i+2] shl 8) or data[i+3]);
  639. inc(i,4);
  640. result:=tsym(pm.symlist[idx]);
  641. end;
  642. deref_nil :
  643. begin
  644. result:=nil;
  645. { Only allowed when no other deref is available }
  646. if len<>1 then
  647. internalerror(200306232);
  648. end;
  649. else
  650. internalerror(200212277);
  651. end;
  652. end;
  653. end;
  654. {*****************************************************************************
  655. TCompilerPPUFile
  656. *****************************************************************************}
  657. procedure tcompilerppufile.checkerror;
  658. begin
  659. if error then
  660. Message(unit_f_ppu_read_error);
  661. end;
  662. procedure tcompilerppufile.getguid(var g: tguid);
  663. begin
  664. longint(g.d1):=getlongint;
  665. g.d2:=getword;
  666. g.d3:=getword;
  667. getdata(g.d4,sizeof(g.d4));
  668. end;
  669. function tcompilerppufile.getexprint:Tconstexprint;
  670. begin
  671. getexprint.overflow:=false;
  672. getexprint.signed:=boolean(getbyte);
  673. getexprint.svalue:=getint64;
  674. end;
  675. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  676. begin
  677. if sizeof(TConstPtrUInt)=8 then
  678. result:=tconstptruint(getint64)
  679. else
  680. result:=TConstPtrUInt(getlongint);
  681. end;
  682. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  683. var
  684. info : byte;
  685. begin
  686. {
  687. info byte layout in bits:
  688. 0-1 - amount of bytes for fileindex
  689. 2-3 - amount of bytes for line
  690. 4-5 - amount of bytes for column
  691. }
  692. info:=getbyte;
  693. case (info and $03) of
  694. 0 : p.fileindex:=getbyte;
  695. 1 : p.fileindex:=getword;
  696. 2 : p.fileindex:=(getbyte shl 16) or getword;
  697. 3 : p.fileindex:=getlongint;
  698. end;
  699. case ((info shr 2) and $03) of
  700. 0 : p.line:=getbyte;
  701. 1 : p.line:=getword;
  702. 2 : p.line:=(getbyte shl 16) or getword;
  703. 3 : p.line:=getlongint;
  704. end;
  705. case ((info shr 4) and $03) of
  706. 0 : p.column:=getbyte;
  707. 1 : p.column:=getword;
  708. 2 : p.column:=(getbyte shl 16) or getword;
  709. 3 : p.column:=getlongint;
  710. end;
  711. p.moduleindex:=current_module.unit_index;
  712. end;
  713. procedure tcompilerppufile.getderef(var d:tderef);
  714. begin
  715. d.dataidx:=getlongint;
  716. end;
  717. function tcompilerppufile.getpropaccesslist:tpropaccesslist;
  718. var
  719. hderef : tderef;
  720. slt : tsltype;
  721. idx : longint;
  722. p : tpropaccesslist;
  723. begin
  724. p:=tpropaccesslist.create;
  725. getderef(p.procdefderef);
  726. repeat
  727. slt:=tsltype(getbyte);
  728. case slt of
  729. sl_none :
  730. break;
  731. sl_call,
  732. sl_load,
  733. sl_subscript :
  734. begin
  735. getderef(hderef);
  736. p.addsymderef(slt,hderef);
  737. end;
  738. sl_absolutetype,
  739. sl_typeconv :
  740. begin
  741. getderef(hderef);
  742. p.addtypederef(slt,hderef);
  743. end;
  744. sl_vec :
  745. begin
  746. idx:=getlongint;
  747. getderef(hderef);
  748. p.addconstderef(slt,idx,hderef);
  749. end;
  750. else
  751. internalerror(200110204);
  752. end;
  753. until false;
  754. getpropaccesslist:=tpropaccesslist(p);
  755. end;
  756. function tcompilerppufile.getasmsymbol:tasmsymbol;
  757. begin
  758. getlongint;
  759. getasmsymbol:=nil;
  760. end;
  761. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  762. var
  763. oldcrc : boolean;
  764. info : byte;
  765. begin
  766. { posinfo is not relevant for changes in PPU }
  767. oldcrc:=do_crc;
  768. do_crc:=false;
  769. {
  770. info byte layout in bits:
  771. 0-1 - amount of bytes for fileindex
  772. 2-3 - amount of bytes for line
  773. 4-5 - amount of bytes for column
  774. }
  775. info:=0;
  776. { calculate info byte }
  777. if (p.fileindex>$ff) then
  778. begin
  779. if (p.fileindex<=$ffff) then
  780. info:=info or $1
  781. else
  782. if (p.fileindex<=$ffffff) then
  783. info:=info or $2
  784. else
  785. info:=info or $3;
  786. end;
  787. if (p.line>$ff) then
  788. begin
  789. if (p.line<=$ffff) then
  790. info:=info or $4
  791. else
  792. if (p.line<=$ffffff) then
  793. info:=info or $8
  794. else
  795. info:=info or $c;
  796. end;
  797. if (p.column>$ff) then
  798. begin
  799. if (p.column<=$ffff) then
  800. info:=info or $10
  801. else
  802. if (p.column<=$ffffff) then
  803. info:=info or $20
  804. else
  805. info:=info or $30;
  806. end;
  807. { write data }
  808. putbyte(info);
  809. case (info and $03) of
  810. 0 : putbyte(p.fileindex);
  811. 1 : putword(p.fileindex);
  812. 2 : begin
  813. putbyte(p.fileindex shr 16);
  814. putword(p.fileindex and $ffff);
  815. end;
  816. 3 : putlongint(p.fileindex);
  817. end;
  818. case ((info shr 2) and $03) of
  819. 0 : putbyte(p.line);
  820. 1 : putword(p.line);
  821. 2 : begin
  822. putbyte(p.line shr 16);
  823. putword(p.line and $ffff);
  824. end;
  825. 3 : putlongint(p.line);
  826. end;
  827. case ((info shr 4) and $03) of
  828. 0 : putbyte(p.column);
  829. 1 : putword(p.column);
  830. 2 : begin
  831. putbyte(p.column shr 16);
  832. putword(p.column and $ffff);
  833. end;
  834. 3 : putlongint(p.column);
  835. end;
  836. do_crc:=oldcrc;
  837. end;
  838. procedure tcompilerppufile.putguid(const g: tguid);
  839. begin
  840. putlongint(longint(g.d1));
  841. putword(g.d2);
  842. putword(g.d3);
  843. putdata(g.d4,sizeof(g.d4));
  844. end;
  845. procedure Tcompilerppufile.putexprint(const v:Tconstexprint);
  846. begin
  847. if v.overflow then
  848. internalerror(200706102);
  849. putbyte(byte(v.signed));
  850. putint64(v.svalue);
  851. end;
  852. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  853. begin
  854. if sizeof(TConstPtrUInt)=8 then
  855. putint64(int64(v))
  856. else if sizeof(TConstPtrUInt)=4 then
  857. putlongint(longint(v))
  858. else
  859. internalerror(2002082601);
  860. end;
  861. procedure tcompilerppufile.putderef(const d:tderef);
  862. var
  863. oldcrc : boolean;
  864. begin
  865. oldcrc:=do_crc;
  866. do_crc:=false;
  867. putlongint(d.dataidx);
  868. do_crc:=oldcrc;
  869. end;
  870. procedure tcompilerppufile.putpropaccesslist(p:tpropaccesslist);
  871. var
  872. hp : ppropaccesslistitem;
  873. begin
  874. putderef(p.procdefderef);
  875. hp:=p.firstsym;
  876. while assigned(hp) do
  877. begin
  878. putbyte(byte(hp^.sltype));
  879. case hp^.sltype of
  880. sl_call,
  881. sl_load,
  882. sl_subscript :
  883. putderef(hp^.symderef);
  884. sl_absolutetype,
  885. sl_typeconv :
  886. putderef(hp^.defderef);
  887. sl_vec :
  888. begin
  889. putlongint(int64(hp^.value));
  890. putderef(hp^.valuedefderef);
  891. end;
  892. else
  893. internalerror(200110205);
  894. end;
  895. hp:=hp^.next;
  896. end;
  897. putbyte(byte(sl_none));
  898. end;
  899. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  900. begin
  901. putlongint(0);
  902. end;
  903. {$ifdef MEMDEBUG}
  904. initialization
  905. memmanglednames:=TMemDebug.create('Manglednames');
  906. memmanglednames.stop;
  907. memprocpara:=TMemDebug.create('ProcPara');
  908. memprocpara.stop;
  909. memprocparast:=TMemDebug.create('ProcParaSt');
  910. memprocparast.stop;
  911. memproclocalst:=TMemDebug.create('ProcLocalSt');
  912. memproclocalst.stop;
  913. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  914. memprocnodetree.stop;
  915. finalization
  916. memmanglednames.free;
  917. memprocpara.free;
  918. memprocparast.free;
  919. memproclocalst.free;
  920. memprocnodetree.free;
  921. {$endif MEMDEBUG}
  922. end.