symbase.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  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
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symbase;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,globals,
  26. { symtable }
  27. symconst
  28. ;
  29. {************************************************
  30. Some internal constants
  31. ************************************************}
  32. const
  33. hasharraysize = 256;
  34. indexgrowsize = 64;
  35. {$ifdef GDB}
  36. memsizeinc = 2048; { for long stabstrings }
  37. {$endif GDB}
  38. {************************************************
  39. Needed forward pointers
  40. ************************************************}
  41. type
  42. tsymtable = class;
  43. {************************************************
  44. TSymtableEntry
  45. ************************************************}
  46. tsymtableentry = class(TNamedIndexItem)
  47. owner : tsymtable;
  48. end;
  49. {************************************************
  50. TDefEntry
  51. ************************************************}
  52. tdefentry = class(tsymtableentry)
  53. deftype : tdeftype;
  54. end;
  55. {************************************************
  56. TSymEntry
  57. ************************************************}
  58. { this object is the base for all symbol objects }
  59. tsymentry = class(tsymtableentry)
  60. typ : tsymtyp;
  61. end;
  62. {************************************************
  63. TSymtable
  64. ************************************************}
  65. tsearchhasharray = array[0..hasharraysize-1] of tsymentry;
  66. psearchhasharray = ^tsearchhasharray;
  67. tsymtable = class
  68. {$ifdef EXTDEBUG}
  69. private
  70. procedure dumpsym(p : TNamedIndexItem;arg:pointer);
  71. {$endif EXTDEBUG}
  72. public
  73. name : pstring;
  74. realname : pstring;
  75. symindex,
  76. defindex : TIndexArray;
  77. symsearch : Tdictionary;
  78. next : tsymtable;
  79. defowner : tdefentry; { for records and objects }
  80. symtabletype : tsymtabletype;
  81. { each symtable gets a number }
  82. unitid : word;
  83. { level of symtable, used for nested procedures }
  84. symtablelevel : byte;
  85. constructor Create(const s:string);
  86. destructor destroy;override;
  87. procedure clear;virtual;
  88. function rename(const olds,news : stringid):tsymentry;
  89. procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
  90. procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
  91. procedure insert(sym : tsymentry);virtual;
  92. procedure replace(oldsym,newsym:tsymentry);
  93. function search(const s : stringid) : tsymentry;
  94. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
  95. procedure registerdef(p : tdefentry);
  96. {$ifdef EXTDEBUG}
  97. procedure dump;
  98. {$endif EXTDEBUG}
  99. function getdefnr(l : longint) : tdefentry;
  100. function getsymnr(l : longint) : tsymentry;
  101. {$ifdef GDB}
  102. function getnewtypecount : word; virtual;
  103. {$endif GDB}
  104. end;
  105. var
  106. registerdef : boolean; { true, when defs should be registered }
  107. defaultsymtablestack : tsymtable; { symtablestack after default units have been loaded }
  108. symtablestack : tsymtable; { linked list of symtables }
  109. aktrecordsymtable : tsymtable; { current record symtable }
  110. aktstaticsymtable : tsymtable; { current static symtable }
  111. aktglobalsymtable : tsymtable; { current global symtable }
  112. aktparasymtable : tsymtable; { current proc para symtable }
  113. aktlocalsymtable : tsymtable; { current proc local symtable }
  114. implementation
  115. uses
  116. verbose;
  117. {****************************************************************************
  118. TSYMTABLE
  119. ****************************************************************************}
  120. constructor tsymtable.Create(const s:string);
  121. begin
  122. if s<>'' then
  123. begin
  124. name:=stringdup(upper(s));
  125. realname:=stringdup(s);
  126. end
  127. else
  128. begin
  129. name:=nil;
  130. realname:=nil;
  131. end;
  132. symtabletype:=abstractsymtable;
  133. symtablelevel:=0;
  134. defowner:=nil;
  135. next:=nil;
  136. symindex:=tindexarray.create(indexgrowsize);
  137. defindex:=TIndexArray.create(indexgrowsize);
  138. symsearch:=tdictionary.create;
  139. symsearch.noclear:=true;
  140. unitid:=0;
  141. end;
  142. destructor tsymtable.destroy;
  143. begin
  144. stringdispose(name);
  145. stringdispose(realname);
  146. symindex.destroy;
  147. defindex.destroy;
  148. { symsearch can already be disposed or set to nil for withsymtable }
  149. if assigned(symsearch) then
  150. begin
  151. symsearch.destroy;
  152. symsearch:=nil;
  153. end;
  154. end;
  155. {$ifdef EXTDEBUG}
  156. procedure tsymtable.dumpsym(p : TNamedIndexItem;arg:pointer);
  157. begin
  158. writeln(p.name);
  159. end;
  160. procedure tsymtable.dump;
  161. begin
  162. if assigned(name) then
  163. writeln('Symtable ',name^)
  164. else
  165. writeln('Symtable <not named>');
  166. symsearch.foreach({$ifdef FPCPROCVAR}@{$endif}dumpsym,nil);
  167. end;
  168. {$endif EXTDEBUG}
  169. procedure tsymtable.registerdef(p : tdefentry);
  170. begin
  171. defindex.insert(p);
  172. { set def owner and indexnb }
  173. p.owner:=self;
  174. end;
  175. procedure tsymtable.foreach(proc2call : tnamedindexcallback;arg:pointer);
  176. begin
  177. symindex.foreach(proc2call,arg);
  178. end;
  179. procedure tsymtable.foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
  180. begin
  181. symindex.foreach_static(proc2call,arg);
  182. end;
  183. {***********************************************
  184. Table Access
  185. ***********************************************}
  186. procedure tsymtable.clear;
  187. begin
  188. symindex.clear;
  189. defindex.clear;
  190. end;
  191. procedure tsymtable.insert(sym:tsymentry);
  192. begin
  193. sym.owner:=self;
  194. { insert in index and search hash }
  195. symindex.insert(sym);
  196. symsearch.insert(sym);
  197. end;
  198. procedure tsymtable.replace(oldsym,newsym:tsymentry);
  199. begin
  200. { Replace the entry in the dictionary, this checks
  201. the name }
  202. if not symsearch.replace(oldsym,newsym) then
  203. internalerror(200209061);
  204. { replace in index }
  205. symindex.replace(oldsym,newsym);
  206. { set owner of new symb }
  207. newsym.owner:=self;
  208. end;
  209. function tsymtable.search(const s : stringid) : tsymentry;
  210. begin
  211. search:=speedsearch(s,getspeedvalue(s));
  212. end;
  213. function tsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  214. begin
  215. speedsearch:=tsymentry(symsearch.speedsearch(s,speedvalue));
  216. end;
  217. function tsymtable.rename(const olds,news : stringid):tsymentry;
  218. begin
  219. rename:=tsymentry(symsearch.rename(olds,news));
  220. end;
  221. function tsymtable.getsymnr(l : longint) : tsymentry;
  222. var
  223. hp : tsymentry;
  224. begin
  225. hp:=tsymentry(symindex.search(l));
  226. if hp=nil then
  227. internalerror(10999);
  228. getsymnr:=hp;
  229. end;
  230. function tsymtable.getdefnr(l : longint) : tdefentry;
  231. var
  232. hp : tdefentry;
  233. begin
  234. hp:=tdefentry(defindex.search(l));
  235. if hp=nil then
  236. internalerror(10998);
  237. getdefnr:=hp;
  238. end;
  239. {$ifdef GDB}
  240. function tsymtable.getnewtypecount : word;
  241. begin
  242. getnewtypecount:=0;
  243. end;
  244. {$endif GDB}
  245. end.
  246. {
  247. $Log$
  248. Revision 1.15 2003-09-23 17:56:06 peter
  249. * locals and paras are allocated in the code generation
  250. * tvarsym.localloc contains the location of para/local when
  251. generating code for the current procedure
  252. Revision 1.14 2003/06/25 18:31:23 peter
  253. * sym,def resolving partly rewritten to support also parent objects
  254. not directly available through the uses clause
  255. Revision 1.13 2003/06/07 20:26:32 peter
  256. * re-resolving added instead of reloading from ppu
  257. * tderef object added to store deref info for resolving
  258. Revision 1.12 2003/04/27 11:21:34 peter
  259. * aktprocdef renamed to current_procdef
  260. * procinfo renamed to current_procinfo
  261. * procinfo will now be stored in current_module so it can be
  262. cleaned up properly
  263. * gen_main_procsym changed to create_main_proc and release_main_proc
  264. to also generate a tprocinfo structure
  265. * fixed unit implicit initfinal
  266. Revision 1.11 2003/04/27 07:29:51 peter
  267. * current_procdef cleanup, current_procdef is now always nil when parsing
  268. a new procdef declaration
  269. * aktprocsym removed
  270. * lexlevel removed, use symtable.symtablelevel instead
  271. * implicit init/final code uses the normal genentry/genexit
  272. * funcret state checking updated for new funcret handling
  273. Revision 1.10 2002/12/07 14:27:09 carl
  274. * 3% memory optimization
  275. * changed some types
  276. + added type checking with different size for call node and for
  277. parameters
  278. Revision 1.9 2002/10/02 20:51:59 peter
  279. * tsymtable.dump to dump the names in a symtable to stdout
  280. Revision 1.8 2002/09/09 17:34:15 peter
  281. * tdicationary.replace added to replace and item in a dictionary. This
  282. is only allowed for the same name
  283. * varsyms are inserted in symtable before the types are parsed. This
  284. fixes the long standing "var longint : longint" bug
  285. - consume_idlist and idstringlist removed. The loops are inserted
  286. at the callers place and uses the symtable for duplicate id checking
  287. Revision 1.7 2002/08/25 19:25:20 peter
  288. * sym.insert_in_data removed
  289. * symtable.insertvardata/insertconstdata added
  290. * removed insert_in_data call from symtable.insert, it needs to be
  291. called separatly. This allows to deref the address calculation
  292. * procedures now calculate the parast addresses after the procedure
  293. directives are parsed. This fixes the cdecl parast problem
  294. * push_addr_param has an extra argument that specifies if cdecl is used
  295. or not
  296. Revision 1.6 2002/05/18 13:34:18 peter
  297. * readded missing revisions
  298. Revision 1.5 2002/05/16 19:46:44 carl
  299. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  300. + try to fix temp allocation (still in ifdef)
  301. + generic constructor calls
  302. + start of tassembler / tmodulebase class cleanup
  303. Revision 1.3 2002/05/12 16:53:10 peter
  304. * moved entry and exitcode to ncgutil and cgobj
  305. * foreach gets extra argument for passing local data to the
  306. iterator function
  307. * -CR checks also class typecasts at runtime by changing them
  308. into as
  309. * fixed compiler to cycle with the -CR option
  310. * fixed stabs with elf writer, finally the global variables can
  311. be watched
  312. * removed a lot of routines from cga unit and replaced them by
  313. calls to cgobj
  314. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  315. u32bit then the other is typecasted also to u32bit without giving
  316. a rangecheck warning/error.
  317. * fixed pascal calling method with reversing also the high tree in
  318. the parast, detected by tcalcst3 test
  319. }