pdecl.pas 45 KB

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