pdecl.pas 35 KB

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