pdecl.pas 52 KB

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