pdecl.pas 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  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. generictokenbuf : 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. generictokenbuf:=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. generictokenbuf:=tdynamicarray.create(256);
  548. current_scanner.startrecordtokens(generictokenbuf);
  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. if (po_hascallingconvention in tprocvardef(hdef).procoptions) and
  856. (tprocvardef(hdef).proccalloption in [pocall_cdecl,pocall_mwpascal]) then
  857. begin
  858. include(tprocvardef(hdef).procoptions,po_is_block);
  859. { can't check yet whether the parameter types
  860. are valid for a block, since some of them
  861. may still be forwarddefs }
  862. end
  863. else
  864. { a regular anonymous function type: not yet supported }
  865. { the }
  866. Comment(V_Error,'Function references are not yet supported, only C blocks (add "cdecl;" at the end)');
  867. end
  868. end;
  869. handle_calling_convention(tprocvardef(hdef),hcc_default_actions_intf);
  870. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  871. consume(_SEMICOLON);
  872. end;
  873. end;
  874. objectdef :
  875. begin
  876. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  877. consume(_SEMICOLON);
  878. { change a forward and external class declaration into
  879. formal external definition, so the compiler does not
  880. expect an real definition later }
  881. if is_objc_class_or_protocol(hdef) or
  882. is_java_class_or_interface(hdef) then
  883. finalize_class_external_status(tobjectdef(hdef));
  884. { Build VMT indexes, skip for type renaming and forward classes }
  885. if (hdef.typesym=newtype) and
  886. not(oo_is_forward in tobjectdef(hdef).objectoptions) then
  887. begin
  888. vmtbuilder:=TVMTBuilder.Create(tobjectdef(hdef));
  889. vmtbuilder.generate_vmt;
  890. vmtbuilder.free;
  891. end;
  892. { In case of an objcclass, verify that all methods have a message
  893. name set. We only check this now, because message names can be set
  894. during the protocol (interface) mapping. At the same time, set the
  895. mangled names (these depend on the "external" name of the class),
  896. and mark private fields of external classes as "used" (to avoid
  897. bogus notes about them being unused)
  898. }
  899. { watch out for crashes in case of errors }
  900. if is_objc_class_or_protocol(hdef) and
  901. (not is_objccategory(hdef) or
  902. assigned(tobjectdef(hdef).childof)) then
  903. begin
  904. tobjectdef(hdef).finish_objc_data;
  905. tobjectdef(hdef).symtable.DefList.ForEachCall(@pd_set_objc_related_result,nil);
  906. end;
  907. if is_cppclass(hdef) then
  908. tobjectdef(hdef).finish_cpp_data;
  909. end;
  910. recorddef :
  911. begin
  912. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  913. consume(_SEMICOLON);
  914. end;
  915. else
  916. begin
  917. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  918. consume(_SEMICOLON);
  919. end;
  920. end;
  921. end;
  922. if isgeneric and (not(hdef.typ in [objectdef,recorddef,arraydef,procvardef])
  923. or is_objectpascal_helper(hdef)) then
  924. message(parser_e_cant_create_generics_of_this_type);
  925. { Stop recording a generic template }
  926. if assigned(generictypelist) then
  927. begin
  928. current_scanner.stoprecordtokens;
  929. tstoreddef(hdef).generictokenbuf:=generictokenbuf;
  930. { Generic is never a type renaming }
  931. hdef.typesym:=newtype;
  932. generictypelist.free;
  933. end;
  934. if not (m_delphi in current_settings.modeswitches) and
  935. (token=_ID) and (idtoken=_GENERIC) then
  936. begin
  937. had_generic:=true;
  938. consume(_ID);
  939. if token in [_PROCEDURE,_FUNCTION,_CLASS] then
  940. break;
  941. end
  942. else
  943. had_generic:=false;
  944. first:=false;
  945. until (token<>_ID) or
  946. (in_structure and
  947. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  948. ((m_final_fields in current_settings.modeswitches) and
  949. (idtoken=_FINAL))));
  950. { resolve type block forward declarations and restore a unit
  951. container for them }
  952. resolve_forward_types;
  953. current_module.checkforwarddefs.free;
  954. current_module.checkforwarddefs:=old_checkforwarddefs;
  955. block_type:=old_block_type;
  956. end;
  957. { reads a type declaration to the symbol table }
  958. procedure type_dec(out had_generic:boolean);
  959. begin
  960. consume(_TYPE);
  961. types_dec(false,had_generic);
  962. end;
  963. procedure var_dec(out had_generic:boolean);
  964. { parses variable declarations and inserts them in }
  965. { the top symbol table of symtablestack }
  966. begin
  967. consume(_VAR);
  968. read_var_decls([vd_check_generic],had_generic);
  969. end;
  970. procedure property_dec;
  971. { parses a global property (fpc mode feature) }
  972. var
  973. old_block_type: tblock_type;
  974. begin
  975. consume(_PROPERTY);
  976. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  977. message(parser_e_property_only_sgr);
  978. old_block_type:=block_type;
  979. block_type:=bt_const;
  980. repeat
  981. read_property_dec(false, nil);
  982. consume(_SEMICOLON);
  983. until token<>_ID;
  984. block_type:=old_block_type;
  985. end;
  986. procedure threadvar_dec(out had_generic:boolean);
  987. { parses thread variable declarations and inserts them in }
  988. { the top symbol table of symtablestack }
  989. begin
  990. consume(_THREADVAR);
  991. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  992. message(parser_e_threadvars_only_sg);
  993. if f_threading in features then
  994. read_var_decls([vd_threadvar,vd_check_generic],had_generic)
  995. else
  996. begin
  997. Message1(parser_f_unsupported_feature,featurestr[f_threading]);
  998. read_var_decls([vd_check_generic],had_generic);
  999. end;
  1000. end;
  1001. procedure resourcestring_dec(out had_generic:boolean);
  1002. var
  1003. orgname : TIDString;
  1004. p : tnode;
  1005. dummysymoptions : tsymoptions;
  1006. deprecatedmsg : pshortstring;
  1007. storetokenpos,filepos : tfileposinfo;
  1008. old_block_type : tblock_type;
  1009. sp : pchar;
  1010. sym : tsym;
  1011. first,
  1012. isgeneric : boolean;
  1013. begin
  1014. if target_info.system in systems_managed_vm then
  1015. message(parser_e_feature_unsupported_for_vm);
  1016. consume(_RESOURCESTRING);
  1017. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  1018. message(parser_e_resourcestring_only_sg);
  1019. first:=true;
  1020. had_generic:=false;
  1021. old_block_type:=block_type;
  1022. block_type:=bt_const;
  1023. repeat
  1024. orgname:=orgpattern;
  1025. filepos:=current_tokenpos;
  1026. isgeneric:=not (m_delphi in current_settings.modeswitches) and (token=_ID) and (idtoken=_GENERIC);
  1027. consume(_ID);
  1028. case token of
  1029. _EQ:
  1030. begin
  1031. consume(_EQ);
  1032. p:=comp_expr([ef_accept_equal]);
  1033. storetokenpos:=current_tokenpos;
  1034. current_tokenpos:=filepos;
  1035. sym:=nil;
  1036. case p.nodetype of
  1037. ordconstn:
  1038. begin
  1039. if is_constcharnode(p) then
  1040. begin
  1041. getmem(sp,2);
  1042. sp[0]:=chr(tordconstnode(p).value.svalue);
  1043. sp[1]:=#0;
  1044. sym:=cconstsym.create_string(orgname,constresourcestring,sp,1,nil);
  1045. end
  1046. else
  1047. Message(parser_e_illegal_expression);
  1048. end;
  1049. stringconstn:
  1050. with Tstringconstnode(p) do
  1051. begin
  1052. { resourcestrings are currently always single byte }
  1053. if cst_type in [cst_widestring,cst_unicodestring] then
  1054. changestringtype(getansistringdef);
  1055. getmem(sp,len+1);
  1056. move(value_str^,sp^,len+1);
  1057. sym:=cconstsym.create_string(orgname,constresourcestring,sp,len,nil);
  1058. end;
  1059. else
  1060. Message(parser_e_illegal_expression);
  1061. end;
  1062. current_tokenpos:=storetokenpos;
  1063. { Support hint directives }
  1064. dummysymoptions:=[];
  1065. deprecatedmsg:=nil;
  1066. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  1067. if assigned(sym) then
  1068. begin
  1069. sym.symoptions:=sym.symoptions+dummysymoptions;
  1070. sym.deprecatedmsg:=deprecatedmsg;
  1071. symtablestack.top.insert(sym);
  1072. end
  1073. else
  1074. stringdispose(deprecatedmsg);
  1075. consume(_SEMICOLON);
  1076. p.free;
  1077. end;
  1078. else
  1079. if not first and isgeneric and
  1080. (token in [_PROCEDURE, _FUNCTION, _CLASS]) then
  1081. begin
  1082. had_generic:=true;
  1083. break;
  1084. end
  1085. else
  1086. consume(_EQ);
  1087. end;
  1088. first:=false;
  1089. until token<>_ID;
  1090. block_type:=old_block_type;
  1091. end;
  1092. end.