pdecvar.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Parses variable declarations. Used for var statement and record
  5. definitions
  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. unit pdecvar;
  20. {$i defines.inc}
  21. interface
  22. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  23. implementation
  24. uses
  25. { common }
  26. cutils,
  27. { global }
  28. globtype,globals,tokens,verbose,
  29. systems,
  30. { symtable }
  31. symconst,symbase,symtype,symdef,symsym,symtable,types,fmodule,
  32. { pass 1 }
  33. node,
  34. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  35. { parser }
  36. scanner,
  37. pbase,pexpr,ptype,ptconst,pdecsub,
  38. { link }
  39. import;
  40. const
  41. variantrecordlevel : longint = 0;
  42. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  43. { reads the filed of a record into a }
  44. { symtablestack, if record=false }
  45. { variants are forbidden, so this procedure }
  46. { can be used to read object fields }
  47. { if absolute is true, ABSOLUTE and file }
  48. { types are allowed }
  49. { => the procedure is also used to read }
  50. { a sequence of variable declaration }
  51. procedure insert_syms(st : tsymtable;sc : tidstringlist;tt : ttype;is_threadvar : boolean);
  52. { inserts the symbols of sc in st with def as definition or sym as ttypesym, sc is disposed }
  53. var
  54. s : string;
  55. filepos : tfileposinfo;
  56. ss : tvarsym;
  57. begin
  58. filepos:=akttokenpos;
  59. while not sc.empty do
  60. begin
  61. s:=sc.get(akttokenpos);
  62. ss:=tvarsym.Create(s,tt);
  63. if is_threadvar then
  64. include(ss.varoptions,vo_is_thread_var);
  65. st.insert(ss);
  66. { static data fields are inserted in the globalsymtable }
  67. if (st.symtabletype=objectsymtable) and
  68. (sp_static in current_object_option) then
  69. begin
  70. s:='$'+lower(st.name^)+'_'+upper(s);
  71. st.defowner.owner.insert(tvarsym.create(s,tt));
  72. end;
  73. end;
  74. {$ifdef fixLeaksOnError}
  75. if strContStack.pop <> sc then
  76. writeln('problem with strContStack in pdecl (2)');
  77. {$endif fixLeaksOnError}
  78. sc.free;
  79. akttokenpos:=filepos;
  80. end;
  81. var
  82. sc : tidstringList;
  83. s : stringid;
  84. old_block_type : tblock_type;
  85. declarepos,storetokenpos : tfileposinfo;
  86. oldsymtablestack : tsymtable;
  87. symdone : boolean;
  88. { to handle absolute }
  89. abssym : tabsolutesym;
  90. { c var }
  91. newtype : ttypesym;
  92. is_dll,
  93. is_gpc_name,is_cdecl,
  94. extern_aktvarsym,export_aktvarsym : boolean;
  95. old_current_object_option : tsymoptions;
  96. dll_name,
  97. C_name : string;
  98. tt,casetype : ttype;
  99. { Delphi initialized vars }
  100. tconstsym : ttypedconstsym;
  101. { maxsize contains the max. size of a variant }
  102. { startvarrec contains the start of the variant part of a record }
  103. usedalign,
  104. maxsize,minalignment,maxalignment,startvarrecalign,startvarrecsize : longint;
  105. pt : tnode;
  106. srsym : tsym;
  107. srsymtable : tsymtable;
  108. unionsymtable : tsymtable;
  109. offset : longint;
  110. uniondef : trecorddef;
  111. unionsym : tvarsym;
  112. uniontype : ttype;
  113. dummysymoptions : tsymoptions;
  114. begin
  115. old_current_object_option:=current_object_option;
  116. { all variables are public if not in a object declaration }
  117. if not is_object then
  118. current_object_option:=[sp_public];
  119. old_block_type:=block_type;
  120. block_type:=bt_type;
  121. is_gpc_name:=false;
  122. { Force an expected ID error message }
  123. if not (token in [_ID,_CASE,_END]) then
  124. consume(_ID);
  125. { read vars }
  126. while (token=_ID) and
  127. not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
  128. begin
  129. C_name:=orgpattern;
  130. sc:=consume_idlist;
  131. {$ifdef fixLeaksOnError}
  132. strContStack.push(sc);
  133. {$endif fixLeaksOnError}
  134. consume(_COLON);
  135. if (m_gpc in aktmodeswitches) and
  136. not(is_record or is_object or is_threadvar) and
  137. (token=_ID) and (orgpattern='__asmname__') then
  138. begin
  139. consume(_ID);
  140. C_name:=get_stringconst;
  141. Is_gpc_name:=true;
  142. end;
  143. { this is needed for Delphi mode at least
  144. but should be OK for all modes !! (PM) }
  145. ignore_equal:=true;
  146. if is_record then
  147. begin
  148. { for records, don't search the recordsymtable for
  149. the symbols of the types }
  150. oldsymtablestack:=symtablestack;
  151. symtablestack:=symtablestack.next;
  152. read_type(tt,'');
  153. symtablestack:=oldsymtablestack;
  154. end
  155. else
  156. read_type(tt,'');
  157. { types that use init/final are not allowed in variant parts, but
  158. classes are allowed }
  159. if (variantrecordlevel>0) and
  160. (tt.def.needs_inittable and not is_class(tt.def)) then
  161. Message(parser_e_cant_use_inittable_here);
  162. ignore_equal:=false;
  163. symdone:=false;
  164. if is_gpc_name then
  165. begin
  166. storetokenpos:=akttokenpos;
  167. s:=sc.get(akttokenpos);
  168. if not sc.empty then
  169. Message(parser_e_absolute_only_one_var);
  170. {$ifdef fixLeaksOnError}
  171. if strContStack.pop <> sc then
  172. writeln('problem with strContStack in pdecl (3)');
  173. {$endif fixLeaksOnError}
  174. sc.free;
  175. aktvarsym:=tvarsym.create_C(s,target_info.Cprefix+C_name,tt);
  176. include(aktvarsym.varoptions,vo_is_external);
  177. symtablestack.insert(aktvarsym);
  178. akttokenpos:=storetokenpos;
  179. symdone:=true;
  180. end;
  181. { check for absolute }
  182. if not symdone and
  183. (idtoken=_ABSOLUTE) and not(is_record or is_object or is_threadvar) then
  184. begin
  185. consume(_ABSOLUTE);
  186. { only allowed for one var }
  187. s:=sc.get(declarepos);
  188. if not sc.empty then
  189. Message(parser_e_absolute_only_one_var);
  190. {$ifdef fixLeaksOnError}
  191. if strContStack.pop <> sc then
  192. writeln('problem with strContStack in pdecl (4)');
  193. {$endif fixLeaksOnError}
  194. sc.free;
  195. { parse the rest }
  196. pt:=expr;
  197. if (pt.nodetype=stringconstn) or (is_constcharnode(pt)) then
  198. begin
  199. storetokenpos:=akttokenpos;
  200. akttokenpos:=declarepos;
  201. abssym:=tabsolutesym.create(s,tt);
  202. if pt.nodetype=stringconstn then
  203. s:=strpas(tstringconstnode(pt).value_str)
  204. else
  205. s:=chr(tordconstnode(pt).value);
  206. consume(token);
  207. abssym.abstyp:=toasm;
  208. abssym.asmname:=stringdup(s);
  209. symtablestack.insert(abssym);
  210. akttokenpos:=storetokenpos;
  211. symdone:=true;
  212. end;
  213. if not symdone then
  214. begin
  215. { variable }
  216. if (pt.nodetype=loadn) then
  217. begin
  218. { we should check the result type of srsym }
  219. if not (tloadnode(pt).symtableentry.typ in [varsym,typedconstsym,funcretsym]) then
  220. Message(parser_e_absolute_only_to_var_or_const);
  221. storetokenpos:=akttokenpos;
  222. akttokenpos:=declarepos;
  223. abssym:=tabsolutesym.create(s,tt);
  224. abssym.abstyp:=tovar;
  225. abssym.ref:=tstoredsym(tloadnode(pt).symtableentry);
  226. symtablestack.insert(abssym);
  227. akttokenpos:=storetokenpos;
  228. symdone:=true;
  229. end
  230. { funcret }
  231. else if (pt.nodetype=funcretn) then
  232. begin
  233. storetokenpos:=akttokenpos;
  234. akttokenpos:=declarepos;
  235. abssym:=tabsolutesym.create(s,tt);
  236. abssym.abstyp:=tovar;
  237. abssym.ref:=tstoredsym(tfuncretnode(pt).funcretsym);
  238. symtablestack.insert(abssym);
  239. akttokenpos:=storetokenpos;
  240. symdone:=true;
  241. end;
  242. { address }
  243. if (not symdone) and
  244. ((target_info.target=target_i386_go32v2) or
  245. (m_objfpc in aktmodeswitches) or
  246. (m_delphi in aktmodeswitches)) then
  247. begin
  248. if is_constintnode(pt) then
  249. begin
  250. storetokenpos:=akttokenpos;
  251. akttokenpos:=declarepos;
  252. abssym:=tabsolutesym.create(s,tt);
  253. abssym.abstyp:=toaddr;
  254. abssym.absseg:=false;
  255. abssym.address:=tordconstnode(pt).value;
  256. if (token=_COLON) and
  257. (target_info.target=target_i386_go32v2) then
  258. begin
  259. consume(token);
  260. pt:=expr;
  261. if is_constintnode(pt) then
  262. begin
  263. abssym.address:=abssym.address shl 4+tordconstnode(pt).value;
  264. abssym.absseg:=true;
  265. end
  266. else
  267. Message(parser_e_absolute_only_to_var_or_const);
  268. end;
  269. symtablestack.insert(abssym);
  270. akttokenpos:=storetokenpos;
  271. end
  272. else
  273. Message(parser_e_absolute_only_to_var_or_const);
  274. end;
  275. end
  276. else
  277. Message(parser_e_absolute_only_to_var_or_const);
  278. symdone:=true;
  279. end;
  280. { Handling of Delphi typed const = initialized vars ! }
  281. { When should this be rejected ?
  282. - in parasymtable
  283. - in record or object
  284. - ... (PM) }
  285. if (m_delphi in aktmodeswitches) and (token=_EQUAL) and
  286. not (symtablestack.symtabletype in [parasymtable]) and
  287. not is_record and not is_object then
  288. begin
  289. storetokenpos:=akttokenpos;
  290. s:=sc.get(akttokenpos);
  291. if not sc.empty then
  292. Message(parser_e_initialized_only_one_var);
  293. tconstsym:=ttypedconstsym.createtype(s,tt,false);
  294. symtablestack.insert(tconstsym);
  295. akttokenpos:=storetokenpos;
  296. consume(_EQUAL);
  297. readtypedconst(tt,tconstsym,false);
  298. symdone:=true;
  299. end;
  300. { hint directive }
  301. {$warning hintdirective not stored in syms}
  302. dummysymoptions:=[];
  303. try_consume_hintdirective(dummysymoptions);
  304. { for a record there doesn't need to be a ; before the END or ) }
  305. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  306. consume(_SEMICOLON);
  307. { procvar handling }
  308. if (tt.def.deftype=procvardef) and (tt.def.typesym=nil) then
  309. begin
  310. newtype:=ttypesym.create('unnamed',tt);
  311. parse_var_proc_directives(tsym(newtype));
  312. newtype.restype.def:=nil;
  313. tt.def.typesym:=nil;
  314. newtype.free;
  315. end;
  316. { Check for variable directives }
  317. if not symdone and (token=_ID) then
  318. begin
  319. { Check for C Variable declarations }
  320. if (m_cvar_support in aktmodeswitches) and
  321. not(is_record or is_object or is_threadvar) and
  322. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  323. begin
  324. { only allowed for one var }
  325. s:=sc.get(declarepos);
  326. if not sc.empty then
  327. Message(parser_e_absolute_only_one_var);
  328. {$ifdef fixLeaksOnError}
  329. if strContStack.pop <> sc then
  330. writeln('problem with strContStack in pdecl (5)');
  331. {$endif fixLeaksOnError}
  332. sc.free;
  333. { defaults }
  334. is_dll:=false;
  335. is_cdecl:=false;
  336. extern_aktvarsym:=false;
  337. export_aktvarsym:=false;
  338. { cdecl }
  339. if idtoken=_CVAR then
  340. begin
  341. consume(_CVAR);
  342. consume(_SEMICOLON);
  343. is_cdecl:=true;
  344. C_name:=target_info.Cprefix+C_name;
  345. end;
  346. { external }
  347. if idtoken=_EXTERNAL then
  348. begin
  349. consume(_EXTERNAL);
  350. extern_aktvarsym:=true;
  351. end;
  352. { export }
  353. if idtoken in [_EXPORT,_PUBLIC] then
  354. begin
  355. consume(_ID);
  356. if extern_aktvarsym or
  357. (symtablestack.symtabletype in [parasymtable,localsymtable]) then
  358. Message(parser_e_not_external_and_export)
  359. else
  360. export_aktvarsym:=true;
  361. end;
  362. { external and export need a name after when no cdecl is used }
  363. if not is_cdecl then
  364. begin
  365. { dll name ? }
  366. if (extern_aktvarsym) and (idtoken<>_NAME) then
  367. begin
  368. is_dll:=true;
  369. dll_name:=get_stringconst;
  370. end;
  371. consume(_NAME);
  372. C_name:=get_stringconst;
  373. end;
  374. { consume the ; when export or external is used }
  375. if extern_aktvarsym or export_aktvarsym then
  376. consume(_SEMICOLON);
  377. { insert in the symtable }
  378. storetokenpos:=akttokenpos;
  379. akttokenpos:=declarepos;
  380. if is_dll then
  381. aktvarsym:=tvarsym.create_dll(s,tt)
  382. else
  383. aktvarsym:=tvarsym.create_C(s,C_name,tt);
  384. { set some vars options }
  385. if export_aktvarsym then
  386. begin
  387. inc(aktvarsym.refs);
  388. include(aktvarsym.varoptions,vo_is_exported);
  389. end;
  390. if extern_aktvarsym then
  391. include(aktvarsym.varoptions,vo_is_external);
  392. { insert in the stack/datasegment }
  393. symtablestack.insert(aktvarsym);
  394. akttokenpos:=storetokenpos;
  395. { now we can insert it in the import lib if its a dll, or
  396. add it to the externals }
  397. if extern_aktvarsym then
  398. begin
  399. if is_dll then
  400. begin
  401. if not(current_module.uses_imports) then
  402. begin
  403. current_module.uses_imports:=true;
  404. importlib.preparelib(current_module.modulename^);
  405. end;
  406. importlib.importvariable(aktvarsym.mangledname,dll_name,C_name)
  407. end
  408. else
  409. if target_info.DllScanSupported then
  410. current_module.Externals.insert(tExternalsItem.create(aktvarsym.mangledname));
  411. end;
  412. symdone:=true;
  413. end
  414. else
  415. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  416. begin
  417. include(current_object_option,sp_static);
  418. insert_syms(symtablestack,sc,tt,false);
  419. exclude(current_object_option,sp_static);
  420. consume(_STATIC);
  421. consume(_SEMICOLON);
  422. symdone:=true;
  423. end;
  424. end;
  425. { insert it in the symtable, if not done yet }
  426. if not symdone then
  427. begin
  428. { save object option, because we can turn of the sp_published }
  429. if (sp_published in current_object_option) and
  430. not(is_class(tt.def)) then
  431. begin
  432. Message(parser_e_cant_publish_that);
  433. exclude(current_object_option,sp_published);
  434. end
  435. else
  436. if (sp_published in current_object_option) and
  437. not(oo_can_have_published in tobjectdef(tt.def).objectoptions) then
  438. begin
  439. Message(parser_e_only_publishable_classes_can__be_published);
  440. exclude(current_object_option,sp_published);
  441. end;
  442. insert_syms(symtablestack,sc,tt,is_threadvar);
  443. current_object_option:=old_current_object_option;
  444. end;
  445. end;
  446. { Check for Case }
  447. if is_record and (token=_CASE) then
  448. begin
  449. maxsize:=0;
  450. maxalignment:=0;
  451. consume(_CASE);
  452. s:=pattern;
  453. searchsym(s,srsym,srsymtable);
  454. { may be only a type: }
  455. if assigned(srsym) and (srsym.typ in [typesym,unitsym]) then
  456. begin
  457. { for records, don't search the recordsymtable for
  458. the symbols of the types }
  459. oldsymtablestack:=symtablestack;
  460. symtablestack:=symtablestack.next;
  461. read_type(casetype,'');
  462. symtablestack:=oldsymtablestack;
  463. end
  464. else
  465. begin
  466. consume(_ID);
  467. consume(_COLON);
  468. { for records, don't search the recordsymtable for
  469. the symbols of the types }
  470. oldsymtablestack:=symtablestack;
  471. symtablestack:=symtablestack.next;
  472. read_type(casetype,'');
  473. symtablestack:=oldsymtablestack;
  474. symtablestack.insert(tvarsym.create(s,casetype));
  475. end;
  476. if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
  477. Message(type_e_ordinal_expr_expected);
  478. consume(_OF);
  479. UnionSymtable:=trecordsymtable.create;
  480. Unionsymtable.next:=symtablestack;
  481. registerdef:=false;
  482. UnionDef:=trecorddef.create(unionsymtable);
  483. registerdef:=true;
  484. symtablestack:=UnionSymtable;
  485. startvarrecsize:=symtablestack.datasize;
  486. startvarrecalign:=symtablestack.dataalignment;
  487. repeat
  488. repeat
  489. pt:=comp_expr(true);
  490. if not(pt.nodetype=ordconstn) then
  491. Message(cg_e_illegal_expression);
  492. pt.free;
  493. if token=_COMMA then
  494. consume(_COMMA)
  495. else
  496. break;
  497. until false;
  498. consume(_COLON);
  499. { read the vars }
  500. consume(_LKLAMMER);
  501. inc(variantrecordlevel);
  502. if token<>_RKLAMMER then
  503. read_var_decs(true,false,false);
  504. dec(variantrecordlevel);
  505. consume(_RKLAMMER);
  506. { calculates maximal variant size }
  507. maxsize:=max(maxsize,symtablestack.datasize);
  508. maxalignment:=max(maxalignment,symtablestack.dataalignment);
  509. { the items of the next variant are overlayed }
  510. symtablestack.datasize:=startvarrecsize;
  511. symtablestack.dataalignment:=startvarrecalign;
  512. if (token<>_END) and (token<>_RKLAMMER) then
  513. consume(_SEMICOLON)
  514. else
  515. break;
  516. until (token=_END) or (token=_RKLAMMER);
  517. { at last set the record size to that of the biggest variant }
  518. symtablestack.datasize:=maxsize;
  519. symtablestack.dataalignment:=maxalignment;
  520. uniontype.def:=uniondef;
  521. uniontype.sym:=nil;
  522. UnionSym:=tvarsym.create('case',uniontype);
  523. symtablestack:=symtablestack.next;
  524. { we do NOT call symtablestack.insert
  525. on purpose PM }
  526. if aktalignment.recordalignmax=-1 then
  527. begin
  528. {$ifdef i386}
  529. if maxalignment>2 then
  530. minalignment:=4
  531. else if maxalignment>1 then
  532. minalignment:=2
  533. else
  534. minalignment:=1;
  535. {$else}
  536. {$ifdef m68k}
  537. minalignment:=2;
  538. {$endif}
  539. minalignment:=1;
  540. {$endif}
  541. end
  542. else
  543. minalignment:=maxalignment;
  544. usedalign:=used_align(maxalignment,minalignment,maxalignment);
  545. offset:=align(symtablestack.datasize,usedalign);
  546. symtablestack.datasize:=offset+unionsymtable.datasize;
  547. if maxalignment>symtablestack.dataalignment then
  548. symtablestack.dataalignment:=maxalignment;
  549. trecordsymtable(Unionsymtable).Insert_in(symtablestack,offset);
  550. Unionsym.owner:=nil;
  551. unionsym.free;
  552. uniondef.free;
  553. end;
  554. block_type:=old_block_type;
  555. current_object_option:=old_current_object_option;
  556. end;
  557. end.
  558. {
  559. $Log$
  560. Revision 1.20 2001-09-30 21:15:48 peter
  561. * merged absolute support for constants
  562. Revision 1.19 2001/08/30 20:13:53 peter
  563. * rtti/init table updates
  564. * rttisym for reusable global rtti/init info
  565. * support published for interfaces
  566. Revision 1.18 2001/07/01 20:16:16 peter
  567. * alignmentinfo record added
  568. * -Oa argument supports more alignment settings that can be specified
  569. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  570. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  571. required alignment and the maximum usefull alignment. The final
  572. alignment will be choosen per variable size dependent on these
  573. settings
  574. Revision 1.17 2001/06/03 21:57:36 peter
  575. + hint directive parsing support
  576. Revision 1.16 2001/04/18 22:01:57 peter
  577. * registration of targets and assemblers
  578. Revision 1.15 2001/04/13 01:22:12 peter
  579. * symtable change to classes
  580. * range check generation and errors fixed, make cycle DEBUG=1 works
  581. * memory leaks fixed
  582. Revision 1.14 2001/04/04 22:43:52 peter
  583. * remove unnecessary calls to firstpass
  584. Revision 1.13 2001/04/04 21:30:45 florian
  585. * applied several fixes to get the DD8 Delphi Unit compiled
  586. e.g. "forward"-interfaces are working now
  587. Revision 1.12 2001/04/02 21:20:33 peter
  588. * resulttype rewrite
  589. Revision 1.11 2001/03/11 22:58:50 peter
  590. * getsym redesign, removed the globals srsym,srsymtable
  591. Revision 1.10 2001/03/06 18:28:02 peter
  592. * patch from Pavel with a new and much faster DLL Scanner for
  593. automatic importing so $linklib works for DLLs. Thanks Pavel!
  594. Revision 1.9 2001/02/20 21:42:54 peter
  595. * record and object declaration with same field as type fixed
  596. Revision 1.7 2001/02/20 11:19:45 marco
  597. * Fix passing tvarrec to array of const
  598. Revision 1.6 2000/12/25 00:07:27 peter
  599. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  600. tlinkedlist objects)
  601. Revision 1.5 2000/12/17 14:00:18 peter
  602. * fixed static variables
  603. Revision 1.4 2000/11/29 00:30:36 florian
  604. * unused units removed from uses clause
  605. * some changes for widestrings
  606. Revision 1.3 2000/11/04 14:25:20 florian
  607. + merged Attila's changes for interfaces, not tested yet
  608. Revision 1.2 2000/10/31 22:02:49 peter
  609. * symtable splitted, no real code changes
  610. Revision 1.1 2000/10/14 10:14:51 peter
  611. * moehrendorf oct 2000 rewrite
  612. }