2
0

symtype.pas 41 KB

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