pdecl.pas 48 KB

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