symtype.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  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. 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.23 2002-12-29 14:57:50 peter
  494. * unit loading changed to first register units and load them
  495. afterwards. This is needed to support uses xxx in yyy correctly
  496. * unit dependency check fixed
  497. Revision 1.22 2002/09/05 19:29:46 peter
  498. * memdebug enhancements
  499. Revision 1.21 2002/08/18 20:06:28 peter
  500. * inlining is now also allowed in interface
  501. * renamed write/load to ppuwrite/ppuload
  502. * tnode storing in ppu
  503. * nld,ncon,nbas are already updated for storing in ppu
  504. Revision 1.20 2002/08/11 13:24:16 peter
  505. * saving of asmsymbols in ppu supported
  506. * asmsymbollist global is removed and moved into a new class
  507. tasmlibrarydata that will hold the info of a .a file which
  508. corresponds with a single module. Added librarydata to tmodule
  509. to keep the library info stored for the module. In the future the
  510. objectfiles will also be stored to the tasmlibrarydata class
  511. * all getlabel/newasmsymbol and friends are moved to the new class
  512. Revision 1.19 2002/07/01 18:46:29 peter
  513. * internal linker
  514. * reorganized aasm layer
  515. Revision 1.18 2002/05/18 13:34:21 peter
  516. * readded missing revisions
  517. Revision 1.17 2002/05/16 19:46:45 carl
  518. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  519. + try to fix temp allocation (still in ifdef)
  520. + generic constructor calls
  521. + start of tassembler / tmodulebase class cleanup
  522. Revision 1.15 2002/05/12 16:53:15 peter
  523. * moved entry and exitcode to ncgutil and cgobj
  524. * foreach gets extra argument for passing local data to the
  525. iterator function
  526. * -CR checks also class typecasts at runtime by changing them
  527. into as
  528. * fixed compiler to cycle with the -CR option
  529. * fixed stabs with elf writer, finally the global variables can
  530. be watched
  531. * removed a lot of routines from cga unit and replaced them by
  532. calls to cgobj
  533. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  534. u32bit then the other is typecasted also to u32bit without giving
  535. a rangecheck warning/error.
  536. * fixed pascal calling method with reversing also the high tree in
  537. the parast, detected by tcalcst3 test
  538. Revision 1.14 2002/04/19 15:46:04 peter
  539. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  540. in most cases and not written to the ppu
  541. * add mangeledname_prefix() routine to generate the prefix of
  542. manglednames depending on the current procedure, object and module
  543. * removed static procprefix since the mangledname is now build only
  544. on demand from tprocdef.mangledname
  545. }