pdecl.pas 47 KB

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