symtype.pas 15 KB

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