symtype.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  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=procvardef) 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. end
  264. else
  265. resolvedef(pointer(def));
  266. end;
  267. {****************************************************************************
  268. TSymList
  269. ****************************************************************************}
  270. constructor tsymlist.create;
  271. begin
  272. def:=nil; { needed for procedures }
  273. firstsym:=nil;
  274. lastsym:=nil;
  275. end;
  276. destructor tsymlist.destroy;
  277. begin
  278. clear;
  279. end;
  280. function tsymlist.empty:boolean;
  281. begin
  282. empty:=(firstsym=nil);
  283. end;
  284. procedure tsymlist.clear;
  285. var
  286. hp : psymlistitem;
  287. begin
  288. while assigned(firstsym) do
  289. begin
  290. hp:=firstsym;
  291. firstsym:=firstsym^.next;
  292. dispose(hp);
  293. end;
  294. firstsym:=nil;
  295. lastsym:=nil;
  296. def:=nil;
  297. end;
  298. procedure tsymlist.setdef(p:tdef);
  299. begin
  300. def:=p;
  301. end;
  302. procedure tsymlist.addsym(slt:tsltype;p:tsym);
  303. var
  304. hp : psymlistitem;
  305. begin
  306. if not assigned(p) then
  307. internalerror(200110203);
  308. new(hp);
  309. hp^.sltype:=slt;
  310. hp^.sym:=p;
  311. hp^.value:=0;
  312. hp^.next:=nil;
  313. if assigned(lastsym) then
  314. lastsym^.next:=hp
  315. else
  316. firstsym:=hp;
  317. lastsym:=hp;
  318. end;
  319. procedure tsymlist.addconst(slt:tsltype;v:longint);
  320. var
  321. hp : psymlistitem;
  322. begin
  323. new(hp);
  324. hp^.sltype:=slt;
  325. hp^.sym:=nil;
  326. hp^.value:=v;
  327. hp^.next:=nil;
  328. if assigned(lastsym) then
  329. lastsym^.next:=hp
  330. else
  331. firstsym:=hp;
  332. lastsym:=hp;
  333. end;
  334. function tsymlist.getcopy:tsymlist;
  335. var
  336. hp : tsymlist;
  337. hp2 : psymlistitem;
  338. hpn : psymlistitem;
  339. begin
  340. hp:=tsymlist.create;
  341. hp.def:=def;
  342. hp2:=firstsym;
  343. while assigned(hp2) do
  344. begin
  345. new(hpn);
  346. hpn^:=hp2^;
  347. hpn^.next:=nil;
  348. if assigned(hp.lastsym) then
  349. hp.lastsym^.next:=hpn
  350. else
  351. hp.firstsym:=hpn;
  352. hp.lastsym:=hpn;
  353. hp2:=hp2^.next;
  354. end;
  355. getcopy:=hp;
  356. end;
  357. procedure tsymlist.resolve;
  358. var
  359. hp : psymlistitem;
  360. begin
  361. resolvedef(pointer(def));
  362. hp:=firstsym;
  363. while assigned(hp) do
  364. begin
  365. if assigned(hp^.sym) then
  366. resolvesym(pointer(hp^.sym));
  367. hp:=hp^.next;
  368. end;
  369. end;
  370. {*****************************************************************************
  371. Symbol / Definition Resolving
  372. *****************************************************************************}
  373. procedure resolvederef(var p:tderef;var st:tsymtable;var idx:word);
  374. var
  375. hp : tderef;
  376. pd : tdef;
  377. begin
  378. st:=nil;
  379. idx:=0;
  380. while assigned(p) do
  381. begin
  382. case p.dereftype of
  383. derefaktrecordindex :
  384. begin
  385. st:=aktrecordsymtable;
  386. idx:=p.index;
  387. end;
  388. derefaktstaticindex :
  389. begin
  390. st:=aktstaticsymtable;
  391. idx:=p.index;
  392. end;
  393. derefaktlocal :
  394. begin
  395. st:=aktlocalsymtable;
  396. idx:=p.index;
  397. end;
  398. derefunit :
  399. begin
  400. {$ifdef NEWMAP}
  401. st:=tsymtable(current_module.map^[p.index]^.globalsymtable);
  402. {$else NEWMAP}
  403. st:=tsymtable(current_module.map^[p.index]);
  404. {$endif NEWMAP}
  405. end;
  406. derefrecord :
  407. begin
  408. pd:=tdef(st.getdefnr(p.index));
  409. st:=pd.getsymtable(gs_record);
  410. if not assigned(st) then
  411. internalerror(556658);
  412. end;
  413. dereflocal :
  414. begin
  415. pd:=tdef(st.getdefnr(p.index));
  416. st:=pd.getsymtable(gs_local);
  417. if not assigned(st) then
  418. internalerror(556658);
  419. end;
  420. derefpara :
  421. begin
  422. pd:=tdef(st.getdefnr(p.index));
  423. st:=pd.getsymtable(gs_para);
  424. if not assigned(st) then
  425. internalerror(556658);
  426. end;
  427. derefindex :
  428. begin
  429. idx:=p.index;
  430. end;
  431. else
  432. internalerror(556658);
  433. end;
  434. hp:=p;
  435. p:=p.next;
  436. hp.free;
  437. end;
  438. end;
  439. procedure resolvedef(var def:pointer);
  440. var
  441. st : tsymtable;
  442. idx : word;
  443. begin
  444. resolvederef(tderef(pointer(def)),st,idx);
  445. if assigned(st) then
  446. def:=tdef(st.getdefnr(idx))
  447. else
  448. def:=nil;
  449. end;
  450. procedure resolvesym(var sym:pointer);
  451. var
  452. st : tsymtable;
  453. idx : word;
  454. begin
  455. resolvederef(tderef(pointer(sym)),st,idx);
  456. if assigned(st) then
  457. sym:=tsym(st.getsymnr(idx))
  458. else
  459. sym:=nil;
  460. end;
  461. {$ifdef MEMDEBUG}
  462. initialization
  463. membrowser:=TMemDebug.create('BrowserRefs');
  464. membrowser.stop;
  465. memrealnames:=TMemDebug.create('Realnames');
  466. memrealnames.stop;
  467. memmanglednames:=TMemDebug.create('Manglednames');
  468. memmanglednames.stop;
  469. memprocparast:=TMemDebug.create('ProcParaSt');
  470. memprocparast.stop;
  471. memproclocalst:=TMemDebug.create('ProcLocalSt');
  472. memproclocalst.stop;
  473. memprocnodetree:=TMemDebug.create('ProcNodeTree');
  474. memprocnodetree.stop;
  475. finalization
  476. membrowser.free;
  477. memrealnames.free;
  478. memmanglednames.free;
  479. memprocparast.free;
  480. memproclocalst.free;
  481. memprocnodetree.free;
  482. {$endif MEMDEBUG}
  483. end.
  484. {
  485. $Log$
  486. Revision 1.22 2002-09-05 19:29:46 peter
  487. * memdebug enhancements
  488. Revision 1.21 2002/08/18 20:06:28 peter
  489. * inlining is now also allowed in interface
  490. * renamed write/load to ppuwrite/ppuload
  491. * tnode storing in ppu
  492. * nld,ncon,nbas are already updated for storing in ppu
  493. Revision 1.20 2002/08/11 13:24:16 peter
  494. * saving of asmsymbols in ppu supported
  495. * asmsymbollist global is removed and moved into a new class
  496. tasmlibrarydata that will hold the info of a .a file which
  497. corresponds with a single module. Added librarydata to tmodule
  498. to keep the library info stored for the module. In the future the
  499. objectfiles will also be stored to the tasmlibrarydata class
  500. * all getlabel/newasmsymbol and friends are moved to the new class
  501. Revision 1.19 2002/07/01 18:46:29 peter
  502. * internal linker
  503. * reorganized aasm layer
  504. Revision 1.18 2002/05/18 13:34:21 peter
  505. * readded missing revisions
  506. Revision 1.17 2002/05/16 19:46:45 carl
  507. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  508. + try to fix temp allocation (still in ifdef)
  509. + generic constructor calls
  510. + start of tassembler / tmodulebase class cleanup
  511. Revision 1.15 2002/05/12 16:53:15 peter
  512. * moved entry and exitcode to ncgutil and cgobj
  513. * foreach gets extra argument for passing local data to the
  514. iterator function
  515. * -CR checks also class typecasts at runtime by changing them
  516. into as
  517. * fixed compiler to cycle with the -CR option
  518. * fixed stabs with elf writer, finally the global variables can
  519. be watched
  520. * removed a lot of routines from cga unit and replaced them by
  521. calls to cgobj
  522. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  523. u32bit then the other is typecasted also to u32bit without giving
  524. a rangecheck warning/error.
  525. * fixed pascal calling method with reversing also the high tree in
  526. the parast, detected by tcalcst3 test
  527. Revision 1.14 2002/04/19 15:46:04 peter
  528. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  529. in most cases and not written to the ppu
  530. * add mangeledname_prefix() routine to generate the prefix of
  531. manglednames depending on the current procedure, object and module
  532. * removed static procprefix since the mangledname is now build only
  533. on demand from tprocdef.mangledname
  534. }