pdecl.pas 35 KB

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