pdecl.pas 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  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_current_object_option:=current_object_option;
  304. { all variables are public if not in a object declaration }
  305. if not is_object then
  306. current_object_option:=[sp_public];
  307. old_block_type:=block_type;
  308. block_type:=bt_type;
  309. is_gpc_name:=false;
  310. { Force an expected ID error message }
  311. if not (token in [_ID,_CASE,_END]) then
  312. consume(_ID);
  313. { read vars }
  314. while (token=_ID) and
  315. not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
  316. begin
  317. C_name:=orgpattern;
  318. sc:=idlist;
  319. {$ifdef fixLeaksOnError}
  320. strContStack.push(sc);
  321. {$endif fixLeaksOnError}
  322. consume(_COLON);
  323. if (m_gpc in aktmodeswitches) and
  324. not(is_record or is_object or is_threadvar) and
  325. (token=_ID) and (orgpattern='__asmname__') then
  326. begin
  327. consume(_ID);
  328. C_name:=pattern;
  329. if token=_CCHAR then
  330. consume(_CCHAR)
  331. else
  332. consume(_CSTRING);
  333. Is_gpc_name:=true;
  334. end;
  335. { this is needed for Delphi mode at least
  336. but should be OK for all modes !! (PM) }
  337. ignore_equal:=true;
  338. read_type(tt,'');
  339. if (variantrecordlevel>0) and tt.def^.needs_inittable then
  340. Message(parser_e_cant_use_inittable_here);
  341. ignore_equal:=false;
  342. symdone:=false;
  343. if is_gpc_name then
  344. begin
  345. storetokenpos:=tokenpos;
  346. s:=sc^.get_with_tokeninfo(tokenpos);
  347. if not sc^.empty then
  348. Message(parser_e_absolute_only_one_var);
  349. {$ifdef fixLeaksOnError}
  350. if strContStack.pop <> sc then
  351. writeln('problem with strContStack in pdecl (3)');
  352. {$endif fixLeaksOnError}
  353. dispose(sc,done);
  354. aktvarsym:=new(pvarsym,init_C(s,target_os.Cprefix+C_name,tt));
  355. {$ifdef INCLUDEOK}
  356. include(aktvarsym^.varoptions,vo_is_external);
  357. {$else}
  358. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  359. {$endif}
  360. symtablestack^.insert(aktvarsym);
  361. tokenpos:=storetokenpos;
  362. symdone:=true;
  363. end;
  364. { check for absolute }
  365. if not symdone and
  366. (idtoken=_ABSOLUTE) and not(is_record or is_object or is_threadvar) then
  367. begin
  368. consume(_ABSOLUTE);
  369. { only allowed for one var }
  370. s:=sc^.get_with_tokeninfo(declarepos);
  371. if not sc^.empty then
  372. Message(parser_e_absolute_only_one_var);
  373. {$ifdef fixLeaksOnError}
  374. if strContStack.pop <> sc then
  375. writeln('problem with strContStack in pdecl (4)');
  376. {$endif fixLeaksOnError}
  377. dispose(sc,done);
  378. { parse the rest }
  379. if token=_ID then
  380. begin
  381. getsym(pattern,true);
  382. consume(_ID);
  383. { support unit.variable }
  384. if srsym^.typ=unitsym then
  385. begin
  386. consume(_POINT);
  387. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  388. consume(_ID);
  389. end;
  390. { we should check the result type of srsym }
  391. if not (srsym^.typ in [varsym,typedconstsym]) then
  392. Message(parser_e_absolute_only_to_var_or_const);
  393. storetokenpos:=tokenpos;
  394. tokenpos:=declarepos;
  395. abssym:=new(pabsolutesym,init(s,tt));
  396. abssym^.abstyp:=tovar;
  397. abssym^.ref:=srsym;
  398. symtablestack^.insert(abssym);
  399. tokenpos:=storetokenpos;
  400. end
  401. else
  402. if (token=_CSTRING) or (token=_CCHAR) then
  403. begin
  404. storetokenpos:=tokenpos;
  405. tokenpos:=declarepos;
  406. abssym:=new(pabsolutesym,init(s,tt));
  407. s:=pattern;
  408. consume(token);
  409. abssym^.abstyp:=toasm;
  410. abssym^.asmname:=stringdup(s);
  411. symtablestack^.insert(abssym);
  412. tokenpos:=storetokenpos;
  413. end
  414. else
  415. { absolute address ?!? }
  416. if token=_INTCONST then
  417. begin
  418. if (target_info.target=target_i386_go32v2) then
  419. begin
  420. storetokenpos:=tokenpos;
  421. tokenpos:=declarepos;
  422. abssym:=new(pabsolutesym,init(s,tt));
  423. abssym^.abstyp:=toaddr;
  424. abssym^.absseg:=false;
  425. s:=pattern;
  426. consume(_INTCONST);
  427. val(s,abssym^.address,code);
  428. if token=_COLON then
  429. begin
  430. consume(token);
  431. s:=pattern;
  432. consume(_INTCONST);
  433. val(s,l,code);
  434. abssym^.address:=abssym^.address shl 4+l;
  435. abssym^.absseg:=true;
  436. end;
  437. symtablestack^.insert(abssym);
  438. tokenpos:=storetokenpos;
  439. end
  440. else
  441. Message(parser_e_absolute_only_to_var_or_const);
  442. end
  443. else
  444. Message(parser_e_absolute_only_to_var_or_const);
  445. symdone:=true;
  446. end;
  447. { Handling of Delphi typed const = initialized vars ! }
  448. { When should this be rejected ?
  449. - in parasymtable
  450. - in record or object
  451. - ... (PM) }
  452. if (m_delphi in aktmodeswitches) and (token=_EQUAL) and
  453. not (symtablestack^.symtabletype in [parasymtable]) and
  454. not is_record and not is_object then
  455. begin
  456. storetokenpos:=tokenpos;
  457. s:=sc^.get_with_tokeninfo(tokenpos);
  458. if not sc^.empty then
  459. Message(parser_e_initialized_only_one_var);
  460. pconstsym:=new(ptypedconstsym,inittype(s,tt,false));
  461. symtablestack^.insert(pconstsym);
  462. tokenpos:=storetokenpos;
  463. consume(_EQUAL);
  464. readtypedconst(tt.def,pconstsym,false);
  465. symdone:=true;
  466. end;
  467. { for a record there doesn't need to be a ; before the END or ) }
  468. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  469. consume(_SEMICOLON);
  470. { procvar handling }
  471. if (tt.def^.deftype=procvardef) and (tt.def^.typesym=nil) then
  472. begin
  473. newtype:=new(ptypesym,init('unnamed',tt));
  474. parse_var_proc_directives(psym(newtype));
  475. newtype^.restype.def:=nil;
  476. tt.def^.typesym:=nil;
  477. dispose(newtype,done);
  478. end;
  479. { Check for variable directives }
  480. if not symdone and (token=_ID) then
  481. begin
  482. { Check for C Variable declarations }
  483. if (m_cvar_support in aktmodeswitches) and
  484. not(is_record or is_object or is_threadvar) and
  485. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  486. begin
  487. { only allowed for one var }
  488. s:=sc^.get_with_tokeninfo(declarepos);
  489. if not sc^.empty then
  490. Message(parser_e_absolute_only_one_var);
  491. {$ifdef fixLeaksOnError}
  492. if strContStack.pop <> sc then
  493. writeln('problem with strContStack in pdecl (5)');
  494. {$endif fixLeaksOnError}
  495. dispose(sc,done);
  496. { defaults }
  497. is_dll:=false;
  498. is_cdecl:=false;
  499. extern_aktvarsym:=false;
  500. export_aktvarsym:=false;
  501. { cdecl }
  502. if idtoken=_CVAR then
  503. begin
  504. consume(_CVAR);
  505. consume(_SEMICOLON);
  506. is_cdecl:=true;
  507. C_name:=target_os.Cprefix+C_name;
  508. end;
  509. { external }
  510. if idtoken=_EXTERNAL then
  511. begin
  512. consume(_EXTERNAL);
  513. extern_aktvarsym:=true;
  514. end;
  515. { export }
  516. if idtoken in [_EXPORT,_PUBLIC] then
  517. begin
  518. consume(_ID);
  519. if extern_aktvarsym or
  520. (symtablestack^.symtabletype in [parasymtable,localsymtable]) then
  521. Message(parser_e_not_external_and_export)
  522. else
  523. export_aktvarsym:=true;
  524. end;
  525. { external and export need a name after when no cdecl is used }
  526. if not is_cdecl then
  527. begin
  528. { dll name ? }
  529. if (extern_aktvarsym) and (idtoken<>_NAME) then
  530. begin
  531. is_dll:=true;
  532. dll_name:=get_stringconst;
  533. end;
  534. consume(_NAME);
  535. C_name:=get_stringconst;
  536. end;
  537. { consume the ; when export or external is used }
  538. if extern_aktvarsym or export_aktvarsym then
  539. consume(_SEMICOLON);
  540. { insert in the symtable }
  541. storetokenpos:=tokenpos;
  542. tokenpos:=declarepos;
  543. if is_dll then
  544. aktvarsym:=new(pvarsym,init_dll(s,tt))
  545. else
  546. aktvarsym:=new(pvarsym,init_C(s,C_name,tt));
  547. { set some vars options }
  548. if export_aktvarsym then
  549. begin
  550. inc(aktvarsym^.refs);
  551. {$ifdef INCLUDEOK}
  552. include(aktvarsym^.varoptions,vo_is_exported);
  553. {$else}
  554. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_exported];
  555. {$endif}
  556. end;
  557. if extern_aktvarsym then
  558. {$ifdef INCLUDEOK}
  559. include(aktvarsym^.varoptions,vo_is_external);
  560. {$else}
  561. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  562. {$endif}
  563. { insert in the stack/datasegment }
  564. symtablestack^.insert(aktvarsym);
  565. tokenpos:=storetokenpos;
  566. { now we can insert it in the import lib if its a dll, or
  567. add it to the externals }
  568. if extern_aktvarsym then
  569. begin
  570. if is_dll then
  571. begin
  572. if not(current_module^.uses_imports) then
  573. begin
  574. current_module^.uses_imports:=true;
  575. importlib^.preparelib(current_module^.modulename^);
  576. end;
  577. importlib^.importvariable(aktvarsym^.mangledname,dll_name,C_name)
  578. end
  579. end;
  580. symdone:=true;
  581. end
  582. else
  583. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  584. begin
  585. {$ifdef INCLUDEOK}
  586. include(current_object_option,sp_static);
  587. {$else}
  588. current_object_option:=current_object_option+[sp_static];
  589. {$endif}
  590. insert_syms(symtablestack,sc,tt,false);
  591. {$ifdef INCLUDEOK}
  592. exclude(current_object_option,sp_static);
  593. {$else}
  594. current_object_option:=current_object_option-[sp_static];
  595. {$endif}
  596. consume(_STATIC);
  597. consume(_SEMICOLON);
  598. symdone:=true;
  599. end;
  600. end;
  601. { insert it in the symtable, if not done yet }
  602. if not symdone then
  603. begin
  604. { save object option, because we can turn of the sp_published }
  605. if (sp_published in current_object_option) and
  606. (not((tt.def^.deftype=objectdef) and (pobjectdef(tt.def)^.is_class))) then
  607. begin
  608. Message(parser_e_cant_publish_that);
  609. exclude(current_object_option,sp_published);
  610. end
  611. else
  612. if (sp_published in current_object_option) and
  613. not(oo_can_have_published in pobjectdef(tt.def)^.objectoptions) then
  614. begin
  615. Message(parser_e_only_publishable_classes_can__be_published);
  616. exclude(current_object_option,sp_published);
  617. end;
  618. insert_syms(symtablestack,sc,tt,is_threadvar);
  619. current_object_option:=old_current_object_option;
  620. end;
  621. end;
  622. { Check for Case }
  623. if is_record and (token=_CASE) then
  624. begin
  625. maxsize:=0;
  626. maxalignment:=0;
  627. consume(_CASE);
  628. s:=pattern;
  629. getsym(s,false);
  630. { may be only a type: }
  631. if assigned(srsym) and (srsym^.typ in [typesym,unitsym]) then
  632. read_type(casetype,'')
  633. else
  634. begin
  635. consume(_ID);
  636. consume(_COLON);
  637. read_type(casetype,'');
  638. symtablestack^.insert(new(pvarsym,init(s,casetype)));
  639. end;
  640. if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
  641. Message(type_e_ordinal_expr_expected);
  642. consume(_OF);
  643. startvarrecsize:=symtablestack^.datasize;
  644. startvarrecalign:=symtablestack^.dataalignment;
  645. repeat
  646. repeat
  647. pt:=comp_expr(true);
  648. do_firstpass(pt);
  649. if not(pt^.treetype=ordconstn) then
  650. Message(cg_e_illegal_expression);
  651. disposetree(pt);
  652. if token=_COMMA then
  653. consume(_COMMA)
  654. else
  655. break;
  656. until false;
  657. consume(_COLON);
  658. { read the vars }
  659. consume(_LKLAMMER);
  660. inc(variantrecordlevel);
  661. if token<>_RKLAMMER then
  662. read_var_decs(true,false,false);
  663. dec(variantrecordlevel);
  664. consume(_RKLAMMER);
  665. { calculates maximal variant size }
  666. maxsize:=max(maxsize,symtablestack^.datasize);
  667. maxalignment:=max(maxalignment,symtablestack^.dataalignment);
  668. { the items of the next variant are overlayed }
  669. symtablestack^.datasize:=startvarrecsize;
  670. symtablestack^.dataalignment:=startvarrecalign;
  671. if (token<>_END) and (token<>_RKLAMMER) then
  672. consume(_SEMICOLON)
  673. else
  674. break;
  675. until (token=_END) or (token=_RKLAMMER);
  676. { at last set the record size to that of the biggest variant }
  677. symtablestack^.datasize:=maxsize;
  678. symtablestack^.dataalignment:=maxalignment;
  679. end;
  680. block_type:=old_block_type;
  681. current_object_option:=old_current_object_option;
  682. end;
  683. procedure const_dec;
  684. var
  685. name : stringid;
  686. p : ptree;
  687. tt : ttype;
  688. sym : psym;
  689. storetokenpos,filepos : tfileposinfo;
  690. old_block_type : tblock_type;
  691. ps : pconstset;
  692. pd : pbestreal;
  693. sp : pchar;
  694. skipequal : boolean;
  695. begin
  696. consume(_CONST);
  697. old_block_type:=block_type;
  698. block_type:=bt_const;
  699. repeat
  700. name:=pattern;
  701. filepos:=tokenpos;
  702. consume(_ID);
  703. case token of
  704. _EQUAL:
  705. begin
  706. consume(_EQUAL);
  707. p:=comp_expr(true);
  708. do_firstpass(p);
  709. storetokenpos:=tokenpos;
  710. tokenpos:=filepos;
  711. case p^.treetype of
  712. ordconstn:
  713. begin
  714. if is_constintnode(p) then
  715. symtablestack^.insert(new(pconstsym,init_def(name,constint,p^.value,nil)))
  716. else if is_constcharnode(p) then
  717. symtablestack^.insert(new(pconstsym,init_def(name,constchar,p^.value,nil)))
  718. else if is_constboolnode(p) then
  719. symtablestack^.insert(new(pconstsym,init_def(name,constbool,p^.value,nil)))
  720. else if p^.resulttype^.deftype=enumdef then
  721. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  722. else if p^.resulttype^.deftype=pointerdef then
  723. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  724. else internalerror(111);
  725. end;
  726. stringconstn:
  727. begin
  728. getmem(sp,p^.length+1);
  729. move(p^.value_str^,sp^,p^.length+1);
  730. symtablestack^.insert(new(pconstsym,init_string(name,conststring,sp,p^.length)));
  731. end;
  732. realconstn :
  733. begin
  734. new(pd);
  735. pd^:=p^.value_real;
  736. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd))));
  737. end;
  738. setconstn :
  739. begin
  740. new(ps);
  741. ps^:=p^.value_set^;
  742. symtablestack^.insert(new(pconstsym,init_def(name,constset,longint(ps),p^.resulttype)));
  743. end;
  744. pointerconstn :
  745. begin
  746. symtablestack^.insert(new(pconstsym,init_def(name,constpointer,p^.value,p^.resulttype)))
  747. end;
  748. niln :
  749. begin
  750. symtablestack^.insert(new(pconstsym,init_def(name,constnil,0,p^.resulttype)));
  751. end;
  752. else
  753. Message(cg_e_illegal_expression);
  754. end;
  755. tokenpos:=storetokenpos;
  756. consume(_SEMICOLON);
  757. disposetree(p);
  758. end;
  759. _COLON:
  760. begin
  761. { set the blocktype first so a consume also supports a
  762. caret, to support const s : ^string = nil }
  763. block_type:=bt_type;
  764. consume(_COLON);
  765. ignore_equal:=true;
  766. read_type(tt,'');
  767. ignore_equal:=false;
  768. block_type:=bt_const;
  769. skipequal:=false;
  770. { create symbol }
  771. storetokenpos:=tokenpos;
  772. tokenpos:=filepos;
  773. {$ifdef DELPHI_CONST_IN_RODATA}
  774. if m_delphi in aktmodeswitches then
  775. begin
  776. if assigned(readtypesym) then
  777. sym:=new(ptypedconstsym,initsym(name,readtypesym,true))
  778. else
  779. sym:=new(ptypedconstsym,init(name,def,true))
  780. end
  781. else
  782. {$endif DELPHI_CONST_IN_RODATA}
  783. begin
  784. sym:=new(ptypedconstsym,inittype(name,tt,false))
  785. end;
  786. tokenpos:=storetokenpos;
  787. symtablestack^.insert(sym);
  788. { procvar can have proc directives }
  789. if (tt.def^.deftype=procvardef) then
  790. begin
  791. { support p : procedure;stdcall=nil; }
  792. if (token=_SEMICOLON) then
  793. begin
  794. consume(_SEMICOLON);
  795. if is_proc_directive(token) then
  796. parse_var_proc_directives(sym)
  797. else
  798. begin
  799. Message(parser_e_proc_directive_expected);
  800. skipequal:=true;
  801. end;
  802. end
  803. else
  804. { support p : procedure stdcall=nil; }
  805. begin
  806. if is_proc_directive(token) then
  807. parse_var_proc_directives(sym);
  808. end;
  809. end;
  810. if not skipequal then
  811. begin
  812. { get init value }
  813. consume(_EQUAL);
  814. {$ifdef DELPHI_CONST_IN_RODATA}
  815. if m_delphi in aktmodeswitches then
  816. readtypedconst(tt.def,ptypedconstsym(sym),true)
  817. else
  818. {$endif DELPHI_CONST_IN_RODATA}
  819. readtypedconst(tt.def,ptypedconstsym(sym),false);
  820. consume(_SEMICOLON);
  821. end;
  822. end;
  823. else
  824. { generate an error }
  825. consume(_EQUAL);
  826. end;
  827. until token<>_ID;
  828. block_type:=old_block_type;
  829. end;
  830. procedure label_dec;
  831. var
  832. hl : pasmlabel;
  833. begin
  834. consume(_LABEL);
  835. if not(cs_support_goto in aktmoduleswitches) then
  836. Message(sym_e_goto_and_label_not_supported);
  837. repeat
  838. if not(token in [_ID,_INTCONST]) then
  839. consume(_ID)
  840. else
  841. begin
  842. getlabel(hl);
  843. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  844. consume(token);
  845. end;
  846. if token<>_SEMICOLON then consume(_COMMA);
  847. until not(token in [_ID,_INTCONST]);
  848. consume(_SEMICOLON);
  849. end;
  850. { search in symtablestack used, but not defined type }
  851. procedure resolve_type_forward(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
  852. var
  853. hpd,pd : pdef;
  854. stpos : tfileposinfo;
  855. again : boolean;
  856. begin
  857. { Check only typesyms or record/object fields }
  858. case psym(p)^.typ of
  859. typesym :
  860. pd:=ptypesym(p)^.restype.def;
  861. varsym :
  862. if (psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  863. pd:=pvarsym(p)^.vartype.def
  864. else
  865. exit;
  866. else
  867. exit;
  868. end;
  869. repeat
  870. again:=false;
  871. case pd^.deftype of
  872. arraydef :
  873. begin
  874. { elementtype could also be defined using a forwarddef }
  875. pd:=parraydef(pd)^.elementtype.def;
  876. again:=true;
  877. end;
  878. pointerdef,
  879. classrefdef :
  880. begin
  881. { classrefdef inherits from pointerdef }
  882. hpd:=ppointerdef(pd)^.pointertype.def;
  883. { still a forward def ? }
  884. if hpd^.deftype=forwarddef then
  885. begin
  886. { try to resolve the forward }
  887. { get the correct position for it }
  888. stpos:=tokenpos;
  889. tokenpos:=pforwarddef(hpd)^.forwardpos;
  890. resolving_forward:=true;
  891. make_ref:=false;
  892. getsym(pforwarddef(hpd)^.tosymname,false);
  893. make_ref:=true;
  894. resolving_forward:=false;
  895. tokenpos:=stpos;
  896. { we don't need the forwarddef anymore, dispose it }
  897. dispose(hpd,done);
  898. { was a type sym found ? }
  899. if assigned(srsym) and
  900. (srsym^.typ=typesym) then
  901. begin
  902. ppointerdef(pd)^.pointertype.setsym(srsym);
  903. { avoid wrong unused warnings web bug 801 PM }
  904. inc(srsym^.refs);
  905. {$ifdef GDB}
  906. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  907. (psym(p)^.owner^.symtabletype in [globalsymtable,staticsymtable]) then
  908. begin
  909. ptypesym(p)^.isusedinstab := true;
  910. psym(p)^.concatstabto(debuglist);
  911. end;
  912. {$endif GDB}
  913. { we need a class type for classrefdef }
  914. if (pd^.deftype=classrefdef) and
  915. not((ptypesym(srsym)^.restype.def^.deftype=objectdef) and
  916. pobjectdef(ptypesym(srsym)^.restype.def)^.is_class) then
  917. Message1(type_e_class_type_expected,ptypesym(srsym)^.restype.def^.typename);
  918. end
  919. else
  920. begin
  921. MessagePos1(psym(p)^.fileinfo,sym_e_forward_type_not_resolved,p^.name);
  922. { try to recover }
  923. ppointerdef(pd)^.pointertype.def:=generrordef;
  924. end;
  925. end;
  926. end;
  927. recorddef :
  928. precorddef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  929. objectdef :
  930. { Don't check objectdefs in objects/records, because these can't
  931. exist (anonymous objects aren't allowed) }
  932. if not(psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  933. pobjectdef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  934. end;
  935. until not again;
  936. end;
  937. { reads a type declaration to the symbol table }
  938. procedure type_dec;
  939. var
  940. typename : stringid;
  941. newtype : ptypesym;
  942. sym : psym;
  943. tt : ttype;
  944. defpos,storetokenpos : tfileposinfo;
  945. old_block_type : tblock_type;
  946. begin
  947. old_block_type:=block_type;
  948. block_type:=bt_type;
  949. consume(_TYPE);
  950. typecanbeforward:=true;
  951. repeat
  952. typename:=pattern;
  953. defpos:=tokenpos;
  954. consume(_ID);
  955. consume(_EQUAL);
  956. { support 'ttype=type word' syntax }
  957. if token=_TYPE then
  958. Consume(_TYPE);
  959. { is the type already defined? }
  960. getsym(typename,false);
  961. sym:=srsym;
  962. newtype:=nil;
  963. { found a symbol with this name? }
  964. if assigned(sym) then
  965. begin
  966. if (sym^.typ=typesym) then
  967. begin
  968. if (token=_CLASS) and
  969. (assigned(ptypesym(sym)^.restype.def)) and
  970. (ptypesym(sym)^.restype.def^.deftype=objectdef) and
  971. pobjectdef(ptypesym(sym)^.restype.def)^.is_class and
  972. (oo_is_forward in pobjectdef(ptypesym(sym)^.restype.def)^.objectoptions) then
  973. begin
  974. { we can ignore the result }
  975. { the definition is modified }
  976. object_dec(typename,pobjectdef(ptypesym(sym)^.restype.def));
  977. newtype:=ptypesym(sym);
  978. end;
  979. end;
  980. end;
  981. { no old type reused ? Then insert this new type }
  982. if not assigned(newtype) then
  983. begin
  984. read_type(tt,typename);
  985. storetokenpos:=tokenpos;
  986. tokenpos:=defpos;
  987. newtype:=new(ptypesym,init(typename,tt));
  988. symtablestack^.insert(newtype);
  989. tokenpos:=storetokenpos;
  990. end;
  991. if assigned(newtype^.restype.def) and
  992. (newtype^.restype.def^.deftype=procvardef) then
  993. begin
  994. if not is_proc_directive(token) then
  995. consume(_SEMICOLON);
  996. parse_var_proc_directives(psym(newtype));
  997. end
  998. else
  999. consume(_SEMICOLON);
  1000. until token<>_ID;
  1001. typecanbeforward:=false;
  1002. symtablestack^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  1003. block_type:=old_block_type;
  1004. end;
  1005. procedure var_dec;
  1006. { parses variable declarations and inserts them in }
  1007. { the top symbol table of symtablestack }
  1008. begin
  1009. consume(_VAR);
  1010. read_var_decs(false,false,false);
  1011. end;
  1012. procedure threadvar_dec;
  1013. { parses thread variable declarations and inserts them in }
  1014. { the top symbol table of symtablestack }
  1015. begin
  1016. consume(_THREADVAR);
  1017. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  1018. message(parser_e_threadvars_only_sg);
  1019. read_var_decs(false,false,true);
  1020. end;
  1021. procedure resourcestring_dec;
  1022. var
  1023. name : stringid;
  1024. p : ptree;
  1025. storetokenpos,filepos : tfileposinfo;
  1026. old_block_type : tblock_type;
  1027. sp : pchar;
  1028. begin
  1029. consume(_RESOURCESTRING);
  1030. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  1031. message(parser_e_resourcestring_only_sg);
  1032. old_block_type:=block_type;
  1033. block_type:=bt_const;
  1034. repeat
  1035. name:=pattern;
  1036. filepos:=tokenpos;
  1037. consume(_ID);
  1038. case token of
  1039. _EQUAL:
  1040. begin
  1041. consume(_EQUAL);
  1042. p:=comp_expr(true);
  1043. do_firstpass(p);
  1044. storetokenpos:=tokenpos;
  1045. tokenpos:=filepos;
  1046. case p^.treetype of
  1047. ordconstn:
  1048. begin
  1049. if is_constcharnode(p) then
  1050. begin
  1051. getmem(sp,2);
  1052. sp[0]:=chr(p^.value);
  1053. sp[1]:=#0;
  1054. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,1)));
  1055. end
  1056. else
  1057. Message(cg_e_illegal_expression);
  1058. end;
  1059. stringconstn:
  1060. begin
  1061. getmem(sp,p^.length+1);
  1062. move(p^.value_str^,sp^,p^.length+1);
  1063. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,p^.length)));
  1064. end;
  1065. else
  1066. Message(cg_e_illegal_expression);
  1067. end;
  1068. tokenpos:=storetokenpos;
  1069. consume(_SEMICOLON);
  1070. disposetree(p);
  1071. end;
  1072. else consume(_EQUAL);
  1073. end;
  1074. until token<>_ID;
  1075. block_type:=old_block_type;
  1076. end;
  1077. procedure Not_supported_for_inline(t : ttoken);
  1078. begin
  1079. if assigned(aktprocsym) and
  1080. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1081. Begin
  1082. Message1(parser_w_not_supported_for_inline,tokenstring(t));
  1083. Message(parser_w_inlining_disabled);
  1084. {$ifdef INCLUDEOK}
  1085. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  1086. {$else}
  1087. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions-[pocall_inline];
  1088. {$endif}
  1089. End;
  1090. end;
  1091. procedure read_declarations(islibrary : boolean);
  1092. begin
  1093. repeat
  1094. case token of
  1095. _LABEL:
  1096. begin
  1097. Not_supported_for_inline(token);
  1098. label_dec;
  1099. end;
  1100. _CONST:
  1101. begin
  1102. Not_supported_for_inline(token);
  1103. const_dec;
  1104. end;
  1105. _TYPE:
  1106. begin
  1107. Not_supported_for_inline(token);
  1108. type_dec;
  1109. end;
  1110. _VAR:
  1111. var_dec;
  1112. _THREADVAR:
  1113. threadvar_dec;
  1114. _CONSTRUCTOR,_DESTRUCTOR,
  1115. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1116. begin
  1117. Not_supported_for_inline(token);
  1118. read_proc;
  1119. end;
  1120. _RESOURCESTRING:
  1121. resourcestring_dec;
  1122. _EXPORTS:
  1123. begin
  1124. Not_supported_for_inline(token);
  1125. { here we should be at lexlevel 1, no ? PM }
  1126. if (lexlevel<>main_program_level) or
  1127. (current_module^.is_unit) then
  1128. begin
  1129. Message(parser_e_syntax_error);
  1130. consume_all_until(_SEMICOLON);
  1131. end
  1132. else if islibrary or (target_info.target=target_i386_WIN32) then
  1133. read_exports;
  1134. end
  1135. else break;
  1136. end;
  1137. until false;
  1138. end;
  1139. procedure read_interface_declarations;
  1140. begin
  1141. {Since the body is now parsed at lexlevel 1, and the declarations
  1142. must be parsed at the same lexlevel we increase the lexlevel.}
  1143. inc(lexlevel);
  1144. repeat
  1145. case token of
  1146. _CONST : const_dec;
  1147. _TYPE : type_dec;
  1148. _VAR : var_dec;
  1149. _THREADVAR : threadvar_dec;
  1150. _RESOURCESTRING:
  1151. resourcestring_dec;
  1152. _FUNCTION,
  1153. _PROCEDURE,
  1154. _OPERATOR : read_proc;
  1155. else
  1156. break;
  1157. end;
  1158. until false;
  1159. dec(lexlevel);
  1160. end;
  1161. end.
  1162. {
  1163. $Log$
  1164. Revision 1.187 2000-06-23 20:14:39 peter
  1165. * reset current_object_option when reading other symtables than
  1166. object declarations
  1167. Revision 1.186 2000/06/18 18:11:32 peter
  1168. * C record packing fixed to also check first entry of the record
  1169. if bigger than the recordalignment itself
  1170. * variant record alignment uses alignment per variant and saves the
  1171. highest alignment value
  1172. Revision 1.185 2000/06/11 06:59:36 peter
  1173. * support procvar directive without ; before the directives
  1174. Revision 1.184 2000/06/09 21:34:40 peter
  1175. * checking for dup id with para of methods fixed for delphi mode
  1176. Revision 1.183 2000/06/02 21:18:13 pierre
  1177. + set vo_is_exported for vars
  1178. Revision 1.182 2000/06/01 19:14:09 peter
  1179. * symtable.insert changed to procedure
  1180. Revision 1.181 2000/04/17 18:44:22 peter
  1181. * fixed forward resolving with redefined types
  1182. Revision 1.180 2000/02/09 13:22:56 peter
  1183. * log truncated
  1184. Revision 1.179 2000/01/20 12:29:02 pierre
  1185. * bug 801 fixed
  1186. Revision 1.178 2000/01/11 17:16:05 jonas
  1187. * removed a lot of memory leaks when an error is encountered (caused by
  1188. procinfo and pstringcontainers). There are still plenty left though :)
  1189. Revision 1.177 2000/01/10 11:14:19 peter
  1190. * fixed memory leak with options, you must use StopOptions instead of
  1191. Stop
  1192. * fixed memory leak with forward resolving, make_ref is now false
  1193. Revision 1.176 2000/01/07 01:14:28 peter
  1194. * updated copyright to 2000
  1195. Revision 1.175 1999/12/10 10:04:21 peter
  1196. * also check elementtype of arraydef for forwarddef
  1197. Revision 1.174 1999/12/01 12:42:32 peter
  1198. * fixed bug 698
  1199. * removed some notes about unused vars
  1200. Revision 1.173 1999/11/30 10:40:44 peter
  1201. + ttype, tsymlist
  1202. Revision 1.172 1999/11/29 15:18:27 pierre
  1203. + allow exports in win32 executables
  1204. Revision 1.171 1999/11/09 23:43:08 pierre
  1205. * better browser info
  1206. Revision 1.170 1999/11/09 23:06:45 peter
  1207. * esi_offset -> selfpointer_offset to be newcg compatible
  1208. * hcogegen -> cgbase fixes for newcg
  1209. Revision 1.169 1999/11/09 12:58:29 peter
  1210. * support absolute unit.variable
  1211. Revision 1.168 1999/11/06 14:34:21 peter
  1212. * truncated log to 20 revs
  1213. Revision 1.167 1999/10/26 12:30:44 peter
  1214. * const parameter is now checked
  1215. * better and generic check if a node can be used for assigning
  1216. * export fixes
  1217. * procvar equal works now (it never had worked at least from 0.99.8)
  1218. * defcoll changed to linkedlist with pparaitem so it can easily be
  1219. walked both directions
  1220. Revision 1.166 1999/10/22 10:39:34 peter
  1221. * split type reading from pdecl to ptype unit
  1222. * parameter_dec routine is now used for procedure and procvars
  1223. Revision 1.165 1999/10/21 16:41:41 florian
  1224. * problems with readln fixed: esi wasn't restored correctly when
  1225. reading ordinal fields of objects futher the register allocation
  1226. didn't take care of the extra register when reading ordinal values
  1227. * enumerations can now be used in constant indexes of properties
  1228. Revision 1.164 1999/10/14 14:57:52 florian
  1229. - removed the hcodegen use in the new cg, use cgbase instead
  1230. Revision 1.163 1999/10/06 17:39:14 peter
  1231. * fixed stabs writting for forward types
  1232. Revision 1.162 1999/10/03 19:44:42 peter
  1233. * removed objpasunit reference, tvarrec is now searched in systemunit
  1234. where it already was located
  1235. Revision 1.161 1999/10/01 11:18:02 peter
  1236. * class/record type forward checking fixed
  1237. Revision 1.159 1999/10/01 10:05:42 peter
  1238. + procedure directive support in const declarations, fixes bug 232
  1239. }