symtable.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. This unit handles the symbol tables
  5. Copyright (C) 1998-2000 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.