pdecl.pas 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Does declaration (but not type) parsing for Free Pascal
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit pdecl;
  19. interface
  20. uses
  21. globtype,tokens,globals,symtable;
  22. procedure parameter_dec(aktprocdef:pabstractprocdef);
  23. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  24. { reads the declaration blocks }
  25. procedure read_declarations(islibrary : boolean);
  26. { reads declarations in the interface part of a unit }
  27. procedure read_interface_declarations;
  28. implementation
  29. uses
  30. cobjects,scanner,
  31. symconst,aasm,tree,pass_1,strings,
  32. files,types,verbose,systems,import,
  33. cpubase
  34. {$ifndef newcg}
  35. ,tccnv
  36. {$endif newcg}
  37. {$ifdef GDB}
  38. ,gdb
  39. {$endif GDB}
  40. { parser specific stuff }
  41. ,pbase,ptconst,pexpr,ptype,psub,pexports
  42. { processor specific stuff }
  43. { codegen }
  44. {$ifdef newcg}
  45. ,cgbase
  46. {$else}
  47. ,hcodegen
  48. {$endif}
  49. ,hcgdata
  50. ;
  51. procedure parameter_dec(aktprocdef:pabstractprocdef);
  52. {
  53. handle_procvar needs the same changes
  54. }
  55. var
  56. is_procvar : boolean;
  57. sc : Pstringcontainer;
  58. s : string;
  59. storetokenpos : tfileposinfo;
  60. tt : ttype;
  61. hvs,
  62. vs : Pvarsym;
  63. hs1,hs2 : string;
  64. varspez : Tvarspez;
  65. inserthigh : boolean;
  66. begin
  67. { parsing a proc or procvar ? }
  68. is_procvar:=(aktprocdef^.deftype=procvardef);
  69. consume(_LKLAMMER);
  70. inc(testcurobject);
  71. repeat
  72. if try_to_consume(_VAR) then
  73. varspez:=vs_var
  74. else
  75. if try_to_consume(_CONST) then
  76. varspez:=vs_const
  77. else
  78. varspez:=vs_value;
  79. inserthigh:=false;
  80. tt.reset;
  81. if idtoken=_SELF then
  82. begin
  83. { only allowed in procvars and class methods }
  84. if is_procvar or
  85. (assigned(procinfo^._class) and procinfo^._class^.is_class) then
  86. begin
  87. if not is_procvar then
  88. begin
  89. {$ifndef UseNiceNames}
  90. hs2:=hs2+'$'+'self';
  91. {$else UseNiceNames}
  92. hs2:=hs2+tostr(length('self'))+'self';
  93. {$endif UseNiceNames}
  94. vs:=new(Pvarsym,initdef('@',procinfo^._class));
  95. vs^.varspez:=vs_var;
  96. { insert the sym in the parasymtable }
  97. pprocdef(aktprocdef)^.parast^.insert(vs);
  98. {$ifdef INCLUDEOK}
  99. include(aktprocdef^.procoptions,po_containsself);
  100. {$else}
  101. aktprocdef^.procoptions:=aktprocdef^.procoptions+[po_containsself];
  102. {$endif}
  103. inc(procinfo^.selfpointer_offset,vs^.address);
  104. end;
  105. consume(idtoken);
  106. consume(_COLON);
  107. single_type(tt,hs1,false);
  108. aktprocdef^.concatpara(tt,vs_value);
  109. { check the types for procedures only }
  110. if not is_procvar then
  111. CheckTypes(tt.def,procinfo^._class);
  112. end
  113. else
  114. consume(_ID);
  115. end
  116. else
  117. begin
  118. { read identifiers }
  119. sc:=idlist;
  120. {$ifdef fixLeaksOnError}
  121. strContStack.push(sc);
  122. {$endif fixLeaksOnError}
  123. { read type declaration, force reading for value and const paras }
  124. if (token=_COLON) or (varspez=vs_value) then
  125. begin
  126. consume(_COLON);
  127. { check for an open array }
  128. if token=_ARRAY then
  129. begin
  130. consume(_ARRAY);
  131. consume(_OF);
  132. { define range and type of range }
  133. tt.setdef(new(Parraydef,init(0,-1,s32bitdef)));
  134. { array of const ? }
  135. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  136. begin
  137. consume(_CONST);
  138. srsym:=nil;
  139. getsymonlyin(systemunit,'TVARREC');
  140. if not assigned(srsym) then
  141. InternalError(1234124);
  142. Parraydef(tt.def)^.elementtype:=ptypesym(srsym)^.restype;
  143. Parraydef(tt.def)^.IsArrayOfConst:=true;
  144. hs1:='array_of_const';
  145. end
  146. else
  147. begin
  148. { define field type }
  149. single_type(parraydef(tt.def)^.elementtype,hs1,false);
  150. hs1:='array_of_'+hs1;
  151. end;
  152. inserthigh:=true;
  153. end
  154. { open string ? }
  155. else if (varspez=vs_var) and
  156. (
  157. (
  158. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  159. (cs_openstring in aktmoduleswitches) and
  160. not(cs_ansistrings in aktlocalswitches)
  161. ) or
  162. (idtoken=_OPENSTRING)) then
  163. begin
  164. consume(token);
  165. tt.setdef(openshortstringdef);
  166. hs1:='openstring';
  167. inserthigh:=true;
  168. end
  169. { everything else }
  170. else
  171. single_type(tt,hs1,false);
  172. end
  173. else
  174. begin
  175. {$ifndef UseNiceNames}
  176. hs1:='$$$';
  177. {$else UseNiceNames}
  178. hs1:='var';
  179. {$endif UseNiceNames}
  180. tt.setdef(cformaldef);
  181. end;
  182. if not is_procvar then
  183. hs2:=pprocdef(aktprocdef)^.mangledname;
  184. storetokenpos:=tokenpos;
  185. while not sc^.empty do
  186. begin
  187. s:=sc^.get_with_tokeninfo(tokenpos);
  188. aktprocdef^.concatpara(tt,varspez);
  189. { For proc vars we only need the definitions }
  190. if not is_procvar then
  191. begin
  192. {$ifndef UseNiceNames}
  193. hs2:=hs2+'$'+hs1;
  194. {$else UseNiceNames}
  195. hs2:=hs2+tostr(length(hs1))+hs1;
  196. {$endif UseNiceNames}
  197. vs:=new(pvarsym,init(s,tt));
  198. vs^.varspez:=varspez;
  199. { we have to add this to avoid var param to be in registers !!!}
  200. if (varspez in [vs_var,vs_const]) and push_addr_param(tt.def) then
  201. include(vs^.varoptions,vo_regable);
  202. { insert the sym in the parasymtable }
  203. pprocdef(aktprocdef)^.parast^.insert(vs);
  204. { do we need a local copy? Then rename the varsym, do this after the
  205. insert so the dup id checking is done correctly }
  206. if (varspez=vs_value) and
  207. push_addr_param(tt.def) and
  208. not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
  209. pprocdef(aktprocdef)^.parast^.rename(vs^.name,'val'+vs^.name);
  210. { also need to push a high value? }
  211. if inserthigh then
  212. begin
  213. hvs:=new(Pvarsym,initdef('high'+s,s32bitdef));
  214. hvs^.varspez:=vs_const;
  215. pprocdef(aktprocdef)^.parast^.insert(hvs);
  216. end;
  217. end;
  218. end;
  219. {$ifdef fixLeaksOnError}
  220. if PStringContainer(strContStack.pop) <> sc then
  221. writeln('problem with strContStack in pdecl (1)');
  222. {$endif fixLeaksOnError}
  223. dispose(sc,done);
  224. tokenpos:=storetokenpos;
  225. end;
  226. { set the new mangled name }
  227. if not is_procvar then
  228. pprocdef(aktprocdef)^.setmangledname(hs2);
  229. until not try_to_consume(_SEMICOLON);
  230. dec(testcurobject);
  231. consume(_RKLAMMER);
  232. end;
  233. const
  234. variantrecordlevel : longint = 0;
  235. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  236. { reads the filed of a record into a }
  237. { symtablestack, if record=false }
  238. { variants are forbidden, so this procedure }
  239. { can be used to read object fields }
  240. { if absolute is true, ABSOLUTE and file }
  241. { types are allowed }
  242. { => the procedure is also used to read }
  243. { a sequence of variable declaration }
  244. procedure insert_syms(st : psymtable;sc : pstringcontainer;tt : ttype;is_threadvar : boolean);
  245. { inserts the symbols of sc in st with def as definition or sym as ptypesym, sc is disposed }
  246. var
  247. s : string;
  248. filepos : tfileposinfo;
  249. ss : pvarsym;
  250. begin
  251. filepos:=tokenpos;
  252. while not sc^.empty do
  253. begin
  254. s:=sc^.get_with_tokeninfo(tokenpos);
  255. ss:=new(pvarsym,init(s,tt));
  256. if is_threadvar then
  257. {$ifdef INCLUDEOK}
  258. include(ss^.varoptions,vo_is_thread_var);
  259. {$else}
  260. ss^.varoptions:=ss^.varoptions+[vo_is_thread_var];
  261. {$endif}
  262. st^.insert(ss);
  263. { static data fields are inserted in the globalsymtable }
  264. if (st^.symtabletype=objectsymtable) and
  265. (sp_static in current_object_option) then
  266. begin
  267. s:=lower(st^.name^)+'_'+s;
  268. st^.defowner^.owner^.insert(new(pvarsym,init(s,tt)));
  269. end;
  270. end;
  271. {$ifdef fixLeaksOnError}
  272. if strContStack.pop <> sc then
  273. writeln('problem with strContStack in pdecl (2)');
  274. {$endif fixLeaksOnError}
  275. dispose(sc,done);
  276. tokenpos:=filepos;
  277. end;
  278. var
  279. sc : pstringcontainer;
  280. s : stringid;
  281. old_block_type : tblock_type;
  282. declarepos,storetokenpos : tfileposinfo;
  283. symdone : boolean;
  284. { to handle absolute }
  285. abssym : pabsolutesym;
  286. l : longint;
  287. code : integer;
  288. { c var }
  289. newtype : ptypesym;
  290. is_dll,
  291. is_gpc_name,is_cdecl,extern_aktvarsym,export_aktvarsym : boolean;
  292. old_current_object_option : tsymoptions;
  293. dll_name,
  294. C_name : string;
  295. tt,casetype : ttype;
  296. { Delphi initialized vars }
  297. pconstsym : ptypedconstsym;
  298. { maxsize contains the max. size of a variant }
  299. { startvarrec contains the start of the variant part of a record }
  300. maxsize,maxalignment,startvarrecalign,startvarrecsize : longint;
  301. pt : ptree;
  302. begin
  303. old_block_type:=block_type;
  304. block_type:=bt_type;
  305. is_gpc_name:=false;
  306. { Force an expected ID error message }
  307. if not (token in [_ID,_CASE,_END]) then
  308. consume(_ID);
  309. { read vars }
  310. while (token=_ID) and
  311. not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
  312. begin
  313. C_name:=orgpattern;
  314. sc:=idlist;
  315. {$ifdef fixLeaksOnError}
  316. strContStack.push(sc);
  317. {$endif fixLeaksOnError}
  318. consume(_COLON);
  319. if (m_gpc in aktmodeswitches) and
  320. not(is_record or is_object or is_threadvar) and
  321. (token=_ID) and (orgpattern='__asmname__') then
  322. begin
  323. consume(_ID);
  324. C_name:=pattern;
  325. if token=_CCHAR then
  326. consume(_CCHAR)
  327. else
  328. consume(_CSTRING);
  329. Is_gpc_name:=true;
  330. end;
  331. { this is needed for Delphi mode at least
  332. but should be OK for all modes !! (PM) }
  333. ignore_equal:=true;
  334. read_type(tt,'');
  335. if (variantrecordlevel>0) and tt.def^.needs_inittable then
  336. Message(parser_e_cant_use_inittable_here);
  337. ignore_equal:=false;
  338. symdone:=false;
  339. if is_gpc_name then
  340. begin
  341. storetokenpos:=tokenpos;
  342. s:=sc^.get_with_tokeninfo(tokenpos);
  343. if not sc^.empty then
  344. Message(parser_e_absolute_only_one_var);
  345. {$ifdef fixLeaksOnError}
  346. if strContStack.pop <> sc then
  347. writeln('problem with strContStack in pdecl (3)');
  348. {$endif fixLeaksOnError}
  349. dispose(sc,done);
  350. aktvarsym:=new(pvarsym,init_C(s,target_os.Cprefix+C_name,tt));
  351. {$ifdef INCLUDEOK}
  352. include(aktvarsym^.varoptions,vo_is_external);
  353. {$else}
  354. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  355. {$endif}
  356. symtablestack^.insert(aktvarsym);
  357. tokenpos:=storetokenpos;
  358. symdone:=true;
  359. end;
  360. { check for absolute }
  361. if not symdone and
  362. (idtoken=_ABSOLUTE) and not(is_record or is_object or is_threadvar) then
  363. begin
  364. consume(_ABSOLUTE);
  365. { only allowed for one var }
  366. s:=sc^.get_with_tokeninfo(declarepos);
  367. if not sc^.empty then
  368. Message(parser_e_absolute_only_one_var);
  369. {$ifdef fixLeaksOnError}
  370. if strContStack.pop <> sc then
  371. writeln('problem with strContStack in pdecl (4)');
  372. {$endif fixLeaksOnError}
  373. dispose(sc,done);
  374. { parse the rest }
  375. if token=_ID then
  376. begin
  377. getsym(pattern,true);
  378. consume(_ID);
  379. { support unit.variable }
  380. if srsym^.typ=unitsym then
  381. begin
  382. consume(_POINT);
  383. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  384. consume(_ID);
  385. end;
  386. { we should check the result type of srsym }
  387. if not (srsym^.typ in [varsym,typedconstsym]) then
  388. Message(parser_e_absolute_only_to_var_or_const);
  389. storetokenpos:=tokenpos;
  390. tokenpos:=declarepos;
  391. abssym:=new(pabsolutesym,init(s,tt));
  392. abssym^.abstyp:=tovar;
  393. abssym^.ref:=srsym;
  394. symtablestack^.insert(abssym);
  395. tokenpos:=storetokenpos;
  396. end
  397. else
  398. if (token=_CSTRING) or (token=_CCHAR) then
  399. begin
  400. storetokenpos:=tokenpos;
  401. tokenpos:=declarepos;
  402. abssym:=new(pabsolutesym,init(s,tt));
  403. s:=pattern;
  404. consume(token);
  405. abssym^.abstyp:=toasm;
  406. abssym^.asmname:=stringdup(s);
  407. symtablestack^.insert(abssym);
  408. tokenpos:=storetokenpos;
  409. end
  410. else
  411. { absolute address ?!? }
  412. if token=_INTCONST then
  413. begin
  414. if (target_info.target=target_i386_go32v2) then
  415. begin
  416. storetokenpos:=tokenpos;
  417. tokenpos:=declarepos;
  418. abssym:=new(pabsolutesym,init(s,tt));
  419. abssym^.abstyp:=toaddr;
  420. abssym^.absseg:=false;
  421. s:=pattern;
  422. consume(_INTCONST);
  423. val(s,abssym^.address,code);
  424. if token=_COLON then
  425. begin
  426. consume(token);
  427. s:=pattern;
  428. consume(_INTCONST);
  429. val(s,l,code);
  430. abssym^.address:=abssym^.address shl 4+l;
  431. abssym^.absseg:=true;
  432. end;
  433. symtablestack^.insert(abssym);
  434. tokenpos:=storetokenpos;
  435. end
  436. else
  437. Message(parser_e_absolute_only_to_var_or_const);
  438. end
  439. else
  440. Message(parser_e_absolute_only_to_var_or_const);
  441. symdone:=true;
  442. end;
  443. { Handling of Delphi typed const = initialized vars ! }
  444. { When should this be rejected ?
  445. - in parasymtable
  446. - in record or object
  447. - ... (PM) }
  448. if (m_delphi in aktmodeswitches) and (token=_EQUAL) and
  449. not (symtablestack^.symtabletype in [parasymtable]) and
  450. not is_record and not is_object then
  451. begin
  452. storetokenpos:=tokenpos;
  453. s:=sc^.get_with_tokeninfo(tokenpos);
  454. if not sc^.empty then
  455. Message(parser_e_initialized_only_one_var);
  456. pconstsym:=new(ptypedconstsym,inittype(s,tt,false));
  457. symtablestack^.insert(pconstsym);
  458. tokenpos:=storetokenpos;
  459. consume(_EQUAL);
  460. readtypedconst(tt.def,pconstsym,false);
  461. symdone:=true;
  462. end;
  463. { for a record there doesn't need to be a ; before the END or ) }
  464. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  465. consume(_SEMICOLON);
  466. { procvar handling }
  467. if (tt.def^.deftype=procvardef) and (tt.def^.typesym=nil) then
  468. begin
  469. newtype:=new(ptypesym,init('unnamed',tt));
  470. parse_var_proc_directives(psym(newtype));
  471. newtype^.restype.def:=nil;
  472. tt.def^.typesym:=nil;
  473. dispose(newtype,done);
  474. end;
  475. { Check for variable directives }
  476. if not symdone and (token=_ID) then
  477. begin
  478. { Check for C Variable declarations }
  479. if (m_cvar_support in aktmodeswitches) and
  480. not(is_record or is_object or is_threadvar) and
  481. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  482. begin
  483. { only allowed for one var }
  484. s:=sc^.get_with_tokeninfo(declarepos);
  485. if not sc^.empty then
  486. Message(parser_e_absolute_only_one_var);
  487. {$ifdef fixLeaksOnError}
  488. if strContStack.pop <> sc then
  489. writeln('problem with strContStack in pdecl (5)');
  490. {$endif fixLeaksOnError}
  491. dispose(sc,done);
  492. { defaults }
  493. is_dll:=false;
  494. is_cdecl:=false;
  495. extern_aktvarsym:=false;
  496. export_aktvarsym:=false;
  497. { cdecl }
  498. if idtoken=_CVAR then
  499. begin
  500. consume(_CVAR);
  501. consume(_SEMICOLON);
  502. is_cdecl:=true;
  503. C_name:=target_os.Cprefix+C_name;
  504. end;
  505. { external }
  506. if idtoken=_EXTERNAL then
  507. begin
  508. consume(_EXTERNAL);
  509. extern_aktvarsym:=true;
  510. end;
  511. { export }
  512. if idtoken in [_EXPORT,_PUBLIC] then
  513. begin
  514. consume(_ID);
  515. if extern_aktvarsym or
  516. (symtablestack^.symtabletype in [parasymtable,localsymtable]) then
  517. Message(parser_e_not_external_and_export)
  518. else
  519. export_aktvarsym:=true;
  520. end;
  521. { external and export need a name after when no cdecl is used }
  522. if not is_cdecl then
  523. begin
  524. { dll name ? }
  525. if (extern_aktvarsym) and (idtoken<>_NAME) then
  526. begin
  527. is_dll:=true;
  528. dll_name:=get_stringconst;
  529. end;
  530. consume(_NAME);
  531. C_name:=get_stringconst;
  532. end;
  533. { consume the ; when export or external is used }
  534. if extern_aktvarsym or export_aktvarsym then
  535. consume(_SEMICOLON);
  536. { insert in the symtable }
  537. storetokenpos:=tokenpos;
  538. tokenpos:=declarepos;
  539. if is_dll then
  540. aktvarsym:=new(pvarsym,init_dll(s,tt))
  541. else
  542. aktvarsym:=new(pvarsym,init_C(s,C_name,tt));
  543. { set some vars options }
  544. if export_aktvarsym then
  545. begin
  546. inc(aktvarsym^.refs);
  547. {$ifdef INCLUDEOK}
  548. include(aktvarsym^.varoptions,vo_is_exported);
  549. {$else}
  550. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_exported];
  551. {$endif}
  552. end;
  553. if extern_aktvarsym then
  554. {$ifdef INCLUDEOK}
  555. include(aktvarsym^.varoptions,vo_is_external);
  556. {$else}
  557. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  558. {$endif}
  559. { insert in the stack/datasegment }
  560. symtablestack^.insert(aktvarsym);
  561. tokenpos:=storetokenpos;
  562. { now we can insert it in the import lib if its a dll, or
  563. add it to the externals }
  564. if extern_aktvarsym then
  565. begin
  566. if is_dll then
  567. begin
  568. if not(current_module^.uses_imports) then
  569. begin
  570. current_module^.uses_imports:=true;
  571. importlib^.preparelib(current_module^.modulename^);
  572. end;
  573. importlib^.importvariable(aktvarsym^.mangledname,dll_name,C_name)
  574. end
  575. end;
  576. symdone:=true;
  577. end
  578. else
  579. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  580. begin
  581. {$ifdef INCLUDEOK}
  582. include(current_object_option,sp_static);
  583. {$else}
  584. current_object_option:=current_object_option+[sp_static];
  585. {$endif}
  586. insert_syms(symtablestack,sc,tt,false);
  587. {$ifdef INCLUDEOK}
  588. exclude(current_object_option,sp_static);
  589. {$else}
  590. current_object_option:=current_object_option-[sp_static];
  591. {$endif}
  592. consume(_STATIC);
  593. consume(_SEMICOLON);
  594. symdone:=true;
  595. end;
  596. end;
  597. { insert it in the symtable, if not done yet }
  598. if not symdone then
  599. begin
  600. { save object option, because we can turn of the sp_published }
  601. old_current_object_option:=current_object_option;
  602. if (sp_published in current_object_option) and
  603. (not((tt.def^.deftype=objectdef) and (pobjectdef(tt.def)^.is_class))) then
  604. begin
  605. Message(parser_e_cant_publish_that);
  606. exclude(current_object_option,sp_published);
  607. end
  608. else
  609. if (sp_published in current_object_option) and
  610. not(oo_can_have_published in pobjectdef(tt.def)^.objectoptions) then
  611. begin
  612. Message(parser_e_only_publishable_classes_can__be_published);
  613. exclude(current_object_option,sp_published);
  614. end;
  615. insert_syms(symtablestack,sc,tt,is_threadvar);
  616. current_object_option:=old_current_object_option;
  617. end;
  618. end;
  619. { Check for Case }
  620. if is_record and (token=_CASE) then
  621. begin
  622. maxsize:=0;
  623. maxalignment:=0;
  624. consume(_CASE);
  625. s:=pattern;
  626. getsym(s,false);
  627. { may be only a type: }
  628. if assigned(srsym) and (srsym^.typ in [typesym,unitsym]) then
  629. read_type(casetype,'')
  630. else
  631. begin
  632. consume(_ID);
  633. consume(_COLON);
  634. read_type(casetype,'');
  635. symtablestack^.insert(new(pvarsym,init(s,casetype)));
  636. end;
  637. if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
  638. Message(type_e_ordinal_expr_expected);
  639. consume(_OF);
  640. startvarrecsize:=symtablestack^.datasize;
  641. startvarrecalign:=symtablestack^.dataalignment;
  642. repeat
  643. repeat
  644. pt:=comp_expr(true);
  645. do_firstpass(pt);
  646. if not(pt^.treetype=ordconstn) then
  647. Message(cg_e_illegal_expression);
  648. disposetree(pt);
  649. if token=_COMMA then
  650. consume(_COMMA)
  651. else
  652. break;
  653. until false;
  654. consume(_COLON);
  655. { read the vars }
  656. consume(_LKLAMMER);
  657. inc(variantrecordlevel);
  658. if token<>_RKLAMMER then
  659. read_var_decs(true,false,false);
  660. dec(variantrecordlevel);
  661. consume(_RKLAMMER);
  662. { calculates maximal variant size }
  663. maxsize:=max(maxsize,symtablestack^.datasize);
  664. maxalignment:=max(maxalignment,symtablestack^.dataalignment);
  665. { the items of the next variant are overlayed }
  666. symtablestack^.datasize:=startvarrecsize;
  667. symtablestack^.dataalignment:=startvarrecalign;
  668. if (token<>_END) and (token<>_RKLAMMER) then
  669. consume(_SEMICOLON)
  670. else
  671. break;
  672. until (token=_END) or (token=_RKLAMMER);
  673. { at last set the record size to that of the biggest variant }
  674. symtablestack^.datasize:=maxsize;
  675. symtablestack^.dataalignment:=maxalignment;
  676. end;
  677. block_type:=old_block_type;
  678. end;
  679. procedure const_dec;
  680. var
  681. name : stringid;
  682. p : ptree;
  683. tt : ttype;
  684. sym : psym;
  685. storetokenpos,filepos : tfileposinfo;
  686. old_block_type : tblock_type;
  687. ps : pconstset;
  688. pd : pbestreal;
  689. sp : pchar;
  690. skipequal : boolean;
  691. begin
  692. consume(_CONST);
  693. old_block_type:=block_type;
  694. block_type:=bt_const;
  695. repeat
  696. name:=pattern;
  697. filepos:=tokenpos;
  698. consume(_ID);
  699. case token of
  700. _EQUAL:
  701. begin
  702. consume(_EQUAL);
  703. p:=comp_expr(true);
  704. do_firstpass(p);
  705. storetokenpos:=tokenpos;
  706. tokenpos:=filepos;
  707. case p^.treetype of
  708. ordconstn:
  709. begin
  710. if is_constintnode(p) then
  711. symtablestack^.insert(new(pconstsym,init_def(name,constint,p^.value,nil)))
  712. else if is_constcharnode(p) then
  713. symtablestack^.insert(new(pconstsym,init_def(name,constchar,p^.value,nil)))
  714. else if is_constboolnode(p) then
  715. symtablestack^.insert(new(pconstsym,init_def(name,constbool,p^.value,nil)))
  716. else if p^.resulttype^.deftype=enumdef then
  717. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  718. else if p^.resulttype^.deftype=pointerdef then
  719. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  720. else internalerror(111);
  721. end;
  722. stringconstn:
  723. begin
  724. getmem(sp,p^.length+1);
  725. move(p^.value_str^,sp^,p^.length+1);
  726. symtablestack^.insert(new(pconstsym,init_string(name,conststring,sp,p^.length)));
  727. end;
  728. realconstn :
  729. begin
  730. new(pd);
  731. pd^:=p^.value_real;
  732. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd))));
  733. end;
  734. setconstn :
  735. begin
  736. new(ps);
  737. ps^:=p^.value_set^;
  738. symtablestack^.insert(new(pconstsym,init_def(name,constset,longint(ps),p^.resulttype)));
  739. end;
  740. pointerconstn :
  741. begin
  742. symtablestack^.insert(new(pconstsym,init_def(name,constpointer,p^.value,p^.resulttype)))
  743. end;
  744. niln :
  745. begin
  746. symtablestack^.insert(new(pconstsym,init_def(name,constnil,0,p^.resulttype)));
  747. end;
  748. else
  749. Message(cg_e_illegal_expression);
  750. end;
  751. tokenpos:=storetokenpos;
  752. consume(_SEMICOLON);
  753. disposetree(p);
  754. end;
  755. _COLON:
  756. begin
  757. { set the blocktype first so a consume also supports a
  758. caret, to support const s : ^string = nil }
  759. block_type:=bt_type;
  760. consume(_COLON);
  761. ignore_equal:=true;
  762. read_type(tt,'');
  763. ignore_equal:=false;
  764. block_type:=bt_const;
  765. skipequal:=false;
  766. { create symbol }
  767. storetokenpos:=tokenpos;
  768. tokenpos:=filepos;
  769. {$ifdef DELPHI_CONST_IN_RODATA}
  770. if m_delphi in aktmodeswitches then
  771. begin
  772. if assigned(readtypesym) then
  773. sym:=new(ptypedconstsym,initsym(name,readtypesym,true))
  774. else
  775. sym:=new(ptypedconstsym,init(name,def,true))
  776. end
  777. else
  778. {$endif DELPHI_CONST_IN_RODATA}
  779. begin
  780. sym:=new(ptypedconstsym,inittype(name,tt,false))
  781. end;
  782. tokenpos:=storetokenpos;
  783. symtablestack^.insert(sym);
  784. { procvar can have proc directives }
  785. if (tt.def^.deftype=procvardef) then
  786. begin
  787. { support p : procedure;stdcall=nil; }
  788. if (token=_SEMICOLON) then
  789. begin
  790. consume(_SEMICOLON);
  791. if is_proc_directive(token) then
  792. parse_var_proc_directives(sym)
  793. else
  794. begin
  795. Message(parser_e_proc_directive_expected);
  796. skipequal:=true;
  797. end;
  798. end
  799. else
  800. { support p : procedure stdcall=nil; }
  801. begin
  802. if is_proc_directive(token) then
  803. parse_var_proc_directives(sym);
  804. end;
  805. end;
  806. if not skipequal then
  807. begin
  808. { get init value }
  809. consume(_EQUAL);
  810. {$ifdef DELPHI_CONST_IN_RODATA}
  811. if m_delphi in aktmodeswitches then
  812. readtypedconst(tt.def,ptypedconstsym(sym),true)
  813. else
  814. {$endif DELPHI_CONST_IN_RODATA}
  815. readtypedconst(tt.def,ptypedconstsym(sym),false);
  816. consume(_SEMICOLON);
  817. end;
  818. end;
  819. else
  820. { generate an error }
  821. consume(_EQUAL);
  822. end;
  823. until token<>_ID;
  824. block_type:=old_block_type;
  825. end;
  826. procedure label_dec;
  827. var
  828. hl : pasmlabel;
  829. begin
  830. consume(_LABEL);
  831. if not(cs_support_goto in aktmoduleswitches) then
  832. Message(sym_e_goto_and_label_not_supported);
  833. repeat
  834. if not(token in [_ID,_INTCONST]) then
  835. consume(_ID)
  836. else
  837. begin
  838. getlabel(hl);
  839. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  840. consume(token);
  841. end;
  842. if token<>_SEMICOLON then consume(_COMMA);
  843. until not(token in [_ID,_INTCONST]);
  844. consume(_SEMICOLON);
  845. end;
  846. { search in symtablestack used, but not defined type }
  847. procedure resolve_type_forward(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
  848. var
  849. hpd,pd : pdef;
  850. stpos : tfileposinfo;
  851. again : boolean;
  852. begin
  853. { Check only typesyms or record/object fields }
  854. case psym(p)^.typ of
  855. typesym :
  856. pd:=ptypesym(p)^.restype.def;
  857. varsym :
  858. if (psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  859. pd:=pvarsym(p)^.vartype.def
  860. else
  861. exit;
  862. else
  863. exit;
  864. end;
  865. repeat
  866. again:=false;
  867. case pd^.deftype of
  868. arraydef :
  869. begin
  870. { elementtype could also be defined using a forwarddef }
  871. pd:=parraydef(pd)^.elementtype.def;
  872. again:=true;
  873. end;
  874. pointerdef,
  875. classrefdef :
  876. begin
  877. { classrefdef inherits from pointerdef }
  878. hpd:=ppointerdef(pd)^.pointertype.def;
  879. { still a forward def ? }
  880. if hpd^.deftype=forwarddef then
  881. begin
  882. { try to resolve the forward }
  883. { get the correct position for it }
  884. stpos:=tokenpos;
  885. tokenpos:=pforwarddef(hpd)^.forwardpos;
  886. resolving_forward:=true;
  887. make_ref:=false;
  888. getsym(pforwarddef(hpd)^.tosymname,false);
  889. make_ref:=true;
  890. resolving_forward:=false;
  891. tokenpos:=stpos;
  892. { we don't need the forwarddef anymore, dispose it }
  893. dispose(hpd,done);
  894. { was a type sym found ? }
  895. if assigned(srsym) and
  896. (srsym^.typ=typesym) then
  897. begin
  898. ppointerdef(pd)^.pointertype.setsym(srsym);
  899. { avoid wrong unused warnings web bug 801 PM }
  900. inc(srsym^.refs);
  901. {$ifdef GDB}
  902. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  903. (psym(p)^.owner^.symtabletype in [globalsymtable,staticsymtable]) then
  904. begin
  905. ptypesym(p)^.isusedinstab := true;
  906. psym(p)^.concatstabto(debuglist);
  907. end;
  908. {$endif GDB}
  909. { we need a class type for classrefdef }
  910. if (pd^.deftype=classrefdef) and
  911. not((ptypesym(srsym)^.restype.def^.deftype=objectdef) and
  912. pobjectdef(ptypesym(srsym)^.restype.def)^.is_class) then
  913. Message1(type_e_class_type_expected,ptypesym(srsym)^.restype.def^.typename);
  914. end
  915. else
  916. begin
  917. MessagePos1(psym(p)^.fileinfo,sym_e_forward_type_not_resolved,p^.name);
  918. { try to recover }
  919. ppointerdef(pd)^.pointertype.def:=generrordef;
  920. end;
  921. end;
  922. end;
  923. recorddef :
  924. precorddef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  925. objectdef :
  926. { Don't check objectdefs in objects/records, because these can't
  927. exist (anonymous objects aren't allowed) }
  928. if not(psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  929. pobjectdef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  930. end;
  931. until not again;
  932. end;
  933. { reads a type declaration to the symbol table }
  934. procedure type_dec;
  935. var
  936. typename : stringid;
  937. newtype : ptypesym;
  938. sym : psym;
  939. tt : ttype;
  940. defpos,storetokenpos : tfileposinfo;
  941. old_block_type : tblock_type;
  942. begin
  943. old_block_type:=block_type;
  944. block_type:=bt_type;
  945. consume(_TYPE);
  946. typecanbeforward:=true;
  947. repeat
  948. typename:=pattern;
  949. defpos:=tokenpos;
  950. consume(_ID);
  951. consume(_EQUAL);
  952. { support 'ttype=type word' syntax }
  953. if token=_TYPE then
  954. Consume(_TYPE);
  955. { is the type already defined? }
  956. getsym(typename,false);
  957. sym:=srsym;
  958. newtype:=nil;
  959. { found a symbol with this name? }
  960. if assigned(sym) then
  961. begin
  962. if (sym^.typ=typesym) then
  963. begin
  964. if (token=_CLASS) and
  965. (assigned(ptypesym(sym)^.restype.def)) and
  966. (ptypesym(sym)^.restype.def^.deftype=objectdef) and
  967. pobjectdef(ptypesym(sym)^.restype.def)^.is_class and
  968. (oo_is_forward in pobjectdef(ptypesym(sym)^.restype.def)^.objectoptions) then
  969. begin
  970. { we can ignore the result }
  971. { the definition is modified }
  972. object_dec(typename,pobjectdef(ptypesym(sym)^.restype.def));
  973. newtype:=ptypesym(sym);
  974. end;
  975. end;
  976. end;
  977. { no old type reused ? Then insert this new type }
  978. if not assigned(newtype) then
  979. begin
  980. read_type(tt,typename);
  981. storetokenpos:=tokenpos;
  982. tokenpos:=defpos;
  983. newtype:=new(ptypesym,init(typename,tt));
  984. symtablestack^.insert(newtype);
  985. tokenpos:=storetokenpos;
  986. end;
  987. if assigned(newtype^.restype.def) and
  988. (newtype^.restype.def^.deftype=procvardef) then
  989. begin
  990. if not is_proc_directive(token) then
  991. consume(_SEMICOLON);
  992. parse_var_proc_directives(psym(newtype));
  993. end
  994. else
  995. consume(_SEMICOLON);
  996. until token<>_ID;
  997. typecanbeforward:=false;
  998. symtablestack^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  999. block_type:=old_block_type;
  1000. end;
  1001. procedure var_dec;
  1002. { parses variable declarations and inserts them in }
  1003. { the top symbol table of symtablestack }
  1004. begin
  1005. consume(_VAR);
  1006. read_var_decs(false,false,false);
  1007. end;
  1008. procedure threadvar_dec;
  1009. { parses thread variable declarations and inserts them in }
  1010. { the top symbol table of symtablestack }
  1011. begin
  1012. consume(_THREADVAR);
  1013. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  1014. message(parser_e_threadvars_only_sg);
  1015. read_var_decs(false,false,true);
  1016. end;
  1017. procedure resourcestring_dec;
  1018. var
  1019. name : stringid;
  1020. p : ptree;
  1021. storetokenpos,filepos : tfileposinfo;
  1022. old_block_type : tblock_type;
  1023. sp : pchar;
  1024. begin
  1025. consume(_RESOURCESTRING);
  1026. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  1027. message(parser_e_resourcestring_only_sg);
  1028. old_block_type:=block_type;
  1029. block_type:=bt_const;
  1030. repeat
  1031. name:=pattern;
  1032. filepos:=tokenpos;
  1033. consume(_ID);
  1034. case token of
  1035. _EQUAL:
  1036. begin
  1037. consume(_EQUAL);
  1038. p:=comp_expr(true);
  1039. do_firstpass(p);
  1040. storetokenpos:=tokenpos;
  1041. tokenpos:=filepos;
  1042. case p^.treetype of
  1043. ordconstn:
  1044. begin
  1045. if is_constcharnode(p) then
  1046. begin
  1047. getmem(sp,2);
  1048. sp[0]:=chr(p^.value);
  1049. sp[1]:=#0;
  1050. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,1)));
  1051. end
  1052. else
  1053. Message(cg_e_illegal_expression);
  1054. end;
  1055. stringconstn:
  1056. begin
  1057. getmem(sp,p^.length+1);
  1058. move(p^.value_str^,sp^,p^.length+1);
  1059. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,p^.length)));
  1060. end;
  1061. else
  1062. Message(cg_e_illegal_expression);
  1063. end;
  1064. tokenpos:=storetokenpos;
  1065. consume(_SEMICOLON);
  1066. disposetree(p);
  1067. end;
  1068. else consume(_EQUAL);
  1069. end;
  1070. until token<>_ID;
  1071. block_type:=old_block_type;
  1072. end;
  1073. procedure Not_supported_for_inline(t : ttoken);
  1074. begin
  1075. if assigned(aktprocsym) and
  1076. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1077. Begin
  1078. Message1(parser_w_not_supported_for_inline,tokenstring(t));
  1079. Message(parser_w_inlining_disabled);
  1080. {$ifdef INCLUDEOK}
  1081. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  1082. {$else}
  1083. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions-[pocall_inline];
  1084. {$endif}
  1085. End;
  1086. end;
  1087. procedure read_declarations(islibrary : boolean);
  1088. begin
  1089. repeat
  1090. case token of
  1091. _LABEL:
  1092. begin
  1093. Not_supported_for_inline(token);
  1094. label_dec;
  1095. end;
  1096. _CONST:
  1097. begin
  1098. Not_supported_for_inline(token);
  1099. const_dec;
  1100. end;
  1101. _TYPE:
  1102. begin
  1103. Not_supported_for_inline(token);
  1104. type_dec;
  1105. end;
  1106. _VAR:
  1107. var_dec;
  1108. _THREADVAR:
  1109. threadvar_dec;
  1110. _CONSTRUCTOR,_DESTRUCTOR,
  1111. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1112. begin
  1113. Not_supported_for_inline(token);
  1114. read_proc;
  1115. end;
  1116. _RESOURCESTRING:
  1117. resourcestring_dec;
  1118. _EXPORTS:
  1119. begin
  1120. Not_supported_for_inline(token);
  1121. { here we should be at lexlevel 1, no ? PM }
  1122. if (lexlevel<>main_program_level) or
  1123. (current_module^.is_unit) then
  1124. begin
  1125. Message(parser_e_syntax_error);
  1126. consume_all_until(_SEMICOLON);
  1127. end
  1128. else if islibrary or (target_info.target=target_i386_WIN32) then
  1129. read_exports;
  1130. end
  1131. else break;
  1132. end;
  1133. until false;
  1134. end;
  1135. procedure read_interface_declarations;
  1136. begin
  1137. {Since the body is now parsed at lexlevel 1, and the declarations
  1138. must be parsed at the same lexlevel we increase the lexlevel.}
  1139. inc(lexlevel);
  1140. repeat
  1141. case token of
  1142. _CONST : const_dec;
  1143. _TYPE : type_dec;
  1144. _VAR : var_dec;
  1145. _THREADVAR : threadvar_dec;
  1146. _RESOURCESTRING:
  1147. resourcestring_dec;
  1148. _FUNCTION,
  1149. _PROCEDURE,
  1150. _OPERATOR : read_proc;
  1151. else
  1152. break;
  1153. end;
  1154. until false;
  1155. dec(lexlevel);
  1156. end;
  1157. end.
  1158. {
  1159. $Log$
  1160. Revision 1.186 2000-06-18 18:11:32 peter
  1161. * C record packing fixed to also check first entry of the record
  1162. if bigger than the recordalignment itself
  1163. * variant record alignment uses alignment per variant and saves the
  1164. highest alignment value
  1165. Revision 1.185 2000/06/11 06:59:36 peter
  1166. * support procvar directive without ; before the directives
  1167. Revision 1.184 2000/06/09 21:34:40 peter
  1168. * checking for dup id with para of methods fixed for delphi mode
  1169. Revision 1.183 2000/06/02 21:18:13 pierre
  1170. + set vo_is_exported for vars
  1171. Revision 1.182 2000/06/01 19:14:09 peter
  1172. * symtable.insert changed to procedure
  1173. Revision 1.181 2000/04/17 18:44:22 peter
  1174. * fixed forward resolving with redefined types
  1175. Revision 1.180 2000/02/09 13:22:56 peter
  1176. * log truncated
  1177. Revision 1.179 2000/01/20 12:29:02 pierre
  1178. * bug 801 fixed
  1179. Revision 1.178 2000/01/11 17:16:05 jonas
  1180. * removed a lot of memory leaks when an error is encountered (caused by
  1181. procinfo and pstringcontainers). There are still plenty left though :)
  1182. Revision 1.177 2000/01/10 11:14:19 peter
  1183. * fixed memory leak with options, you must use StopOptions instead of
  1184. Stop
  1185. * fixed memory leak with forward resolving, make_ref is now false
  1186. Revision 1.176 2000/01/07 01:14:28 peter
  1187. * updated copyright to 2000
  1188. Revision 1.175 1999/12/10 10:04:21 peter
  1189. * also check elementtype of arraydef for forwarddef
  1190. Revision 1.174 1999/12/01 12:42:32 peter
  1191. * fixed bug 698
  1192. * removed some notes about unused vars
  1193. Revision 1.173 1999/11/30 10:40:44 peter
  1194. + ttype, tsymlist
  1195. Revision 1.172 1999/11/29 15:18:27 pierre
  1196. + allow exports in win32 executables
  1197. Revision 1.171 1999/11/09 23:43:08 pierre
  1198. * better browser info
  1199. Revision 1.170 1999/11/09 23:06:45 peter
  1200. * esi_offset -> selfpointer_offset to be newcg compatible
  1201. * hcogegen -> cgbase fixes for newcg
  1202. Revision 1.169 1999/11/09 12:58:29 peter
  1203. * support absolute unit.variable
  1204. Revision 1.168 1999/11/06 14:34:21 peter
  1205. * truncated log to 20 revs
  1206. Revision 1.167 1999/10/26 12:30:44 peter
  1207. * const parameter is now checked
  1208. * better and generic check if a node can be used for assigning
  1209. * export fixes
  1210. * procvar equal works now (it never had worked at least from 0.99.8)
  1211. * defcoll changed to linkedlist with pparaitem so it can easily be
  1212. walked both directions
  1213. Revision 1.166 1999/10/22 10:39:34 peter
  1214. * split type reading from pdecl to ptype unit
  1215. * parameter_dec routine is now used for procedure and procvars
  1216. Revision 1.165 1999/10/21 16:41:41 florian
  1217. * problems with readln fixed: esi wasn't restored correctly when
  1218. reading ordinal fields of objects futher the register allocation
  1219. didn't take care of the extra register when reading ordinal values
  1220. * enumerations can now be used in constant indexes of properties
  1221. Revision 1.164 1999/10/14 14:57:52 florian
  1222. - removed the hcodegen use in the new cg, use cgbase instead
  1223. Revision 1.163 1999/10/06 17:39:14 peter
  1224. * fixed stabs writting for forward types
  1225. Revision 1.162 1999/10/03 19:44:42 peter
  1226. * removed objpasunit reference, tvarrec is now searched in systemunit
  1227. where it already was located
  1228. Revision 1.161 1999/10/01 11:18:02 peter
  1229. * class/record type forward checking fixed
  1230. Revision 1.159 1999/10/01 10:05:42 peter
  1231. + procedure directive support in const declarations, fixes bug 232
  1232. }