symtablt.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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. function varsymprefix:string;virtual;
  42. end;
  43. Timplsymtable=object(Tglobalsymtable)
  44. unitid:word;
  45. function varsymprefix:string;virtual;
  46. end;
  47. Tabstractrecordsymtable=object(Tcontainingsymtable)
  48. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  49. end;
  50. Precordsymtable=^Trecordsymtable;
  51. Trecordsymtable=object(Tabstractrecordsymtable)
  52. end;
  53. Tobjectsymtable=object(Tabstractrecordsymtable)
  54. defowner:Pobjectsymtable;
  55. { function speedsearch(const s:stringid;
  56. speedvalue:longint):Psym;virtual;}
  57. end;
  58. Tprocsymtable=object(Tcontainingsymtable)
  59. {Replaces the old local and paramsymtables.}
  60. lexlevel:byte;
  61. paramdatasize:longint;
  62. {If this is a method, this points to the objectdef. It is
  63. possible to make another Tmethodsymtable and move this field
  64. to it, but I think the advantage is not worth it. (DM)}
  65. method:Pdef;
  66. function insert(sym:Psym):boolean;virtual;
  67. function speedsearch(const s:stringid;
  68. speedvalue:longint):Psym;virtual;
  69. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  70. end;
  71. Tunitsymtable=object(Tcontainingsymtable)
  72. unittypecount:word;
  73. unitsym:Psym;
  74. constructor init(const n:string);
  75. {Checks if all used units are used.}
  76. procedure check_units;
  77. function speedsearch(const s:stringid;
  78. speedvalue:longint):Psym;virtual;
  79. function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
  80. function varsymprefix:string;virtual;
  81. destructor done;virtual;
  82. end;
  83. Twithsymtable=object(Tsymtable)
  84. link:Pcontainingsymtable;
  85. {If with a^.b.c is encountered, withrefnode points to a tree
  86. a^.b.c .}
  87. withrefnode:pointer;
  88. constructor init(Alink:Pcontainingsymtable);
  89. function speedsearch(const s:stringid;
  90. speedvalue:longint):Psym;virtual;
  91. end;
  92. implementation
  93. uses symbols,files,globals,aasm,systems,defs,verbose;
  94. function data_align(length:longint):longint;
  95. begin
  96. if length>2 then
  97. data_align:=4
  98. else if length>1 then
  99. data_align:=2
  100. else
  101. data_align:=1;
  102. end;
  103. {****************************************************************************
  104. Tglobalsymtable
  105. ****************************************************************************}
  106. constructor Tglobalsymtable.init;
  107. begin
  108. inherited init;
  109. index_growsize:=128;
  110. end;
  111. procedure Tglobalsymtable.check_units;
  112. begin
  113. end;
  114. function Tglobalsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  115. var ali:longint;
  116. segment:Paasmoutput;
  117. begin
  118. if Ptypedconstsym(sym)^.is_really_const then
  119. segment:=consts
  120. else
  121. segment:=datasegment;
  122. if (cs_create_smart in aktmoduleswitches) then
  123. segment^.concat(new(Pai_cut,init));
  124. ali:=data_align(len);
  125. align(datasize,ali);
  126. {$ifdef GDB}
  127. if cs_debuginfo in aktmoduleswitches then
  128. concatstabto(segment);
  129. {$endif GDB}
  130. segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname,len)));
  131. end;
  132. function Tglobalsymtable.varsymtodata(sym:Psym;len:longint):longint;
  133. var ali:longint;
  134. begin
  135. if (cs_create_smart in aktmoduleswitches) then
  136. bsssegment^.concat(new(Pai_cut,init));
  137. ali:=data_align(len);
  138. align(datasize,ali);
  139. {$ifdef GDB}
  140. if cs_debuginfo in aktmoduleswitches then
  141. concatstabto(bsssegment);
  142. {$endif GDB}
  143. bsssegment^.concat(new(Pai_datablock,
  144. init_global(sym^.mangledname,len)));
  145. varsymtodata:=inherited varsymtodata(sym,len);
  146. {This symbol can't be loaded to a register.}
  147. exclude(Pvarsym(sym)^.properties,vo_regable);
  148. end;
  149. {****************************************************************************
  150. Timplsymtable
  151. ****************************************************************************}
  152. function Timplsymtable.varsymprefix:string;
  153. begin
  154. varsymprefix:='U_'+name^+'_';
  155. end;
  156. {****************************************************************************
  157. Tinterfacesymtable
  158. ****************************************************************************}
  159. function Tinterfacesymtable.varsymprefix:string;
  160. begin
  161. varsymprefix:='_'+name^+'$$$'+'_';
  162. end;
  163. {****************************************************************************
  164. Tabstractrecordsymtable
  165. ****************************************************************************}
  166. function Tabstractrecordsymtable.varsymtodata(sym:Psym;
  167. len:longint):longint;
  168. begin
  169. datasize:=(datasize+(packrecordalignment[aktpackrecords]-1))
  170. and not (packrecordalignment[aktpackrecords]-1);
  171. varsymtodata:=inherited varsymtodata(sym,len);
  172. end;
  173. {****************************************************************************
  174. Trecordsymtable
  175. ****************************************************************************}
  176. {****************************************************************************
  177. Tobjectsymtable
  178. ****************************************************************************}
  179. {This is not going to work this way, because the definition isn't known yet
  180. when the symbol hasn't been found. For procsyms the object properties
  181. are stored in the definitions, because they can be overloaded.
  182. function Tobjectsymtable.speedsearch(const s:stringid;
  183. speedvalue:longint):Psym;
  184. var r:Psym;
  185. begin
  186. r:=inherited speedsearch(s,speedvalue);
  187. if (r<>nil) and (Pprocdef(r)^.objprop=sp_static) and
  188. allow_only_static then
  189. begin
  190. message(sym_e_only_static_in_static);
  191. speedsearch:=nil;
  192. end
  193. else
  194. speedsearch:=r;
  195. end;}
  196. {****************************************************************************
  197. Tprocsymsymtable
  198. ****************************************************************************}
  199. function Tprocsymtable.insert(sym:Psym):boolean;
  200. begin
  201. if (method<>nil) and (Pobjectdef(method)^.search(sym^.name)<>nil) then
  202. insert:=inherited insert(sym)
  203. else
  204. duplicatesym(sym);
  205. end;
  206. function Tprocsymtable.speedsearch(const s:stringid;
  207. speedvalue:longint):Psym;
  208. begin
  209. speedsearch:=inherited speedsearch(s,speedvalue);
  210. end;
  211. function Tprocsymtable.varsymtodata(sym:Psym;
  212. len:longint):longint;
  213. var modulo:longint;
  214. begin
  215. if typeof(sym^)=typeof(Tparamsym) then
  216. begin
  217. varsymtodata:=paramdatasize;
  218. paramdatasize:=align(datasize+len,target_os.stackalignment);
  219. end
  220. else
  221. begin
  222. {Sym must be a varsym.}
  223. {Align datastructures >=4 on a dword.}
  224. if len>=4 then
  225. align(len,4)
  226. else
  227. {$ifdef m68k}
  228. {Align datastructures with size 1,2,3 on a word.}
  229. align(len,2);
  230. {$else}
  231. {Align datastructures with size 2 or 3 on a word.}
  232. if len>=2 then
  233. align(len,2);
  234. {$endif}
  235. varsymtodata:=inherited varsymtodata(sym,len);
  236. end;
  237. end;
  238. {****************************************************************************
  239. Tunitsymtable
  240. ****************************************************************************}
  241. constructor Tunitsymtable.init(const n:string);
  242. begin
  243. inherited init;
  244. name:=stringdup(n);
  245. index_growsize:=128;
  246. end;
  247. procedure Tunitsymtable.check_units;
  248. begin
  249. end;
  250. function Tunitsymtable.speedsearch(const s:stringid;
  251. speedvalue:longint):Psym;
  252. var r:Psym;
  253. begin
  254. r:=inherited speedsearch(s,speedvalue);
  255. { if unitsym<>nil then
  256. Punitsym(unitsym)^.refs;}
  257. { if (r^.typ=unitsym) and assigned(current_module) and
  258. (current_module^.interfacesymtable<>@self) then
  259. r:=nil;}
  260. speedsearch:=r;
  261. end;
  262. function Tunitsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  263. var ali:longint;
  264. segment:Paasmoutput;
  265. begin
  266. if Ptypedconstsym(sym)^.is_really_const then
  267. segment:=consts
  268. else
  269. segment:=datasegment;
  270. if (cs_create_smart in aktmoduleswitches) then
  271. segment^.concat(new(Pai_cut,init));
  272. ali:=data_align(len);
  273. align(datasize,ali);
  274. {$ifdef GDB}
  275. if cs_debuginfo in aktmoduleswitches then
  276. concatstabto(segment);
  277. {$endif GDB}
  278. if (cs_create_smart in aktmoduleswitches) then
  279. segment^.concat(new(Pai_symbol,
  280. initname_global(sym^.mangledname,len)))
  281. else
  282. segment^.concat(new(Pai_symbol,
  283. initname(sym^.mangledname,len)));
  284. end;
  285. function Tunitsymtable.varsymprefix:string;
  286. begin
  287. varsymprefix:='U_'+name^+'_';
  288. end;
  289. destructor Tunitsymtable.done;
  290. begin
  291. stringdispose(name);
  292. inherited done;
  293. end;
  294. {****************************************************************************
  295. Twithsymtable
  296. ****************************************************************************}
  297. constructor Twithsymtable.init(Alink:Pcontainingsymtable);
  298. begin
  299. inherited init;
  300. link:=Alink;
  301. end;
  302. function Twithsymtable.speedsearch(const s:stringid;speedvalue:longint):Psym;
  303. begin
  304. speedsearch:=link^.speedsearch(s,speedvalue);
  305. end;
  306. end.