pdecl.pas 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Does declaration (but not type) parsing for Free Pascal
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit pdecl;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cclasses,
  23. { global }
  24. globtype,
  25. { symtable }
  26. symsym,symdef,
  27. { pass_1 }
  28. node;
  29. function readconstant(const orgname:string;const filepos:tfileposinfo):tconstsym;
  30. procedure const_dec;
  31. procedure consts_dec(in_structure, allow_typed_const: boolean);
  32. procedure label_dec;
  33. procedure type_dec;
  34. procedure types_dec(in_structure: boolean);
  35. procedure var_dec;
  36. procedure threadvar_dec;
  37. procedure property_dec;
  38. procedure resourcestring_dec;
  39. implementation
  40. uses
  41. SysUtils,
  42. { common }
  43. cutils,
  44. { global }
  45. globals,tokens,verbose,widestr,constexp,
  46. systems,
  47. { aasm }
  48. aasmbase,aasmtai,aasmdata,fmodule,
  49. { symtable }
  50. symconst,symbase,symtype,symtable,symcreat,paramgr,defutil,
  51. { pass 1 }
  52. htypechk,
  53. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,nobj,
  54. { codegen }
  55. ncgutil,ngenutil,
  56. { parser }
  57. scanner,
  58. pbase,pexpr,ptype,ptconst,pdecsub,pdecvar,pdecobj,pgenutil,
  59. {$ifdef jvm}
  60. pjvm,
  61. {$endif}
  62. { cpu-information }
  63. cpuinfo
  64. ;
  65. function readconstant(const orgname:string;const filepos:tfileposinfo):tconstsym;
  66. var
  67. hp : tconstsym;
  68. p : tnode;
  69. ps : pconstset;
  70. pd : pbestreal;
  71. pg : pguid;
  72. sp : pchar;
  73. pw : pcompilerwidestring;
  74. storetokenpos : tfileposinfo;
  75. begin
  76. readconstant:=nil;
  77. if orgname='' then
  78. internalerror(9584582);
  79. hp:=nil;
  80. p:=comp_expr(true,false);
  81. storetokenpos:=current_tokenpos;
  82. current_tokenpos:=filepos;
  83. case p.nodetype of
  84. ordconstn:
  85. begin
  86. if p.resultdef.typ=pointerdef then
  87. hp:=tconstsym.create_ordptr(orgname,constpointer,tordconstnode(p).value.uvalue,p.resultdef)
  88. else
  89. hp:=tconstsym.create_ord(orgname,constord,tordconstnode(p).value,p.resultdef);
  90. end;
  91. stringconstn:
  92. begin
  93. if is_wide_or_unicode_string(p.resultdef) then
  94. begin
  95. initwidestring(pw);
  96. copywidestring(pcompilerwidestring(tstringconstnode(p).value_str),pw);
  97. hp:=tconstsym.create_wstring(orgname,constwstring,pw);
  98. end
  99. else
  100. begin
  101. getmem(sp,tstringconstnode(p).len+1);
  102. move(tstringconstnode(p).value_str^,sp^,tstringconstnode(p).len+1);
  103. hp:=tconstsym.create_string(orgname,conststring,sp,tstringconstnode(p).len);
  104. end;
  105. end;
  106. realconstn :
  107. begin
  108. new(pd);
  109. pd^:=trealconstnode(p).value_real;
  110. hp:=tconstsym.create_ptr(orgname,constreal,pd,p.resultdef);
  111. end;
  112. setconstn :
  113. begin
  114. new(ps);
  115. ps^:=tsetconstnode(p).value_set^;
  116. hp:=tconstsym.create_ptr(orgname,constset,ps,p.resultdef);
  117. end;
  118. pointerconstn :
  119. begin
  120. hp:=tconstsym.create_ordptr(orgname,constpointer,tpointerconstnode(p).value,p.resultdef);
  121. end;
  122. niln :
  123. begin
  124. hp:=tconstsym.create_ord(orgname,constnil,0,p.resultdef);
  125. end;
  126. typen :
  127. begin
  128. if is_interface(p.resultdef) then
  129. begin
  130. if assigned(tobjectdef(p.resultdef).iidguid) then
  131. begin
  132. new(pg);
  133. pg^:=tobjectdef(p.resultdef).iidguid^;
  134. hp:=tconstsym.create_ptr(orgname,constguid,pg,p.resultdef);
  135. end
  136. else
  137. Message1(parser_e_interface_has_no_guid,tobjectdef(p.resultdef).objrealname^);
  138. end
  139. else
  140. Message(parser_e_illegal_expression);
  141. end;
  142. else
  143. if not(parse_generic) then
  144. Message(parser_e_illegal_expression);
  145. end;
  146. current_tokenpos:=storetokenpos;
  147. p.free;
  148. readconstant:=hp;
  149. end;
  150. procedure const_dec;
  151. begin
  152. consume(_CONST);
  153. consts_dec(false,true);
  154. end;
  155. procedure consts_dec(in_structure, allow_typed_const: boolean);
  156. var
  157. orgname : TIDString;
  158. hdef : tdef;
  159. sym : tsym;
  160. dummysymoptions : tsymoptions;
  161. deprecatedmsg : pshortstring;
  162. storetokenpos,filepos : tfileposinfo;
  163. old_block_type : tblock_type;
  164. skipequal : boolean;
  165. tclist : tasmlist;
  166. varspez : tvarspez;
  167. begin
  168. old_block_type:=block_type;
  169. block_type:=bt_const;
  170. repeat
  171. orgname:=orgpattern;
  172. filepos:=current_tokenpos;
  173. consume(_ID);
  174. case token of
  175. _EQ:
  176. begin
  177. consume(_EQ);
  178. sym:=readconstant(orgname,filepos);
  179. { Support hint directives }
  180. dummysymoptions:=[];
  181. deprecatedmsg:=nil;
  182. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  183. if assigned(sym) then
  184. begin
  185. sym.symoptions:=sym.symoptions+dummysymoptions;
  186. sym.deprecatedmsg:=deprecatedmsg;
  187. sym.visibility:=symtablestack.top.currentvisibility;
  188. symtablestack.top.insert(sym);
  189. {$ifdef jvm}
  190. { for the JVM target, some constants need to be
  191. initialized at run time (enums, sets) -> create fake
  192. typed const to do so }
  193. if assigned(tconstsym(sym).constdef) and
  194. (tconstsym(sym).constdef.typ in [enumdef,setdef]) then
  195. jvm_add_typed_const_initializer(tconstsym(sym));
  196. {$endif}
  197. end
  198. else
  199. stringdispose(deprecatedmsg);
  200. consume(_SEMICOLON);
  201. end;
  202. _COLON:
  203. begin
  204. if not allow_typed_const then
  205. begin
  206. Message(parser_e_no_typed_const);
  207. consume_all_until(_SEMICOLON);
  208. end;
  209. { set the blocktype first so a consume also supports a
  210. caret, to support const s : ^string = nil }
  211. block_type:=bt_const_type;
  212. consume(_COLON);
  213. read_anon_type(hdef,false);
  214. block_type:=bt_const;
  215. skipequal:=false;
  216. { create symbol }
  217. storetokenpos:=current_tokenpos;
  218. current_tokenpos:=filepos;
  219. if not (cs_typed_const_writable in current_settings.localswitches) then
  220. varspez:=vs_const
  221. else
  222. varspez:=vs_value;
  223. { if we are dealing with structure const then we need to handle it as a
  224. structure static variable: create a symbol in unit symtable and a reference
  225. to it from the structure or linking will fail }
  226. if symtablestack.top.symtabletype in [recordsymtable,ObjectSymtable] then
  227. begin
  228. sym:=tfieldvarsym.create(orgname,varspez,hdef,[]);
  229. symtablestack.top.insert(sym);
  230. sym:=make_field_static(symtablestack.top,tfieldvarsym(sym));
  231. end
  232. else
  233. begin
  234. sym:=tstaticvarsym.create(orgname,varspez,hdef,[]);
  235. sym.visibility:=symtablestack.top.currentvisibility;
  236. symtablestack.top.insert(sym);
  237. end;
  238. current_tokenpos:=storetokenpos;
  239. { procvar can have proc directives, but not type references }
  240. if (hdef.typ=procvardef) and
  241. (hdef.typesym=nil) then
  242. begin
  243. { support p : procedure;stdcall=nil; }
  244. if try_to_consume(_SEMICOLON) then
  245. begin
  246. if check_proc_directive(true) then
  247. parse_var_proc_directives(sym)
  248. else
  249. begin
  250. Message(parser_e_proc_directive_expected);
  251. skipequal:=true;
  252. end;
  253. end
  254. else
  255. { support p : procedure stdcall=nil; }
  256. begin
  257. if check_proc_directive(true) then
  258. parse_var_proc_directives(sym);
  259. end;
  260. { add default calling convention }
  261. handle_calling_convention(tabstractprocdef(hdef));
  262. end;
  263. if not skipequal then
  264. begin
  265. { get init value }
  266. consume(_EQ);
  267. if (cs_typed_const_writable in current_settings.localswitches) then
  268. tclist:=current_asmdata.asmlists[al_typedconsts]
  269. else
  270. tclist:=current_asmdata.asmlists[al_rotypedconsts];
  271. read_typed_const(tclist,tstaticvarsym(sym),in_structure);
  272. end;
  273. end;
  274. else
  275. { generate an error }
  276. consume(_EQ);
  277. end;
  278. until (token<>_ID) or
  279. (in_structure and
  280. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  281. ((m_final_fields in current_settings.modeswitches) and
  282. (idtoken=_FINAL))));
  283. block_type:=old_block_type;
  284. end;
  285. procedure label_dec;
  286. var
  287. labelsym : tlabelsym;
  288. begin
  289. consume(_LABEL);
  290. if not(cs_support_goto in current_settings.moduleswitches) then
  291. Message(sym_e_goto_and_label_not_supported);
  292. repeat
  293. if not(token in [_ID,_INTCONST]) then
  294. consume(_ID)
  295. else
  296. begin
  297. if token=_ID then
  298. labelsym:=tlabelsym.create(orgpattern)
  299. else
  300. labelsym:=tlabelsym.create(pattern);
  301. symtablestack.top.insert(labelsym);
  302. if m_non_local_goto in current_settings.modeswitches then
  303. begin
  304. if symtablestack.top.symtabletype=localsymtable then
  305. begin
  306. labelsym.jumpbuf:=tlocalvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  307. symtablestack.top.insert(labelsym.jumpbuf);
  308. end
  309. else
  310. begin
  311. labelsym.jumpbuf:=tstaticvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  312. symtablestack.top.insert(labelsym.jumpbuf);
  313. cnodeutils.insertbssdata(tstaticvarsym(labelsym.jumpbuf));
  314. end;
  315. include(labelsym.jumpbuf.symoptions,sp_internal);
  316. { the buffer will be setup later, but avoid a hint }
  317. tabstractvarsym(labelsym.jumpbuf).varstate:=vs_written;
  318. end;
  319. consume(token);
  320. end;
  321. if token<>_SEMICOLON then consume(_COMMA);
  322. until not(token in [_ID,_INTCONST]);
  323. consume(_SEMICOLON);
  324. end;
  325. procedure types_dec(in_structure: boolean);
  326. procedure finalize_class_external_status(od: tobjectdef);
  327. begin
  328. if [oo_is_external,oo_is_forward] <= od.objectoptions then
  329. begin
  330. { formal definition: x = objcclass external; }
  331. exclude(od.objectoptions,oo_is_forward);
  332. include(od.objectoptions,oo_is_formal);
  333. end;
  334. end;
  335. var
  336. typename,orgtypename,
  337. gentypename,genorgtypename : TIDString;
  338. newtype : ttypesym;
  339. sym : tsym;
  340. hdef : tdef;
  341. defpos,storetokenpos : tfileposinfo;
  342. old_block_type : tblock_type;
  343. old_checkforwarddefs: TFPObjectList;
  344. objecttype : tobjecttyp;
  345. isgeneric,
  346. isunique,
  347. istyperenaming : boolean;
  348. generictypelist : TFPObjectList;
  349. generictokenbuf : tdynamicarray;
  350. vmtbuilder : TVMTBuilder;
  351. p:tnode;
  352. gendef : tstoreddef;
  353. s : shortstring;
  354. pd: tprocdef;
  355. hashedid : thashedidstring;
  356. begin
  357. old_block_type:=block_type;
  358. { save unit container of forward declarations -
  359. we can be inside nested class type block }
  360. old_checkforwarddefs:=current_module.checkforwarddefs;
  361. current_module.checkforwarddefs:=TFPObjectList.Create(false);
  362. block_type:=bt_type;
  363. repeat
  364. defpos:=current_tokenpos;
  365. istyperenaming:=false;
  366. generictypelist:=nil;
  367. generictokenbuf:=nil;
  368. { fpc generic declaration? }
  369. isgeneric:=not(m_delphi in current_settings.modeswitches) and try_to_consume(_GENERIC);
  370. typename:=pattern;
  371. orgtypename:=orgpattern;
  372. consume(_ID);
  373. { delphi generic declaration? }
  374. if (m_delphi in current_settings.modeswitches) then
  375. isgeneric:=token=_LSHARPBRACKET;
  376. { Generic type declaration? }
  377. if isgeneric then
  378. begin
  379. if assigned(current_genericdef) then
  380. Message(parser_f_no_generic_inside_generic);
  381. consume(_LSHARPBRACKET);
  382. generictypelist:=parse_generic_parameters;
  383. consume(_RSHARPBRACKET);
  384. str(generictypelist.Count,s);
  385. gentypename:=typename+'$'+s;
  386. genorgtypename:=orgtypename+'$'+s;
  387. end
  388. else
  389. begin
  390. gentypename:=typename;
  391. genorgtypename:=orgtypename;
  392. end;
  393. consume(_EQ);
  394. { support 'ttype=type word' syntax }
  395. isunique:=try_to_consume(_TYPE);
  396. { MacPas object model is more like Delphi's than like TP's, but }
  397. { uses the object keyword instead of class }
  398. if (m_mac in current_settings.modeswitches) and
  399. (token = _OBJECT) then
  400. token := _CLASS;
  401. { Start recording a generic template }
  402. if assigned(generictypelist) then
  403. begin
  404. generictokenbuf:=tdynamicarray.create(256);
  405. current_scanner.startrecordtokens(generictokenbuf);
  406. end;
  407. { is the type already defined? -- must be in the current symtable,
  408. not in a nested symtable or one higher up the stack -> don't
  409. use searchsym & frinds! }
  410. sym:=tsym(symtablestack.top.find(gentypename));
  411. newtype:=nil;
  412. { found a symbol with this name? }
  413. if assigned(sym) then
  414. begin
  415. if (sym.typ=typesym) and
  416. { this should not be a symbol that was created by a generic
  417. that was declared earlier }
  418. not (
  419. (ttypesym(sym).typedef.typ=undefineddef) and
  420. (sp_generic_dummy in sym.symoptions)
  421. ) then
  422. begin
  423. if ((token=_CLASS) or
  424. (token=_INTERFACE) or
  425. (token=_DISPINTERFACE) or
  426. (token=_OBJCCLASS) or
  427. (token=_OBJCPROTOCOL) or
  428. (token=_OBJCCATEGORY)) and
  429. (assigned(ttypesym(sym).typedef)) and
  430. is_implicit_pointer_object_type(ttypesym(sym).typedef) and
  431. (oo_is_forward in tobjectdef(ttypesym(sym).typedef).objectoptions) then
  432. begin
  433. case token of
  434. _CLASS :
  435. objecttype:=default_class_type;
  436. _INTERFACE :
  437. case current_settings.interfacetype of
  438. it_interfacecom:
  439. objecttype:=odt_interfacecom;
  440. it_interfacecorba:
  441. objecttype:=odt_interfacecorba;
  442. it_interfacejava:
  443. objecttype:=odt_interfacejava;
  444. else
  445. internalerror(2010122611);
  446. end;
  447. _DISPINTERFACE :
  448. objecttype:=odt_dispinterface;
  449. _OBJCCLASS,
  450. _OBJCCATEGORY :
  451. objecttype:=odt_objcclass;
  452. _OBJCPROTOCOL :
  453. objecttype:=odt_objcprotocol;
  454. else
  455. internalerror(200811072);
  456. end;
  457. consume(token);
  458. { we can ignore the result, the definition is modified }
  459. object_dec(objecttype,genorgtypename,nil,nil,tobjectdef(ttypesym(sym).typedef),ht_none);
  460. newtype:=ttypesym(sym);
  461. hdef:=newtype.typedef;
  462. end
  463. else
  464. message1(parser_h_type_redef,genorgtypename);
  465. end;
  466. end;
  467. { no old type reused ? Then insert this new type }
  468. if not assigned(newtype) then
  469. begin
  470. { insert the new type first with an errordef, so that
  471. referencing the type before it's really set it
  472. will give an error (PFV) }
  473. hdef:=generrordef;
  474. gendef:=nil;
  475. storetokenpos:=current_tokenpos;
  476. if isgeneric then
  477. begin
  478. { for generics we need to check whether a non-generic type
  479. already exists and if not we need to insert a symbol with
  480. the non-generic name (available in (org)typename) that is a
  481. undefineddef, so that inline specializations can be used }
  482. sym:=tsym(symtablestack.top.Find(typename));
  483. if not assigned(sym) then
  484. begin
  485. sym:=ttypesym.create(orgtypename,tundefineddef.create);
  486. Include(sym.symoptions,sp_generic_dummy);
  487. ttypesym(sym).typedef.typesym:=sym;
  488. sym.visibility:=symtablestack.top.currentvisibility;
  489. symtablestack.top.insert(sym);
  490. ttypesym(sym).typedef.owner:=sym.owner;
  491. end
  492. else
  493. { this is not allowed in non-Delphi modes }
  494. if not (m_delphi in current_settings.modeswitches) then
  495. Message1(sym_e_duplicate_id,genorgtypename)
  496. else
  497. { we need to find this symbol even if it's a variable or
  498. something else when doing an inline specialization }
  499. Include(sym.symoptions,sp_generic_dummy);
  500. end
  501. else
  502. begin
  503. if assigned(sym) and (sym.typ=typesym) and
  504. (ttypesym(sym).typedef.typ=undefineddef) and
  505. (sp_generic_dummy in sym.symoptions) then
  506. begin
  507. { this is a symbol that was added by an earlier generic
  508. declaration, reuse it }
  509. newtype:=ttypesym(sym);
  510. newtype.typedef:=hdef;
  511. sym:=nil;
  512. end;
  513. { check whether this is a declaration of a type inside a
  514. specialization }
  515. if assigned(current_structdef) and
  516. (df_specialization in current_structdef.defoptions) then
  517. begin
  518. if not assigned(current_structdef.genericdef) or
  519. not (current_structdef.genericdef.typ in [recorddef,objectdef]) then
  520. internalerror(2011052301);
  521. hashedid.id:=gentypename;
  522. { we could be inside a method of the specialization
  523. instead of its declaration, so check that first (as
  524. local nested types aren't allowed we don't need to
  525. walk the symtablestack to find the localsymtable) }
  526. if symtablestack.top.symtabletype=localsymtable then
  527. begin
  528. { we are in a method }
  529. if not assigned(symtablestack.top.defowner) or
  530. (symtablestack.top.defowner.typ<>procdef) then
  531. internalerror(2011120701);
  532. pd:=tprocdef(symtablestack.top.defowner);
  533. if not assigned(pd.genericdef) or (pd.genericdef.typ<>procdef) then
  534. internalerror(2011120702);
  535. sym:=tsym(tprocdef(pd.genericdef).localst.findwithhash(hashedid));
  536. end
  537. else
  538. sym:=nil;
  539. if not assigned(sym) or not (sym.typ=typesym) then
  540. begin
  541. { now search in the declaration of the generic }
  542. sym:=tsym(tabstractrecorddef(current_structdef.genericdef).symtable.findwithhash(hashedid));
  543. if not assigned(sym) or not (sym.typ=typesym) then
  544. internalerror(2011052302);
  545. end;
  546. { use the corresponding type in the generic's symtable as
  547. genericdef for the specialized type }
  548. gendef:=tstoreddef(ttypesym(sym).typedef);
  549. end;
  550. end;
  551. { insert a new type if we don't reuse an existing symbol }
  552. if not assigned(newtype) then
  553. begin
  554. newtype:=ttypesym.create(genorgtypename,hdef);
  555. newtype.visibility:=symtablestack.top.currentvisibility;
  556. symtablestack.top.insert(newtype);
  557. end;
  558. current_tokenpos:=defpos;
  559. current_tokenpos:=storetokenpos;
  560. { read the type definition }
  561. read_named_type(hdef,genorgtypename,gendef,generictypelist,false);
  562. { update the definition of the type }
  563. if assigned(hdef) then
  564. begin
  565. if assigned(hdef.typesym) then
  566. begin
  567. istyperenaming:=true;
  568. include(newtype.symoptions,sp_explicitrename);
  569. end;
  570. if isunique then
  571. begin
  572. if is_objc_class_or_protocol(hdef) or
  573. is_java_class_or_interface(hdef) then
  574. Message(parser_e_unique_unsupported);
  575. hdef:=tstoreddef(hdef).getcopy;
  576. { check if it is an ansistirng(codepage) declaration }
  577. if is_ansistring(hdef) and try_to_consume(_LKLAMMER) then
  578. begin
  579. p:=comp_expr(true,false);
  580. consume(_RKLAMMER);
  581. if not is_constintnode(p) then
  582. begin
  583. Message(parser_e_illegal_expression);
  584. { error recovery }
  585. end
  586. else
  587. begin
  588. if (tordconstnode(p).value<0) or (tordconstnode(p).value>65535) then
  589. begin
  590. Message(parser_e_invalid_codepage);
  591. tordconstnode(p).value:=0;
  592. end;
  593. tstringdef(hdef).encoding:=int64(tordconstnode(p).value);
  594. end;
  595. p.free;
  596. end;
  597. { fix name, it is used e.g. for tables }
  598. if is_class_or_interface_or_dispinterface(hdef) then
  599. with tobjectdef(hdef) do
  600. begin
  601. stringdispose(objname);
  602. stringdispose(objrealname);
  603. objrealname:=stringdup(genorgtypename);
  604. objname:=stringdup(upper(genorgtypename));
  605. end;
  606. include(hdef.defoptions,df_unique);
  607. if (hdef.typ in [pointerdef,classrefdef]) and
  608. (tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
  609. current_module.checkforwarddefs.add(hdef);
  610. end;
  611. if not assigned(hdef.typesym) then
  612. hdef.typesym:=newtype;
  613. end;
  614. { in non-Delphi modes we need a reference to the generic def
  615. without the generic suffix, so it can be found easily when
  616. parsing method implementations }
  617. if isgeneric and assigned(sym) and
  618. not (m_delphi in current_settings.modeswitches) and
  619. (ttypesym(sym).typedef.typ=undefineddef) then
  620. { don't free the undefineddef as the defids rely on the count
  621. of the defs in the def list of the module}
  622. ttypesym(sym).typedef:=hdef;
  623. newtype.typedef:=hdef;
  624. { KAZ: handle TGUID declaration in system unit }
  625. if (cs_compilesystem in current_settings.moduleswitches) and not assigned(rec_tguid) and
  626. (gentypename='TGUID') and { name: TGUID and size=16 bytes that is 128 bits }
  627. assigned(hdef) and (hdef.typ=recorddef) and (hdef.size=16) then
  628. rec_tguid:=trecorddef(hdef);
  629. end;
  630. if assigned(hdef) then
  631. begin
  632. case hdef.typ of
  633. pointerdef :
  634. begin
  635. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  636. consume(_SEMICOLON);
  637. if try_to_consume(_FAR) then
  638. begin
  639. tpointerdef(hdef).is_far:=true;
  640. consume(_SEMICOLON);
  641. end;
  642. end;
  643. procvardef :
  644. begin
  645. { in case of type renaming, don't parse proc directives }
  646. if istyperenaming then
  647. begin
  648. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  649. consume(_SEMICOLON);
  650. end
  651. else
  652. begin
  653. if not check_proc_directive(true) then
  654. begin
  655. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  656. consume(_SEMICOLON);
  657. end;
  658. parse_var_proc_directives(tsym(newtype));
  659. handle_calling_convention(tprocvardef(hdef));
  660. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  661. consume(_SEMICOLON);
  662. end;
  663. end;
  664. objectdef :
  665. begin
  666. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  667. consume(_SEMICOLON);
  668. { change a forward and external class declaration into
  669. formal external definition, so the compiler does not
  670. expect an real definition later }
  671. if is_objc_class_or_protocol(hdef) or
  672. is_java_class_or_interface(hdef) then
  673. finalize_class_external_status(tobjectdef(hdef));
  674. { Build VMT indexes, skip for type renaming and forward classes }
  675. if (hdef.typesym=newtype) and
  676. not(oo_is_forward in tobjectdef(hdef).objectoptions) and
  677. not(df_generic in hdef.defoptions) then
  678. begin
  679. vmtbuilder:=TVMTBuilder.Create(tobjectdef(hdef));
  680. vmtbuilder.generate_vmt;
  681. vmtbuilder.free;
  682. end;
  683. { In case of an objcclass, verify that all methods have a message
  684. name set. We only check this now, because message names can be set
  685. during the protocol (interface) mapping. At the same time, set the
  686. mangled names (these depend on the "external" name of the class),
  687. and mark private fields of external classes as "used" (to avoid
  688. bogus notes about them being unused)
  689. }
  690. { watch out for crashes in case of errors }
  691. if is_objc_class_or_protocol(hdef) and
  692. (not is_objccategory(hdef) or
  693. assigned(tobjectdef(hdef).childof)) then
  694. tobjectdef(hdef).finish_objc_data;
  695. if is_cppclass(hdef) then
  696. tobjectdef(hdef).finish_cpp_data;
  697. end;
  698. recorddef :
  699. begin
  700. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  701. consume(_SEMICOLON);
  702. end;
  703. else
  704. begin
  705. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  706. consume(_SEMICOLON);
  707. end;
  708. end;
  709. end;
  710. if isgeneric and (not(hdef.typ in [objectdef,recorddef,arraydef,procvardef])
  711. or is_objectpascal_helper(hdef)) then
  712. message(parser_e_cant_create_generics_of_this_type);
  713. { Stop recording a generic template }
  714. if assigned(generictypelist) then
  715. begin
  716. current_scanner.stoprecordtokens;
  717. tstoreddef(hdef).generictokenbuf:=generictokenbuf;
  718. { Generic is never a type renaming }
  719. hdef.typesym:=newtype;
  720. generictypelist.free;
  721. end;
  722. until (token<>_ID) or
  723. (in_structure and
  724. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  725. ((m_final_fields in current_settings.modeswitches) and
  726. (idtoken=_FINAL))));
  727. { resolve type block forward declarations and restore a unit
  728. container for them }
  729. resolve_forward_types;
  730. current_module.checkforwarddefs.free;
  731. current_module.checkforwarddefs:=old_checkforwarddefs;
  732. block_type:=old_block_type;
  733. end;
  734. { reads a type declaration to the symbol table }
  735. procedure type_dec;
  736. begin
  737. consume(_TYPE);
  738. types_dec(false);
  739. end;
  740. procedure var_dec;
  741. { parses variable declarations and inserts them in }
  742. { the top symbol table of symtablestack }
  743. begin
  744. consume(_VAR);
  745. read_var_decls([]);
  746. end;
  747. procedure property_dec;
  748. { parses a global property (fpc mode feature) }
  749. var
  750. old_block_type: tblock_type;
  751. begin
  752. consume(_PROPERTY);
  753. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  754. message(parser_e_resourcestring_only_sg);
  755. old_block_type:=block_type;
  756. block_type:=bt_const;
  757. repeat
  758. read_property_dec(false, nil);
  759. consume(_SEMICOLON);
  760. until token<>_ID;
  761. block_type:=old_block_type;
  762. end;
  763. procedure threadvar_dec;
  764. { parses thread variable declarations and inserts them in }
  765. { the top symbol table of symtablestack }
  766. begin
  767. consume(_THREADVAR);
  768. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  769. message(parser_e_threadvars_only_sg);
  770. read_var_decls([vd_threadvar]);
  771. end;
  772. procedure resourcestring_dec;
  773. var
  774. orgname : TIDString;
  775. p : tnode;
  776. dummysymoptions : tsymoptions;
  777. deprecatedmsg : pshortstring;
  778. storetokenpos,filepos : tfileposinfo;
  779. old_block_type : tblock_type;
  780. sp : pchar;
  781. sym : tsym;
  782. begin
  783. if target_info.system in systems_managed_vm then
  784. message(parser_e_feature_unsupported_for_vm);
  785. consume(_RESOURCESTRING);
  786. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  787. message(parser_e_resourcestring_only_sg);
  788. old_block_type:=block_type;
  789. block_type:=bt_const;
  790. repeat
  791. orgname:=orgpattern;
  792. filepos:=current_tokenpos;
  793. consume(_ID);
  794. case token of
  795. _EQ:
  796. begin
  797. consume(_EQ);
  798. p:=comp_expr(true,false);
  799. storetokenpos:=current_tokenpos;
  800. current_tokenpos:=filepos;
  801. sym:=nil;
  802. case p.nodetype of
  803. ordconstn:
  804. begin
  805. if is_constcharnode(p) then
  806. begin
  807. getmem(sp,2);
  808. sp[0]:=chr(tordconstnode(p).value.svalue);
  809. sp[1]:=#0;
  810. sym:=tconstsym.create_string(orgname,constresourcestring,sp,1);
  811. end
  812. else
  813. Message(parser_e_illegal_expression);
  814. end;
  815. stringconstn:
  816. with Tstringconstnode(p) do
  817. begin
  818. getmem(sp,len+1);
  819. move(value_str^,sp^,len+1);
  820. sym:=tconstsym.create_string(orgname,constresourcestring,sp,len);
  821. end;
  822. else
  823. Message(parser_e_illegal_expression);
  824. end;
  825. current_tokenpos:=storetokenpos;
  826. { Support hint directives }
  827. dummysymoptions:=[];
  828. deprecatedmsg:=nil;
  829. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  830. if assigned(sym) then
  831. begin
  832. sym.symoptions:=sym.symoptions+dummysymoptions;
  833. sym.deprecatedmsg:=deprecatedmsg;
  834. symtablestack.top.insert(sym);
  835. end
  836. else
  837. stringdispose(deprecatedmsg);
  838. consume(_SEMICOLON);
  839. p.free;
  840. end;
  841. else consume(_EQ);
  842. end;
  843. until token<>_ID;
  844. block_type:=old_block_type;
  845. end;
  846. end.