pdecl.pas 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419
  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,symtype,
  27. { pass_1 }
  28. node;
  29. function readconstant(const orgname:string;const filepos:tfileposinfo; out nodetype: tnodetype):tconstsym;
  30. procedure const_dec(out had_generic:boolean);
  31. procedure consts_dec(in_structure, allow_typed_const: boolean;out had_generic:boolean);
  32. procedure label_dec;
  33. procedure type_dec(out had_generic:boolean);
  34. procedure types_dec(in_structure: boolean;out had_generic:boolean;var rtti_attrs_def: trtti_attribute_list);
  35. procedure var_dec(out had_generic:boolean);
  36. procedure threadvar_dec(out had_generic:boolean);
  37. procedure property_dec;
  38. procedure resourcestring_dec(out had_generic:boolean);
  39. procedure parse_rttiattributes(var rtti_attrs_def:trtti_attribute_list);
  40. function parse_forward_declaration(sym:tsym;gentypename,genorgtypename:tidstring;genericdef:tdef;generictypelist:tfphashobjectlist;out newtype:ttypesym):tdef;
  41. implementation
  42. uses
  43. SysUtils,
  44. { common }
  45. cutils,
  46. { global }
  47. globals,tokens,verbose,widestr,constexp,
  48. systems,aasmdata,fmodule,compinnr,
  49. { symtable }
  50. symconst,symbase,symcpu,symcreat,defutil,defcmp,symtable,symutil,
  51. { pass 1 }
  52. ninl,ncon,nobj,ngenutil,nld,nmem,ncal,pass_1,
  53. { parser }
  54. scanner,
  55. pbase,pexpr,ptype,ptconst,pdecsub,pdecvar,pdecobj,pgenutil,pparautl,
  56. procdefutil,
  57. {$ifdef jvm}
  58. pjvm,
  59. {$endif}
  60. { cpu-information }
  61. cpuinfo
  62. ;
  63. function is_system_custom_attribute_descendant(def:tdef):boolean;
  64. begin
  65. if not assigned(class_tcustomattribute) then
  66. class_tcustomattribute:=tobjectdef(search_system_type('TCUSTOMATTRIBUTE').typedef);
  67. Result:=def_is_related(def,class_tcustomattribute);
  68. end;
  69. function readconstant(const orgname:string;const filepos:tfileposinfo; out nodetype: tnodetype):tconstsym;
  70. var
  71. hp : tconstsym;
  72. p : tnode;
  73. ps : pconstset;
  74. pd : pbestreal;
  75. pg : pguid;
  76. sp : pchar;
  77. pw : tcompilerwidestring;
  78. storetokenpos : tfileposinfo;
  79. begin
  80. readconstant:=nil;
  81. if orgname='' then
  82. internalerror(9584582);
  83. hp:=nil;
  84. p:=comp_expr([ef_accept_equal]);
  85. nodetype:=p.nodetype;
  86. storetokenpos:=current_tokenpos;
  87. current_tokenpos:=filepos;
  88. case p.nodetype of
  89. ordconstn:
  90. begin
  91. if p.resultdef.typ=pointerdef then
  92. hp:=cconstsym.create_ordptr(orgname,constpointer,tordconstnode(p).value.uvalue,p.resultdef)
  93. else
  94. hp:=cconstsym.create_ord(orgname,constord,tordconstnode(p).value,p.resultdef);
  95. end;
  96. stringconstn:
  97. begin
  98. if is_wide_or_unicode_string(p.resultdef) then
  99. begin
  100. initwidestring(pw);
  101. copywidestring(tstringconstnode(p).valuews,pw);
  102. hp:=cconstsym.create_wstring(orgname,constwstring,pw);
  103. end
  104. else
  105. begin
  106. getmem(sp,tstringconstnode(p).len+1);
  107. sp[tstringconstnode(p).len]:=#0;
  108. if tstringconstnode(p).len>0 then
  109. move(tstringconstnode(p).valueas[0],sp^,tstringconstnode(p).len+1);
  110. { if a non-default ansistring code page has been specified,
  111. keep it }
  112. if is_ansistring(p.resultdef) and
  113. (tstringdef(p.resultdef).encoding<>0) then
  114. hp:=cconstsym.create_string(orgname,conststring,sp,tstringconstnode(p).len,p.resultdef)
  115. else
  116. hp:=cconstsym.create_string(orgname,conststring,sp,tstringconstnode(p).len,nil);
  117. end;
  118. end;
  119. realconstn :
  120. begin
  121. new(pd);
  122. pd^:=trealconstnode(p).value_real;
  123. hp:=cconstsym.create_ptr(orgname,constreal,pd,p.resultdef);
  124. end;
  125. setconstn :
  126. begin
  127. new(ps);
  128. if assigned(tsetconstnode(p).value_set) then
  129. ps^:=tsetconstnode(p).value_set^
  130. else
  131. ps^:=[];
  132. hp:=cconstsym.create_ptr(orgname,constset,ps,p.resultdef);
  133. end;
  134. pointerconstn :
  135. begin
  136. hp:=cconstsym.create_ordptr(orgname,constpointer,tpointerconstnode(p).value,p.resultdef);
  137. end;
  138. niln :
  139. begin
  140. hp:=cconstsym.create_ord(orgname,constnil,0,p.resultdef);
  141. end;
  142. typen :
  143. begin
  144. if is_interface(p.resultdef) then
  145. begin
  146. if assigned(tobjectdef(p.resultdef).iidguid) then
  147. begin
  148. new(pg);
  149. pg^:=tobjectdef(p.resultdef).iidguid^;
  150. hp:=cconstsym.create_ptr(orgname,constguid,pg,p.resultdef);
  151. end
  152. else
  153. Message1(parser_e_interface_has_no_guid,tobjectdef(p.resultdef).objrealname^);
  154. end
  155. else
  156. Message(parser_e_illegal_expression);
  157. end;
  158. inlinen:
  159. begin
  160. { this situation only happens if a intrinsic is parsed that has a
  161. generic type as its argument. As we don't know certain
  162. information about the final type yet, we need to use safe
  163. values (mostly 0, except for (Bit)SizeOf()) }
  164. if not parse_generic then
  165. Message(parser_e_cannot_evaluate_expression_at_compile_time);
  166. case tinlinenode(p).inlinenumber of
  167. in_sizeof_x:
  168. begin
  169. hp:=cconstsym.create_ord(orgname,constord,1,p.resultdef);
  170. end;
  171. in_bitsizeof_x:
  172. begin
  173. hp:=cconstsym.create_ord(orgname,constord,8,p.resultdef);
  174. end;
  175. { add other cases here if necessary }
  176. else
  177. Message(parser_e_illegal_expression);
  178. end;
  179. end;
  180. else
  181. begin
  182. { the node is from a generic parameter constant and is
  183. untyped so we need to pass a placeholder constant
  184. instead of givng an error }
  185. if nf_generic_para in p.flags then
  186. hp:=cconstsym.create_ord(orgname,constnil,0,p.resultdef)
  187. else
  188. Message(parser_e_illegal_expression);
  189. end;
  190. end;
  191. { transfer generic param flag from node to symbol }
  192. if nf_generic_para in p.flags then
  193. begin
  194. include(hp.symoptions,sp_generic_const);
  195. include(hp.symoptions,sp_generic_para);
  196. end;
  197. current_tokenpos:=storetokenpos;
  198. p.free;
  199. readconstant:=hp;
  200. end;
  201. procedure const_dec(out had_generic:boolean);
  202. begin
  203. consume(_CONST);
  204. consts_dec(false,true,had_generic);
  205. end;
  206. procedure consts_dec(in_structure, allow_typed_const: boolean;out had_generic:boolean);
  207. var
  208. orgname : TIDString;
  209. hdef : tdef;
  210. sym : tsym;
  211. flags : thccflags;
  212. dummysymoptions : tsymoptions;
  213. deprecatedmsg : pshortstring;
  214. storetokenpos,filepos : tfileposinfo;
  215. nodetype : tnodetype;
  216. old_block_type : tblock_type;
  217. first,
  218. isgeneric,
  219. expect_directive,
  220. skip_initialiser : boolean;
  221. varspez : tvarspez;
  222. asmtype : tasmlisttype;
  223. begin
  224. old_block_type:=block_type;
  225. block_type:=bt_const;
  226. had_generic:=false;
  227. first:=true;
  228. repeat
  229. orgname:=orgpattern;
  230. filepos:=current_tokenpos;
  231. isgeneric:=not (m_delphi in current_settings.modeswitches) and (token=_ID) and (idtoken=_GENERIC);
  232. consume(_ID);
  233. case token of
  234. _EQ:
  235. begin
  236. consume(_EQ);
  237. sym:=readconstant(orgname,filepos,nodetype);
  238. { Support hint directives }
  239. dummysymoptions:=[];
  240. deprecatedmsg:=nil;
  241. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  242. if assigned(sym) then
  243. begin
  244. sym.symoptions:=sym.symoptions+dummysymoptions;
  245. sym.deprecatedmsg:=deprecatedmsg;
  246. sym.visibility:=symtablestack.top.currentvisibility;
  247. symtablestack.top.insertsym(sym);
  248. sym.register_sym;
  249. {$ifdef jvm}
  250. { for the JVM target, some constants need to be
  251. initialized at run time (enums, sets) -> create fake
  252. typed const to do so (at least if they are visible
  253. outside this routine, since we won't directly access
  254. these symbols in the generated code) }
  255. if (symtablestack.top.symtablelevel<normal_function_level) and
  256. assigned(tconstsym(sym).constdef) and
  257. (tconstsym(sym).constdef.typ in [enumdef,setdef]) then
  258. jvm_add_typed_const_initializer(tconstsym(sym));
  259. {$endif}
  260. end
  261. else
  262. stringdispose(deprecatedmsg);
  263. consume(_SEMICOLON);
  264. end;
  265. _COLON:
  266. begin
  267. if not allow_typed_const then
  268. begin
  269. Message(parser_e_no_typed_const);
  270. consume_all_until(_SEMICOLON);
  271. end;
  272. { set the blocktype first so a consume also supports a
  273. caret, to support const s : ^string = nil }
  274. block_type:=bt_const_type;
  275. consume(_COLON);
  276. read_anon_type(hdef,false,nil);
  277. block_type:=bt_const;
  278. { create symbol }
  279. storetokenpos:=current_tokenpos;
  280. current_tokenpos:=filepos;
  281. if not (cs_typed_const_writable in current_settings.localswitches) then
  282. begin
  283. varspez:=vs_const;
  284. asmtype:=al_rotypedconsts;
  285. end
  286. else
  287. begin
  288. varspez:=vs_value;
  289. asmtype:=al_typedconsts;
  290. end;
  291. { if we are dealing with structure const then we need to handle it as a
  292. structure static variable: create a symbol in unit symtable and a reference
  293. to it from the structure or linking will fail }
  294. if symtablestack.top.symtabletype in [recordsymtable,ObjectSymtable] then
  295. begin
  296. { note: we keep hdef so that we might at least read the
  297. constant data correctly for error recovery }
  298. check_allowed_for_var_or_const(hdef,false);
  299. sym:=cfieldvarsym.create(orgname,varspez,hdef,[]);
  300. symtablestack.top.insertsym(sym);
  301. sym:=make_field_static(symtablestack.top,tfieldvarsym(sym));
  302. end
  303. else
  304. begin
  305. sym:=cstaticvarsym.create(orgname,varspez,hdef,[]);
  306. sym.visibility:=symtablestack.top.currentvisibility;
  307. symtablestack.top.insertsym(sym);
  308. end;
  309. sym.register_sym;
  310. current_tokenpos:=storetokenpos;
  311. skip_initialiser:=false;
  312. { Anonymous proctype definitions can have proc directives }
  313. if (
  314. (hdef.typ=procvardef) or
  315. is_funcref(hdef)
  316. ) and
  317. (hdef.typesym=nil) then
  318. begin
  319. { Either "procedure; stdcall" or "procedure stdcall" }
  320. expect_directive:=try_to_consume(_SEMICOLON);
  321. if check_proc_directive(true) then
  322. parse_proctype_directives(hdef)
  323. else if expect_directive then
  324. begin
  325. Message(parser_e_proc_directive_expected);
  326. skip_initialiser:=true;
  327. end;
  328. { add default calling convention }
  329. if hdef.typ=procvardef then
  330. flags:=hcc_default_actions_intf
  331. else
  332. flags:=hcc_default_actions_intf_struct;
  333. handle_calling_convention(hdef,flags);
  334. end;
  335. { Parse the initialiser }
  336. if not skip_initialiser then
  337. begin
  338. consume(_EQ);
  339. maybe_guarantee_record_typesym(tstaticvarsym(sym).vardef,tstaticvarsym(sym).vardef.owner);
  340. read_typed_const(current_asmdata.asmlists[asmtype],tstaticvarsym(sym),in_structure);
  341. end;
  342. end;
  343. else
  344. if not first and isgeneric and (token in [_PROCEDURE,_FUNCTION,_CLASS]) then
  345. begin
  346. had_generic:=true;
  347. break;
  348. end
  349. else
  350. { generate an error }
  351. consume(_EQ);
  352. end;
  353. first:=false;
  354. until (token<>_ID) or
  355. (in_structure and
  356. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  357. ((m_final_fields in current_settings.modeswitches) and
  358. (idtoken=_FINAL))));
  359. block_type:=old_block_type;
  360. end;
  361. procedure label_dec;
  362. var
  363. labelsym : tlabelsym;
  364. begin
  365. consume(_LABEL);
  366. if not(cs_support_goto in current_settings.moduleswitches) then
  367. Message(sym_e_goto_and_label_not_supported);
  368. repeat
  369. if not(token in [_ID,_INTCONST]) then
  370. consume(_ID)
  371. else
  372. begin
  373. if token=_ID then
  374. labelsym:=clabelsym.create(orgpattern)
  375. else
  376. begin
  377. { strip leading 0's in iso mode }
  378. if (([m_iso,m_extpas]*current_settings.modeswitches)<>[]) then
  379. while (length(pattern)>1) and (pattern[1]='0') do
  380. delete(pattern,1,1);
  381. labelsym:=clabelsym.create(pattern);
  382. end;
  383. symtablestack.top.insertsym(labelsym);
  384. if m_non_local_goto in current_settings.modeswitches then
  385. begin
  386. if symtablestack.top.symtabletype=localsymtable then
  387. begin
  388. labelsym.jumpbuf:=clocalvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  389. symtablestack.top.insertsym(labelsym.jumpbuf);
  390. end
  391. else
  392. begin
  393. labelsym.jumpbuf:=cstaticvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  394. symtablestack.top.insertsym(labelsym.jumpbuf);
  395. cnodeutils.insertbssdata(tstaticvarsym(labelsym.jumpbuf));
  396. end;
  397. include(labelsym.jumpbuf.symoptions,sp_internal);
  398. { the buffer will be setup later, but avoid a hint }
  399. tabstractvarsym(labelsym.jumpbuf).varstate:=vs_written;
  400. end;
  401. consume(token);
  402. end;
  403. if token<>_SEMICOLON then consume(_COMMA);
  404. until not(token in [_ID,_INTCONST]);
  405. consume(_SEMICOLON);
  406. end;
  407. function find_create_constructor(objdef:tobjectdef):tsymentry;
  408. begin
  409. while assigned(objdef) do
  410. begin
  411. result:=objdef.symtable.Find('CREATE');
  412. if assigned(result) then
  413. exit;
  414. objdef:=objdef.childof;
  415. end;
  416. // A class without a constructor called 'create'?!?
  417. internalerror(2012111101);
  418. end;
  419. procedure parse_rttiattributes(var rtti_attrs_def:trtti_attribute_list);
  420. function read_attr_paras:tnode;
  421. var
  422. old_block_type : tblock_type;
  423. begin
  424. if try_to_consume(_LKLAMMER) then
  425. begin
  426. { we only want constants here }
  427. old_block_type:=block_type;
  428. block_type:=bt_const;
  429. result:=parse_paras(false,false,_RKLAMMER);
  430. block_type:=old_block_type;
  431. consume(_RKLAMMER);
  432. end
  433. else
  434. result:=nil;
  435. end;
  436. var
  437. p,paran,pcalln,ptmp : tnode;
  438. ecnt : longint;
  439. i,pcount : sizeint;
  440. paras : array of tnode;
  441. od : tobjectdef;
  442. constrsym : tsymentry;
  443. typesym : ttypesym;
  444. parasok : boolean;
  445. begin
  446. consume(_LECKKLAMMER);
  447. repeat
  448. { Parse attribute type }
  449. p:=factor(false,[ef_type_only,ef_check_attr_suffix]);
  450. if p.nodetype=typen then
  451. begin
  452. typesym:=ttypesym(ttypenode(p).typesym);
  453. od:=tobjectdef(ttypenode(p).typedef);
  454. { Check if the attribute class is related to TCustomAttribute }
  455. if not is_system_custom_attribute_descendant(od) then
  456. begin
  457. incompatibletypes(od,class_tcustomattribute);
  458. read_attr_paras.free;
  459. continue;
  460. end;
  461. paran:=read_attr_paras;
  462. { Search the tprocdef of the constructor which has to be called. }
  463. constrsym:=find_create_constructor(od);
  464. if constrsym.typ<>procsym then
  465. internalerror(2018102301);
  466. pcalln:=ccallnode.create(paran,tprocsym(constrsym),od.symtable,cloadvmtaddrnode.create(p),[cnf_no_convert_procvar],nil);
  467. p:=nil;
  468. ecnt:=errorcount;
  469. typecheckpass(pcalln);
  470. if (pcalln.nodetype=calln) and assigned(tcallnode(pcalln).procdefinition) and not codegenerror then
  471. begin
  472. { TODO: once extended RTTI for methods is supported, reject a
  473. constructor if it doesn't have extended RTTI enabled }
  474. { collect the parameters of the call node as there might be
  475. compile time type conversions (e.g. a Byte parameter being
  476. passed a value > 255) }
  477. paran:=tcallnode(pcalln).left;
  478. { only count visible parameters (thankfully open arrays are not
  479. supported, otherwise we'd need to handle those as well) }
  480. parasok:=true;
  481. paras:=nil;
  482. if assigned(paran) then
  483. begin
  484. ptmp:=paran;
  485. pcount:=0;
  486. while assigned(ptmp) do
  487. begin
  488. if not (vo_is_hidden_para in tcallparanode(ptmp).parasym.varoptions) then
  489. inc(pcount);
  490. ptmp:=tcallparanode(ptmp).right;
  491. end;
  492. setlength(paras,pcount);
  493. ptmp:=paran;
  494. pcount:=0;
  495. while assigned(ptmp) do
  496. begin
  497. if not (vo_is_hidden_para in tcallparanode(ptmp).parasym.varoptions) then
  498. begin
  499. if not is_constnode(tcallparanode(ptmp).left) then
  500. begin
  501. parasok:=false;
  502. messagepos(tcallparanode(ptmp).left.fileinfo,type_e_constant_expr_expected);
  503. end;
  504. paras[high(paras)-pcount]:=tcallparanode(ptmp).left.getcopy;
  505. inc(pcount);
  506. end;
  507. ptmp:=tcallparanode(ptmp).right;
  508. end;
  509. end;
  510. if parasok then
  511. begin
  512. { Add attribute to attribute list which will be added
  513. to the property which is defined next. }
  514. if not assigned(rtti_attrs_def) then
  515. rtti_attrs_def:=trtti_attribute_list.create;
  516. rtti_attrs_def.addattribute(typesym,tcallnode(pcalln).procdefinition,pcalln,paras);
  517. end
  518. else
  519. begin
  520. { cleanup }
  521. pcalln.free;
  522. for i:=0 to high(paras) do
  523. paras[i].free;
  524. end;
  525. end
  526. else begin
  527. { provide *some* error in case there hasn't been one }
  528. if errorcount=ecnt then
  529. message(parser_e_illegal_expression);
  530. pcalln.free;
  531. end;
  532. end
  533. else
  534. begin
  535. Message(type_e_type_id_expected);
  536. { try to recover by nevertheless reading the parameters (if any) }
  537. read_attr_paras.free;
  538. end;
  539. p.free;
  540. until not try_to_consume(_COMMA);
  541. consume(_RECKKLAMMER);
  542. end;
  543. function parse_forward_declaration(sym:tsym;gentypename,genorgtypename:tidstring;genericdef:tdef;generictypelist:tfphashobjectlist;out newtype:ttypesym):tdef;
  544. var
  545. wasforward : boolean;
  546. objecttype : tobjecttyp;
  547. gendef : tstoreddef;
  548. begin
  549. newtype:=nil;
  550. wasforward:=false;
  551. if ((token=_CLASS) or
  552. (token=_INTERFACE) or
  553. (token=_DISPINTERFACE) or
  554. (token=_OBJCCLASS) or
  555. (token=_OBJCPROTOCOL) or
  556. (token=_OBJCCATEGORY)) and
  557. (assigned(ttypesym(sym).typedef)) and
  558. is_implicit_pointer_object_type(ttypesym(sym).typedef) and
  559. (oo_is_forward in tobjectdef(ttypesym(sym).typedef).objectoptions) then
  560. begin
  561. wasforward:=true;
  562. objecttype:=odt_none;
  563. case token of
  564. _CLASS :
  565. objecttype:=default_class_type;
  566. _INTERFACE :
  567. case current_settings.interfacetype of
  568. it_interfacecom:
  569. objecttype:=odt_interfacecom;
  570. it_interfacecorba:
  571. objecttype:=odt_interfacecorba;
  572. it_interfacejava:
  573. objecttype:=odt_interfacejava;
  574. end;
  575. _DISPINTERFACE :
  576. objecttype:=odt_dispinterface;
  577. _OBJCCLASS,
  578. _OBJCCATEGORY :
  579. objecttype:=odt_objcclass;
  580. _OBJCPROTOCOL :
  581. objecttype:=odt_objcprotocol;
  582. else
  583. internalerror(200811072);
  584. end;
  585. consume(token);
  586. if assigned(genericdef) then
  587. gendef:=tstoreddef(genericdef)
  588. else
  589. { determine the generic def in case we are in a nested type
  590. of a specialization }
  591. gendef:=determine_generic_def(gentypename);
  592. { we can ignore the result, the definition is modified }
  593. object_dec(objecttype,genorgtypename,newtype,gendef,generictypelist,tobjectdef(ttypesym(sym).typedef),ht_none);
  594. if wasforward and
  595. (tobjectdef(ttypesym(sym).typedef).objecttype<>objecttype) then
  596. Message1(type_e_forward_interface_type_does_not_match,tobjectdef(ttypesym(sym).typedef).GetTypeName);
  597. newtype:=ttypesym(sym);
  598. result:=newtype.typedef;
  599. end
  600. else
  601. begin
  602. message1(parser_h_type_redef,genorgtypename);
  603. result:=generrordef;
  604. end;
  605. end;
  606. { From http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features :
  607. To determine whether a method has an inferred related result type, the first word in the camel-case selector
  608. (e.g., “init” in “initWithObjects”) is considered, and the method will have a related result type if its return
  609. type is compatible with the type of its class and if:
  610. * the first word is "alloc" or "new", and the method is a class method, or
  611. * the first word is "autorelease", "init", "retain", or "self", and the method is an instance method.
  612. If a method with a related result type is overridden by a subclass method, the subclass method must also return
  613. a type that is compatible with the subclass type.
  614. }
  615. procedure pd_set_objc_related_result(def: tobject; para: pointer);
  616. var
  617. pd: tprocdef;
  618. i, firstcamelend: longint;
  619. inferresult: boolean;
  620. begin
  621. if tdef(def).typ<>procdef then
  622. exit;
  623. pd:=tprocdef(def);
  624. if not(po_msgstr in pd.procoptions) then
  625. internalerror(2019082401);
  626. firstcamelend:=length(pd.messageinf.str^);
  627. for i:=1 to length(pd.messageinf.str^) do
  628. if pd.messageinf.str^[i] in ['A'..'Z'] then
  629. begin
  630. firstcamelend:=pred(i);
  631. break;
  632. end;
  633. case copy(pd.messageinf.str^,1,firstcamelend) of
  634. 'alloc',
  635. 'new':
  636. inferresult:=po_classmethod in pd.procoptions;
  637. 'autorelease',
  638. 'init',
  639. 'retain',
  640. 'self':
  641. inferresult:=not(po_classmethod in pd.procoptions);
  642. else
  643. inferresult:=false;
  644. end;
  645. if inferresult and
  646. def_is_related(tdef(pd.procsym.owner.defowner),pd.returndef) then
  647. include(pd.procoptions,po_objc_related_result_type);
  648. end;
  649. procedure types_dec(in_structure: boolean;out had_generic:boolean;var rtti_attrs_def: trtti_attribute_list);
  650. procedure finalize_class_external_status(od: tobjectdef);
  651. begin
  652. if [oo_is_external,oo_is_forward] <= od.objectoptions then
  653. begin
  654. { formal definition: x = objcclass external; }
  655. exclude(od.objectoptions,oo_is_forward);
  656. include(od.objectoptions,oo_is_formal);
  657. end;
  658. end;
  659. var
  660. typename,orgtypename,
  661. gentypename,genorgtypename : TIDString;
  662. newtype : ttypesym;
  663. dummysym,
  664. sym : tsym;
  665. hdef,
  666. hdef2 : tdef;
  667. defpos,storetokenpos : tfileposinfo;
  668. old_block_type : tblock_type;
  669. old_checkforwarddefs: TFPObjectList;
  670. flags : thccflags;
  671. setdummysym,
  672. first,
  673. isgeneric,
  674. isunique,
  675. istyperenaming : boolean;
  676. generictypelist : tfphashobjectlist;
  677. localgenerictokenbuf : tdynamicarray;
  678. p:tnode;
  679. gendef : tstoreddef;
  680. s : shortstring;
  681. i : longint;
  682. {$ifdef x86}
  683. segment_register: string;
  684. {$endif x86}
  685. begin
  686. old_block_type:=block_type;
  687. { save unit container of forward declarations -
  688. we can be inside nested class type block }
  689. old_checkforwarddefs:=current_module.checkforwarddefs;
  690. current_module.checkforwarddefs:=TFPObjectList.Create(false);
  691. block_type:=bt_type;
  692. hdef:=nil;
  693. first:=true;
  694. had_generic:=false;
  695. storetokenpos:=Default(tfileposinfo);
  696. repeat
  697. defpos:=current_tokenpos;
  698. istyperenaming:=false;
  699. setdummysym:=false;
  700. generictypelist:=nil;
  701. localgenerictokenbuf:=nil;
  702. { class attribute definitions? }
  703. if m_prefixed_attributes in current_settings.modeswitches then
  704. while token=_LECKKLAMMER do
  705. parse_rttiattributes(rtti_attrs_def);
  706. { fpc generic declaration? }
  707. if first then
  708. had_generic:=not(m_delphi in current_settings.modeswitches) and try_to_consume(_GENERIC);
  709. isgeneric:=had_generic;
  710. typename:=pattern;
  711. orgtypename:=orgpattern;
  712. consume(_ID);
  713. { delphi generic declaration? }
  714. if (m_delphi in current_settings.modeswitches) then
  715. isgeneric:=token=_LSHARPBRACKET;
  716. { Generic type declaration? }
  717. if isgeneric then
  718. begin
  719. if assigned(current_genericdef) then
  720. Message(parser_f_no_generic_inside_generic);
  721. consume(_LSHARPBRACKET);
  722. generictypelist:=parse_generic_parameters(true);
  723. consume(_RSHARPBRACKET);
  724. str(generictypelist.Count,s);
  725. gentypename:=typename+'$'+s;
  726. genorgtypename:=orgtypename+'$'+s;
  727. end
  728. else
  729. begin
  730. gentypename:=typename;
  731. genorgtypename:=orgtypename;
  732. end;
  733. consume(_EQ);
  734. { support 'ttype=type word' syntax }
  735. isunique:=try_to_consume(_TYPE);
  736. { MacPas object model is more like Delphi's than like TP's, but }
  737. { uses the object keyword instead of class }
  738. if (m_mac in current_settings.modeswitches) and
  739. (token = _OBJECT) then
  740. token := _CLASS;
  741. { Start recording a generic template }
  742. if assigned(generictypelist) then
  743. begin
  744. localgenerictokenbuf:=tdynamicarray.create(256);
  745. current_scanner.startrecordtokens(localgenerictokenbuf);
  746. end;
  747. { is the type already defined? -- must be in the current symtable,
  748. not in a nested symtable or one higher up the stack -> don't
  749. use searchsym & friends! }
  750. sym:=tsym(symtablestack.top.find(gentypename));
  751. newtype:=nil;
  752. { found a symbol with this name? }
  753. if assigned(sym) then
  754. begin
  755. if (sym.typ=typesym) and
  756. { this should not be a symbol that was created by a generic
  757. that was declared earlier }
  758. not (
  759. (ttypesym(sym).typedef.typ=undefineddef) and
  760. (sp_generic_dummy in sym.symoptions)
  761. ) then
  762. begin
  763. hdef:=parse_forward_declaration(sym,gentypename,genorgtypename,nil,generictypelist,newtype);
  764. end;
  765. end;
  766. { no old type reused ? Then insert this new type }
  767. if not assigned(newtype) then
  768. begin
  769. if isgeneric then
  770. begin
  771. { we are not freeing the type parameters, so register them }
  772. for i:=0 to generictypelist.count-1 do
  773. begin
  774. tstoredsym(generictypelist[i]).register_sym;
  775. if tstoredsym(generictypelist[i]).typ=typesym then
  776. tstoreddef(ttypesym(generictypelist[i]).typedef).register_def;
  777. end;
  778. end;
  779. { insert the new type first with an errordef, so that
  780. referencing the type before it's really set it
  781. will give an error (PFV) }
  782. hdef:=generrordef;
  783. gendef:=nil;
  784. storetokenpos:=current_tokenpos;
  785. if isgeneric then
  786. begin
  787. { for generics we need to check whether a non-generic type
  788. already exists and if not we need to insert a symbol with
  789. the non-generic name (available in (org)typename) that is a
  790. undefineddef, so that inline specializations can be used }
  791. sym:=tsym(symtablestack.top.Find(typename));
  792. if not assigned(sym) then
  793. begin
  794. sym:=ctypesym.create(orgtypename,cundefineddef.create(true));
  795. Include(sym.symoptions,sp_generic_dummy);
  796. ttypesym(sym).typedef.typesym:=sym;
  797. sym.visibility:=symtablestack.top.currentvisibility;
  798. symtablestack.top.insertsym(sym);
  799. ttypesym(sym).typedef.owner:=sym.owner;
  800. end
  801. else
  802. { this is not allowed in non-Delphi modes }
  803. if not (m_delphi in current_settings.modeswitches) then
  804. Message1(sym_e_duplicate_id,genorgtypename)
  805. else
  806. begin
  807. { we need to find this symbol even if it's a variable or
  808. something else when doing an inline specialization }
  809. Include(sym.symoptions,sp_generic_dummy);
  810. add_generic_dummysym(sym);
  811. end;
  812. end
  813. else
  814. begin
  815. if assigned(sym) and (sym.typ=typesym) and
  816. (ttypesym(sym).typedef.typ=undefineddef) and
  817. (sp_generic_dummy in sym.symoptions) then
  818. begin
  819. { this is a symbol that was added by an earlier generic
  820. declaration, reuse it }
  821. newtype:=ttypesym(sym);
  822. newtype.typedef:=hdef;
  823. { use the correct casing }
  824. newtype.RealName:=genorgtypename;
  825. sym:=nil;
  826. end;
  827. { determine the generic def in case we are in a nested type
  828. of a specialization }
  829. gendef:=determine_generic_def(gentypename);
  830. end;
  831. { insert a new type if we don't reuse an existing symbol }
  832. if not assigned(newtype) then
  833. begin
  834. newtype:=ctypesym.create(genorgtypename,hdef);
  835. newtype.visibility:=symtablestack.top.currentvisibility;
  836. symtablestack.top.insertsym(newtype);
  837. end;
  838. current_tokenpos:=defpos;
  839. current_tokenpos:=storetokenpos;
  840. { read the type definition }
  841. read_named_type(hdef,newtype,gendef,generictypelist,false,isunique);
  842. { update the definition of the type }
  843. if assigned(hdef) then
  844. begin
  845. if assigned(hdef.typesym) then
  846. begin
  847. istyperenaming:=true;
  848. include(newtype.symoptions,sp_explicitrename);
  849. end;
  850. if isunique then
  851. begin
  852. if is_objc_class_or_protocol(hdef) or
  853. is_java_class_or_interface(hdef) then
  854. Message(parser_e_unique_unsupported);
  855. if is_object(hdef) or
  856. is_class_or_interface_or_dispinterface(hdef) then
  857. begin
  858. { just create a copy that is a child of the original class class type; this is
  859. Delphi-compatible }
  860. hdef2:=tstoreddef(hdef).getcopy;
  861. tobjectdef(hdef2).childof:=tobjectdef(hdef);
  862. tstoreddef(hdef2).orgdef:=tstoreddef(hdef);
  863. hdef:=hdef2;
  864. end
  865. else
  866. begin
  867. hdef2:=tstoreddef(hdef).getcopy;
  868. tstoreddef(hdef2).orgdef:=tstoreddef(hdef);
  869. hdef:=hdef2;
  870. { check if it is an ansistring(codepage) declaration }
  871. if is_ansistring(hdef) and try_to_consume(_LKLAMMER) then
  872. begin
  873. p:=comp_expr([ef_accept_equal]);
  874. consume(_RKLAMMER);
  875. if not is_constintnode(p) then
  876. begin
  877. Message(parser_e_illegal_expression);
  878. { error recovery }
  879. end
  880. else
  881. begin
  882. if (tordconstnode(p).value<0) or (tordconstnode(p).value>65535) then
  883. begin
  884. Message(parser_e_invalid_codepage);
  885. tordconstnode(p).value:=0;
  886. end;
  887. tstringdef(hdef).encoding:=int64(tordconstnode(p).value);
  888. end;
  889. p.free;
  890. end;
  891. if (hdef.typ in [pointerdef,classrefdef]) and
  892. (tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
  893. current_module.checkforwarddefs.add(hdef);
  894. end;
  895. include(hdef.defoptions,df_unique);
  896. end;
  897. if not assigned(hdef.typesym) then
  898. begin
  899. hdef.typesym:=newtype;
  900. if sp_generic_dummy in newtype.symoptions then
  901. add_generic_dummysym(newtype);
  902. end;
  903. end;
  904. { in non-Delphi modes we need a reference to the generic def
  905. without the generic suffix, so it can be found easily when
  906. parsing method implementations }
  907. if isgeneric and assigned(sym) and
  908. not (m_delphi in current_settings.modeswitches) and
  909. (ttypesym(sym).typedef.typ=undefineddef) then
  910. begin
  911. { don't free the undefineddef as the defids rely on the count
  912. of the defs in the def list of the module}
  913. ttypesym(sym).typedef:=hdef;
  914. setdummysym:=true;
  915. end;
  916. newtype.typedef:=hdef;
  917. { ensure that the type is registered when no specialization is
  918. currently done }
  919. if (current_scanner.replay_stack_depth=0) and
  920. (
  921. (hdef.typ<>procvardef) or
  922. not (po_is_function_ref in tabstractprocdef(hdef).procoptions)
  923. ) then
  924. hdef.register_def;
  925. { KAZ: handle TGUID declaration in system unit }
  926. if (cs_compilesystem in current_settings.moduleswitches) and
  927. assigned(hdef) and
  928. (hdef.typ=recorddef) then
  929. begin
  930. if not assigned(rec_tguid) and
  931. (gentypename='TGUID') and
  932. (hdef.size=16) then
  933. rec_tguid:=trecorddef(hdef)
  934. else if not assigned(rec_jmp_buf) and
  935. (gentypename='JMP_BUF') then
  936. rec_jmp_buf:=trecorddef(hdef)
  937. else if not assigned(rec_exceptaddr) and
  938. (gentypename='TEXCEPTADDR') then
  939. rec_exceptaddr:=trecorddef(hdef);
  940. end;
  941. end;
  942. if assigned(hdef) then
  943. begin
  944. case hdef.typ of
  945. pointerdef :
  946. begin
  947. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  948. consume(_SEMICOLON);
  949. {$ifdef x86}
  950. {$ifdef i8086}
  951. if try_to_consume(_HUGE) then
  952. begin
  953. tcpupointerdef(hdef).x86pointertyp:=x86pt_huge;
  954. consume(_SEMICOLON);
  955. end
  956. else
  957. {$endif i8086}
  958. if try_to_consume(_FAR) then
  959. begin
  960. {$if defined(i8086)}
  961. tcpupointerdef(hdef).x86pointertyp:=x86pt_far;
  962. {$elseif defined(i386)}
  963. tcpupointerdef(hdef).x86pointertyp:=x86pt_near_fs;
  964. {$elseif defined(x86_64)}
  965. { for compatibility with previous versions of fpc,
  966. far pointer = regular pointer on x86_64 }
  967. Message1(parser_w_ptr_type_ignored,'FAR');
  968. {$endif}
  969. consume(_SEMICOLON);
  970. end
  971. else
  972. if try_to_consume(_NEAR) then
  973. begin
  974. if token <> _SEMICOLON then
  975. begin
  976. segment_register:=get_stringconst;
  977. case UpCase(segment_register) of
  978. 'CS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_cs;
  979. 'DS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_ds;
  980. 'SS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_ss;
  981. 'ES': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_es;
  982. 'FS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_fs;
  983. 'GS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_gs;
  984. else
  985. Message(asmr_e_invalid_register);
  986. end;
  987. end
  988. else
  989. tcpupointerdef(hdef).x86pointertyp:=x86pt_near;
  990. consume(_SEMICOLON);
  991. end;
  992. {$else x86}
  993. { Previous versions of FPC support declaring a pointer as
  994. far even on non-x86 platforms. }
  995. if try_to_consume(_FAR) then
  996. begin
  997. Message1(parser_w_ptr_type_ignored,'FAR');
  998. consume(_SEMICOLON);
  999. end;
  1000. {$endif x86}
  1001. end;
  1002. procvardef :
  1003. begin
  1004. { in case of type renaming, don't parse proc directives }
  1005. if istyperenaming then
  1006. begin
  1007. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1008. consume(_SEMICOLON);
  1009. end
  1010. else
  1011. begin
  1012. if not check_proc_directive(true) then
  1013. begin
  1014. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1015. consume(_SEMICOLON);
  1016. end;
  1017. parse_proctype_directives(tprocvardef(hdef));
  1018. if po_is_function_ref in tprocvardef(hdef).procoptions then
  1019. begin
  1020. if not (m_function_references in current_settings.modeswitches) and
  1021. not (po_is_block in tprocvardef(hdef).procoptions) then
  1022. messagepos(storetokenpos,sym_e_error_in_type_def)
  1023. else
  1024. begin
  1025. if setdummysym then
  1026. dummysym:=sym
  1027. else
  1028. dummysym:=nil;
  1029. adjust_funcref(hdef,newtype,dummysym);
  1030. end;
  1031. if current_scanner.replay_stack_depth=0 then
  1032. hdef.register_def;
  1033. end;
  1034. if hdef.typ=procvardef then
  1035. flags:=hcc_default_actions_intf
  1036. else
  1037. flags:=hcc_default_actions_intf_struct;
  1038. handle_calling_convention(hdef,flags);
  1039. if (hdef.typ=procvardef) and (po_is_function_ref in tprocvardef(hdef).procoptions) then
  1040. begin
  1041. if (po_is_block in tprocvardef(hdef).procoptions) and
  1042. not (tprocvardef(hdef).proccalloption in [pocall_cdecl,pocall_mwpascal]) then
  1043. message(type_e_cblock_callconv);
  1044. end;
  1045. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  1046. consume(_SEMICOLON);
  1047. end;
  1048. end;
  1049. objectdef :
  1050. begin
  1051. if is_funcref(hdef) then
  1052. begin
  1053. if not check_proc_directive(true) then
  1054. begin
  1055. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1056. consume(_SEMICOLON);
  1057. end;
  1058. parse_proctype_directives(hdef);
  1059. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  1060. consume(_SEMICOLON);
  1061. end
  1062. else
  1063. begin
  1064. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1065. consume(_SEMICOLON);
  1066. end;
  1067. { change a forward and external class declaration into
  1068. formal external definition, so the compiler does not
  1069. expect an real definition later }
  1070. if is_objc_class_or_protocol(hdef) or
  1071. is_java_class_or_interface(hdef) then
  1072. finalize_class_external_status(tobjectdef(hdef));
  1073. { Build VMT indexes, skip for type renaming and forward classes }
  1074. if not istyperenaming and
  1075. not(oo_is_forward in tobjectdef(hdef).objectoptions) then
  1076. if not (oo_inherits_not_specialized in tobjectdef(hdef).objectoptions) then
  1077. build_vmt(tobjectdef(hdef))
  1078. else
  1079. { update the procdevs to add hidden self param }
  1080. insert_struct_hidden_paras(tobjectdef(hdef));
  1081. { In case of an objcclass, verify that all methods have a message
  1082. name set. We only check this now, because message names can be set
  1083. during the protocol (interface) mapping. At the same time, set the
  1084. mangled names (these depend on the "external" name of the class),
  1085. and mark private fields of external classes as "used" (to avoid
  1086. bogus notes about them being unused)
  1087. }
  1088. { watch out for crashes in case of errors }
  1089. if is_objc_class_or_protocol(hdef) and
  1090. (not is_objccategory(hdef) or
  1091. assigned(tobjectdef(hdef).childof)) then
  1092. begin
  1093. tobjectdef(hdef).finish_objc_data;
  1094. tobjectdef(hdef).symtable.DefList.ForEachCall(@pd_set_objc_related_result,nil);
  1095. end;
  1096. if is_cppclass(hdef) then
  1097. tobjectdef(hdef).finish_cpp_data;
  1098. end;
  1099. recorddef :
  1100. begin
  1101. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1102. consume(_SEMICOLON);
  1103. end;
  1104. else
  1105. begin
  1106. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  1107. consume(_SEMICOLON);
  1108. end;
  1109. end;
  1110. { if we have a real type definition or a unique type we may bind
  1111. attributes to this def }
  1112. if not istyperenaming or isunique then
  1113. trtti_attribute_list.bind(rtti_attrs_def,tstoreddef(hdef).rtti_attribute_list);
  1114. if df_generic in hdef.defoptions then
  1115. { flag parent symtables that they now contain a generic }
  1116. hdef.owner.includeoption(sto_has_generic);
  1117. end;
  1118. if isgeneric and (not(hdef.typ in [objectdef,recorddef,arraydef,procvardef])
  1119. or is_objectpascal_helper(hdef)) then
  1120. begin
  1121. newtype.typedef:=generrordef;
  1122. message(parser_e_cant_create_generics_of_this_type);
  1123. end;
  1124. { Stop recording a generic template }
  1125. if assigned(generictypelist) then
  1126. begin
  1127. current_scanner.stoprecordtokens;
  1128. tstoreddef(hdef).generictokenbuf:=localgenerictokenbuf;
  1129. { Generic is never a type renaming }
  1130. hdef.typesym:=newtype;
  1131. { reusing a forward declared type also reuses the type parameters,
  1132. so free them if they haven't been used }
  1133. for i:=0 to generictypelist.count-1 do
  1134. begin
  1135. if (tstoredsym(generictypelist[i]).typ=typesym) and
  1136. not ttypesym(generictypelist[i]).typedef.is_registered then
  1137. ttypesym(generictypelist[i]).typedef.free;
  1138. if not tstoredsym(generictypelist[i]).is_registered then
  1139. tstoredsym(generictypelist[i]).free;
  1140. end;
  1141. generictypelist.free;
  1142. end;
  1143. if not (m_delphi in current_settings.modeswitches) and
  1144. (token=_ID) and (idtoken=_GENERIC) then
  1145. begin
  1146. had_generic:=true;
  1147. consume(_ID);
  1148. if token in [_PROCEDURE,_FUNCTION,_CLASS] then
  1149. break;
  1150. end
  1151. else
  1152. had_generic:=false;
  1153. first:=false;
  1154. if assigned(rtti_attrs_def) and (rtti_attrs_def.get_attribute_count>0) then
  1155. Message1(parser_e_unbound_attribute,trtti_attribute(rtti_attrs_def.rtti_attributes[0]).typesym.prettyname);
  1156. {$ifdef DEBUG_NODE_XML}
  1157. if Assigned(hdef) then
  1158. hdef.XMLPrintDef(newtype);
  1159. {$endif DEBUG_NODE_XML}
  1160. until ((token<>_ID) and (token<>_LECKKLAMMER)) or
  1161. (in_structure and
  1162. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  1163. ((m_final_fields in current_settings.modeswitches) and
  1164. (idtoken=_FINAL))));
  1165. { resolve type block forward declarations and restore a unit
  1166. container for them }
  1167. resolve_forward_types;
  1168. current_module.checkforwarddefs.free;
  1169. current_module.checkforwarddefs:=old_checkforwarddefs;
  1170. block_type:=old_block_type;
  1171. end;
  1172. { reads a type declaration to the symbol table }
  1173. procedure type_dec(out had_generic:boolean);
  1174. var
  1175. rtti_attrs_def: trtti_attribute_list;
  1176. begin
  1177. consume(_TYPE);
  1178. rtti_attrs_def := nil;
  1179. types_dec(false,had_generic,rtti_attrs_def);
  1180. rtti_attrs_def.free;
  1181. end;
  1182. procedure var_dec(out had_generic:boolean);
  1183. { parses variable declarations and inserts them in }
  1184. { the top symbol table of symtablestack }
  1185. begin
  1186. consume(_VAR);
  1187. read_var_decls([vd_check_generic],had_generic);
  1188. end;
  1189. procedure property_dec;
  1190. { parses a global property (fpc mode feature) }
  1191. var
  1192. old_block_type: tblock_type;
  1193. begin
  1194. consume(_PROPERTY);
  1195. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  1196. message(parser_e_property_only_sgr);
  1197. old_block_type:=block_type;
  1198. block_type:=bt_const;
  1199. repeat
  1200. read_property_dec(false, nil);
  1201. consume(_SEMICOLON);
  1202. until token<>_ID;
  1203. block_type:=old_block_type;
  1204. end;
  1205. procedure threadvar_dec(out had_generic:boolean);
  1206. { parses thread variable declarations and inserts them in }
  1207. { the top symbol table of symtablestack }
  1208. begin
  1209. consume(_THREADVAR);
  1210. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  1211. message(parser_e_threadvars_only_sg);
  1212. if f_threading in features then
  1213. read_var_decls([vd_threadvar,vd_check_generic],had_generic)
  1214. else
  1215. begin
  1216. Message1(parser_f_unsupported_feature,featurestr[f_threading]);
  1217. read_var_decls([vd_check_generic],had_generic);
  1218. end;
  1219. end;
  1220. procedure resourcestring_dec(out had_generic:boolean);
  1221. var
  1222. orgname : TIDString;
  1223. p : tnode;
  1224. dummysymoptions : tsymoptions;
  1225. deprecatedmsg : pshortstring;
  1226. storetokenpos,filepos : tfileposinfo;
  1227. old_block_type : tblock_type;
  1228. sp : pchar;
  1229. sym : tsym;
  1230. first,
  1231. isgeneric : boolean;
  1232. pw : tcompilerwidestring;
  1233. begin
  1234. if target_info.system in systems_managed_vm then
  1235. message(parser_e_feature_unsupported_for_vm);
  1236. consume(_RESOURCESTRING);
  1237. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  1238. message(parser_e_resourcestring_only_sg);
  1239. first:=true;
  1240. had_generic:=false;
  1241. old_block_type:=block_type;
  1242. block_type:=bt_const;
  1243. repeat
  1244. orgname:=orgpattern;
  1245. filepos:=current_tokenpos;
  1246. isgeneric:=not (m_delphi in current_settings.modeswitches) and (token=_ID) and (idtoken=_GENERIC);
  1247. consume(_ID);
  1248. case token of
  1249. _EQ:
  1250. begin
  1251. consume(_EQ);
  1252. p:=comp_expr([ef_accept_equal]);
  1253. storetokenpos:=current_tokenpos;
  1254. current_tokenpos:=filepos;
  1255. sym:=nil;
  1256. case p.nodetype of
  1257. ordconstn:
  1258. begin
  1259. if is_constcharnode(p) then
  1260. begin
  1261. if not is_systemunit_unicode then
  1262. begin
  1263. getmem(sp,2);
  1264. sp[0]:=chr(tordconstnode(p).value.svalue);
  1265. sp[1]:=#0;
  1266. sym:=cconstsym.create_string(orgname,constresourcestring,sp,1,nil);
  1267. end
  1268. else
  1269. begin
  1270. initwidestring(pw);
  1271. setlengthwidestring(pw,1);
  1272. pw.data[0]:=tordconstnode(p).value.svalue;
  1273. sym:=cconstsym.create_wstring(orgname,constwresourcestring,pw);
  1274. end;
  1275. end
  1276. else
  1277. Message(parser_e_illegal_expression);
  1278. end;
  1279. stringconstn:
  1280. with Tstringconstnode(p) do
  1281. begin
  1282. if not is_systemunit_unicode then
  1283. begin
  1284. if cst_type in [cst_widestring,cst_unicodestring] then
  1285. changestringtype(getansistringdef);
  1286. getmem(sp,len+1);
  1287. sp[len]:=#0;
  1288. if len>0 then
  1289. move(valueas[0],sp^,len);
  1290. sym:=cconstsym.create_string(orgname,constresourcestring,sp,len,nil);
  1291. end
  1292. else
  1293. begin
  1294. // For unicode rtl, resourcestrings are unicodestrings
  1295. if cst_type in [cst_conststring,cst_longstring, cst_shortstring,cst_ansistring] then
  1296. changestringtype(cunicodestringtype);
  1297. initwidestring(pw);
  1298. copywidestring(valuews,pw);
  1299. sym:=cconstsym.create_wstring(orgname,constwresourcestring,pw);
  1300. end;
  1301. end;
  1302. else
  1303. Message(parser_e_illegal_expression);
  1304. end;
  1305. current_tokenpos:=storetokenpos;
  1306. { Support hint directives }
  1307. dummysymoptions:=[];
  1308. deprecatedmsg:=nil;
  1309. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  1310. if assigned(sym) then
  1311. begin
  1312. sym.symoptions:=sym.symoptions+dummysymoptions;
  1313. sym.deprecatedmsg:=deprecatedmsg;
  1314. symtablestack.top.insertsym(sym);
  1315. end
  1316. else
  1317. stringdispose(deprecatedmsg);
  1318. consume(_SEMICOLON);
  1319. p.free;
  1320. end;
  1321. else
  1322. if not first and isgeneric and
  1323. (token in [_PROCEDURE, _FUNCTION, _CLASS]) then
  1324. begin
  1325. had_generic:=true;
  1326. break;
  1327. end
  1328. else
  1329. consume(_EQ);
  1330. end;
  1331. first:=false;
  1332. until token<>_ID;
  1333. block_type:=old_block_type;
  1334. end;
  1335. end.