pdecl.pas 51 KB

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