pdecl.pas 52 KB

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