pdecl.pas 43 KB

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