symtype.pas 29 KB

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