pdecl.pas 45 KB

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