pdecl.pas 53 KB

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