symtype.pas 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487
  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; valuett: ttype);
  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;const tt:ttype);
  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;const tt:ttype);
  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. hp^.valuett:=tt;
  611. if assigned(lastsym) then
  612. lastsym^.next:=hp
  613. else
  614. firstsym:=hp;
  615. lastsym:=hp;
  616. end;
  617. procedure tsymlist.addtype(slt:tsltype;const tt:ttype);
  618. var
  619. hp : psymlistitem;
  620. begin
  621. new(hp);
  622. fillchar(hp^,sizeof(tsymlistitem),0);
  623. hp^.sltype:=slt;
  624. hp^.tt:=tt;
  625. if assigned(lastsym) then
  626. lastsym^.next:=hp
  627. else
  628. firstsym:=hp;
  629. lastsym:=hp;
  630. end;
  631. function tsymlist.getcopy:tsymlist;
  632. var
  633. hp : tsymlist;
  634. hp2 : psymlistitem;
  635. hpn : psymlistitem;
  636. begin
  637. hp:=tsymlist.create;
  638. hp.procdef:=procdef;
  639. hp2:=firstsym;
  640. while assigned(hp2) do
  641. begin
  642. new(hpn);
  643. hpn^:=hp2^;
  644. hpn^.next:=nil;
  645. if assigned(hp.lastsym) then
  646. hp.lastsym^.next:=hpn
  647. else
  648. hp.firstsym:=hpn;
  649. hp.lastsym:=hpn;
  650. hp2:=hp2^.next;
  651. end;
  652. getcopy:=hp;
  653. end;
  654. procedure tsymlist.resolve;
  655. var
  656. hp : psymlistitem;
  657. begin
  658. procdef:=tdef(procdefderef.resolve);
  659. hp:=firstsym;
  660. while assigned(hp) do
  661. begin
  662. case hp^.sltype of
  663. sl_call,
  664. sl_load,
  665. sl_subscript :
  666. hp^.sym:=tsym(hp^.symderef.resolve);
  667. sl_vec,
  668. sl_absolutetype,
  669. sl_typeconv :
  670. hp^.tt.resolve;
  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_vec,
  691. sl_absolutetype,
  692. sl_typeconv :
  693. hp^.tt.buildderef;
  694. else
  695. internalerror(200110205);
  696. end;
  697. hp:=hp^.next;
  698. end;
  699. end;
  700. {****************************************************************************
  701. Tderef
  702. ****************************************************************************}
  703. procedure tderef.reset;
  704. begin
  705. dataidx:=-1;
  706. end;
  707. procedure tderef.build(s:tsymtableentry);
  708. var
  709. len : byte;
  710. data : array[0..255] of byte;
  711. function is_child(currdef,ownerdef:tdef):boolean;
  712. begin
  713. while assigned(currdef) and
  714. (currdef<>ownerdef) do
  715. currdef:=currdef.getparentdef;
  716. result:=assigned(currdef);
  717. end;
  718. procedure addowner(s:tsymtableentry);
  719. var
  720. idx : longint;
  721. begin
  722. if not assigned(s.owner) then
  723. internalerror(200306063);
  724. case s.owner.symtabletype of
  725. globalsymtable :
  726. begin
  727. if s.owner.iscurrentunit then
  728. begin
  729. data[len]:=ord(deref_aktglobal);
  730. inc(len);
  731. end
  732. else
  733. begin
  734. { register that the unit is needed for resolving }
  735. idx:=current_module.derefidx_unit(s.owner.moduleid);
  736. data[len]:=ord(deref_unit);
  737. data[len+1]:=idx shr 8;
  738. data[len+2]:=idx and $ff;
  739. inc(len,3);
  740. end;
  741. end;
  742. staticsymtable :
  743. begin
  744. { only references to the current static symtable are allowed }
  745. if not s.owner.iscurrentunit then
  746. internalerror(200306233);
  747. data[len]:=ord(deref_aktstatic);
  748. inc(len);
  749. end;
  750. localsymtable :
  751. begin
  752. addowner(s.owner.defowner);
  753. data[len]:=ord(deref_def);
  754. data[len+1]:=s.owner.defowner.indexnr shr 8;
  755. data[len+2]:=s.owner.defowner.indexnr and $ff;
  756. data[len+3]:=ord(deref_local);
  757. inc(len,4);
  758. end;
  759. parasymtable :
  760. begin
  761. addowner(s.owner.defowner);
  762. data[len]:=ord(deref_def);
  763. data[len+1]:=s.owner.defowner.indexnr shr 8;
  764. data[len+2]:=s.owner.defowner.indexnr and $ff;
  765. data[len+3]:=ord(deref_para);
  766. inc(len,4);
  767. end;
  768. objectsymtable,
  769. recordsymtable :
  770. begin
  771. addowner(s.owner.defowner);
  772. data[len]:=ord(deref_def);
  773. data[len+1]:=s.owner.defowner.indexnr shr 8;
  774. data[len+2]:=s.owner.defowner.indexnr and $ff;
  775. data[len+3]:=ord(deref_record);
  776. inc(len,4);
  777. end;
  778. else
  779. internalerror(200306065);
  780. end;
  781. if len>252 then
  782. internalerror(200306062);
  783. end;
  784. procedure addparentobject(currdef,ownerdef:tdef);
  785. var
  786. nextdef : tdef;
  787. begin
  788. if not assigned(currdef) then
  789. internalerror(200306185);
  790. { Already handled by derefaktrecordindex }
  791. if currdef=ownerdef then
  792. internalerror(200306188);
  793. { Generate a direct reference to the top parent
  794. class available in the current unit, this is required because
  795. the parent class is maybe not resolved yet and therefor
  796. has the childof value not available yet }
  797. while (currdef<>ownerdef) do
  798. begin
  799. nextdef:=currdef.getparentdef;
  800. { objects are only allowed in globalsymtable,staticsymtable }
  801. if not(nextdef.owner.symtabletype in [globalsymtable,staticsymtable]) then
  802. internalerror(200306187);
  803. { Next parent is in a different unit, then stop }
  804. if not(nextdef.owner.iscurrentunit) then
  805. break;
  806. currdef:=nextdef;
  807. end;
  808. { Add reference where to start the parent lookup }
  809. if currdef=aktrecordsymtable.defowner then
  810. begin
  811. data[len]:=ord(deref_aktrecord);
  812. inc(len);
  813. end
  814. else
  815. begin
  816. if currdef.owner.symtabletype=globalsymtable then
  817. data[len]:=ord(deref_aktglobal)
  818. else
  819. data[len]:=ord(deref_aktstatic);
  820. data[len+1]:=ord(deref_def);
  821. data[len+2]:=currdef.indexnr shr 8;
  822. data[len+3]:=currdef.indexnr and $ff;
  823. data[len+4]:=ord(deref_record);
  824. inc(len,5);
  825. end;
  826. { When the current found parent in this module is not the owner we
  827. add derefs for the parent classes not available in this unit }
  828. while (currdef<>ownerdef) do
  829. begin
  830. data[len]:=ord(deref_parent_object);
  831. inc(len);
  832. currdef:=currdef.getparentdef;
  833. { It should be valid as it is checked by is_child }
  834. if not assigned(currdef) then
  835. internalerror(200306186);
  836. end;
  837. end;
  838. begin
  839. { skip length byte }
  840. len:=1;
  841. if assigned(s) then
  842. begin
  843. { Static symtable of current unit ? }
  844. if (s.owner.symtabletype=staticsymtable) and
  845. s.owner.iscurrentunit then
  846. begin
  847. data[len]:=ord(deref_aktstatic);
  848. inc(len);
  849. end
  850. { Global symtable of current unit ? }
  851. else if (s.owner.symtabletype=globalsymtable) and
  852. s.owner.iscurrentunit then
  853. begin
  854. data[len]:=ord(deref_aktglobal);
  855. inc(len);
  856. end
  857. { Current record/object symtable ? }
  858. else if (s.owner=aktrecordsymtable) then
  859. begin
  860. data[len]:=ord(deref_aktrecord);
  861. inc(len);
  862. end
  863. { Current local symtable ? }
  864. else if (s.owner=aktlocalsymtable) then
  865. begin
  866. data[len]:=ord(deref_aktlocal);
  867. inc(len);
  868. end
  869. { Current para symtable ? }
  870. else if (s.owner=aktparasymtable) then
  871. begin
  872. data[len]:=ord(deref_aktpara);
  873. inc(len);
  874. end
  875. { Parent class? }
  876. else if assigned(aktrecordsymtable) and
  877. (aktrecordsymtable.symtabletype=objectsymtable) and
  878. (s.owner.symtabletype=objectsymtable) and
  879. is_child(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner)) then
  880. begin
  881. addparentobject(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner));
  882. end
  883. else
  884. { Default, start by building from unit symtable }
  885. begin
  886. addowner(s);
  887. end;
  888. { Add index of the symbol/def }
  889. if s is tsym then
  890. data[len]:=ord(deref_sym)
  891. else
  892. data[len]:=ord(deref_def);
  893. data[len+1]:=s.indexnr shr 8;
  894. data[len+2]:=s.indexnr and $ff;
  895. inc(len,3);
  896. end
  897. else
  898. begin
  899. { nil pointer }
  900. data[len]:=0;
  901. inc(len);
  902. end;
  903. { store data length in first byte }
  904. data[0]:=len-1;
  905. { store index and write to derefdata }
  906. dataidx:=current_module.derefdata.size;
  907. current_module.derefdata.write(data,len);
  908. end;
  909. function tderef.resolve:tsymtableentry;
  910. var
  911. pd : tdef;
  912. pm : tmodule;
  913. typ : tdereftype;
  914. st : tsymtable;
  915. idx : word;
  916. i : aint;
  917. len : byte;
  918. data : array[0..255] of byte;
  919. begin
  920. result:=nil;
  921. { not initialized or error }
  922. if dataidx<0 then
  923. internalerror(200306067);
  924. { read data }
  925. current_module.derefdata.seek(dataidx);
  926. if current_module.derefdata.read(len,1)<>1 then
  927. internalerror(200310221);
  928. if len>0 then
  929. begin
  930. if current_module.derefdata.read(data,len)<>len then
  931. internalerror(200310222);
  932. end;
  933. { process data }
  934. st:=nil;
  935. i:=0;
  936. while (i<len) do
  937. begin
  938. typ:=tdereftype(data[i]);
  939. inc(i);
  940. case typ of
  941. deref_nil :
  942. begin
  943. result:=nil;
  944. { Only allowed when no other deref is available }
  945. if len<>1 then
  946. internalerror(200306232);
  947. end;
  948. deref_sym :
  949. begin
  950. if not assigned(st) then
  951. internalerror(200309141);
  952. idx:=(data[i] shl 8) or data[i+1];
  953. inc(i,2);
  954. result:=st.getsymnr(idx);
  955. end;
  956. deref_def :
  957. begin
  958. if not assigned(st) then
  959. internalerror(200309142);
  960. idx:=(data[i] shl 8) or data[i+1];
  961. inc(i,2);
  962. result:=st.getdefnr(idx);
  963. end;
  964. deref_aktrecord :
  965. st:=aktrecordsymtable;
  966. deref_aktstatic :
  967. st:=current_module.localsymtable;
  968. deref_aktglobal :
  969. st:=current_module.globalsymtable;
  970. deref_aktlocal :
  971. st:=aktlocalsymtable;
  972. deref_aktpara :
  973. st:=aktparasymtable;
  974. deref_unit :
  975. begin
  976. idx:=(data[i] shl 8) or data[i+1];
  977. inc(i,2);
  978. pm:=current_module.resolve_unit(idx);
  979. st:=pm.globalsymtable;
  980. end;
  981. deref_local :
  982. begin
  983. if not assigned(result) then
  984. internalerror(200306069);
  985. st:=tdef(result).getsymtable(gs_local);
  986. result:=nil;
  987. if not assigned(st) then
  988. internalerror(200212275);
  989. end;
  990. deref_para :
  991. begin
  992. if not assigned(result) then
  993. internalerror(2003060610);
  994. st:=tdef(result).getsymtable(gs_para);
  995. result:=nil;
  996. if not assigned(st) then
  997. internalerror(200212276);
  998. end;
  999. deref_record :
  1000. begin
  1001. if not assigned(result) then
  1002. internalerror(200306068);
  1003. st:=tdef(result).getsymtable(gs_record);
  1004. result:=nil;
  1005. if not assigned(st) then
  1006. internalerror(200212274);
  1007. end;
  1008. deref_parent_object :
  1009. begin
  1010. { load current object symtable if no
  1011. symtable is available yet }
  1012. if st=nil then
  1013. begin
  1014. st:=aktrecordsymtable;
  1015. if not assigned(st) then
  1016. internalerror(200306068);
  1017. end;
  1018. if st.symtabletype<>objectsymtable then
  1019. internalerror(200306189);
  1020. pd:=tdef(st.defowner).getparentdef;
  1021. if not assigned(pd) then
  1022. internalerror(200306184);
  1023. st:=pd.getsymtable(gs_record);
  1024. if not assigned(st) then
  1025. internalerror(200212274);
  1026. end;
  1027. else
  1028. internalerror(200212277);
  1029. end;
  1030. end;
  1031. end;
  1032. {*****************************************************************************
  1033. TCompilerPPUFile
  1034. *****************************************************************************}
  1035. procedure tcompilerppufile.checkerror;
  1036. begin
  1037. if error then
  1038. Message(unit_f_ppu_read_error);
  1039. end;
  1040. procedure tcompilerppufile.getguid(var g: tguid);
  1041. begin
  1042. getdata(g,sizeof(g));
  1043. end;
  1044. function tcompilerppufile.getexprint:tconstexprint;
  1045. begin
  1046. if sizeof(tconstexprint)=8 then
  1047. result:=tconstexprint(getint64)
  1048. else
  1049. result:=tconstexprint(getlongint);
  1050. end;
  1051. function tcompilerppufile.getPtrUInt:TConstPtrUInt;
  1052. begin
  1053. if sizeof(TConstPtrUInt)=8 then
  1054. result:=tconstptruint(getint64)
  1055. else
  1056. result:=TConstPtrUInt(getlongint);
  1057. end;
  1058. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  1059. var
  1060. info : byte;
  1061. begin
  1062. {
  1063. info byte layout in bits:
  1064. 0-1 - amount of bytes for fileindex
  1065. 2-3 - amount of bytes for line
  1066. 4-5 - amount of bytes for column
  1067. }
  1068. info:=getbyte;
  1069. case (info and $03) of
  1070. 0 : p.fileindex:=getbyte;
  1071. 1 : p.fileindex:=getword;
  1072. 2 : p.fileindex:=(getbyte shl 16) or getword;
  1073. 3 : p.fileindex:=getlongint;
  1074. end;
  1075. case ((info shr 2) and $03) of
  1076. 0 : p.line:=getbyte;
  1077. 1 : p.line:=getword;
  1078. 2 : p.line:=(getbyte shl 16) or getword;
  1079. 3 : p.line:=getlongint;
  1080. end;
  1081. case ((info shr 4) and $03) of
  1082. 0 : p.column:=getbyte;
  1083. 1 : p.column:=getword;
  1084. 2 : p.column:=(getbyte shl 16) or getword;
  1085. 3 : p.column:=getlongint;
  1086. end;
  1087. end;
  1088. procedure tcompilerppufile.getderef(var d:tderef);
  1089. begin
  1090. d.dataidx:=getlongint;
  1091. end;
  1092. function tcompilerppufile.getsymlist:tsymlist;
  1093. var
  1094. symderef : tderef;
  1095. tt : ttype;
  1096. slt : tsltype;
  1097. idx : longint;
  1098. p : tsymlist;
  1099. begin
  1100. p:=tsymlist.create;
  1101. getderef(p.procdefderef);
  1102. repeat
  1103. slt:=tsltype(getbyte);
  1104. case slt of
  1105. sl_none :
  1106. break;
  1107. sl_call,
  1108. sl_load,
  1109. sl_subscript :
  1110. begin
  1111. getderef(symderef);
  1112. p.addsymderef(slt,symderef);
  1113. end;
  1114. sl_absolutetype,
  1115. sl_typeconv :
  1116. begin
  1117. gettype(tt);
  1118. p.addtype(slt,tt);
  1119. end;
  1120. sl_vec :
  1121. begin
  1122. idx:=getlongint;
  1123. gettype(tt);
  1124. p.addconst(slt,idx,tt);
  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. begin
  1269. putlongint(hp^.value);
  1270. puttype(hp^.valuett);
  1271. end;
  1272. else
  1273. internalerror(200110205);
  1274. end;
  1275. hp:=hp^.next;
  1276. end;
  1277. putbyte(byte(sl_none));
  1278. end;
  1279. procedure tcompilerppufile.puttype(const t:ttype);
  1280. begin
  1281. putderef(t.deref);
  1282. end;
  1283. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  1284. begin
  1285. if assigned(s) then
  1286. begin
  1287. if s.ppuidx=-1 then
  1288. begin
  1289. inc(objectlibrary.asmsymbolppuidx);
  1290. s.ppuidx:=objectlibrary.asmsymbolppuidx;
  1291. end;
  1292. putlongint(s.ppuidx);
  1293. end
  1294. else
  1295. putlongint(0);
  1296. end;
  1297. {$ifdef MEMDEBUG}
  1298. initialization
  1299. membrowser:=TMemDebug.create('BrowserRefs');
  1300. membrowser.stop;
  1301. memrealnames:=TMemDebug.create('Realnames');
  1302. memrealnames.stop;
  1303. memmanglednames:=TMemDebug.create('Manglednames');
  1304. memmanglednames.stop;
  1305. memprocpara:=TMemDebug.create('ProcPara');
  1306. memprocpara.stop;
  1307. memprocparast:=TMemDebug.create('ProcParaSt');
  1308. memprocparast.stop;
  1309. memproclocalst:=TMemDebug.create('ProcLocalSt');
  1310. memproclocalst.stop;
  1311. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  1312. memprocnodetree.stop;
  1313. finalization
  1314. membrowser.free;
  1315. memrealnames.free;
  1316. memmanglednames.free;
  1317. memprocpara.free;
  1318. memprocparast.free;
  1319. memproclocalst.free;
  1320. memprocnodetree.free;
  1321. {$endif MEMDEBUG}
  1322. end.