symtable.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. This unit handles the symbol tables
  5. Copyright (C) 1999 by Daniel Mantione,
  6. member of the Free Pascal development team
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ****************************************************************************
  19. }
  20. {$ifdef TP}
  21. {$N+,E+,F+}
  22. {$endif}
  23. unit symtable;
  24. interface
  25. uses objects,cobjects,aasm,globtype,i386base;
  26. type Tdefprop=(dp_regable, {Can be stored into a register.}
  27. dp_pointer_param, {A pointer should be used
  28. instead of the value for
  29. parameters of this definition.}
  30. dp_ret_in_acc); {Function results of this
  31. definition can be returned into
  32. the accumulator.}
  33. Tdefpropset=set of Tdefprop;
  34. Psymtable=^Tsymtable;
  35. Pcontainingsymtable=^Tcontainingsymtable;
  36. Pref=^Tref;
  37. Psymtableentry=^Tsymtableentry;
  38. Psym=^Tsym;
  39. Pdef=^Tdef;
  40. Tsymtable=object(Tobject)
  41. name:Pstring;
  42. datasize:longint;
  43. procedure foreach(proc2call:Tnamedindexcallback);virtual;
  44. procedure insert(sym:Psym);virtual;
  45. function search(const s:stringid):Psym;
  46. function speedsearch(const s:stringid;
  47. speedvalue:longint):Psym;virtual;
  48. function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
  49. function varsymprefix:string;virtual;
  50. function varsymtodata(sym:Psym;len:longint):longint;virtual;
  51. end;
  52. Tcontainingsymtable=object(Tsymtable)
  53. alignment:byte; {Aligment used in this symtable.}
  54. index_growsize:word; {The delta of the defindex collection.}
  55. defindex:Pcollection; {Contains all definitions in symtable.}
  56. symsearch:Pdictionary;
  57. constructor init;
  58. constructor load(var s:Tstream);
  59. procedure set_contents(s:Pdictionary;d:Pcollection);
  60. {Get_contents disposes the symtable object!!}
  61. procedure get_contents(var s:Pdictionary;var d:Pcollection);
  62. {Checks if all variabeles are used.}
  63. procedure check_vars;
  64. {Checks if all forwards resolved.}
  65. procedure check_forwards;
  66. {Checks if all labels used.}
  67. procedure check_labels;
  68. procedure foreach(proc2call:Tnamedindexcallback);virtual;
  69. procedure insert(sym:Psym);virtual;
  70. function speedsearch(const s:stringid;
  71. speedvalue:longint):Psym;virtual;
  72. procedure store(var s:Tstream);virtual;
  73. procedure registerdef(p:Pdef);
  74. destructor done;virtual;
  75. end;
  76. Tref=object(Tobject)
  77. posinfo:Tfileposinfo;
  78. moduleindex:word;
  79. constructor init(const pos:Tfileposinfo);
  80. destructor done;virtual;
  81. end;
  82. Tsymtableentry=object(Tnamedindexobject)
  83. owner:Pcontainingsymtable;
  84. end;
  85. Tsymprop=byte;
  86. Tsym=object(Tsymtableentry)
  87. fileinfo:Tfileposinfo;
  88. references:Pcollection; {Contains all references to symbol.}
  89. constructor init(const n : string);
  90. constructor load(var s:Tstream);
  91. procedure deref;virtual;
  92. procedure make_reference;
  93. function mangledname:string;virtual;
  94. procedure insert_in_data;virtual;
  95. procedure load_references;virtual;
  96. procedure register_defs;virtual;
  97. procedure store(var s:Tstream);virtual;
  98. function write_references:boolean;virtual;
  99. {$ifdef BrowserLog}
  100. procedure add_to_browserlog;virtual;
  101. {$endif BrowserLog}
  102. destructor done;virtual;
  103. end;
  104. Tdef=object(Tobject)
  105. savesize:longint;
  106. sym:Psym;
  107. owner:Pcontainingsymtable;
  108. properties:Tdefpropset;
  109. inittable:Pasmlabel; {Nil, or pointer to inittable.}
  110. rtti:Pasmlabel; {Nil, or pointer to rtti.}
  111. constructor init(Aowner:Pcontainingsymtable);
  112. constructor load(var s:Tstream);
  113. destructor done;virtual;
  114. {procedure correct_owner_symtable; REMOVED
  115. enumdefs can be safely in a record or object symtable,
  116. but the enum symbols must be in owners symtable.}
  117. procedure store(var s:Tstream);virtual;
  118. {Returns the typename of this definition.}
  119. function typename:string;virtual;
  120. procedure deref;virtual;
  121. function size:longint;virtual;
  122. procedure symderef;virtual;
  123. {Init. tables }
  124. function needs_inittable:boolean;virtual;
  125. procedure generate_inittable;
  126. function get_inittable_label:Pasmlabel;
  127. {The default implemenation calls write_rtti_data
  128. if init and rtti data is different these procedures
  129. must be overloaded.}
  130. procedure write_init_data;virtual;
  131. {Writes rtti of child to avoid mixup of rtti.}
  132. procedure write_child_init_data;virtual;
  133. {Rtti}
  134. procedure write_rtti_name;
  135. function get_rtti_label:string;virtual;
  136. procedure generate_rtti;virtual;
  137. procedure write_rtti_data;virtual;
  138. procedure write_child_rtti_data;virtual;
  139. { returns true, if the definition can be published }
  140. function is_publishable : boolean;virtual;
  141. function gettypename:string;virtual;
  142. end;
  143. const systemunit:Psymtable = nil; {Pointer to the system unit.}
  144. objpasunit:Psymtable = nil; {Pointer to the objpas unit.}
  145. var read_member : boolean; {True, wenn Members aus einer PPU-
  146. Datei gelesen werden, d.h. ein
  147. varsym seine Adresse einlesen soll }
  148. procprefix:stringid;
  149. {**************************************************************************}
  150. implementation
  151. {**************************************************************************}
  152. uses symtablt,files,verbose,globals;
  153. {****************************************************************************
  154. Tsymtable
  155. ****************************************************************************}
  156. procedure Tsymtable.foreach(proc2call:Tnamedindexcallback);
  157. begin
  158. abstract;
  159. end;
  160. procedure Tsymtable.insert(sym:Psym);
  161. begin
  162. abstract;
  163. end;
  164. function Tsymtable.search(const s:stringid):Psym;
  165. begin
  166. search:=speedsearch(s,getspeedvalue(s));
  167. end;
  168. function Tsymtable.speedsearch(const s:stringid;speedvalue:longint):Psym;
  169. begin
  170. abstract;
  171. end;
  172. function Tsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
  173. begin
  174. tconstsymtodata:=datasize;
  175. inc(datasize,len);
  176. end;
  177. function Tsymtable.varsymprefix:string;
  178. begin
  179. abstract;
  180. end;
  181. function Tsymtable.varsymtodata(sym:Psym;len:longint):longint;
  182. begin
  183. varsymtodata:=datasize;
  184. inc(datasize,len);
  185. end;
  186. {****************************************************************************
  187. Tcontainingsymtable
  188. ****************************************************************************}
  189. constructor Tcontainingsymtable.init;
  190. var indexgrow:word;
  191. begin
  192. indexgrow:=index_growsize;
  193. new(defindex,init(2*indexgrow,indexgrow));
  194. new(symsearch,init);
  195. alignment:=def_alignment;
  196. index_growsize:=16;
  197. end;
  198. constructor Tcontainingsymtable.load;
  199. begin
  200. end;
  201. procedure Tcontainingsymtable.get_contents(var s:Pdictionary;
  202. var d:Pcollection);
  203. begin
  204. s:=symsearch;
  205. d:=defindex;
  206. free;
  207. end;
  208. procedure Tcontainingsymtable.store(var s:Tstream);
  209. begin
  210. end;
  211. procedure Tcontainingsymtable.check_vars;
  212. begin
  213. end;
  214. procedure Tcontainingsymtable.check_forwards;
  215. begin
  216. end;
  217. procedure Tcontainingsymtable.check_labels;
  218. begin
  219. end;
  220. procedure Tcontainingsymtable.foreach(proc2call:Tnamedindexcallback);
  221. begin
  222. symsearch^.foreach(proc2call);
  223. end;
  224. procedure Tcontainingsymtable.insert(sym:Psym);
  225. begin
  226. symsearch^.insert(sym);
  227. sym^.register_defs;
  228. end;
  229. procedure Tcontainingsymtable.set_contents(s:Pdictionary;d:Pcollection);
  230. begin
  231. dispose(defindex,done);
  232. dispose(symsearch,done);
  233. defindex:=d;
  234. symsearch:=s;
  235. end;
  236. function Tcontainingsymtable.speedsearch(const s:stringid;
  237. speedvalue:longint):Psym;
  238. var r:Psym;
  239. begin
  240. r:=Psym(symsearch^.speedsearch(s,speedvalue));
  241. {Make a notice that the symbol is referenced.}
  242. if (r<>nil) and (cs_browser in aktmoduleswitches) and make_ref then
  243. r^.make_reference;
  244. speedsearch:=r;
  245. end;
  246. procedure Tcontainingsymtable.registerdef(p:Pdef);
  247. begin
  248. defindex^.insert(p);
  249. p^.owner:=@self;
  250. end;
  251. destructor Tcontainingsymtable.done;
  252. begin
  253. dispose(defindex,done);
  254. dispose(symsearch,done);
  255. inherited done;
  256. end;
  257. {****************************************************************************
  258. Tref
  259. ****************************************************************************}
  260. constructor Tref.init(const pos:Tfileposinfo);
  261. begin
  262. inherited init;
  263. posinfo:=pos;
  264. moduleindex:=current_module^.unit_index;
  265. end;
  266. destructor Tref.done;
  267. var inputfile:Pinputfile;
  268. begin
  269. inputfile:=get_source_file(moduleindex,posinfo.fileindex);
  270. if inputfile<>nil then
  271. dec(inputfile^.ref_count);
  272. end;
  273. procedure duplicatesym(sym:Psym);
  274. begin
  275. message1(sym_e_duplicate_id,sym^.name);
  276. with sym^.fileinfo do
  277. message2(sym_h_duplicate_id_where,
  278. current_module^.sourcefiles^.get_file_name(fileindex),tostr(line));
  279. end;
  280. {****************************************************************************
  281. Tsym
  282. ****************************************************************************}
  283. constructor Tsym.init(const n:string);
  284. begin
  285. inherited init(n);
  286. fileinfo:=tokenpos;
  287. if cs_browser in aktmoduleswitches then
  288. new(references,init(32,16));
  289. {The place where a symbol is defined is also a reference. You can safely
  290. assume that the first reference in the references collection is the
  291. place where the symbol is defined.}
  292. make_reference;
  293. end;
  294. constructor Tsym.load(var s:Tstream);
  295. begin
  296. end;
  297. procedure Tsym.deref;
  298. begin
  299. abstract;
  300. end;
  301. procedure Tsym.insert_in_data;
  302. begin
  303. end;
  304. procedure Tsym.make_reference;
  305. begin
  306. if (cs_browser in aktmoduleswitches) and make_ref then
  307. references^.insert(new(Pref,init(tokenpos)));
  308. end;
  309. function Tsym.mangledname:string;
  310. begin
  311. mangledname:=name;
  312. end;
  313. procedure Tsym.register_defs;
  314. begin
  315. end;
  316. procedure Tsym.store(var s:Tstream);
  317. begin
  318. end;
  319. destructor Tsym.done;
  320. begin
  321. if references<>nil then
  322. dispose(references,done);
  323. inherited done;
  324. end;
  325. procedure Tsym.load_references;
  326. begin
  327. end;
  328. function Tsym.write_references:boolean;
  329. begin
  330. end;
  331. {****************************************************************************
  332. Tdef
  333. ****************************************************************************}
  334. constructor Tdef.init(Aowner:Pcontainingsymtable);
  335. begin
  336. inherited init;
  337. Aowner^.registerdef(@self);
  338. owner:=Aowner;
  339. end;
  340. constructor Tdef.load;
  341. begin
  342. end;
  343. procedure Tdef.store(var s:Tstream);
  344. begin
  345. end;
  346. function Tdef.typename:string;
  347. begin
  348. typename:='<unknown type>';
  349. end;
  350. procedure Tdef.deref;
  351. begin
  352. end;
  353. function Tdef.size:longint;
  354. begin
  355. size:=savesize;
  356. end;
  357. procedure Tdef.symderef;
  358. begin
  359. end;
  360. function Tdef.needs_inittable:boolean;
  361. begin
  362. end;
  363. procedure Tdef.generate_inittable;
  364. begin
  365. end;
  366. function Tdef.get_inittable_label:Pasmlabel;
  367. begin
  368. end;
  369. procedure Tdef.write_init_data;
  370. begin
  371. end;
  372. procedure Tdef.write_child_init_data;
  373. begin
  374. end;
  375. procedure Tdef.write_rtti_name;
  376. begin
  377. end;
  378. function Tdef.get_rtti_label:string;
  379. begin
  380. end;
  381. procedure Tdef.generate_rtti;
  382. begin
  383. end;
  384. procedure Tdef.write_rtti_data;
  385. begin
  386. end;
  387. procedure Tdef.write_child_rtti_data;
  388. begin
  389. end;
  390. function Tdef.is_publishable:boolean;
  391. begin
  392. is_publishable:=false;
  393. end;
  394. function Tdef.gettypename:string;
  395. begin
  396. gettypename:='<unknown type>';
  397. end;
  398. destructor Tdef.done;
  399. {var s:Ptypesym;}
  400. begin
  401. { s:=sym;
  402. while s<>nil do
  403. begin
  404. s^.definition:=nil;
  405. s:=s^.synonym;
  406. end;}
  407. inherited done;
  408. end;
  409. end.