pdecl.pas 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  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. inlinen:
  143. begin
  144. { this situation only happens if a intrinsic is parsed that has a
  145. generic type as its argument. As we don't know certain
  146. information about the final type yet, we need to use safe
  147. values (mostly 0) }
  148. if not parse_generic then
  149. Message(parser_e_illegal_expression);
  150. case tinlinenode(p).inlinenumber of
  151. in_sizeof_x,
  152. in_bitsizeof_x:
  153. begin
  154. hp:=tconstsym.create_ord(orgname,constord,0,p.resultdef);
  155. end;
  156. { add other cases here if necessary }
  157. else
  158. Message(parser_e_illegal_expression);
  159. end;
  160. end;
  161. else
  162. Message(parser_e_illegal_expression);
  163. end;
  164. current_tokenpos:=storetokenpos;
  165. p.free;
  166. readconstant:=hp;
  167. end;
  168. procedure const_dec;
  169. begin
  170. consume(_CONST);
  171. consts_dec(false,true);
  172. end;
  173. procedure consts_dec(in_structure, allow_typed_const: boolean);
  174. var
  175. orgname : TIDString;
  176. hdef : tdef;
  177. sym : tsym;
  178. dummysymoptions : tsymoptions;
  179. deprecatedmsg : pshortstring;
  180. storetokenpos,filepos : tfileposinfo;
  181. old_block_type : tblock_type;
  182. skipequal : boolean;
  183. tclist : tasmlist;
  184. varspez : tvarspez;
  185. begin
  186. old_block_type:=block_type;
  187. block_type:=bt_const;
  188. repeat
  189. orgname:=orgpattern;
  190. filepos:=current_tokenpos;
  191. consume(_ID);
  192. case token of
  193. _EQ:
  194. begin
  195. consume(_EQ);
  196. sym:=readconstant(orgname,filepos);
  197. { Support hint directives }
  198. dummysymoptions:=[];
  199. deprecatedmsg:=nil;
  200. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  201. if assigned(sym) then
  202. begin
  203. sym.symoptions:=sym.symoptions+dummysymoptions;
  204. sym.deprecatedmsg:=deprecatedmsg;
  205. sym.visibility:=symtablestack.top.currentvisibility;
  206. symtablestack.top.insert(sym);
  207. {$ifdef jvm}
  208. { for the JVM target, some constants need to be
  209. initialized at run time (enums, sets) -> create fake
  210. typed const to do so }
  211. if assigned(tconstsym(sym).constdef) and
  212. (tconstsym(sym).constdef.typ in [enumdef,setdef]) then
  213. jvm_add_typed_const_initializer(tconstsym(sym));
  214. {$endif}
  215. end
  216. else
  217. stringdispose(deprecatedmsg);
  218. consume(_SEMICOLON);
  219. end;
  220. _COLON:
  221. begin
  222. if not allow_typed_const then
  223. begin
  224. Message(parser_e_no_typed_const);
  225. consume_all_until(_SEMICOLON);
  226. end;
  227. { set the blocktype first so a consume also supports a
  228. caret, to support const s : ^string = nil }
  229. block_type:=bt_const_type;
  230. consume(_COLON);
  231. read_anon_type(hdef,false);
  232. block_type:=bt_const;
  233. skipequal:=false;
  234. { create symbol }
  235. storetokenpos:=current_tokenpos;
  236. current_tokenpos:=filepos;
  237. if not (cs_typed_const_writable in current_settings.localswitches) then
  238. varspez:=vs_const
  239. else
  240. varspez:=vs_value;
  241. { if we are dealing with structure const then we need to handle it as a
  242. structure static variable: create a symbol in unit symtable and a reference
  243. to it from the structure or linking will fail }
  244. if symtablestack.top.symtabletype in [recordsymtable,ObjectSymtable] then
  245. begin
  246. sym:=tfieldvarsym.create(orgname,varspez,hdef,[]);
  247. symtablestack.top.insert(sym);
  248. sym:=make_field_static(symtablestack.top,tfieldvarsym(sym));
  249. end
  250. else
  251. begin
  252. sym:=tstaticvarsym.create(orgname,varspez,hdef,[]);
  253. sym.visibility:=symtablestack.top.currentvisibility;
  254. symtablestack.top.insert(sym);
  255. end;
  256. current_tokenpos:=storetokenpos;
  257. { procvar can have proc directives, but not type references }
  258. if (hdef.typ=procvardef) and
  259. (hdef.typesym=nil) then
  260. begin
  261. { support p : procedure;stdcall=nil; }
  262. if try_to_consume(_SEMICOLON) then
  263. begin
  264. if check_proc_directive(true) then
  265. parse_var_proc_directives(sym)
  266. else
  267. begin
  268. Message(parser_e_proc_directive_expected);
  269. skipequal:=true;
  270. end;
  271. end
  272. else
  273. { support p : procedure stdcall=nil; }
  274. begin
  275. if check_proc_directive(true) then
  276. parse_var_proc_directives(sym);
  277. end;
  278. { add default calling convention }
  279. handle_calling_convention(tabstractprocdef(hdef));
  280. end;
  281. if not skipequal then
  282. begin
  283. { get init value }
  284. consume(_EQ);
  285. if (cs_typed_const_writable in current_settings.localswitches) then
  286. tclist:=current_asmdata.asmlists[al_typedconsts]
  287. else
  288. tclist:=current_asmdata.asmlists[al_rotypedconsts];
  289. read_typed_const(tclist,tstaticvarsym(sym),in_structure);
  290. end;
  291. end;
  292. else
  293. { generate an error }
  294. consume(_EQ);
  295. end;
  296. until (token<>_ID) or
  297. (in_structure and
  298. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  299. ((m_final_fields in current_settings.modeswitches) and
  300. (idtoken=_FINAL))));
  301. block_type:=old_block_type;
  302. end;
  303. procedure label_dec;
  304. var
  305. labelsym : tlabelsym;
  306. begin
  307. consume(_LABEL);
  308. if not(cs_support_goto in current_settings.moduleswitches) then
  309. Message(sym_e_goto_and_label_not_supported);
  310. repeat
  311. if not(token in [_ID,_INTCONST]) then
  312. consume(_ID)
  313. else
  314. begin
  315. if token=_ID then
  316. labelsym:=tlabelsym.create(orgpattern)
  317. else
  318. labelsym:=tlabelsym.create(pattern);
  319. symtablestack.top.insert(labelsym);
  320. if m_non_local_goto in current_settings.modeswitches then
  321. begin
  322. if symtablestack.top.symtabletype=localsymtable then
  323. begin
  324. labelsym.jumpbuf:=tlocalvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  325. symtablestack.top.insert(labelsym.jumpbuf);
  326. end
  327. else
  328. begin
  329. labelsym.jumpbuf:=tstaticvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  330. symtablestack.top.insert(labelsym.jumpbuf);
  331. cnodeutils.insertbssdata(tstaticvarsym(labelsym.jumpbuf));
  332. end;
  333. include(labelsym.jumpbuf.symoptions,sp_internal);
  334. { the buffer will be setup later, but avoid a hint }
  335. tabstractvarsym(labelsym.jumpbuf).varstate:=vs_written;
  336. end;
  337. consume(token);
  338. end;
  339. if token<>_SEMICOLON then consume(_COMMA);
  340. until not(token in [_ID,_INTCONST]);
  341. consume(_SEMICOLON);
  342. end;
  343. procedure types_dec(in_structure: boolean);
  344. procedure finalize_class_external_status(od: tobjectdef);
  345. begin
  346. if [oo_is_external,oo_is_forward] <= od.objectoptions then
  347. begin
  348. { formal definition: x = objcclass external; }
  349. exclude(od.objectoptions,oo_is_forward);
  350. include(od.objectoptions,oo_is_formal);
  351. end;
  352. end;
  353. var
  354. typename,orgtypename,
  355. gentypename,genorgtypename : TIDString;
  356. newtype : ttypesym;
  357. sym : tsym;
  358. hdef : tdef;
  359. defpos,storetokenpos : tfileposinfo;
  360. old_block_type : tblock_type;
  361. old_checkforwarddefs: TFPObjectList;
  362. objecttype : tobjecttyp;
  363. isgeneric,
  364. isunique,
  365. istyperenaming : boolean;
  366. generictypelist : TFPObjectList;
  367. generictokenbuf : tdynamicarray;
  368. vmtbuilder : TVMTBuilder;
  369. p:tnode;
  370. gendef : tstoreddef;
  371. s : shortstring;
  372. pd: tprocdef;
  373. hashedid : thashedidstring;
  374. begin
  375. old_block_type:=block_type;
  376. { save unit container of forward declarations -
  377. we can be inside nested class type block }
  378. old_checkforwarddefs:=current_module.checkforwarddefs;
  379. current_module.checkforwarddefs:=TFPObjectList.Create(false);
  380. block_type:=bt_type;
  381. repeat
  382. defpos:=current_tokenpos;
  383. istyperenaming:=false;
  384. generictypelist:=nil;
  385. generictokenbuf:=nil;
  386. { fpc generic declaration? }
  387. isgeneric:=not(m_delphi in current_settings.modeswitches) and try_to_consume(_GENERIC);
  388. typename:=pattern;
  389. orgtypename:=orgpattern;
  390. consume(_ID);
  391. { delphi generic declaration? }
  392. if (m_delphi in current_settings.modeswitches) then
  393. isgeneric:=token=_LSHARPBRACKET;
  394. { Generic type declaration? }
  395. if isgeneric then
  396. begin
  397. if assigned(current_genericdef) then
  398. Message(parser_f_no_generic_inside_generic);
  399. consume(_LSHARPBRACKET);
  400. generictypelist:=parse_generic_parameters;
  401. consume(_RSHARPBRACKET);
  402. str(generictypelist.Count,s);
  403. gentypename:=typename+'$'+s;
  404. genorgtypename:=orgtypename+'$'+s;
  405. end
  406. else
  407. begin
  408. gentypename:=typename;
  409. genorgtypename:=orgtypename;
  410. end;
  411. consume(_EQ);
  412. { support 'ttype=type word' syntax }
  413. isunique:=try_to_consume(_TYPE);
  414. { MacPas object model is more like Delphi's than like TP's, but }
  415. { uses the object keyword instead of class }
  416. if (m_mac in current_settings.modeswitches) and
  417. (token = _OBJECT) then
  418. token := _CLASS;
  419. { Start recording a generic template }
  420. if assigned(generictypelist) then
  421. begin
  422. generictokenbuf:=tdynamicarray.create(256);
  423. current_scanner.startrecordtokens(generictokenbuf);
  424. end;
  425. { is the type already defined? -- must be in the current symtable,
  426. not in a nested symtable or one higher up the stack -> don't
  427. use searchsym & frinds! }
  428. sym:=tsym(symtablestack.top.find(gentypename));
  429. newtype:=nil;
  430. { found a symbol with this name? }
  431. if assigned(sym) then
  432. begin
  433. if (sym.typ=typesym) and
  434. { this should not be a symbol that was created by a generic
  435. that was declared earlier }
  436. not (
  437. (ttypesym(sym).typedef.typ=undefineddef) and
  438. (sp_generic_dummy in sym.symoptions)
  439. ) then
  440. begin
  441. if ((token=_CLASS) or
  442. (token=_INTERFACE) or
  443. (token=_DISPINTERFACE) or
  444. (token=_OBJCCLASS) or
  445. (token=_OBJCPROTOCOL) or
  446. (token=_OBJCCATEGORY)) and
  447. (assigned(ttypesym(sym).typedef)) and
  448. is_implicit_pointer_object_type(ttypesym(sym).typedef) and
  449. (oo_is_forward in tobjectdef(ttypesym(sym).typedef).objectoptions) then
  450. begin
  451. case token of
  452. _CLASS :
  453. objecttype:=default_class_type;
  454. _INTERFACE :
  455. case current_settings.interfacetype of
  456. it_interfacecom:
  457. objecttype:=odt_interfacecom;
  458. it_interfacecorba:
  459. objecttype:=odt_interfacecorba;
  460. it_interfacejava:
  461. objecttype:=odt_interfacejava;
  462. else
  463. internalerror(2010122611);
  464. end;
  465. _DISPINTERFACE :
  466. objecttype:=odt_dispinterface;
  467. _OBJCCLASS,
  468. _OBJCCATEGORY :
  469. objecttype:=odt_objcclass;
  470. _OBJCPROTOCOL :
  471. objecttype:=odt_objcprotocol;
  472. else
  473. internalerror(200811072);
  474. end;
  475. consume(token);
  476. { we can ignore the result, the definition is modified }
  477. object_dec(objecttype,genorgtypename,newtype,nil,nil,tobjectdef(ttypesym(sym).typedef),ht_none);
  478. newtype:=ttypesym(sym);
  479. hdef:=newtype.typedef;
  480. end
  481. else
  482. message1(parser_h_type_redef,genorgtypename);
  483. end;
  484. end;
  485. { no old type reused ? Then insert this new type }
  486. if not assigned(newtype) then
  487. begin
  488. { insert the new type first with an errordef, so that
  489. referencing the type before it's really set it
  490. will give an error (PFV) }
  491. hdef:=generrordef;
  492. gendef:=nil;
  493. storetokenpos:=current_tokenpos;
  494. if isgeneric then
  495. begin
  496. { for generics we need to check whether a non-generic type
  497. already exists and if not we need to insert a symbol with
  498. the non-generic name (available in (org)typename) that is a
  499. undefineddef, so that inline specializations can be used }
  500. sym:=tsym(symtablestack.top.Find(typename));
  501. if not assigned(sym) then
  502. begin
  503. sym:=ttypesym.create(orgtypename,tundefineddef.create);
  504. Include(sym.symoptions,sp_generic_dummy);
  505. ttypesym(sym).typedef.typesym:=sym;
  506. sym.visibility:=symtablestack.top.currentvisibility;
  507. symtablestack.top.insert(sym);
  508. ttypesym(sym).typedef.owner:=sym.owner;
  509. end
  510. else
  511. { this is not allowed in non-Delphi modes }
  512. if not (m_delphi in current_settings.modeswitches) then
  513. Message1(sym_e_duplicate_id,genorgtypename)
  514. else
  515. { we need to find this symbol even if it's a variable or
  516. something else when doing an inline specialization }
  517. Include(sym.symoptions,sp_generic_dummy);
  518. end
  519. else
  520. begin
  521. if assigned(sym) and (sym.typ=typesym) and
  522. (ttypesym(sym).typedef.typ=undefineddef) and
  523. (sp_generic_dummy in sym.symoptions) then
  524. begin
  525. { this is a symbol that was added by an earlier generic
  526. declaration, reuse it }
  527. newtype:=ttypesym(sym);
  528. newtype.typedef:=hdef;
  529. sym:=nil;
  530. end;
  531. { check whether this is a declaration of a type inside a
  532. specialization }
  533. if assigned(current_structdef) and
  534. (df_specialization in current_structdef.defoptions) then
  535. begin
  536. if not assigned(current_structdef.genericdef) or
  537. not (current_structdef.genericdef.typ in [recorddef,objectdef]) then
  538. internalerror(2011052301);
  539. hashedid.id:=gentypename;
  540. { we could be inside a method of the specialization
  541. instead of its declaration, so check that first (as
  542. local nested types aren't allowed we don't need to
  543. walk the symtablestack to find the localsymtable) }
  544. if symtablestack.top.symtabletype=localsymtable then
  545. begin
  546. { we are in a method }
  547. if not assigned(symtablestack.top.defowner) or
  548. (symtablestack.top.defowner.typ<>procdef) then
  549. internalerror(2011120701);
  550. pd:=tprocdef(symtablestack.top.defowner);
  551. if not assigned(pd.genericdef) or (pd.genericdef.typ<>procdef) then
  552. internalerror(2011120702);
  553. sym:=tsym(tprocdef(pd.genericdef).localst.findwithhash(hashedid));
  554. end
  555. else
  556. sym:=nil;
  557. if not assigned(sym) or not (sym.typ=typesym) then
  558. begin
  559. { now search in the declaration of the generic }
  560. sym:=tsym(tabstractrecorddef(current_structdef.genericdef).symtable.findwithhash(hashedid));
  561. if not assigned(sym) or not (sym.typ=typesym) then
  562. internalerror(2011052302);
  563. end;
  564. { use the corresponding type in the generic's symtable as
  565. genericdef for the specialized type }
  566. gendef:=tstoreddef(ttypesym(sym).typedef);
  567. end;
  568. end;
  569. { insert a new type if we don't reuse an existing symbol }
  570. if not assigned(newtype) then
  571. begin
  572. newtype:=ttypesym.create(genorgtypename,hdef);
  573. newtype.visibility:=symtablestack.top.currentvisibility;
  574. symtablestack.top.insert(newtype);
  575. end;
  576. current_tokenpos:=defpos;
  577. current_tokenpos:=storetokenpos;
  578. { read the type definition }
  579. read_named_type(hdef,newtype,gendef,generictypelist,false);
  580. { update the definition of the type }
  581. if assigned(hdef) then
  582. begin
  583. if assigned(hdef.typesym) then
  584. begin
  585. istyperenaming:=true;
  586. include(newtype.symoptions,sp_explicitrename);
  587. end;
  588. if isunique then
  589. begin
  590. if is_objc_class_or_protocol(hdef) or
  591. is_java_class_or_interface(hdef) then
  592. Message(parser_e_unique_unsupported);
  593. hdef:=tstoreddef(hdef).getcopy;
  594. { check if it is an ansistirng(codepage) declaration }
  595. if is_ansistring(hdef) and try_to_consume(_LKLAMMER) then
  596. begin
  597. p:=comp_expr(true,false);
  598. consume(_RKLAMMER);
  599. if not is_constintnode(p) then
  600. begin
  601. Message(parser_e_illegal_expression);
  602. { error recovery }
  603. end
  604. else
  605. begin
  606. if (tordconstnode(p).value<0) or (tordconstnode(p).value>65535) then
  607. begin
  608. Message(parser_e_invalid_codepage);
  609. tordconstnode(p).value:=0;
  610. end;
  611. tstringdef(hdef).encoding:=int64(tordconstnode(p).value);
  612. end;
  613. p.free;
  614. end;
  615. { fix name, it is used e.g. for tables }
  616. if is_class_or_interface_or_dispinterface(hdef) then
  617. with tobjectdef(hdef) do
  618. begin
  619. stringdispose(objname);
  620. stringdispose(objrealname);
  621. objrealname:=stringdup(genorgtypename);
  622. objname:=stringdup(upper(genorgtypename));
  623. end;
  624. include(hdef.defoptions,df_unique);
  625. if (hdef.typ in [pointerdef,classrefdef]) and
  626. (tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
  627. current_module.checkforwarddefs.add(hdef);
  628. end;
  629. if not assigned(hdef.typesym) then
  630. hdef.typesym:=newtype;
  631. end;
  632. { in non-Delphi modes we need a reference to the generic def
  633. without the generic suffix, so it can be found easily when
  634. parsing method implementations }
  635. if isgeneric and assigned(sym) and
  636. not (m_delphi in current_settings.modeswitches) and
  637. (ttypesym(sym).typedef.typ=undefineddef) then
  638. { don't free the undefineddef as the defids rely on the count
  639. of the defs in the def list of the module}
  640. ttypesym(sym).typedef:=hdef;
  641. newtype.typedef:=hdef;
  642. { KAZ: handle TGUID declaration in system unit }
  643. if (cs_compilesystem in current_settings.moduleswitches) and not assigned(rec_tguid) and
  644. (gentypename='TGUID') and { name: TGUID and size=16 bytes that is 128 bits }
  645. assigned(hdef) and (hdef.typ=recorddef) and (hdef.size=16) then
  646. rec_tguid:=trecorddef(hdef);
  647. end;
  648. if assigned(hdef) then
  649. begin
  650. case hdef.typ of
  651. pointerdef :
  652. begin
  653. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  654. consume(_SEMICOLON);
  655. if try_to_consume(_FAR) then
  656. begin
  657. tpointerdef(hdef).is_far:=true;
  658. consume(_SEMICOLON);
  659. end;
  660. end;
  661. procvardef :
  662. begin
  663. { in case of type renaming, don't parse proc directives }
  664. if istyperenaming then
  665. begin
  666. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  667. consume(_SEMICOLON);
  668. end
  669. else
  670. begin
  671. if not check_proc_directive(true) then
  672. begin
  673. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  674. consume(_SEMICOLON);
  675. end;
  676. parse_var_proc_directives(tsym(newtype));
  677. handle_calling_convention(tprocvardef(hdef));
  678. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  679. consume(_SEMICOLON);
  680. end;
  681. end;
  682. objectdef :
  683. begin
  684. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  685. consume(_SEMICOLON);
  686. { change a forward and external class declaration into
  687. formal external definition, so the compiler does not
  688. expect an real definition later }
  689. if is_objc_class_or_protocol(hdef) or
  690. is_java_class_or_interface(hdef) then
  691. finalize_class_external_status(tobjectdef(hdef));
  692. { Build VMT indexes, skip for type renaming and forward classes }
  693. if (hdef.typesym=newtype) and
  694. not(oo_is_forward in tobjectdef(hdef).objectoptions) and
  695. not(df_generic in hdef.defoptions) then
  696. begin
  697. vmtbuilder:=TVMTBuilder.Create(tobjectdef(hdef));
  698. vmtbuilder.generate_vmt;
  699. vmtbuilder.free;
  700. end;
  701. { In case of an objcclass, verify that all methods have a message
  702. name set. We only check this now, because message names can be set
  703. during the protocol (interface) mapping. At the same time, set the
  704. mangled names (these depend on the "external" name of the class),
  705. and mark private fields of external classes as "used" (to avoid
  706. bogus notes about them being unused)
  707. }
  708. { watch out for crashes in case of errors }
  709. if is_objc_class_or_protocol(hdef) and
  710. (not is_objccategory(hdef) or
  711. assigned(tobjectdef(hdef).childof)) then
  712. tobjectdef(hdef).finish_objc_data;
  713. if is_cppclass(hdef) then
  714. tobjectdef(hdef).finish_cpp_data;
  715. end;
  716. recorddef :
  717. begin
  718. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  719. consume(_SEMICOLON);
  720. end;
  721. else
  722. begin
  723. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  724. consume(_SEMICOLON);
  725. end;
  726. end;
  727. end;
  728. if isgeneric and (not(hdef.typ in [objectdef,recorddef,arraydef,procvardef])
  729. or is_objectpascal_helper(hdef)) then
  730. message(parser_e_cant_create_generics_of_this_type);
  731. { Stop recording a generic template }
  732. if assigned(generictypelist) then
  733. begin
  734. current_scanner.stoprecordtokens;
  735. tstoreddef(hdef).generictokenbuf:=generictokenbuf;
  736. { Generic is never a type renaming }
  737. hdef.typesym:=newtype;
  738. generictypelist.free;
  739. end;
  740. until (token<>_ID) or
  741. (in_structure and
  742. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  743. ((m_final_fields in current_settings.modeswitches) and
  744. (idtoken=_FINAL))));
  745. { resolve type block forward declarations and restore a unit
  746. container for them }
  747. resolve_forward_types;
  748. current_module.checkforwarddefs.free;
  749. current_module.checkforwarddefs:=old_checkforwarddefs;
  750. block_type:=old_block_type;
  751. end;
  752. { reads a type declaration to the symbol table }
  753. procedure type_dec;
  754. begin
  755. consume(_TYPE);
  756. types_dec(false);
  757. end;
  758. procedure var_dec;
  759. { parses variable declarations and inserts them in }
  760. { the top symbol table of symtablestack }
  761. begin
  762. consume(_VAR);
  763. read_var_decls([]);
  764. end;
  765. procedure property_dec;
  766. { parses a global property (fpc mode feature) }
  767. var
  768. old_block_type: tblock_type;
  769. begin
  770. consume(_PROPERTY);
  771. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  772. message(parser_e_resourcestring_only_sg);
  773. old_block_type:=block_type;
  774. block_type:=bt_const;
  775. repeat
  776. read_property_dec(false, nil);
  777. consume(_SEMICOLON);
  778. until token<>_ID;
  779. block_type:=old_block_type;
  780. end;
  781. procedure threadvar_dec;
  782. { parses thread variable declarations and inserts them in }
  783. { the top symbol table of symtablestack }
  784. begin
  785. consume(_THREADVAR);
  786. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  787. message(parser_e_threadvars_only_sg);
  788. read_var_decls([vd_threadvar]);
  789. end;
  790. procedure resourcestring_dec;
  791. var
  792. orgname : TIDString;
  793. p : tnode;
  794. dummysymoptions : tsymoptions;
  795. deprecatedmsg : pshortstring;
  796. storetokenpos,filepos : tfileposinfo;
  797. old_block_type : tblock_type;
  798. sp : pchar;
  799. sym : tsym;
  800. begin
  801. if target_info.system in systems_managed_vm then
  802. message(parser_e_feature_unsupported_for_vm);
  803. consume(_RESOURCESTRING);
  804. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  805. message(parser_e_resourcestring_only_sg);
  806. old_block_type:=block_type;
  807. block_type:=bt_const;
  808. repeat
  809. orgname:=orgpattern;
  810. filepos:=current_tokenpos;
  811. consume(_ID);
  812. case token of
  813. _EQ:
  814. begin
  815. consume(_EQ);
  816. p:=comp_expr(true,false);
  817. storetokenpos:=current_tokenpos;
  818. current_tokenpos:=filepos;
  819. sym:=nil;
  820. case p.nodetype of
  821. ordconstn:
  822. begin
  823. if is_constcharnode(p) then
  824. begin
  825. getmem(sp,2);
  826. sp[0]:=chr(tordconstnode(p).value.svalue);
  827. sp[1]:=#0;
  828. sym:=tconstsym.create_string(orgname,constresourcestring,sp,1);
  829. end
  830. else
  831. Message(parser_e_illegal_expression);
  832. end;
  833. stringconstn:
  834. with Tstringconstnode(p) do
  835. begin
  836. getmem(sp,len+1);
  837. move(value_str^,sp^,len+1);
  838. sym:=tconstsym.create_string(orgname,constresourcestring,sp,len);
  839. end;
  840. else
  841. Message(parser_e_illegal_expression);
  842. end;
  843. current_tokenpos:=storetokenpos;
  844. { Support hint directives }
  845. dummysymoptions:=[];
  846. deprecatedmsg:=nil;
  847. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  848. if assigned(sym) then
  849. begin
  850. sym.symoptions:=sym.symoptions+dummysymoptions;
  851. sym.deprecatedmsg:=deprecatedmsg;
  852. symtablestack.top.insert(sym);
  853. end
  854. else
  855. stringdispose(deprecatedmsg);
  856. consume(_SEMICOLON);
  857. p.free;
  858. end;
  859. else consume(_EQ);
  860. end;
  861. until token<>_ID;
  862. block_type:=old_block_type;
  863. end;
  864. end.