symtype.pas 40 KB

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