symtype.pas 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  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. 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_absolutetype,
  651. sl_typeconv :
  652. hp^.tt.resolve;
  653. sl_vec :
  654. ;
  655. else
  656. internalerror(200110205);
  657. end;
  658. hp:=hp^.next;
  659. end;
  660. end;
  661. procedure tsymlist.buildderef;
  662. var
  663. hp : psymlistitem;
  664. begin
  665. procdefderef.build(procdef);
  666. hp:=firstsym;
  667. while assigned(hp) do
  668. begin
  669. case hp^.sltype of
  670. sl_call,
  671. sl_load,
  672. sl_subscript :
  673. hp^.symderef.build(hp^.sym);
  674. sl_absolutetype,
  675. sl_typeconv :
  676. hp^.tt.buildderef;
  677. sl_vec :
  678. ;
  679. else
  680. internalerror(200110205);
  681. end;
  682. hp:=hp^.next;
  683. end;
  684. end;
  685. {****************************************************************************
  686. Tderef
  687. ****************************************************************************}
  688. procedure tderef.reset;
  689. begin
  690. dataidx:=-1;
  691. end;
  692. procedure tderef.build(s:tsymtableentry);
  693. var
  694. len : byte;
  695. data : array[0..255] of byte;
  696. function is_child(currdef,ownerdef:tdef):boolean;
  697. begin
  698. while assigned(currdef) and
  699. (currdef<>ownerdef) do
  700. currdef:=currdef.getparentdef;
  701. result:=assigned(currdef);
  702. end;
  703. procedure addowner(s:tsymtableentry);
  704. var
  705. idx : longint;
  706. begin
  707. if not assigned(s.owner) then
  708. internalerror(200306063);
  709. case s.owner.symtabletype of
  710. globalsymtable :
  711. begin
  712. if s.owner.iscurrentunit then
  713. begin
  714. data[len]:=ord(deref_aktglobal);
  715. inc(len);
  716. end
  717. else
  718. begin
  719. { register that the unit is needed for resolving }
  720. idx:=current_module.derefidx_unit(s.owner.moduleid);
  721. data[len]:=ord(deref_unit);
  722. data[len+1]:=idx shr 8;
  723. data[len+2]:=idx and $ff;
  724. inc(len,3);
  725. end;
  726. end;
  727. staticsymtable :
  728. begin
  729. { only references to the current static symtable are allowed }
  730. if not s.owner.iscurrentunit then
  731. internalerror(200306233);
  732. data[len]:=ord(deref_aktstatic);
  733. inc(len);
  734. end;
  735. localsymtable :
  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_local);
  742. inc(len,4);
  743. end;
  744. parasymtable :
  745. begin
  746. addowner(s.owner.defowner);
  747. data[len]:=ord(deref_def);
  748. data[len+1]:=s.owner.defowner.indexnr shr 8;
  749. data[len+2]:=s.owner.defowner.indexnr and $ff;
  750. data[len+3]:=ord(deref_para);
  751. inc(len,4);
  752. end;
  753. objectsymtable,
  754. recordsymtable :
  755. begin
  756. addowner(s.owner.defowner);
  757. data[len]:=ord(deref_def);
  758. data[len+1]:=s.owner.defowner.indexnr shr 8;
  759. data[len+2]:=s.owner.defowner.indexnr and $ff;
  760. data[len+3]:=ord(deref_record);
  761. inc(len,4);
  762. end;
  763. else
  764. internalerror(200306065);
  765. end;
  766. if len>252 then
  767. internalerror(200306062);
  768. end;
  769. procedure addparentobject(currdef,ownerdef:tdef);
  770. var
  771. nextdef : tdef;
  772. begin
  773. if not assigned(currdef) then
  774. internalerror(200306185);
  775. { Already handled by derefaktrecordindex }
  776. if currdef=ownerdef then
  777. internalerror(200306188);
  778. { Generate a direct reference to the top parent
  779. class available in the current unit, this is required because
  780. the parent class is maybe not resolved yet and therefor
  781. has the childof value not available yet }
  782. while (currdef<>ownerdef) do
  783. begin
  784. nextdef:=currdef.getparentdef;
  785. { objects are only allowed in globalsymtable,staticsymtable }
  786. if not(nextdef.owner.symtabletype in [globalsymtable,staticsymtable]) then
  787. internalerror(200306187);
  788. { Next parent is in a different unit, then stop }
  789. if not(nextdef.owner.iscurrentunit) then
  790. break;
  791. currdef:=nextdef;
  792. end;
  793. { Add reference where to start the parent lookup }
  794. if currdef=aktrecordsymtable.defowner then
  795. begin
  796. data[len]:=ord(deref_aktrecord);
  797. inc(len);
  798. end
  799. else
  800. begin
  801. if currdef.owner.symtabletype=globalsymtable then
  802. data[len]:=ord(deref_aktglobal)
  803. else
  804. data[len]:=ord(deref_aktstatic);
  805. data[len+1]:=ord(deref_def);
  806. data[len+2]:=currdef.indexnr shr 8;
  807. data[len+3]:=currdef.indexnr and $ff;
  808. data[len+4]:=ord(deref_record);
  809. inc(len,5);
  810. end;
  811. { When the current found parent in this module is not the owner we
  812. add derefs for the parent classes not available in this unit }
  813. while (currdef<>ownerdef) do
  814. begin
  815. data[len]:=ord(deref_parent_object);
  816. inc(len);
  817. currdef:=currdef.getparentdef;
  818. { It should be valid as it is checked by is_child }
  819. if not assigned(currdef) then
  820. internalerror(200306186);
  821. end;
  822. end;
  823. begin
  824. { skip length byte }
  825. len:=1;
  826. if assigned(s) then
  827. begin
  828. { Static symtable of current unit ? }
  829. if (s.owner.symtabletype=staticsymtable) and
  830. s.owner.iscurrentunit then
  831. begin
  832. data[len]:=ord(deref_aktstatic);
  833. inc(len);
  834. end
  835. { Global symtable of current unit ? }
  836. else if (s.owner.symtabletype=globalsymtable) and
  837. s.owner.iscurrentunit then
  838. begin
  839. data[len]:=ord(deref_aktglobal);
  840. inc(len);
  841. end
  842. { Current record/object symtable ? }
  843. else if (s.owner=aktrecordsymtable) then
  844. begin
  845. data[len]:=ord(deref_aktrecord);
  846. inc(len);
  847. end
  848. { Current local symtable ? }
  849. else if (s.owner=aktlocalsymtable) then
  850. begin
  851. data[len]:=ord(deref_aktlocal);
  852. inc(len);
  853. end
  854. { Current para symtable ? }
  855. else if (s.owner=aktparasymtable) then
  856. begin
  857. data[len]:=ord(deref_aktpara);
  858. inc(len);
  859. end
  860. { Parent class? }
  861. else if assigned(aktrecordsymtable) and
  862. (aktrecordsymtable.symtabletype=objectsymtable) and
  863. (s.owner.symtabletype=objectsymtable) and
  864. is_child(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner)) then
  865. begin
  866. addparentobject(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner));
  867. end
  868. else
  869. { Default, start by building from unit symtable }
  870. begin
  871. addowner(s);
  872. end;
  873. { Add index of the symbol/def }
  874. if s is tsym then
  875. data[len]:=ord(deref_sym)
  876. else
  877. data[len]:=ord(deref_def);
  878. data[len+1]:=s.indexnr shr 8;
  879. data[len+2]:=s.indexnr and $ff;
  880. inc(len,3);
  881. end
  882. else
  883. begin
  884. { nil pointer }
  885. data[len]:=0;
  886. inc(len);
  887. end;
  888. { store data length in first byte }
  889. data[0]:=len-1;
  890. { store index and write to derefdata }
  891. dataidx:=current_module.derefdata.size;
  892. current_module.derefdata.write(data,len);
  893. end;
  894. function tderef.resolve:tsymtableentry;
  895. var
  896. pd : tdef;
  897. pm : tmodule;
  898. typ : tdereftype;
  899. st : tsymtable;
  900. idx : word;
  901. i : aint;
  902. len : byte;
  903. data : array[0..255] of byte;
  904. begin
  905. result:=nil;
  906. { not initialized or error }
  907. if dataidx<0 then
  908. internalerror(200306067);
  909. { read data }
  910. current_module.derefdata.seek(dataidx);
  911. if current_module.derefdata.read(len,1)<>1 then
  912. internalerror(200310221);
  913. if len>0 then
  914. begin
  915. if current_module.derefdata.read(data,len)<>len then
  916. internalerror(200310222);
  917. end;
  918. { process data }
  919. st:=nil;
  920. i:=0;
  921. while (i<len) do
  922. begin
  923. typ:=tdereftype(data[i]);
  924. inc(i);
  925. case typ of
  926. deref_nil :
  927. begin
  928. result:=nil;
  929. { Only allowed when no other deref is available }
  930. if len<>1 then
  931. internalerror(200306232);
  932. end;
  933. deref_sym :
  934. begin
  935. if not assigned(st) then
  936. internalerror(200309141);
  937. idx:=(data[i] shl 8) or data[i+1];
  938. inc(i,2);
  939. result:=st.getsymnr(idx);
  940. end;
  941. deref_def :
  942. begin
  943. if not assigned(st) then
  944. internalerror(200309142);
  945. idx:=(data[i] shl 8) or data[i+1];
  946. inc(i,2);
  947. result:=st.getdefnr(idx);
  948. end;
  949. deref_aktrecord :
  950. st:=aktrecordsymtable;
  951. deref_aktstatic :
  952. st:=current_module.localsymtable;
  953. deref_aktglobal :
  954. st:=current_module.globalsymtable;
  955. deref_aktlocal :
  956. st:=aktlocalsymtable;
  957. deref_aktpara :
  958. st:=aktparasymtable;
  959. deref_unit :
  960. begin
  961. idx:=(data[i] shl 8) or data[i+1];
  962. inc(i,2);
  963. pm:=current_module.resolve_unit(idx);
  964. st:=pm.globalsymtable;
  965. end;
  966. deref_local :
  967. begin
  968. if not assigned(result) then
  969. internalerror(200306069);
  970. st:=tdef(result).getsymtable(gs_local);
  971. result:=nil;
  972. if not assigned(st) then
  973. internalerror(200212275);
  974. end;
  975. deref_para :
  976. begin
  977. if not assigned(result) then
  978. internalerror(2003060610);
  979. st:=tdef(result).getsymtable(gs_para);
  980. result:=nil;
  981. if not assigned(st) then
  982. internalerror(200212276);
  983. end;
  984. deref_record :
  985. begin
  986. if not assigned(result) then
  987. internalerror(200306068);
  988. st:=tdef(result).getsymtable(gs_record);
  989. result:=nil;
  990. if not assigned(st) then
  991. internalerror(200212274);
  992. end;
  993. deref_parent_object :
  994. begin
  995. { load current object symtable if no
  996. symtable is available yet }
  997. if st=nil then
  998. begin
  999. st:=aktrecordsymtable;
  1000. if not assigned(st) then
  1001. internalerror(200306068);
  1002. end;
  1003. if st.symtabletype<>objectsymtable then
  1004. internalerror(200306189);
  1005. pd:=tdef(st.defowner).getparentdef;
  1006. if not assigned(pd) then
  1007. internalerror(200306184);
  1008. st:=pd.getsymtable(gs_record);
  1009. if not assigned(st) then
  1010. internalerror(200212274);
  1011. end;
  1012. else
  1013. internalerror(200212277);
  1014. end;
  1015. end;
  1016. end;
  1017. {*****************************************************************************
  1018. TCompilerPPUFile
  1019. *****************************************************************************}
  1020. procedure tcompilerppufile.checkerror;
  1021. begin
  1022. if error then
  1023. Message(unit_f_ppu_read_error);
  1024. end;
  1025. procedure tcompilerppufile.getguid(var g: tguid);
  1026. begin
  1027. getdata(g,sizeof(g));
  1028. end;
  1029. function tcompilerppufile.getexprint:tconstexprint;
  1030. begin
  1031. if sizeof(tconstexprint)=8 then
  1032. result:=tconstexprint(getint64)
  1033. else
  1034. result:=tconstexprint(getlongint);
  1035. end;
  1036. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  1037. begin
  1038. if sizeof(TConstPtrUInt)=8 then
  1039. result:=tconstptruint(getint64)
  1040. else
  1041. result:=TConstPtrUInt(getlongint);
  1042. end;
  1043. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  1044. var
  1045. info : byte;
  1046. begin
  1047. {
  1048. info byte layout in bits:
  1049. 0-1 - amount of bytes for fileindex
  1050. 2-3 - amount of bytes for line
  1051. 4-5 - amount of bytes for column
  1052. }
  1053. info:=getbyte;
  1054. case (info and $03) of
  1055. 0 : p.fileindex:=getbyte;
  1056. 1 : p.fileindex:=getword;
  1057. 2 : p.fileindex:=(getbyte shl 16) or getword;
  1058. 3 : p.fileindex:=getlongint;
  1059. end;
  1060. case ((info shr 2) and $03) of
  1061. 0 : p.line:=getbyte;
  1062. 1 : p.line:=getword;
  1063. 2 : p.line:=(getbyte shl 16) or getword;
  1064. 3 : p.line:=getlongint;
  1065. end;
  1066. case ((info shr 4) and $03) of
  1067. 0 : p.column:=getbyte;
  1068. 1 : p.column:=getword;
  1069. 2 : p.column:=(getbyte shl 16) or getword;
  1070. 3 : p.column:=getlongint;
  1071. end;
  1072. end;
  1073. procedure tcompilerppufile.getderef(var d:tderef);
  1074. begin
  1075. d.dataidx:=getlongint;
  1076. end;
  1077. function tcompilerppufile.getsymlist:tsymlist;
  1078. var
  1079. symderef : tderef;
  1080. tt : ttype;
  1081. slt : tsltype;
  1082. idx : longint;
  1083. p : tsymlist;
  1084. begin
  1085. p:=tsymlist.create;
  1086. getderef(p.procdefderef);
  1087. repeat
  1088. slt:=tsltype(getbyte);
  1089. case slt of
  1090. sl_none :
  1091. break;
  1092. sl_call,
  1093. sl_load,
  1094. sl_subscript :
  1095. begin
  1096. getderef(symderef);
  1097. p.addsymderef(slt,symderef);
  1098. end;
  1099. sl_absolutetype,
  1100. sl_typeconv :
  1101. begin
  1102. gettype(tt);
  1103. p.addtype(slt,tt);
  1104. end;
  1105. sl_vec :
  1106. begin
  1107. idx:=getlongint;
  1108. p.addconst(slt,idx);
  1109. end;
  1110. else
  1111. internalerror(200110204);
  1112. end;
  1113. until false;
  1114. getsymlist:=tsymlist(p);
  1115. end;
  1116. procedure tcompilerppufile.gettype(var t:ttype);
  1117. begin
  1118. getderef(t.deref);
  1119. t.def:=nil;
  1120. t.sym:=nil;
  1121. end;
  1122. function tcompilerppufile.getasmsymbol:tasmsymbol;
  1123. begin
  1124. getasmsymbol:=tasmsymbol(pointer(ptrint(getlongint)));
  1125. end;
  1126. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  1127. var
  1128. oldcrc : boolean;
  1129. info : byte;
  1130. begin
  1131. { posinfo is not relevant for changes in PPU }
  1132. oldcrc:=do_crc;
  1133. do_crc:=false;
  1134. {
  1135. info byte layout in bits:
  1136. 0-1 - amount of bytes for fileindex
  1137. 2-3 - amount of bytes for line
  1138. 4-5 - amount of bytes for column
  1139. }
  1140. info:=0;
  1141. { calculate info byte }
  1142. if (p.fileindex>$ff) then
  1143. begin
  1144. if (p.fileindex<=$ffff) then
  1145. info:=info or $1
  1146. else
  1147. if (p.fileindex<=$ffffff) then
  1148. info:=info or $2
  1149. else
  1150. info:=info or $3;
  1151. end;
  1152. if (p.line>$ff) then
  1153. begin
  1154. if (p.line<=$ffff) then
  1155. info:=info or $4
  1156. else
  1157. if (p.line<=$ffffff) then
  1158. info:=info or $8
  1159. else
  1160. info:=info or $c;
  1161. end;
  1162. if (p.column>$ff) then
  1163. begin
  1164. if (p.column<=$ffff) then
  1165. info:=info or $10
  1166. else
  1167. if (p.column<=$ffffff) then
  1168. info:=info or $20
  1169. else
  1170. info:=info or $30;
  1171. end;
  1172. { write data }
  1173. putbyte(info);
  1174. case (info and $03) of
  1175. 0 : putbyte(p.fileindex);
  1176. 1 : putword(p.fileindex);
  1177. 2 : begin
  1178. putbyte(p.fileindex shr 16);
  1179. putword(p.fileindex and $ffff);
  1180. end;
  1181. 3 : putlongint(p.fileindex);
  1182. end;
  1183. case ((info shr 2) and $03) of
  1184. 0 : putbyte(p.line);
  1185. 1 : putword(p.line);
  1186. 2 : begin
  1187. putbyte(p.line shr 16);
  1188. putword(p.line and $ffff);
  1189. end;
  1190. 3 : putlongint(p.line);
  1191. end;
  1192. case ((info shr 4) and $03) of
  1193. 0 : putbyte(p.column);
  1194. 1 : putword(p.column);
  1195. 2 : begin
  1196. putbyte(p.column shr 16);
  1197. putword(p.column and $ffff);
  1198. end;
  1199. 3 : putlongint(p.column);
  1200. end;
  1201. do_crc:=oldcrc;
  1202. end;
  1203. procedure tcompilerppufile.putguid(const g: tguid);
  1204. begin
  1205. putdata(g,sizeof(g));
  1206. end;
  1207. procedure tcompilerppufile.putexprint(v:tconstexprint);
  1208. begin
  1209. if sizeof(TConstExprInt)=8 then
  1210. putint64(int64(v))
  1211. else if sizeof(TConstExprInt)=4 then
  1212. putlongint(longint(v))
  1213. else
  1214. internalerror(2002082601);
  1215. end;
  1216. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  1217. begin
  1218. if sizeof(TConstPtrUInt)=8 then
  1219. putint64(int64(v))
  1220. else if sizeof(TConstPtrUInt)=4 then
  1221. putlongint(longint(v))
  1222. else
  1223. internalerror(2002082601);
  1224. end;
  1225. procedure tcompilerppufile.putderef(const d:tderef);
  1226. var
  1227. oldcrc : boolean;
  1228. begin
  1229. oldcrc:=do_crc;
  1230. do_crc:=false;
  1231. putlongint(d.dataidx);
  1232. do_crc:=oldcrc;
  1233. end;
  1234. procedure tcompilerppufile.putsymlist(p:tsymlist);
  1235. var
  1236. hp : psymlistitem;
  1237. begin
  1238. putderef(p.procdefderef);
  1239. hp:=p.firstsym;
  1240. while assigned(hp) do
  1241. begin
  1242. putbyte(byte(hp^.sltype));
  1243. case hp^.sltype of
  1244. sl_call,
  1245. sl_load,
  1246. sl_subscript :
  1247. putderef(hp^.symderef);
  1248. sl_absolutetype,
  1249. sl_typeconv :
  1250. puttype(hp^.tt);
  1251. sl_vec :
  1252. putlongint(hp^.value);
  1253. else
  1254. internalerror(200110205);
  1255. end;
  1256. hp:=hp^.next;
  1257. end;
  1258. putbyte(byte(sl_none));
  1259. end;
  1260. procedure tcompilerppufile.puttype(const t:ttype);
  1261. begin
  1262. putderef(t.deref);
  1263. end;
  1264. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  1265. begin
  1266. if assigned(s) then
  1267. begin
  1268. if s.ppuidx=-1 then
  1269. begin
  1270. inc(objectlibrary.asmsymbolppuidx);
  1271. s.ppuidx:=objectlibrary.asmsymbolppuidx;
  1272. end;
  1273. putlongint(s.ppuidx);
  1274. end
  1275. else
  1276. putlongint(0);
  1277. end;
  1278. {$ifdef MEMDEBUG}
  1279. initialization
  1280. membrowser:=TMemDebug.create('BrowserRefs');
  1281. membrowser.stop;
  1282. memrealnames:=TMemDebug.create('Realnames');
  1283. memrealnames.stop;
  1284. memmanglednames:=TMemDebug.create('Manglednames');
  1285. memmanglednames.stop;
  1286. memprocpara:=TMemDebug.create('ProcPara');
  1287. memprocpara.stop;
  1288. memprocparast:=TMemDebug.create('ProcParaSt');
  1289. memprocparast.stop;
  1290. memproclocalst:=TMemDebug.create('ProcLocalSt');
  1291. memproclocalst.stop;
  1292. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  1293. memprocnodetree.stop;
  1294. finalization
  1295. membrowser.free;
  1296. memrealnames.free;
  1297. memmanglednames.free;
  1298. memprocpara.free;
  1299. memprocparast.free;
  1300. memproclocalst.free;
  1301. memprocnodetree.free;
  1302. {$endif MEMDEBUG}
  1303. end.