symtype.pas 15 KB

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