symtype.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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 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
  32. ;
  33. type
  34. {************************************************
  35. Required Forwards
  36. ************************************************}
  37. tsym = class;
  38. {************************************************
  39. TRef
  40. ************************************************}
  41. tref = class
  42. nextref : tref;
  43. posinfo : tfileposinfo;
  44. moduleindex : longint;
  45. is_written : boolean;
  46. constructor create(ref:tref;pos:pfileposinfo);
  47. procedure freechain;
  48. destructor destroy;override;
  49. end;
  50. {************************************************
  51. TDef
  52. ************************************************}
  53. tgetsymtable = (gs_none,gs_record,gs_local,gs_para);
  54. tdef = class(tdefentry)
  55. typesym : tsym; { which type the definition was generated this def }
  56. defoptions : tdefoptions;
  57. constructor create;
  58. procedure deref;virtual;abstract;
  59. procedure derefimpl;virtual;abstract;
  60. function typename:string;
  61. function gettypename:string;virtual;
  62. function mangledparaname:string;
  63. function getmangledparaname:string;virtual;abstract;
  64. function size:longint;virtual;abstract;
  65. function alignment:longint;virtual;abstract;
  66. function getsymtable(t:tgetsymtable):tsymtable;virtual;
  67. function is_publishable:boolean;virtual;abstract;
  68. function needs_inittable:boolean;virtual;abstract;
  69. end;
  70. {************************************************
  71. TSym
  72. ************************************************}
  73. { this object is the base for all symbol objects }
  74. tsym = class(tsymentry)
  75. _realname : pstring;
  76. fileinfo : tfileposinfo;
  77. symoptions : tsymoptions;
  78. constructor create(const n : string);
  79. destructor destroy;override;
  80. function realname:string;
  81. procedure deref;virtual;abstract;
  82. function gettypedef:tdef;virtual;
  83. end;
  84. {************************************************
  85. TType
  86. ************************************************}
  87. ttype = object
  88. def : tdef;
  89. sym : tsym;
  90. procedure reset;
  91. procedure setdef(p:tdef);
  92. procedure setsym(p:tsym);
  93. procedure resolve;
  94. end;
  95. {************************************************
  96. TSymList
  97. ************************************************}
  98. psymlistitem = ^tsymlistitem;
  99. tsymlistitem = record
  100. sltype : tsltype;
  101. sym : tsym;
  102. value : longint;
  103. next : psymlistitem;
  104. end;
  105. tsymlist = class
  106. def : tdef;
  107. firstsym,
  108. lastsym : psymlistitem;
  109. constructor create;
  110. destructor destroy;override;
  111. function empty:boolean;
  112. procedure setdef(p:tdef);
  113. procedure addsym(slt:tsltype;p:tsym);
  114. procedure addconst(slt:tsltype;v:longint);
  115. procedure clear;
  116. function getcopy:tsymlist;
  117. procedure resolve;
  118. end;
  119. { resolving }
  120. procedure resolvesym(var sym:pointer);
  121. procedure resolvedef(var def:pointer);
  122. {$ifdef MEMDEBUG}
  123. var
  124. membrowser,
  125. memrealnames,
  126. memmanglednames,
  127. memprocparast,
  128. memproclocalst,
  129. memprocnodetree : tmemdebug;
  130. {$endif MEMDEBUG}
  131. implementation
  132. uses
  133. verbose,
  134. fmodule;
  135. {****************************************************************************
  136. Tdef
  137. ****************************************************************************}
  138. constructor tdef.create;
  139. begin
  140. inherited create;
  141. deftype:=abstractdef;
  142. owner := nil;
  143. typesym := nil;
  144. defoptions:=[];
  145. end;
  146. function tdef.typename:string;
  147. begin
  148. if assigned(typesym) and
  149. not(deftype in [procvardef,procdef]) and
  150. assigned(typesym._realname) and
  151. (typesym._realname^[1]<>'$') then
  152. typename:=typesym._realname^
  153. else
  154. typename:=gettypename;
  155. end;
  156. function tdef.gettypename : string;
  157. begin
  158. gettypename:='<unknown type>'
  159. end;
  160. function tdef.mangledparaname:string;
  161. begin
  162. if assigned(typesym) then
  163. mangledparaname:=typesym.name
  164. else
  165. mangledparaname:=getmangledparaname;
  166. end;
  167. function tdef.getsymtable(t:tgetsymtable):tsymtable;
  168. begin
  169. getsymtable:=nil;
  170. end;
  171. {****************************************************************************
  172. TSYM (base for all symtypes)
  173. ****************************************************************************}
  174. constructor tsym.create(const n : string);
  175. begin
  176. if n[1]='$' then
  177. inherited createname(copy(n,2,255))
  178. else
  179. inherited createname(upper(n));
  180. _realname:=stringdup(n);
  181. typ:=abstractsym;
  182. symoptions:=[];
  183. end;
  184. destructor tsym.destroy;
  185. begin
  186. {$ifdef MEMDEBUG}
  187. memrealnames.start;
  188. {$endif MEMDEBUG}
  189. stringdispose(_realname);
  190. {$ifdef MEMDEBUG}
  191. memrealnames.stop;
  192. {$endif MEMDEBUG}
  193. inherited destroy;
  194. end;
  195. function tsym.realname : string;
  196. begin
  197. if assigned(_realname) then
  198. realname:=_realname^
  199. else
  200. realname:=name;
  201. end;
  202. function tsym.gettypedef:tdef;
  203. begin
  204. gettypedef:=nil;
  205. end;
  206. {****************************************************************************
  207. TRef
  208. ****************************************************************************}
  209. constructor tref.create(ref :tref;pos : pfileposinfo);
  210. begin
  211. nextref:=nil;
  212. if pos<>nil then
  213. posinfo:=pos^;
  214. if assigned(current_module) then
  215. moduleindex:=current_module.unit_index;
  216. if assigned(ref) then
  217. ref.nextref:=self;
  218. is_written:=false;
  219. end;
  220. procedure tref.freechain;
  221. var
  222. p,q : tref;
  223. begin
  224. p:=nextref;
  225. nextref:=nil;
  226. while assigned(p) do
  227. begin
  228. q:=p.nextref;
  229. p.free;
  230. p:=q;
  231. end;
  232. end;
  233. destructor tref.destroy;
  234. begin
  235. nextref:=nil;
  236. end;
  237. {****************************************************************************
  238. TType
  239. ****************************************************************************}
  240. procedure ttype.reset;
  241. begin
  242. def:=nil;
  243. sym:=nil;
  244. end;
  245. procedure ttype.setdef(p:tdef);
  246. begin
  247. def:=p;
  248. sym:=nil;
  249. end;
  250. procedure ttype.setsym(p:tsym);
  251. begin
  252. sym:=p;
  253. def:=p.gettypedef;
  254. if not assigned(def) then
  255. internalerror(1234005);
  256. end;
  257. procedure ttype.resolve;
  258. begin
  259. if assigned(sym) then
  260. begin
  261. resolvesym(pointer(sym));
  262. setsym(sym);
  263. if not assigned(def) then
  264. internalerror(200212271);
  265. end
  266. else
  267. if assigned(def) then
  268. begin
  269. resolvedef(pointer(def));
  270. if not assigned(def) then
  271. internalerror(200212272);
  272. end;
  273. end;
  274. {****************************************************************************
  275. TSymList
  276. ****************************************************************************}
  277. constructor tsymlist.create;
  278. begin
  279. def:=nil; { needed for procedures }
  280. firstsym:=nil;
  281. lastsym:=nil;
  282. end;
  283. destructor tsymlist.destroy;
  284. begin
  285. clear;
  286. end;
  287. function tsymlist.empty:boolean;
  288. begin
  289. empty:=(firstsym=nil);
  290. end;
  291. procedure tsymlist.clear;
  292. var
  293. hp : psymlistitem;
  294. begin
  295. while assigned(firstsym) do
  296. begin
  297. hp:=firstsym;
  298. firstsym:=firstsym^.next;
  299. dispose(hp);
  300. end;
  301. firstsym:=nil;
  302. lastsym:=nil;
  303. def:=nil;
  304. end;
  305. procedure tsymlist.setdef(p:tdef);
  306. begin
  307. def:=p;
  308. end;
  309. procedure tsymlist.addsym(slt:tsltype;p:tsym);
  310. var
  311. hp : psymlistitem;
  312. begin
  313. if not assigned(p) then
  314. internalerror(200110203);
  315. new(hp);
  316. hp^.sltype:=slt;
  317. hp^.sym:=p;
  318. hp^.value:=0;
  319. hp^.next:=nil;
  320. if assigned(lastsym) then
  321. lastsym^.next:=hp
  322. else
  323. firstsym:=hp;
  324. lastsym:=hp;
  325. end;
  326. procedure tsymlist.addconst(slt:tsltype;v:longint);
  327. var
  328. hp : psymlistitem;
  329. begin
  330. new(hp);
  331. hp^.sltype:=slt;
  332. hp^.sym:=nil;
  333. hp^.value:=v;
  334. hp^.next:=nil;
  335. if assigned(lastsym) then
  336. lastsym^.next:=hp
  337. else
  338. firstsym:=hp;
  339. lastsym:=hp;
  340. end;
  341. function tsymlist.getcopy:tsymlist;
  342. var
  343. hp : tsymlist;
  344. hp2 : psymlistitem;
  345. hpn : psymlistitem;
  346. begin
  347. hp:=tsymlist.create;
  348. hp.def:=def;
  349. hp2:=firstsym;
  350. while assigned(hp2) do
  351. begin
  352. new(hpn);
  353. hpn^:=hp2^;
  354. hpn^.next:=nil;
  355. if assigned(hp.lastsym) then
  356. hp.lastsym^.next:=hpn
  357. else
  358. hp.firstsym:=hpn;
  359. hp.lastsym:=hpn;
  360. hp2:=hp2^.next;
  361. end;
  362. getcopy:=hp;
  363. end;
  364. procedure tsymlist.resolve;
  365. var
  366. hp : psymlistitem;
  367. begin
  368. resolvedef(pointer(def));
  369. hp:=firstsym;
  370. while assigned(hp) do
  371. begin
  372. if assigned(hp^.sym) then
  373. resolvesym(pointer(hp^.sym));
  374. hp:=hp^.next;
  375. end;
  376. end;
  377. {*****************************************************************************
  378. Symbol / Definition Resolving
  379. *****************************************************************************}
  380. procedure resolvederef(var p:tderef;var st:tsymtable;var idx:word);
  381. var
  382. hp : tderef;
  383. pd : tdef;
  384. pm : tmodule;
  385. begin
  386. st:=nil;
  387. idx:=0;
  388. while assigned(p) do
  389. begin
  390. case p.dereftype of
  391. derefaktrecordindex :
  392. begin
  393. st:=aktrecordsymtable;
  394. idx:=p.index;
  395. end;
  396. derefaktstaticindex :
  397. begin
  398. st:=aktstaticsymtable;
  399. idx:=p.index;
  400. end;
  401. derefaktlocal :
  402. begin
  403. st:=aktlocalsymtable;
  404. idx:=p.index;
  405. end;
  406. derefunit :
  407. begin
  408. pm:=current_module.map^[p.index];
  409. if not assigned(pm) then
  410. internalerror(200212273);
  411. st:=pm.globalsymtable;
  412. end;
  413. derefrecord :
  414. begin
  415. pd:=tdef(st.getdefnr(p.index));
  416. st:=pd.getsymtable(gs_record);
  417. if not assigned(st) then
  418. internalerror(200212274);
  419. end;
  420. dereflocal :
  421. begin
  422. pd:=tdef(st.getdefnr(p.index));
  423. st:=pd.getsymtable(gs_local);
  424. if not assigned(st) then
  425. internalerror(200212275);
  426. end;
  427. derefpara :
  428. begin
  429. pd:=tdef(st.getdefnr(p.index));
  430. st:=pd.getsymtable(gs_para);
  431. if not assigned(st) then
  432. internalerror(200212276);
  433. end;
  434. derefindex :
  435. begin
  436. idx:=p.index;
  437. end;
  438. else
  439. internalerror(200212277);
  440. end;
  441. hp:=p;
  442. p:=p.next;
  443. hp.free;
  444. end;
  445. end;
  446. procedure resolvedef(var def:pointer);
  447. var
  448. st : tsymtable;
  449. idx : word;
  450. begin
  451. resolvederef(tderef(pointer(def)),st,idx);
  452. if assigned(st) then
  453. def:=tdef(st.getdefnr(idx))
  454. else
  455. def:=nil;
  456. end;
  457. procedure resolvesym(var sym:pointer);
  458. var
  459. st : tsymtable;
  460. idx : word;
  461. begin
  462. resolvederef(tderef(pointer(sym)),st,idx);
  463. if assigned(st) then
  464. sym:=tsym(st.getsymnr(idx))
  465. else
  466. sym:=nil;
  467. end;
  468. {$ifdef MEMDEBUG}
  469. initialization
  470. membrowser:=TMemDebug.create('BrowserRefs');
  471. membrowser.stop;
  472. memrealnames:=TMemDebug.create('Realnames');
  473. memrealnames.stop;
  474. memmanglednames:=TMemDebug.create('Manglednames');
  475. memmanglednames.stop;
  476. memprocparast:=TMemDebug.create('ProcParaSt');
  477. memprocparast.stop;
  478. memproclocalst:=TMemDebug.create('ProcLocalSt');
  479. memproclocalst.stop;
  480. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  481. memprocnodetree.stop;
  482. finalization
  483. membrowser.free;
  484. memrealnames.free;
  485. memmanglednames.free;
  486. memprocparast.free;
  487. memproclocalst.free;
  488. memprocnodetree.free;
  489. {$endif MEMDEBUG}
  490. end.
  491. {
  492. $Log$
  493. Revision 1.24 2002-12-29 18:26:31 peter
  494. * also use gettypename for procdef always
  495. Revision 1.23 2002/12/29 14:57:50 peter
  496. * unit loading changed to first register units and load them
  497. afterwards. This is needed to support uses xxx in yyy correctly
  498. * unit dependency check fixed
  499. Revision 1.22 2002/09/05 19:29:46 peter
  500. * memdebug enhancements
  501. Revision 1.21 2002/08/18 20:06:28 peter
  502. * inlining is now also allowed in interface
  503. * renamed write/load to ppuwrite/ppuload
  504. * tnode storing in ppu
  505. * nld,ncon,nbas are already updated for storing in ppu
  506. Revision 1.20 2002/08/11 13:24:16 peter
  507. * saving of asmsymbols in ppu supported
  508. * asmsymbollist global is removed and moved into a new class
  509. tasmlibrarydata that will hold the info of a .a file which
  510. corresponds with a single module. Added librarydata to tmodule
  511. to keep the library info stored for the module. In the future the
  512. objectfiles will also be stored to the tasmlibrarydata class
  513. * all getlabel/newasmsymbol and friends are moved to the new class
  514. Revision 1.19 2002/07/01 18:46:29 peter
  515. * internal linker
  516. * reorganized aasm layer
  517. Revision 1.18 2002/05/18 13:34:21 peter
  518. * readded missing revisions
  519. Revision 1.17 2002/05/16 19:46:45 carl
  520. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  521. + try to fix temp allocation (still in ifdef)
  522. + generic constructor calls
  523. + start of tassembler / tmodulebase class cleanup
  524. Revision 1.15 2002/05/12 16:53:15 peter
  525. * moved entry and exitcode to ncgutil and cgobj
  526. * foreach gets extra argument for passing local data to the
  527. iterator function
  528. * -CR checks also class typecasts at runtime by changing them
  529. into as
  530. * fixed compiler to cycle with the -CR option
  531. * fixed stabs with elf writer, finally the global variables can
  532. be watched
  533. * removed a lot of routines from cga unit and replaced them by
  534. calls to cgobj
  535. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  536. u32bit then the other is typecasted also to u32bit without giving
  537. a rangecheck warning/error.
  538. * fixed pascal calling method with reversing also the high tree in
  539. the parast, detected by tcalcst3 test
  540. Revision 1.14 2002/04/19 15:46:04 peter
  541. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  542. in most cases and not written to the ppu
  543. * add mangeledname_prefix() routine to generate the prefix of
  544. manglednames depending on the current procedure, object and module
  545. * removed static procprefix since the mangledname is now build only
  546. on demand from tprocdef.mangledname
  547. }