symtype.pas 40 KB

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