symtablt.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. Tglobalsymtable=object(Tcontainingsymtable)
  32. constructor init;
  33. {Checks if all used units are used.}
  34. procedure check_units;
  35. function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
  36. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  37. end;
  38. Tinterfacesymtable=object(Tglobalsymtable)
  39. unitid:word;
  40. function varsymprefix:string;virtual;
  41. end;
  42. Timplsymtable=object(Tglobalsymtable)
  43. unitid:word;
  44. function varsymprefix:string;virtual;
  45. end;
  46. Tabstractrecordsymtable=object(Tcontainingsymtable)
  47. procedure insert(sym:Psym);virtual;
  48. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  49. end;
  50. Precordsymtable=^Trecordsymtable;
  51. Trecordsymtable=object(Tabstractsymtable)
  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. procedure insert(sym:Psym);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. constructor init(Alink:Pcontainingsymtable);
  86. function speedsearch(const s:stringid;
  87. speedvalue:longint):Psym;virtual;
  88. end;
  89. implementation
  90. uses symbols,files,globals,aasm,systems,defs,verbose;
  91. function data_align(length:longint):longint;
  92. begin
  93. if length>2 then
  94. data_align:=4
  95. else if length>1 then
  96. data_align:=2
  97. else
  98. data_align:=1;
  99. end;
  100. {****************************************************************************
  101. Tglobalsymtable
  102. ****************************************************************************}
  103. constructor Tglobalsymtable.init;
  104. begin
  105. inherited init;
  106. index_growsize:=128;
  107. end;
  108. procedure Tglobalsymtable.check_units;
  109. begin
  110. end;
  111. function Tglobalsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  112. var ali:longint;
  113. segment:Paasmoutput;
  114. begin
  115. if Ptypedconstsym(sym)^.is_really_const then
  116. segment:=consts
  117. else
  118. segment:=datasegment;
  119. if (cs_smartlink in aktmoduleswitches) then
  120. segment^.concat(new(Pai_cut,init));
  121. ali:=data_align(len);
  122. align(datasize,ali);
  123. {$ifdef GDB}
  124. if cs_debuginfo in aktmoduleswitches then
  125. concatstabto(segment);
  126. {$endif GDB}
  127. segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname)));
  128. end;
  129. function Tglobalsymtable.varsymtodata(sym:Psym;len:longint):longint;
  130. var ali:longint;
  131. begin
  132. if (cs_smartlink in aktmoduleswitches) then
  133. bsssegment^.concat(new(Pai_cut,init));
  134. ali:=data_align(len);
  135. align(datasize,ali);
  136. {$ifdef GDB}
  137. if cs_debuginfo in aktmoduleswitches then
  138. concatstabto(bsssegment);
  139. {$endif GDB}
  140. bsssegment^.concat(new(Pai_datablock,
  141. init_global(sym^.mangledname,len)));
  142. varsymtodata:=inherited varsymtodata(sym,len);
  143. {This symbol can't be loaded to a register.}
  144. exclude(Pvarsym(sym)^.properties,vo_regable);
  145. end;
  146. {****************************************************************************
  147. Timplsymtable
  148. ****************************************************************************}
  149. function Timplsymtable.varsymprefix:string;
  150. begin
  151. varsymprefix:='U_'+name^+'_';
  152. end;
  153. {****************************************************************************
  154. Tinterfacesymtable
  155. ****************************************************************************}
  156. function Tinterfacesymtable.varsymprefix:string;
  157. begin
  158. varsymprefix:='_'+name^+'$$$'+'_';
  159. end;
  160. {****************************************************************************
  161. Tabstractrecordsymtable
  162. ****************************************************************************}
  163. procedure Tabstractrecordsymtable.insert(sym:Psym);
  164. begin
  165. { if typeof(sym)=typeof(Tenumsym) then
  166. if owner<>nil then
  167. owner^.insert(sym)
  168. else
  169. internalerror($990802)
  170. else}
  171. inherited insert(sym);
  172. end;
  173. function Tabstractrecordsymtable.varsymtodata(sym:Psym;
  174. len:longint):longint;
  175. begin
  176. datasize:=(datasize+(aktpackrecords-1)) and (not aktpackrecords-1);
  177. varsymtodata:=inherited varsymtodata(sym,len);
  178. end;
  179. {****************************************************************************
  180. Trecordsymtable
  181. ****************************************************************************}
  182. {****************************************************************************
  183. Tobjectsymtable
  184. ****************************************************************************}
  185. function Tobjectsymtable.speedsearch(const s:stringid;
  186. speedvalue:longint):Psym;
  187. var r:Psym;
  188. begin
  189. r:=inherited speedsearch(s,speedvalue);
  190. if (r<>nil) and (sp_static in Pprocdef(r)^.objprop) and
  191. allow_only_static then
  192. begin
  193. message(sym_e_only_static_in_static);
  194. speedsearch:=nil;
  195. end
  196. else
  197. speedsearch:=r;
  198. end;
  199. {****************************************************************************
  200. Tprocsymsymtable
  201. ****************************************************************************}
  202. procedure Tprocsymtable.insert(sym:Psym);
  203. begin
  204. { if (method<>nil) and (method^.search(sym^.name)<>nil) then}
  205. inherited insert(sym)
  206. { else
  207. duplicatesym(sym)};
  208. end;
  209. function Tprocsymtable.speedsearch(const s:stringid;
  210. speedvalue:longint):Psym;
  211. begin
  212. speedsearch:=inherited speedsearch(s,speedvalue);
  213. end;
  214. function Tprocsymtable.varsymtodata(sym:Psym;
  215. len:longint):longint;
  216. var modulo:longint;
  217. begin
  218. if typeof(sym^)=typeof(Tparamsym) then
  219. begin
  220. varsymtodata:=paramdatasize;
  221. paramdatasize:=align(datasize+len,target_os.stackalignment);
  222. end
  223. else
  224. begin
  225. {Sym must be a varsym.}
  226. {Align datastructures >=4 on a dword.}
  227. if len>=4 then
  228. align(len,4)
  229. else
  230. {$ifdef m68k}
  231. {Align datastructures with size 1,2,3 on a word.}
  232. align(len,2);
  233. {$else}
  234. {Align datastructures with size 2 or 3 on a word.}
  235. if len>=2 then
  236. align(len,2);
  237. {$endif}
  238. varsymtodata:=inherited varsymtodata(sym,len);
  239. end;
  240. end;
  241. {****************************************************************************
  242. Tunitsymtable
  243. ****************************************************************************}
  244. constructor Tunitsymtable.init(const n:string);
  245. begin
  246. inherited init;
  247. name:=stringdup(n);
  248. index_growsize:=128;
  249. end;
  250. procedure Tunitsymtable.check_units;
  251. begin
  252. end;
  253. function Tunitsymtable.speedsearch(const s:stringid;
  254. speedvalue:longint):Psym;
  255. var r:Psym;
  256. begin
  257. r:=inherited speedsearch(s,speedvalue);
  258. { if unitsym<>nil then
  259. Punitsym(unitsym)^.refs;}
  260. { if (r^.typ=unitsym) and assigned(current_module) and
  261. (current_module^.interfacesymtable<>@self) then
  262. r:=nil;}
  263. speedsearch:=r;
  264. end;
  265. function Tunitsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  266. var ali:longint;
  267. segment:Paasmoutput;
  268. begin
  269. if Ptypedconstsym(sym)^.is_really_const then
  270. segment:=consts
  271. else
  272. segment:=datasegment;
  273. if (cs_smartlink in aktmoduleswitches) then
  274. segment^.concat(new(Pai_cut,init));
  275. ali:=data_align(len);
  276. align(datasize,ali);
  277. {$ifdef GDB}
  278. if cs_debuginfo in aktmoduleswitches then
  279. concatstabto(segment);
  280. {$endif GDB}
  281. if (cs_smartlink in aktmoduleswitches) then
  282. segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname)))
  283. else
  284. segment^.concat(new(Pai_symbol,initname(sym^.mangledname)));
  285. end;
  286. function Tunitsymtable.varsymprefix:string;
  287. begin
  288. varsymprefix:='U_'+name^+'_';
  289. end;
  290. destructor Tunitsymtable.done;
  291. begin
  292. stringdispose(name);
  293. inherited done;
  294. end;
  295. {****************************************************************************
  296. Twithsymtable
  297. ****************************************************************************}
  298. constructor Twithsymtable.init(Alink:Pcontainingsymtable);
  299. begin
  300. inherited init;
  301. link:=Alink;
  302. end;
  303. function Twithsymtable.speedsearch(const s:stringid;speedvalue:longint):Psym;
  304. begin
  305. speedsearch:=link^.speedsearch(s,speedvalue);
  306. end;
  307. end.