symtype.pas 40 KB

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