pdecvar.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  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.free;
  261. pt:=expr;
  262. if is_constintnode(pt) then
  263. begin
  264. abssym.address:=abssym.address shl 4+tordconstnode(pt).value;
  265. abssym.absseg:=true;
  266. end
  267. else
  268. Message(parser_e_absolute_only_to_var_or_const);
  269. end;
  270. symtablestack.insert(abssym);
  271. akttokenpos:=storetokenpos;
  272. end
  273. else
  274. Message(parser_e_absolute_only_to_var_or_const);
  275. end;
  276. end
  277. else
  278. Message(parser_e_absolute_only_to_var_or_const);
  279. pt.free;
  280. symdone:=true;
  281. end;
  282. { Handling of Delphi typed const = initialized vars ! }
  283. { When should this be rejected ?
  284. - in parasymtable
  285. - in record or object
  286. - ... (PM) }
  287. if (token=_EQUAL) and
  288. not(m_tp7 in aktmodeswitches) and
  289. not(symtablestack.symtabletype in [parasymtable]) and
  290. not is_record and
  291. not is_object then
  292. begin
  293. storetokenpos:=akttokenpos;
  294. s:=sc.get(akttokenpos);
  295. if not sc.empty then
  296. Message(parser_e_initialized_only_one_var);
  297. tconstsym:=ttypedconstsym.createtype(s,tt,true);
  298. symtablestack.insert(tconstsym);
  299. akttokenpos:=storetokenpos;
  300. consume(_EQUAL);
  301. readtypedconst(tt,tconstsym,true);
  302. symdone:=true;
  303. end;
  304. { hint directive }
  305. {$warning hintdirective not stored in syms}
  306. dummysymoptions:=[];
  307. try_consume_hintdirective(dummysymoptions);
  308. { for a record there doesn't need to be a ; before the END or ) }
  309. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  310. consume(_SEMICOLON);
  311. { procvar handling }
  312. if (tt.def.deftype=procvardef) and (tt.def.typesym=nil) then
  313. begin
  314. newtype:=ttypesym.create('unnamed',tt);
  315. parse_var_proc_directives(tsym(newtype));
  316. newtype.restype.def:=nil;
  317. tt.def.typesym:=nil;
  318. newtype.free;
  319. end;
  320. { Check for variable directives }
  321. if not symdone and (token=_ID) then
  322. begin
  323. { Check for C Variable declarations }
  324. if (m_cvar_support in aktmodeswitches) and
  325. not(is_record or is_object or is_threadvar) and
  326. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  327. begin
  328. { only allowed for one var }
  329. s:=sc.get(declarepos);
  330. if not sc.empty then
  331. Message(parser_e_absolute_only_one_var);
  332. {$ifdef fixLeaksOnError}
  333. if strContStack.pop <> sc then
  334. writeln('problem with strContStack in pdecl (5)');
  335. {$endif fixLeaksOnError}
  336. sc.free;
  337. { defaults }
  338. is_dll:=false;
  339. is_cdecl:=false;
  340. extern_aktvarsym:=false;
  341. export_aktvarsym:=false;
  342. { cdecl }
  343. if idtoken=_CVAR then
  344. begin
  345. consume(_CVAR);
  346. consume(_SEMICOLON);
  347. is_cdecl:=true;
  348. C_name:=target_info.Cprefix+C_name;
  349. end;
  350. { external }
  351. if idtoken=_EXTERNAL then
  352. begin
  353. consume(_EXTERNAL);
  354. extern_aktvarsym:=true;
  355. end;
  356. { export }
  357. if idtoken in [_EXPORT,_PUBLIC] then
  358. begin
  359. consume(_ID);
  360. if extern_aktvarsym or
  361. (symtablestack.symtabletype in [parasymtable,localsymtable]) then
  362. Message(parser_e_not_external_and_export)
  363. else
  364. export_aktvarsym:=true;
  365. end;
  366. { external and export need a name after when no cdecl is used }
  367. if not is_cdecl then
  368. begin
  369. { dll name ? }
  370. if (extern_aktvarsym) and (idtoken<>_NAME) then
  371. begin
  372. is_dll:=true;
  373. dll_name:=get_stringconst;
  374. end;
  375. consume(_NAME);
  376. C_name:=get_stringconst;
  377. end;
  378. { consume the ; when export or external is used }
  379. if extern_aktvarsym or export_aktvarsym then
  380. consume(_SEMICOLON);
  381. { insert in the symtable }
  382. storetokenpos:=akttokenpos;
  383. akttokenpos:=declarepos;
  384. if is_dll then
  385. aktvarsym:=tvarsym.create_dll(s,tt)
  386. else
  387. aktvarsym:=tvarsym.create_C(s,C_name,tt);
  388. { set some vars options }
  389. if export_aktvarsym then
  390. begin
  391. inc(aktvarsym.refs);
  392. include(aktvarsym.varoptions,vo_is_exported);
  393. end;
  394. if extern_aktvarsym then
  395. include(aktvarsym.varoptions,vo_is_external);
  396. { insert in the stack/datasegment }
  397. symtablestack.insert(aktvarsym);
  398. akttokenpos:=storetokenpos;
  399. { now we can insert it in the import lib if its a dll, or
  400. add it to the externals }
  401. if extern_aktvarsym then
  402. begin
  403. if is_dll then
  404. begin
  405. if not(current_module.uses_imports) then
  406. begin
  407. current_module.uses_imports:=true;
  408. importlib.preparelib(current_module.modulename^);
  409. end;
  410. importlib.importvariable(aktvarsym.mangledname,dll_name,C_name)
  411. end
  412. else
  413. if target_info.DllScanSupported then
  414. current_module.Externals.insert(tExternalsItem.create(aktvarsym.mangledname));
  415. end;
  416. symdone:=true;
  417. end
  418. else
  419. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  420. begin
  421. include(current_object_option,sp_static);
  422. insert_syms(symtablestack,sc,tt,false);
  423. exclude(current_object_option,sp_static);
  424. consume(_STATIC);
  425. consume(_SEMICOLON);
  426. symdone:=true;
  427. end;
  428. end;
  429. { insert it in the symtable, if not done yet }
  430. if not symdone then
  431. begin
  432. { save object option, because we can turn of the sp_published }
  433. if (sp_published in current_object_option) and
  434. not(is_class(tt.def)) then
  435. begin
  436. Message(parser_e_cant_publish_that);
  437. exclude(current_object_option,sp_published);
  438. end
  439. else
  440. if (sp_published in current_object_option) and
  441. not(oo_can_have_published in tobjectdef(tt.def).objectoptions) then
  442. begin
  443. Message(parser_e_only_publishable_classes_can__be_published);
  444. exclude(current_object_option,sp_published);
  445. end;
  446. insert_syms(symtablestack,sc,tt,is_threadvar);
  447. current_object_option:=old_current_object_option;
  448. end;
  449. end;
  450. { Check for Case }
  451. if is_record and (token=_CASE) then
  452. begin
  453. maxsize:=0;
  454. maxalignment:=0;
  455. consume(_CASE);
  456. s:=pattern;
  457. searchsym(s,srsym,srsymtable);
  458. { may be only a type: }
  459. if assigned(srsym) and (srsym.typ in [typesym,unitsym]) then
  460. begin
  461. { for records, don't search the recordsymtable for
  462. the symbols of the types }
  463. oldsymtablestack:=symtablestack;
  464. symtablestack:=symtablestack.next;
  465. read_type(casetype,'');
  466. symtablestack:=oldsymtablestack;
  467. end
  468. else
  469. begin
  470. consume(_ID);
  471. consume(_COLON);
  472. { for records, don't search the recordsymtable for
  473. the symbols of the types }
  474. oldsymtablestack:=symtablestack;
  475. symtablestack:=symtablestack.next;
  476. read_type(casetype,'');
  477. symtablestack:=oldsymtablestack;
  478. symtablestack.insert(tvarsym.create(s,casetype));
  479. end;
  480. if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
  481. Message(type_e_ordinal_expr_expected);
  482. consume(_OF);
  483. UnionSymtable:=trecordsymtable.create;
  484. Unionsymtable.next:=symtablestack;
  485. registerdef:=false;
  486. UnionDef:=trecorddef.create(unionsymtable);
  487. registerdef:=true;
  488. symtablestack:=UnionSymtable;
  489. startvarrecsize:=symtablestack.datasize;
  490. startvarrecalign:=symtablestack.dataalignment;
  491. repeat
  492. repeat
  493. pt:=comp_expr(true);
  494. if not(pt.nodetype=ordconstn) then
  495. Message(cg_e_illegal_expression);
  496. pt.free;
  497. if token=_COMMA then
  498. consume(_COMMA)
  499. else
  500. break;
  501. until false;
  502. consume(_COLON);
  503. { read the vars }
  504. consume(_LKLAMMER);
  505. inc(variantrecordlevel);
  506. if token<>_RKLAMMER then
  507. read_var_decs(true,false,false);
  508. dec(variantrecordlevel);
  509. consume(_RKLAMMER);
  510. { calculates maximal variant size }
  511. maxsize:=max(maxsize,symtablestack.datasize);
  512. maxalignment:=max(maxalignment,symtablestack.dataalignment);
  513. { the items of the next variant are overlayed }
  514. symtablestack.datasize:=startvarrecsize;
  515. symtablestack.dataalignment:=startvarrecalign;
  516. if (token<>_END) and (token<>_RKLAMMER) then
  517. consume(_SEMICOLON)
  518. else
  519. break;
  520. until (token=_END) or (token=_RKLAMMER);
  521. { at last set the record size to that of the biggest variant }
  522. symtablestack.datasize:=maxsize;
  523. symtablestack.dataalignment:=maxalignment;
  524. uniontype.def:=uniondef;
  525. uniontype.sym:=nil;
  526. UnionSym:=tvarsym.create('case',uniontype);
  527. symtablestack:=symtablestack.next;
  528. { we do NOT call symtablestack.insert
  529. on purpose PM }
  530. if aktalignment.recordalignmax=-1 then
  531. begin
  532. {$ifdef i386}
  533. if maxalignment>2 then
  534. minalignment:=4
  535. else if maxalignment>1 then
  536. minalignment:=2
  537. else
  538. minalignment:=1;
  539. {$else}
  540. {$ifdef m68k}
  541. minalignment:=2;
  542. {$endif}
  543. minalignment:=1;
  544. {$endif}
  545. end
  546. else
  547. minalignment:=maxalignment;
  548. usedalign:=used_align(maxalignment,minalignment,maxalignment);
  549. offset:=align(symtablestack.datasize,usedalign);
  550. symtablestack.datasize:=offset+unionsymtable.datasize;
  551. if maxalignment>symtablestack.dataalignment then
  552. symtablestack.dataalignment:=maxalignment;
  553. trecordsymtable(Unionsymtable).Insert_in(symtablestack,offset);
  554. Unionsym.owner:=nil;
  555. unionsym.free;
  556. uniondef.free;
  557. end;
  558. block_type:=old_block_type;
  559. current_object_option:=old_current_object_option;
  560. end;
  561. end.
  562. {
  563. $Log$
  564. Revision 1.23 2002-04-21 18:57:24 peter
  565. * fixed memleaks when file can't be opened
  566. Revision 1.22 2001/11/20 18:48:26 peter
  567. * fixed initialized variables
  568. Revision 1.21 2001/10/23 21:49:42 peter
  569. * $calling directive and -Cc commandline patch added
  570. from Pavel Ozerski
  571. Revision 1.20 2001/09/30 21:15:48 peter
  572. * merged absolute support for constants
  573. Revision 1.19 2001/08/30 20:13:53 peter
  574. * rtti/init table updates
  575. * rttisym for reusable global rtti/init info
  576. * support published for interfaces
  577. Revision 1.18 2001/07/01 20:16:16 peter
  578. * alignmentinfo record added
  579. * -Oa argument supports more alignment settings that can be specified
  580. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  581. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  582. required alignment and the maximum usefull alignment. The final
  583. alignment will be choosen per variable size dependent on these
  584. settings
  585. Revision 1.17 2001/06/03 21:57:36 peter
  586. + hint directive parsing support
  587. Revision 1.16 2001/04/18 22:01:57 peter
  588. * registration of targets and assemblers
  589. Revision 1.15 2001/04/13 01:22:12 peter
  590. * symtable change to classes
  591. * range check generation and errors fixed, make cycle DEBUG=1 works
  592. * memory leaks fixed
  593. Revision 1.14 2001/04/04 22:43:52 peter
  594. * remove unnecessary calls to firstpass
  595. Revision 1.13 2001/04/04 21:30:45 florian
  596. * applied several fixes to get the DD8 Delphi Unit compiled
  597. e.g. "forward"-interfaces are working now
  598. Revision 1.12 2001/04/02 21:20:33 peter
  599. * resulttype rewrite
  600. Revision 1.11 2001/03/11 22:58:50 peter
  601. * getsym redesign, removed the globals srsym,srsymtable
  602. Revision 1.10 2001/03/06 18:28:02 peter
  603. * patch from Pavel with a new and much faster DLL Scanner for
  604. automatic importing so $linklib works for DLLs. Thanks Pavel!
  605. Revision 1.9 2001/02/20 21:42:54 peter
  606. * record and object declaration with same field as type fixed
  607. Revision 1.7 2001/02/20 11:19:45 marco
  608. * Fix passing tvarrec to array of const
  609. Revision 1.6 2000/12/25 00:07:27 peter
  610. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  611. tlinkedlist objects)
  612. Revision 1.5 2000/12/17 14:00:18 peter
  613. * fixed static variables
  614. Revision 1.4 2000/11/29 00:30:36 florian
  615. * unused units removed from uses clause
  616. * some changes for widestrings
  617. Revision 1.3 2000/11/04 14:25:20 florian
  618. + merged Attila's changes for interfaces, not tested yet
  619. Revision 1.2 2000/10/31 22:02:49 peter
  620. * symtable splitted, no real code changes
  621. Revision 1.1 2000/10/14 10:14:51 peter
  622. * moehrendorf oct 2000 rewrite
  623. }