symtablt.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. {
  2. $Id$
  3. This unit implements the different types of symbol tables
  4. Copyright (C) 1998-2000 by Daniel Mantione,
  5. member of the Free Pascal development team
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. {$ifdef TP}
  20. {$N+,E+,F+}
  21. {$endif}
  22. unit symtablt;
  23. interface
  24. uses objects,cobjects,symtable,globtype;
  25. type Pglobalsymtable=^Tglobalsymtable;
  26. Pinterfacesymtable=^Tinterfacesymtable;
  27. Pimplsymtable=^Tsymtable;
  28. Pprocsymtable=^Tprocsymtable;
  29. Punitsymtable=^Tunitsymtable;
  30. Pobjectsymtable=^Tobjectsymtable;
  31. Pwithsymtable=^Twithsymtable;
  32. Tglobalsymtable=object(Tcontainingsymtable)
  33. constructor init;
  34. {Checks if all used units are used.}
  35. procedure check_units;
  36. function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
  37. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  38. end;
  39. Tinterfacesymtable=object(Tglobalsymtable)
  40. unitid:word;
  41. {$IFDEF TP}
  42. constructor init;
  43. {$ENDIF TP}
  44. function varsymprefix:string;virtual;
  45. end;
  46. Timplsymtable=object(Tglobalsymtable)
  47. unitid:word;
  48. {$IFDEF TP}
  49. constructor init;
  50. {$ENDIF TP}
  51. function varsymprefix:string;virtual;
  52. end;
  53. Tabstractrecordsymtable=object(Tcontainingsymtable)
  54. {$IFDEF TP}
  55. constructor init;
  56. {$ENDIF TP}
  57. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  58. end;
  59. Precordsymtable=^Trecordsymtable;
  60. Trecordsymtable=object(Tabstractrecordsymtable)
  61. {$IFDEF TP}
  62. constructor init;
  63. {$ENDIF TP}
  64. end;
  65. Tobjectsymtable=object(Tabstractrecordsymtable)
  66. defowner:Pobjectsymtable;
  67. {$IFDEF TP}
  68. constructor init;
  69. {$ENDIF TP}
  70. { function speedsearch(const s:stringid;
  71. speedvalue:longint):Psym;virtual;}
  72. end;
  73. Tprocsymtable=object(Tcontainingsymtable)
  74. {Replaces the old local and paramsymtables.}
  75. lexlevel:byte;
  76. paramdatasize:longint;
  77. {If this is a method, this points to the objectdef. It is
  78. possible to make another Tmethodsymtable and move this field
  79. to it, but I think the advantage is not worth it. (DM)}
  80. method:Pdef;
  81. {$IFDEF TP}
  82. constructor init;
  83. {$ENDIF TP}
  84. function insert(sym:Psym):boolean;virtual;
  85. function speedsearch(const s:stringid;
  86. speedvalue:longint):Psym;virtual;
  87. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  88. end;
  89. Tunitsymtable=object(Tcontainingsymtable)
  90. unittypecount:word;
  91. unitsym:Psym;
  92. constructor init(const n:string);
  93. {Checks if all used units are used.}
  94. procedure check_units;
  95. function speedsearch(const s:stringid;
  96. speedvalue:longint):Psym;virtual;
  97. function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
  98. function varsymprefix:string;virtual;
  99. destructor done;virtual;
  100. end;
  101. Twithsymtable=object(Tsymtable)
  102. link:Pcontainingsymtable;
  103. {If with a^.b.c is encountered, withrefnode points to a tree
  104. a^.b.c .}
  105. withrefnode:pointer;
  106. constructor init(Alink:Pcontainingsymtable);
  107. function speedsearch(const s:stringid;
  108. speedvalue:longint):Psym;virtual;
  109. end;
  110. implementation
  111. uses symbols,files,globals,aasm,systems,defs,verbose;
  112. {****************************************************************************
  113. Tglobalsymtable
  114. ****************************************************************************}
  115. constructor Tglobalsymtable.init;
  116. begin
  117. inherited init;
  118. {$IFDEF TP}setparent(typeof(Tcontainingsymtable));{$ENDIF}
  119. index_growsize:=128;
  120. end;
  121. procedure Tglobalsymtable.check_units;
  122. begin
  123. end;
  124. function Tglobalsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  125. var ali:longint;
  126. segment:Paasmoutput;
  127. begin
  128. if Ptypedconstsym(sym)^.is_really_const then
  129. segment:=consts
  130. else
  131. segment:=datasegment;
  132. if (cs_create_smart in aktmoduleswitches) then
  133. segment^.concat(new(Pai_cut,init));
  134. align_from_size(datasize,len);
  135. {$ifdef GDB}
  136. if cs_debuginfo in aktmoduleswitches then
  137. concatstabto(segment);
  138. {$endif GDB}
  139. segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname,len)));
  140. end;
  141. function Tglobalsymtable.varsymtodata(sym:Psym;len:longint):longint;
  142. var ali:longint;
  143. begin
  144. if (cs_create_smart in aktmoduleswitches) then
  145. bsssegment^.concat(new(Pai_cut,init));
  146. align_from_size(datasize,len);
  147. {$ifdef GDB}
  148. if cs_debuginfo in aktmoduleswitches then
  149. concatstabto(bsssegment);
  150. {$endif GDB}
  151. bsssegment^.concat(new(Pai_datablock,
  152. init_global(sym^.mangledname,len)));
  153. varsymtodata:=inherited varsymtodata(sym,len);
  154. {This symbol can't be loaded to a register.}
  155. exclude(Pvarsym(sym)^.properties,vo_regable);
  156. end;
  157. {****************************************************************************
  158. Timplsymtable
  159. ****************************************************************************}
  160. {$IFDEF TP}
  161. constructor Timplsymtable.init;
  162. begin
  163. inherited init;
  164. setparent(typeof(Tglobalsymtable));
  165. end;
  166. {$ENDIF TP}
  167. function Timplsymtable.varsymprefix:string;
  168. begin
  169. varsymprefix:='U_'+name^+'_';
  170. end;
  171. {****************************************************************************
  172. Tinterfacesymtable
  173. ****************************************************************************}
  174. {$IFDEF TP}
  175. constructor Tinterfacesymtable.init;
  176. begin
  177. inherited init;
  178. setparent(typeof(Tglobalsymtable));
  179. end;
  180. {$ENDIF TP}
  181. function Tinterfacesymtable.varsymprefix:string;
  182. begin
  183. varsymprefix:='_'+name^+'$$$'+'_';
  184. end;
  185. {****************************************************************************
  186. Tabstractrecordsymtable
  187. ****************************************************************************}
  188. {$IFDEF TP}
  189. constructor Tabstractrecordsymtable.init;
  190. begin
  191. inherited init;
  192. setparent(typeof(Tcontainingsymtable));
  193. end;
  194. {$ENDIF TP}
  195. function Tabstractrecordsymtable.varsymtodata(sym:Psym;
  196. len:longint):longint;
  197. begin
  198. datasize:=(datasize+(packrecordalignment[aktpackrecords]-1))
  199. and not (packrecordalignment[aktpackrecords]-1);
  200. varsymtodata:=inherited varsymtodata(sym,len);
  201. end;
  202. {****************************************************************************
  203. Trecordsymtable
  204. ****************************************************************************}
  205. {$IFDEF TP}
  206. constructor Trecordsymtable.init;
  207. begin
  208. inherited init;
  209. setparent(typeof(Tabstractrecordsymtable));
  210. end;
  211. {$ENDIF TP}
  212. {****************************************************************************
  213. Tobjectsymtable
  214. ****************************************************************************}
  215. {$IFDEF TP}
  216. constructor Tobjectsymtable.init;
  217. begin
  218. inherited init;
  219. setparent(typeof(Tabstractrecordsymtable));
  220. end;
  221. {$ENDIF TP}
  222. {This is not going to work this way, because the definition isn't known yet
  223. when the symbol hasn't been found. For procsyms the object properties
  224. are stored in the definitions, because they can be overloaded.
  225. function Tobjectsymtable.speedsearch(const s:stringid;
  226. speedvalue:longint):Psym;
  227. var r:Psym;
  228. begin
  229. r:=inherited speedsearch(s,speedvalue);
  230. if (r<>nil) and (Pprocdef(r)^.objprop=sp_static) and
  231. allow_only_static then
  232. begin
  233. message(sym_e_only_static_in_static);
  234. speedsearch:=nil;
  235. end
  236. else
  237. speedsearch:=r;
  238. end;}
  239. {****************************************************************************
  240. Tprocsymsymtable
  241. ****************************************************************************}
  242. {$IFDEF TP}
  243. constructor Tprocsymtable.init;
  244. begin
  245. inherited init;
  246. setparent(typeof(Tcontainingsymtable));
  247. end;
  248. {$ENDIF TP}
  249. function Tprocsymtable.insert(sym:Psym):boolean;
  250. begin
  251. if (method<>nil) and (Pobjectdef(method)^.search(sym^.name)<>nil) then
  252. insert:=inherited insert(sym)
  253. else
  254. duplicatesym(sym);
  255. end;
  256. function Tprocsymtable.speedsearch(const s:stringid;
  257. speedvalue:longint):Psym;
  258. begin
  259. speedsearch:=inherited speedsearch(s,speedvalue);
  260. end;
  261. function Tprocsymtable.varsymtodata(sym:Psym;
  262. len:longint):longint;
  263. var modulo:longint;
  264. begin
  265. if typeof(sym^)=typeof(Tparamsym) then
  266. begin
  267. varsymtodata:=paramdatasize;
  268. paramdatasize:=align(datasize+len,target_os.stackalignment);
  269. end
  270. else
  271. begin
  272. {Sym must be a varsym.}
  273. {Align datastructures >=4 on a dword.}
  274. align_from_size(len,len);
  275. varsymtodata:=inherited varsymtodata(sym,len);
  276. end;
  277. end;
  278. {****************************************************************************
  279. Tunitsymtable
  280. ****************************************************************************}
  281. constructor Tunitsymtable.init(const n:string);
  282. begin
  283. inherited init;
  284. {$IFDEF TP}setparent(typeof(Tcontainingsymtable));{$ENDIF}
  285. name:=stringdup(n);
  286. index_growsize:=128;
  287. end;
  288. procedure Tunitsymtable.check_units;
  289. begin
  290. end;
  291. function Tunitsymtable.speedsearch(const s:stringid;
  292. speedvalue:longint):Psym;
  293. var r:Psym;
  294. begin
  295. r:=inherited speedsearch(s,speedvalue);
  296. { if unitsym<>nil then
  297. Punitsym(unitsym)^.refs;}
  298. { if (r^.typ=unitsym) and assigned(current_module) and
  299. (current_module^.interfacesymtable<>@self) then
  300. r:=nil;}
  301. speedsearch:=r;
  302. end;
  303. function Tunitsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  304. var ali:longint;
  305. segment:Paasmoutput;
  306. begin
  307. if Ptypedconstsym(sym)^.is_really_const then
  308. segment:=consts
  309. else
  310. segment:=datasegment;
  311. if (cs_create_smart in aktmoduleswitches) then
  312. segment^.concat(new(Pai_cut,init));
  313. align_from_size(datasize,len);
  314. {$ifdef GDB}
  315. if cs_debuginfo in aktmoduleswitches then
  316. concatstabto(segment);
  317. {$endif GDB}
  318. if (cs_create_smart in aktmoduleswitches) then
  319. segment^.concat(new(Pai_symbol,
  320. initname_global(sym^.mangledname,len)))
  321. else
  322. segment^.concat(new(Pai_symbol,
  323. initname(sym^.mangledname,len)));
  324. end;
  325. function Tunitsymtable.varsymprefix:string;
  326. begin
  327. varsymprefix:='U_'+name^+'_';
  328. end;
  329. destructor Tunitsymtable.done;
  330. begin
  331. stringdispose(name);
  332. inherited done;
  333. end;
  334. {****************************************************************************
  335. Twithsymtable
  336. ****************************************************************************}
  337. constructor Twithsymtable.init(Alink:Pcontainingsymtable);
  338. begin
  339. inherited init;
  340. {$IFDEF TP}setparent(typeof(Tsymtable));{$ENDIF}
  341. link:=Alink;
  342. end;
  343. function Twithsymtable.speedsearch(const s:stringid;speedvalue:longint):Psym;
  344. begin
  345. speedsearch:=link^.speedsearch(s,speedvalue);
  346. end;
  347. end.