symtype.pas 14 KB

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