symtype.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,
  23. { global }
  24. globtype,globals,
  25. { symtable }
  26. symconst,symbase,
  27. { aasm }
  28. aasm
  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. function typename:string;
  58. function gettypename:string;virtual;
  59. function size:longint;virtual;abstract;
  60. function alignment:longint;virtual;abstract;
  61. function getsymtable(t:tgetsymtable):tsymtable;virtual;
  62. function is_publishable:boolean;virtual;abstract;
  63. function needs_inittable:boolean;virtual;abstract;
  64. end;
  65. {************************************************
  66. TSym
  67. ************************************************}
  68. { this object is the base for all symbol objects }
  69. tsym = class(tsymentry)
  70. _realname : pstring;
  71. fileinfo : tfileposinfo;
  72. symoptions : tsymoptions;
  73. constructor create(const n : string);
  74. destructor destroy;override;
  75. function realname:string;
  76. procedure deref;virtual;abstract;
  77. function gettypedef:tdef;virtual;
  78. function mangledname : string;virtual;abstract;
  79. end;
  80. {************************************************
  81. TType
  82. ************************************************}
  83. ttype = object
  84. def : tdef;
  85. sym : tsym;
  86. procedure reset;
  87. procedure setdef(p:tdef);
  88. procedure setsym(p:tsym);
  89. procedure resolve;
  90. end;
  91. {************************************************
  92. TSymList
  93. ************************************************}
  94. psymlistitem = ^tsymlistitem;
  95. tsymlistitem = record
  96. sym : tsym;
  97. next : psymlistitem;
  98. end;
  99. tsymlist = class
  100. def : tdef;
  101. firstsym,
  102. lastsym : psymlistitem;
  103. constructor create;
  104. destructor destroy;override;
  105. function empty:boolean;
  106. procedure setdef(p:tdef);
  107. procedure addsym(p:tsym);
  108. procedure clear;
  109. function getcopy:tsymlist;
  110. procedure resolve;
  111. end;
  112. { resolving }
  113. procedure resolvesym(var sym:tsym);
  114. procedure resolvedef(var def:tdef);
  115. implementation
  116. uses
  117. verbose,
  118. fmodule;
  119. {****************************************************************************
  120. Tdef
  121. ****************************************************************************}
  122. constructor tdef.create;
  123. begin
  124. inherited create;
  125. deftype:=abstractdef;
  126. owner := nil;
  127. typesym := nil;
  128. defoptions:=[];
  129. end;
  130. function tdef.typename:string;
  131. begin
  132. if assigned(typesym) and
  133. not(deftype=procvardef) and
  134. assigned(typesym._realname) and
  135. (typesym._realname^[1]<>'$') then
  136. typename:=typesym._realname^
  137. else
  138. typename:=gettypename;
  139. end;
  140. function tdef.gettypename : string;
  141. begin
  142. gettypename:='<unknown type>'
  143. end;
  144. function tdef.getsymtable(t:tgetsymtable):tsymtable;
  145. begin
  146. getsymtable:=nil;
  147. end;
  148. {****************************************************************************
  149. TSYM (base for all symtypes)
  150. ****************************************************************************}
  151. constructor tsym.create(const n : string);
  152. begin
  153. if n[1]='$' then
  154. inherited createname(copy(n,2,255))
  155. else
  156. inherited createname(upper(n));
  157. _realname:=stringdup(n);
  158. typ:=abstractsym;
  159. symoptions:=[];
  160. end;
  161. destructor tsym.destroy;
  162. begin
  163. stringdispose(_realname);
  164. inherited destroy;
  165. end;
  166. function tsym.realname : string;
  167. begin
  168. if assigned(_realname) then
  169. realname:=_realname^
  170. else
  171. realname:=name;
  172. end;
  173. function tsym.gettypedef:tdef;
  174. begin
  175. gettypedef:=nil;
  176. end;
  177. {****************************************************************************
  178. TRef
  179. ****************************************************************************}
  180. constructor tref.create(ref :tref;pos : pfileposinfo);
  181. begin
  182. nextref:=nil;
  183. if pos<>nil then
  184. posinfo:=pos^;
  185. if assigned(current_module) then
  186. moduleindex:=current_module.unit_index;
  187. if assigned(ref) then
  188. ref.nextref:=self;
  189. is_written:=false;
  190. end;
  191. procedure tref.freechain;
  192. var
  193. p,q : tref;
  194. begin
  195. p:=nextref;
  196. nextref:=nil;
  197. while assigned(p) do
  198. begin
  199. q:=p.nextref;
  200. p.free;
  201. p:=q;
  202. end;
  203. end;
  204. destructor tref.destroy;
  205. begin
  206. nextref:=nil;
  207. end;
  208. {****************************************************************************
  209. TType
  210. ****************************************************************************}
  211. procedure ttype.reset;
  212. begin
  213. def:=nil;
  214. sym:=nil;
  215. end;
  216. procedure ttype.setdef(p:tdef);
  217. begin
  218. def:=p;
  219. sym:=nil;
  220. end;
  221. procedure ttype.setsym(p:tsym);
  222. begin
  223. sym:=p;
  224. def:=p.gettypedef;
  225. if not assigned(def) then
  226. internalerror(1234005);
  227. end;
  228. procedure ttype.resolve;
  229. begin
  230. if assigned(sym) then
  231. begin
  232. resolvesym(sym);
  233. setsym(sym);
  234. end
  235. else
  236. resolvedef(def);
  237. end;
  238. {****************************************************************************
  239. TSymList
  240. ****************************************************************************}
  241. constructor tsymlist.create;
  242. begin
  243. def:=nil; { needed for procedures }
  244. firstsym:=nil;
  245. lastsym:=nil;
  246. end;
  247. destructor tsymlist.destroy;
  248. begin
  249. clear;
  250. end;
  251. function tsymlist.empty:boolean;
  252. begin
  253. empty:=(firstsym=nil);
  254. end;
  255. procedure tsymlist.clear;
  256. var
  257. hp : psymlistitem;
  258. begin
  259. while assigned(firstsym) do
  260. begin
  261. hp:=firstsym;
  262. firstsym:=firstsym^.next;
  263. dispose(hp);
  264. end;
  265. firstsym:=nil;
  266. lastsym:=nil;
  267. def:=nil;
  268. end;
  269. procedure tsymlist.setdef(p:tdef);
  270. begin
  271. def:=p;
  272. end;
  273. procedure tsymlist.addsym(p:tsym);
  274. var
  275. hp : psymlistitem;
  276. begin
  277. if not assigned(p) then
  278. exit;
  279. new(hp);
  280. hp^.sym:=p;
  281. hp^.next:=nil;
  282. if assigned(lastsym) then
  283. lastsym^.next:=hp
  284. else
  285. firstsym:=hp;
  286. lastsym:=hp;
  287. end;
  288. function tsymlist.getcopy:tsymlist;
  289. var
  290. hp : tsymlist;
  291. hp2 : psymlistitem;
  292. begin
  293. hp:=tsymlist.create;
  294. hp.def:=def;
  295. hp2:=firstsym;
  296. while assigned(hp2) do
  297. begin
  298. hp.addsym(hp2^.sym);
  299. hp2:=hp2^.next;
  300. end;
  301. getcopy:=hp;
  302. end;
  303. procedure tsymlist.resolve;
  304. var
  305. hp : psymlistitem;
  306. begin
  307. resolvedef(def);
  308. hp:=firstsym;
  309. while assigned(hp) do
  310. begin
  311. resolvesym(hp^.sym);
  312. hp:=hp^.next;
  313. end;
  314. end;
  315. {*****************************************************************************
  316. Symbol / Definition Resolving
  317. *****************************************************************************}
  318. procedure resolvederef(var p:tderef;var st:tsymtable;var idx:word);
  319. var
  320. hp : tderef;
  321. pd : tdef;
  322. begin
  323. st:=nil;
  324. idx:=0;
  325. while assigned(p) do
  326. begin
  327. case p.dereftype of
  328. derefaktrecordindex :
  329. begin
  330. st:=aktrecordsymtable;
  331. idx:=p.index;
  332. end;
  333. derefaktstaticindex :
  334. begin
  335. st:=aktstaticsymtable;
  336. idx:=p.index;
  337. end;
  338. derefaktlocal :
  339. begin
  340. st:=aktlocalsymtable;
  341. idx:=p.index;
  342. end;
  343. derefunit :
  344. begin
  345. {$ifdef NEWMAP}
  346. st:=tsymtable(current_module.map^[p.index]^.globalsymtable);
  347. {$else NEWMAP}
  348. st:=tsymtable(current_module.map^[p.index]);
  349. {$endif NEWMAP}
  350. end;
  351. derefrecord :
  352. begin
  353. pd:=tdef(st.getdefnr(p.index));
  354. st:=pd.getsymtable(gs_record);
  355. if not assigned(st) then
  356. internalerror(556658);
  357. end;
  358. dereflocal :
  359. begin
  360. pd:=tdef(st.getdefnr(p.index));
  361. st:=pd.getsymtable(gs_local);
  362. if not assigned(st) then
  363. internalerror(556658);
  364. end;
  365. derefpara :
  366. begin
  367. pd:=tdef(st.getdefnr(p.index));
  368. st:=pd.getsymtable(gs_para);
  369. if not assigned(st) then
  370. internalerror(556658);
  371. end;
  372. derefindex :
  373. begin
  374. idx:=p.index;
  375. end;
  376. else
  377. internalerror(556658);
  378. end;
  379. hp:=p;
  380. p:=p.next;
  381. hp.free;
  382. end;
  383. end;
  384. procedure resolvedef(var def:tdef);
  385. var
  386. st : tsymtable;
  387. idx : word;
  388. begin
  389. resolvederef(tderef(def),st,idx);
  390. if assigned(st) then
  391. def:=tdef(st.getdefnr(idx))
  392. else
  393. def:=nil;
  394. end;
  395. procedure resolvesym(var sym:tsym);
  396. var
  397. st : tsymtable;
  398. idx : word;
  399. begin
  400. resolvederef(tderef(sym),st,idx);
  401. if assigned(st) then
  402. sym:=tsym(st.getsymnr(idx))
  403. else
  404. sym:=nil;
  405. end;
  406. end.
  407. {
  408. $Log$
  409. Revision 1.9 2001-08-30 20:13:57 peter
  410. * rtti/init table updates
  411. * rttisym for reusable global rtti/init info
  412. * support published for interfaces
  413. Revision 1.8 2001/08/06 21:40:49 peter
  414. * funcret moved from tprocinfo to tprocdef
  415. Revision 1.7 2001/05/06 14:49:19 peter
  416. * ppu object to class rewrite
  417. * move ppu read and write stuff to fppu
  418. Revision 1.6 2001/04/13 01:22:17 peter
  419. * symtable change to classes
  420. * range check generation and errors fixed, make cycle DEBUG=1 works
  421. * memory leaks fixed
  422. Revision 1.5 2001/04/02 21:20:35 peter
  423. * resulttype rewrite
  424. Revision 1.4 2000/12/25 00:07:30 peter
  425. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  426. tlinkedlist objects)
  427. Revision 1.3 2000/11/29 00:30:42 florian
  428. * unused units removed from uses clause
  429. * some changes for widestrings
  430. Revision 1.2 2000/11/07 20:48:33 peter
  431. * removed ref_count from pinputfile it's not used
  432. Revision 1.1 2000/10/31 22:02:53 peter
  433. * symtable splitted, no real code changes
  434. }