symtable.pas 14 KB

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