pdecl.pas 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  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. begin
  342. { strip leading 0's in iso mode }
  343. if (([m_iso,m_extpas]*current_settings.modeswitches)<>[]) then
  344. while (length(pattern)>1) and (pattern[1]='0') do
  345. delete(pattern,1,1);
  346. labelsym:=clabelsym.create(pattern);
  347. end;
  348. symtablestack.top.insert(labelsym);
  349. if m_non_local_goto in current_settings.modeswitches then
  350. begin
  351. if symtablestack.top.symtabletype=localsymtable then
  352. begin
  353. labelsym.jumpbuf:=clocalvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  354. symtablestack.top.insert(labelsym.jumpbuf);
  355. end
  356. else
  357. begin
  358. labelsym.jumpbuf:=cstaticvarsym.create('LABEL$_'+labelsym.name,vs_value,rec_jmp_buf,[]);
  359. symtablestack.top.insert(labelsym.jumpbuf);
  360. cnodeutils.insertbssdata(tstaticvarsym(labelsym.jumpbuf));
  361. end;
  362. include(labelsym.jumpbuf.symoptions,sp_internal);
  363. { the buffer will be setup later, but avoid a hint }
  364. tabstractvarsym(labelsym.jumpbuf).varstate:=vs_written;
  365. end;
  366. consume(token);
  367. end;
  368. if token<>_SEMICOLON then consume(_COMMA);
  369. until not(token in [_ID,_INTCONST]);
  370. consume(_SEMICOLON);
  371. end;
  372. { From http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features :
  373. To determine whether a method has an inferred related result type, the first word in the camel-case selector
  374. (e.g., “init” in “initWithObjects”) is considered, and the method will have a related result type if its return
  375. type is compatible with the type of its class and if:
  376. * the first word is "alloc" or "new", and the method is a class method, or
  377. * the first word is "autorelease", "init", "retain", or "self", and the method is an instance method.
  378. If a method with a related result type is overridden by a subclass method, the subclass method must also return
  379. a type that is compatible with the subclass type.
  380. }
  381. procedure pd_set_objc_related_result(def: tobject; para: pointer);
  382. var
  383. pd: tprocdef;
  384. i, firstcamelend: longint;
  385. inferresult: boolean;
  386. begin
  387. if tdef(def).typ<>procdef then
  388. exit;
  389. pd:=tprocdef(def);
  390. if not(po_msgstr in pd.procoptions) then
  391. internalerror(2019082401);
  392. firstcamelend:=length(pd.messageinf.str^);
  393. for i:=1 to length(pd.messageinf.str^) do
  394. if pd.messageinf.str^[i] in ['A'..'Z'] then
  395. begin
  396. firstcamelend:=pred(i);
  397. break;
  398. end;
  399. case copy(pd.messageinf.str^,1,firstcamelend) of
  400. 'alloc',
  401. 'new':
  402. inferresult:=po_classmethod in pd.procoptions;
  403. 'autorelease',
  404. 'init',
  405. 'retain',
  406. 'self':
  407. inferresult:=not(po_classmethod in pd.procoptions);
  408. else
  409. inferresult:=false;
  410. end;
  411. if inferresult and
  412. def_is_related(tdef(pd.procsym.owner.defowner),pd.returndef) then
  413. include(pd.procoptions,po_objc_related_result_type);
  414. end;
  415. procedure types_dec(in_structure: boolean;out had_generic:boolean);
  416. function determine_generic_def(name:tidstring):tstoreddef;
  417. var
  418. hashedid : THashedIDString;
  419. pd : tprocdef;
  420. sym : tsym;
  421. begin
  422. result:=nil;
  423. { check whether this is a declaration of a type inside a
  424. specialization }
  425. if assigned(current_structdef) and
  426. (df_specialization in current_structdef.defoptions) then
  427. begin
  428. if not assigned(current_structdef.genericdef) or
  429. not (current_structdef.genericdef.typ in [recorddef,objectdef]) then
  430. internalerror(2011052301);
  431. hashedid.id:=name;
  432. { we could be inside a method of the specialization
  433. instead of its declaration, so check that first (as
  434. local nested types aren't allowed we don't need to
  435. walk the symtablestack to find the localsymtable) }
  436. if symtablestack.top.symtabletype=localsymtable then
  437. begin
  438. { we are in a method }
  439. if not assigned(symtablestack.top.defowner) or
  440. (symtablestack.top.defowner.typ<>procdef) then
  441. internalerror(2011120701);
  442. pd:=tprocdef(symtablestack.top.defowner);
  443. if not assigned(pd.genericdef) or (pd.genericdef.typ<>procdef) then
  444. internalerror(2011120702);
  445. sym:=tsym(tprocdef(pd.genericdef).localst.findwithhash(hashedid));
  446. end
  447. else
  448. sym:=nil;
  449. if not assigned(sym) or not (sym.typ=typesym) then
  450. begin
  451. { now search in the declaration of the generic }
  452. sym:=tsym(tabstractrecorddef(current_structdef.genericdef).symtable.findwithhash(hashedid));
  453. if not assigned(sym) or not (sym.typ=typesym) then
  454. internalerror(2011052302);
  455. end;
  456. { use the corresponding type in the generic's symtable as
  457. genericdef for the specialized type }
  458. result:=tstoreddef(ttypesym(sym).typedef);
  459. end;
  460. end;
  461. procedure finalize_class_external_status(od: tobjectdef);
  462. begin
  463. if [oo_is_external,oo_is_forward] <= od.objectoptions then
  464. begin
  465. { formal definition: x = objcclass external; }
  466. exclude(od.objectoptions,oo_is_forward);
  467. include(od.objectoptions,oo_is_formal);
  468. end;
  469. end;
  470. var
  471. typename,orgtypename,
  472. gentypename,genorgtypename : TIDString;
  473. newtype : ttypesym;
  474. sym : tsym;
  475. hdef : tdef;
  476. defpos,storetokenpos : tfileposinfo;
  477. old_block_type : tblock_type;
  478. old_checkforwarddefs: TFPObjectList;
  479. objecttype : tobjecttyp;
  480. first,
  481. isgeneric,
  482. isunique,
  483. istyperenaming : boolean;
  484. generictypelist : tfphashobjectlist;
  485. localgenerictokenbuf : tdynamicarray;
  486. vmtbuilder : TVMTBuilder;
  487. p:tnode;
  488. gendef : tstoreddef;
  489. s : shortstring;
  490. i : longint;
  491. {$ifdef x86}
  492. segment_register: string;
  493. {$endif x86}
  494. begin
  495. old_block_type:=block_type;
  496. { save unit container of forward declarations -
  497. we can be inside nested class type block }
  498. old_checkforwarddefs:=current_module.checkforwarddefs;
  499. current_module.checkforwarddefs:=TFPObjectList.Create(false);
  500. block_type:=bt_type;
  501. hdef:=nil;
  502. first:=true;
  503. had_generic:=false;
  504. repeat
  505. defpos:=current_tokenpos;
  506. istyperenaming:=false;
  507. generictypelist:=nil;
  508. localgenerictokenbuf:=nil;
  509. { fpc generic declaration? }
  510. if first then
  511. had_generic:=not(m_delphi in current_settings.modeswitches) and try_to_consume(_GENERIC);
  512. isgeneric:=had_generic;
  513. typename:=pattern;
  514. orgtypename:=orgpattern;
  515. consume(_ID);
  516. { delphi generic declaration? }
  517. if (m_delphi in current_settings.modeswitches) then
  518. isgeneric:=token=_LSHARPBRACKET;
  519. { Generic type declaration? }
  520. if isgeneric then
  521. begin
  522. if assigned(current_genericdef) then
  523. Message(parser_f_no_generic_inside_generic);
  524. consume(_LSHARPBRACKET);
  525. generictypelist:=parse_generic_parameters(true);
  526. consume(_RSHARPBRACKET);
  527. { we are not freeing the type parameters, so register them }
  528. for i:=0 to generictypelist.count-1 do
  529. begin
  530. ttypesym(generictypelist[i]).register_sym;
  531. tstoreddef(ttypesym(generictypelist[i]).typedef).register_def;
  532. end;
  533. str(generictypelist.Count,s);
  534. gentypename:=typename+'$'+s;
  535. genorgtypename:=orgtypename+'$'+s;
  536. end
  537. else
  538. begin
  539. gentypename:=typename;
  540. genorgtypename:=orgtypename;
  541. end;
  542. consume(_EQ);
  543. { support 'ttype=type word' syntax }
  544. isunique:=try_to_consume(_TYPE);
  545. { MacPas object model is more like Delphi's than like TP's, but }
  546. { uses the object keyword instead of class }
  547. if (m_mac in current_settings.modeswitches) and
  548. (token = _OBJECT) then
  549. token := _CLASS;
  550. { Start recording a generic template }
  551. if assigned(generictypelist) then
  552. begin
  553. localgenerictokenbuf:=tdynamicarray.create(256);
  554. current_scanner.startrecordtokens(localgenerictokenbuf);
  555. end;
  556. { is the type already defined? -- must be in the current symtable,
  557. not in a nested symtable or one higher up the stack -> don't
  558. use searchsym & frinds! }
  559. sym:=tsym(symtablestack.top.find(gentypename));
  560. newtype:=nil;
  561. { found a symbol with this name? }
  562. if assigned(sym) then
  563. begin
  564. if (sym.typ=typesym) and
  565. { this should not be a symbol that was created by a generic
  566. that was declared earlier }
  567. not (
  568. (ttypesym(sym).typedef.typ=undefineddef) and
  569. (sp_generic_dummy in sym.symoptions)
  570. ) then
  571. begin
  572. if ((token=_CLASS) or
  573. (token=_INTERFACE) or
  574. (token=_DISPINTERFACE) or
  575. (token=_OBJCCLASS) or
  576. (token=_OBJCPROTOCOL) or
  577. (token=_OBJCCATEGORY)) and
  578. (assigned(ttypesym(sym).typedef)) and
  579. is_implicit_pointer_object_type(ttypesym(sym).typedef) and
  580. (oo_is_forward in tobjectdef(ttypesym(sym).typedef).objectoptions) then
  581. begin
  582. case token of
  583. _CLASS :
  584. objecttype:=default_class_type;
  585. _INTERFACE :
  586. case current_settings.interfacetype of
  587. it_interfacecom:
  588. objecttype:=odt_interfacecom;
  589. it_interfacecorba:
  590. objecttype:=odt_interfacecorba;
  591. it_interfacejava:
  592. objecttype:=odt_interfacejava;
  593. else
  594. internalerror(2010122611);
  595. end;
  596. _DISPINTERFACE :
  597. objecttype:=odt_dispinterface;
  598. _OBJCCLASS,
  599. _OBJCCATEGORY :
  600. objecttype:=odt_objcclass;
  601. _OBJCPROTOCOL :
  602. objecttype:=odt_objcprotocol;
  603. else
  604. internalerror(200811072);
  605. end;
  606. consume(token);
  607. { determine the generic def in case we are in a nested type
  608. of a specialization }
  609. gendef:=determine_generic_def(gentypename);
  610. { we can ignore the result, the definition is modified }
  611. object_dec(objecttype,genorgtypename,newtype,gendef,generictypelist,tobjectdef(ttypesym(sym).typedef),ht_none);
  612. newtype:=ttypesym(sym);
  613. hdef:=newtype.typedef;
  614. end
  615. else
  616. message1(parser_h_type_redef,genorgtypename);
  617. end;
  618. end;
  619. { no old type reused ? Then insert this new type }
  620. if not assigned(newtype) then
  621. begin
  622. { insert the new type first with an errordef, so that
  623. referencing the type before it's really set it
  624. will give an error (PFV) }
  625. hdef:=generrordef;
  626. gendef:=nil;
  627. storetokenpos:=current_tokenpos;
  628. if isgeneric then
  629. begin
  630. { for generics we need to check whether a non-generic type
  631. already exists and if not we need to insert a symbol with
  632. the non-generic name (available in (org)typename) that is a
  633. undefineddef, so that inline specializations can be used }
  634. sym:=tsym(symtablestack.top.Find(typename));
  635. if not assigned(sym) then
  636. begin
  637. sym:=ctypesym.create(orgtypename,cundefineddef.create(true));
  638. Include(sym.symoptions,sp_generic_dummy);
  639. ttypesym(sym).typedef.typesym:=sym;
  640. sym.visibility:=symtablestack.top.currentvisibility;
  641. symtablestack.top.insert(sym);
  642. ttypesym(sym).typedef.owner:=sym.owner;
  643. end
  644. else
  645. { this is not allowed in non-Delphi modes }
  646. if not (m_delphi in current_settings.modeswitches) then
  647. Message1(sym_e_duplicate_id,genorgtypename)
  648. else
  649. begin
  650. { we need to find this symbol even if it's a variable or
  651. something else when doing an inline specialization }
  652. Include(sym.symoptions,sp_generic_dummy);
  653. add_generic_dummysym(sym);
  654. end;
  655. end
  656. else
  657. begin
  658. if assigned(sym) and (sym.typ=typesym) and
  659. (ttypesym(sym).typedef.typ=undefineddef) and
  660. (sp_generic_dummy in sym.symoptions) then
  661. begin
  662. { this is a symbol that was added by an earlier generic
  663. declaration, reuse it }
  664. newtype:=ttypesym(sym);
  665. newtype.typedef:=hdef;
  666. { use the correct casing }
  667. newtype.RealName:=genorgtypename;
  668. sym:=nil;
  669. end;
  670. { determine the generic def in case we are in a nested type
  671. of a specialization }
  672. gendef:=determine_generic_def(gentypename);
  673. end;
  674. { insert a new type if we don't reuse an existing symbol }
  675. if not assigned(newtype) then
  676. begin
  677. newtype:=ctypesym.create(genorgtypename,hdef);
  678. newtype.visibility:=symtablestack.top.currentvisibility;
  679. symtablestack.top.insert(newtype);
  680. end;
  681. current_tokenpos:=defpos;
  682. current_tokenpos:=storetokenpos;
  683. { read the type definition }
  684. read_named_type(hdef,newtype,gendef,generictypelist,false,isunique);
  685. { update the definition of the type }
  686. if assigned(hdef) then
  687. begin
  688. if df_generic in hdef.defoptions then
  689. { flag parent symtables that they now contain a generic }
  690. hdef.owner.includeoption(sto_has_generic);
  691. if assigned(hdef.typesym) then
  692. begin
  693. istyperenaming:=true;
  694. include(newtype.symoptions,sp_explicitrename);
  695. end;
  696. if isunique then
  697. begin
  698. if is_objc_class_or_protocol(hdef) or
  699. is_java_class_or_interface(hdef) then
  700. Message(parser_e_unique_unsupported);
  701. if is_object(hdef) or
  702. is_class_or_interface_or_dispinterface(hdef) then
  703. begin
  704. { just create a child class type; this is
  705. Delphi-compatible }
  706. hdef:=cobjectdef.create(tobjectdef(hdef).objecttype,genorgtypename,tobjectdef(hdef),true);
  707. end
  708. else
  709. begin
  710. hdef:=tstoreddef(hdef).getcopy;
  711. { check if it is an ansistirng(codepage) declaration }
  712. if is_ansistring(hdef) and try_to_consume(_LKLAMMER) then
  713. begin
  714. p:=comp_expr([ef_accept_equal]);
  715. consume(_RKLAMMER);
  716. if not is_constintnode(p) then
  717. begin
  718. Message(parser_e_illegal_expression);
  719. { error recovery }
  720. end
  721. else
  722. begin
  723. if (tordconstnode(p).value<0) or (tordconstnode(p).value>65535) then
  724. begin
  725. Message(parser_e_invalid_codepage);
  726. tordconstnode(p).value:=0;
  727. end;
  728. tstringdef(hdef).encoding:=int64(tordconstnode(p).value);
  729. end;
  730. p.free;
  731. end;
  732. if (hdef.typ in [pointerdef,classrefdef]) and
  733. (tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
  734. current_module.checkforwarddefs.add(hdef);
  735. end;
  736. include(hdef.defoptions,df_unique);
  737. end;
  738. if not assigned(hdef.typesym) then
  739. begin
  740. hdef.typesym:=newtype;
  741. if sp_generic_dummy in newtype.symoptions then
  742. add_generic_dummysym(newtype);
  743. end;
  744. end;
  745. { in non-Delphi modes we need a reference to the generic def
  746. without the generic suffix, so it can be found easily when
  747. parsing method implementations }
  748. if isgeneric and assigned(sym) and
  749. not (m_delphi in current_settings.modeswitches) and
  750. (ttypesym(sym).typedef.typ=undefineddef) then
  751. { don't free the undefineddef as the defids rely on the count
  752. of the defs in the def list of the module}
  753. ttypesym(sym).typedef:=hdef;
  754. newtype.typedef:=hdef;
  755. { ensure that the type is registered when no specialization is
  756. currently done }
  757. if current_scanner.replay_stack_depth=0 then
  758. hdef.register_def;
  759. { KAZ: handle TGUID declaration in system unit }
  760. if (cs_compilesystem in current_settings.moduleswitches) and
  761. assigned(hdef) and
  762. (hdef.typ=recorddef) then
  763. begin
  764. if not assigned(rec_tguid) and
  765. (gentypename='TGUID') and
  766. (hdef.size=16) then
  767. rec_tguid:=trecorddef(hdef)
  768. else if not assigned(rec_jmp_buf) and
  769. (gentypename='JMP_BUF') then
  770. rec_jmp_buf:=trecorddef(hdef)
  771. else if not assigned(rec_exceptaddr) and
  772. (gentypename='TEXCEPTADDR') then
  773. rec_exceptaddr:=trecorddef(hdef);
  774. end;
  775. end;
  776. if assigned(hdef) then
  777. begin
  778. case hdef.typ of
  779. pointerdef :
  780. begin
  781. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  782. consume(_SEMICOLON);
  783. {$ifdef x86}
  784. {$ifdef i8086}
  785. if try_to_consume(_HUGE) then
  786. begin
  787. tcpupointerdef(hdef).x86pointertyp:=x86pt_huge;
  788. consume(_SEMICOLON);
  789. end
  790. else
  791. {$endif i8086}
  792. if try_to_consume(_FAR) then
  793. begin
  794. {$if defined(i8086)}
  795. tcpupointerdef(hdef).x86pointertyp:=x86pt_far;
  796. {$elseif defined(i386)}
  797. tcpupointerdef(hdef).x86pointertyp:=x86pt_near_fs;
  798. {$elseif defined(x86_64)}
  799. { for compatibility with previous versions of fpc,
  800. far pointer = regular pointer on x86_64 }
  801. Message1(parser_w_ptr_type_ignored,'FAR');
  802. {$endif}
  803. consume(_SEMICOLON);
  804. end
  805. else
  806. if try_to_consume(_NEAR) then
  807. begin
  808. if token <> _SEMICOLON then
  809. begin
  810. segment_register:=get_stringconst;
  811. case UpCase(segment_register) of
  812. 'CS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_cs;
  813. 'DS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_ds;
  814. 'SS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_ss;
  815. 'ES': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_es;
  816. 'FS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_fs;
  817. 'GS': tcpupointerdef(hdef).x86pointertyp:=x86pt_near_gs;
  818. else
  819. Message(asmr_e_invalid_register);
  820. end;
  821. end
  822. else
  823. tcpupointerdef(hdef).x86pointertyp:=x86pt_near;
  824. consume(_SEMICOLON);
  825. end;
  826. {$else x86}
  827. { Previous versions of FPC support declaring a pointer as
  828. far even on non-x86 platforms. }
  829. if try_to_consume(_FAR) then
  830. begin
  831. Message1(parser_w_ptr_type_ignored,'FAR');
  832. consume(_SEMICOLON);
  833. end;
  834. {$endif x86}
  835. end;
  836. procvardef :
  837. begin
  838. { in case of type renaming, don't parse proc directives }
  839. if istyperenaming then
  840. begin
  841. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  842. consume(_SEMICOLON);
  843. end
  844. else
  845. begin
  846. if not check_proc_directive(true) then
  847. begin
  848. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  849. consume(_SEMICOLON);
  850. end;
  851. parse_var_proc_directives(tsym(newtype));
  852. if po_is_function_ref in tprocvardef(hdef).procoptions then
  853. begin
  854. { these always support everything, no "of object" or
  855. "is_nested" is allowed }
  856. if is_nested_pd(tprocvardef(hdef)) or
  857. is_methodpointer(hdef) then
  858. cgmessage(type_e_function_reference_kind)
  859. else
  860. begin
  861. { this message is only temporary; once Delphi style anonymous functions
  862. are supported, this check is no longer required }
  863. if not (po_is_block in tprocvardef(hdef).procoptions) then
  864. comment(v_error,'Function references are not yet supported, only C blocks (add "cblock;" at the end)');
  865. end;
  866. end;
  867. handle_calling_convention(tprocvardef(hdef),hcc_default_actions_intf);
  868. if po_is_function_ref in tprocvardef(hdef).procoptions then
  869. begin
  870. if (po_is_block in tprocvardef(hdef).procoptions) and
  871. not (tprocvardef(hdef).proccalloption in [pocall_cdecl,pocall_mwpascal]) then
  872. message(type_e_cblock_callconv);
  873. end;
  874. if try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg) then
  875. consume(_SEMICOLON);
  876. end;
  877. end;
  878. objectdef :
  879. begin
  880. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  881. consume(_SEMICOLON);
  882. { change a forward and external class declaration into
  883. formal external definition, so the compiler does not
  884. expect an real definition later }
  885. if is_objc_class_or_protocol(hdef) or
  886. is_java_class_or_interface(hdef) then
  887. finalize_class_external_status(tobjectdef(hdef));
  888. { Build VMT indexes, skip for type renaming and forward classes }
  889. if (hdef.typesym=newtype) and
  890. not(oo_is_forward in tobjectdef(hdef).objectoptions) then
  891. begin
  892. vmtbuilder:=TVMTBuilder.Create(tobjectdef(hdef));
  893. vmtbuilder.generate_vmt;
  894. vmtbuilder.free;
  895. end;
  896. { In case of an objcclass, verify that all methods have a message
  897. name set. We only check this now, because message names can be set
  898. during the protocol (interface) mapping. At the same time, set the
  899. mangled names (these depend on the "external" name of the class),
  900. and mark private fields of external classes as "used" (to avoid
  901. bogus notes about them being unused)
  902. }
  903. { watch out for crashes in case of errors }
  904. if is_objc_class_or_protocol(hdef) and
  905. (not is_objccategory(hdef) or
  906. assigned(tobjectdef(hdef).childof)) then
  907. begin
  908. tobjectdef(hdef).finish_objc_data;
  909. tobjectdef(hdef).symtable.DefList.ForEachCall(@pd_set_objc_related_result,nil);
  910. end;
  911. if is_cppclass(hdef) then
  912. tobjectdef(hdef).finish_cpp_data;
  913. end;
  914. recorddef :
  915. begin
  916. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  917. consume(_SEMICOLON);
  918. end;
  919. else
  920. begin
  921. try_consume_hintdirective(newtype.symoptions,newtype.deprecatedmsg);
  922. consume(_SEMICOLON);
  923. end;
  924. end;
  925. end;
  926. if isgeneric and (not(hdef.typ in [objectdef,recorddef,arraydef,procvardef])
  927. or is_objectpascal_helper(hdef)) then
  928. message(parser_e_cant_create_generics_of_this_type);
  929. { Stop recording a generic template }
  930. if assigned(generictypelist) then
  931. begin
  932. current_scanner.stoprecordtokens;
  933. tstoreddef(hdef).generictokenbuf:=localgenerictokenbuf;
  934. { Generic is never a type renaming }
  935. hdef.typesym:=newtype;
  936. generictypelist.free;
  937. end;
  938. if not (m_delphi in current_settings.modeswitches) and
  939. (token=_ID) and (idtoken=_GENERIC) then
  940. begin
  941. had_generic:=true;
  942. consume(_ID);
  943. if token in [_PROCEDURE,_FUNCTION,_CLASS] then
  944. break;
  945. end
  946. else
  947. had_generic:=false;
  948. first:=false;
  949. until (token<>_ID) or
  950. (in_structure and
  951. ((idtoken in [_PRIVATE,_PROTECTED,_PUBLIC,_PUBLISHED,_STRICT]) or
  952. ((m_final_fields in current_settings.modeswitches) and
  953. (idtoken=_FINAL))));
  954. { resolve type block forward declarations and restore a unit
  955. container for them }
  956. resolve_forward_types;
  957. current_module.checkforwarddefs.free;
  958. current_module.checkforwarddefs:=old_checkforwarddefs;
  959. block_type:=old_block_type;
  960. end;
  961. { reads a type declaration to the symbol table }
  962. procedure type_dec(out had_generic:boolean);
  963. begin
  964. consume(_TYPE);
  965. types_dec(false,had_generic);
  966. end;
  967. procedure var_dec(out had_generic:boolean);
  968. { parses variable declarations and inserts them in }
  969. { the top symbol table of symtablestack }
  970. begin
  971. consume(_VAR);
  972. read_var_decls([vd_check_generic],had_generic);
  973. end;
  974. procedure property_dec;
  975. { parses a global property (fpc mode feature) }
  976. var
  977. old_block_type: tblock_type;
  978. begin
  979. consume(_PROPERTY);
  980. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  981. message(parser_e_property_only_sgr);
  982. old_block_type:=block_type;
  983. block_type:=bt_const;
  984. repeat
  985. read_property_dec(false, nil);
  986. consume(_SEMICOLON);
  987. until token<>_ID;
  988. block_type:=old_block_type;
  989. end;
  990. procedure threadvar_dec(out had_generic:boolean);
  991. { parses thread variable declarations and inserts them in }
  992. { the top symbol table of symtablestack }
  993. begin
  994. consume(_THREADVAR);
  995. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  996. message(parser_e_threadvars_only_sg);
  997. if f_threading in features then
  998. read_var_decls([vd_threadvar,vd_check_generic],had_generic)
  999. else
  1000. begin
  1001. Message1(parser_f_unsupported_feature,featurestr[f_threading]);
  1002. read_var_decls([vd_check_generic],had_generic);
  1003. end;
  1004. end;
  1005. procedure resourcestring_dec(out had_generic:boolean);
  1006. var
  1007. orgname : TIDString;
  1008. p : tnode;
  1009. dummysymoptions : tsymoptions;
  1010. deprecatedmsg : pshortstring;
  1011. storetokenpos,filepos : tfileposinfo;
  1012. old_block_type : tblock_type;
  1013. sp : pchar;
  1014. sym : tsym;
  1015. first,
  1016. isgeneric : boolean;
  1017. begin
  1018. if target_info.system in systems_managed_vm then
  1019. message(parser_e_feature_unsupported_for_vm);
  1020. consume(_RESOURCESTRING);
  1021. if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
  1022. message(parser_e_resourcestring_only_sg);
  1023. first:=true;
  1024. had_generic:=false;
  1025. old_block_type:=block_type;
  1026. block_type:=bt_const;
  1027. repeat
  1028. orgname:=orgpattern;
  1029. filepos:=current_tokenpos;
  1030. isgeneric:=not (m_delphi in current_settings.modeswitches) and (token=_ID) and (idtoken=_GENERIC);
  1031. consume(_ID);
  1032. case token of
  1033. _EQ:
  1034. begin
  1035. consume(_EQ);
  1036. p:=comp_expr([ef_accept_equal]);
  1037. storetokenpos:=current_tokenpos;
  1038. current_tokenpos:=filepos;
  1039. sym:=nil;
  1040. case p.nodetype of
  1041. ordconstn:
  1042. begin
  1043. if is_constcharnode(p) then
  1044. begin
  1045. getmem(sp,2);
  1046. sp[0]:=chr(tordconstnode(p).value.svalue);
  1047. sp[1]:=#0;
  1048. sym:=cconstsym.create_string(orgname,constresourcestring,sp,1,nil);
  1049. end
  1050. else
  1051. Message(parser_e_illegal_expression);
  1052. end;
  1053. stringconstn:
  1054. with Tstringconstnode(p) do
  1055. begin
  1056. { resourcestrings are currently always single byte }
  1057. if cst_type in [cst_widestring,cst_unicodestring] then
  1058. changestringtype(getansistringdef);
  1059. getmem(sp,len+1);
  1060. move(value_str^,sp^,len+1);
  1061. sym:=cconstsym.create_string(orgname,constresourcestring,sp,len,nil);
  1062. end;
  1063. else
  1064. Message(parser_e_illegal_expression);
  1065. end;
  1066. current_tokenpos:=storetokenpos;
  1067. { Support hint directives }
  1068. dummysymoptions:=[];
  1069. deprecatedmsg:=nil;
  1070. try_consume_hintdirective(dummysymoptions,deprecatedmsg);
  1071. if assigned(sym) then
  1072. begin
  1073. sym.symoptions:=sym.symoptions+dummysymoptions;
  1074. sym.deprecatedmsg:=deprecatedmsg;
  1075. symtablestack.top.insert(sym);
  1076. end
  1077. else
  1078. stringdispose(deprecatedmsg);
  1079. consume(_SEMICOLON);
  1080. p.free;
  1081. end;
  1082. else
  1083. if not first and isgeneric and
  1084. (token in [_PROCEDURE, _FUNCTION, _CLASS]) then
  1085. begin
  1086. had_generic:=true;
  1087. break;
  1088. end
  1089. else
  1090. consume(_EQ);
  1091. end;
  1092. first:=false;
  1093. until token<>_ID;
  1094. block_type:=old_block_type;
  1095. end;
  1096. end.