ParseDecl.cpp revision 234982
1193326Sed//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Declaration portions of the Parser interfaces. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Parse/Parser.h" 15193326Sed#include "clang/Parse/ParseDiagnostic.h" 16221345Sdim#include "clang/Basic/OpenCL.h" 17212904Sdim#include "clang/Sema/Scope.h" 18212904Sdim#include "clang/Sema/ParsedTemplate.h" 19212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h" 20200583Srdivacky#include "RAIIObjectsForParser.h" 21193326Sed#include "llvm/ADT/SmallSet.h" 22234353Sdim#include "llvm/ADT/SmallString.h" 23226633Sdim#include "llvm/ADT/StringSwitch.h" 24193326Sedusing namespace clang; 25193326Sed 26193326Sed//===----------------------------------------------------------------------===// 27193326Sed// C99 6.7: Declarations. 28193326Sed//===----------------------------------------------------------------------===// 29193326Sed 30193326Sed/// ParseTypeName 31193326Sed/// type-name: [C99 6.7.6] 32193326Sed/// specifier-qualifier-list abstract-declarator[opt] 33193326Sed/// 34193326Sed/// Called type-id in C++. 35218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range, 36224145Sdim Declarator::TheContext Context, 37224145Sdim AccessSpecifier AS, 38224145Sdim Decl **OwnedType) { 39234353Sdim DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context); 40234353Sdim 41193326Sed // Parse the common declaration-specifiers piece. 42221345Sdim DeclSpec DS(AttrFactory); 43234353Sdim ParseSpecifierQualifierList(DS, AS, DSC); 44224145Sdim if (OwnedType) 45224145Sdim *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; 46193326Sed 47193326Sed // Parse the abstract-declarator, if present. 48218893Sdim Declarator DeclaratorInfo(DS, Context); 49193326Sed ParseDeclarator(DeclaratorInfo); 50193326Sed if (Range) 51193326Sed *Range = DeclaratorInfo.getSourceRange(); 52193326Sed 53193326Sed if (DeclaratorInfo.isInvalidType()) 54193326Sed return true; 55193326Sed 56210299Sed return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 57193326Sed} 58193326Sed 59226633Sdim 60226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that 61226633Sdim/// require late parsing. 62226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) { 63226633Sdim return llvm::StringSwitch<bool>(II.getName()) 64226633Sdim#include "clang/Parse/AttrLateParsed.inc" 65226633Sdim .Default(false); 66226633Sdim} 67226633Sdim 68226633Sdim 69199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list. 70193326Sed/// 71193326Sed/// [GNU] attributes: 72193326Sed/// attribute 73193326Sed/// attributes attribute 74193326Sed/// 75193326Sed/// [GNU] attribute: 76193326Sed/// '__attribute__' '(' '(' attribute-list ')' ')' 77193326Sed/// 78193326Sed/// [GNU] attribute-list: 79193326Sed/// attrib 80193326Sed/// attribute_list ',' attrib 81193326Sed/// 82193326Sed/// [GNU] attrib: 83193326Sed/// empty 84193326Sed/// attrib-name 85193326Sed/// attrib-name '(' identifier ')' 86193326Sed/// attrib-name '(' identifier ',' nonempty-expr-list ')' 87193326Sed/// attrib-name '(' argument-expression-list [C99 6.5.2] ')' 88193326Sed/// 89193326Sed/// [GNU] attrib-name: 90193326Sed/// identifier 91193326Sed/// typespec 92193326Sed/// typequal 93193326Sed/// storageclass 94198092Srdivacky/// 95193326Sed/// FIXME: The GCC grammar/code for this construct implies we need two 96198092Srdivacky/// token lookahead. Comment from gcc: "If they start with an identifier 97198092Srdivacky/// which is followed by a comma or close parenthesis, then the arguments 98193326Sed/// start with that identifier; otherwise they are an expression list." 99193326Sed/// 100234353Sdim/// GCC does not require the ',' between attribs in an attribute-list. 101234353Sdim/// 102193326Sed/// At the moment, I am not doing 2 token lookahead. I am also unaware of 103193326Sed/// any attributes that don't work (based on my limited testing). Most 104193326Sed/// attributes are very simple in practice. Until we find a bug, I don't see 105193326Sed/// a pressing need to implement the 2 token lookahead. 106193326Sed 107218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs, 108226633Sdim SourceLocation *endLoc, 109226633Sdim LateParsedAttrList *LateAttrs) { 110199990Srdivacky assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); 111198092Srdivacky 112193326Sed while (Tok.is(tok::kw___attribute)) { 113193326Sed ConsumeToken(); 114193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 115193326Sed "attribute")) { 116193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 117218893Sdim return; 118193326Sed } 119193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { 120193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 121218893Sdim return; 122193326Sed } 123193326Sed // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) 124193326Sed while (Tok.is(tok::identifier) || isDeclarationSpecifier() || 125193326Sed Tok.is(tok::comma)) { 126198092Srdivacky if (Tok.is(tok::comma)) { 127193326Sed // allows for empty/non-empty attributes. ((__vector_size__(16),,,,)) 128193326Sed ConsumeToken(); 129193326Sed continue; 130193326Sed } 131193326Sed // we have an identifier or declaration specifier (const, int, etc.) 132193326Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 133193326Sed SourceLocation AttrNameLoc = ConsumeToken(); 134198092Srdivacky 135226633Sdim if (Tok.is(tok::l_paren)) { 136226633Sdim // handle "parameterized" attributes 137234353Sdim if (LateAttrs && isAttributeLateParsed(*AttrName)) { 138226633Sdim LateParsedAttribute *LA = 139226633Sdim new LateParsedAttribute(this, *AttrName, AttrNameLoc); 140226633Sdim LateAttrs->push_back(LA); 141198092Srdivacky 142234353Sdim // Attributes in a class are parsed at the end of the class, along 143234353Sdim // with other late-parsed declarations. 144234353Sdim if (!ClassStack.empty()) 145234353Sdim getCurrentClass().LateParsedDeclarations.push_back(LA); 146234353Sdim 147226633Sdim // consume everything up to and including the matching right parens 148226633Sdim ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false); 149198092Srdivacky 150226633Sdim Token Eof; 151226633Sdim Eof.startToken(); 152226633Sdim Eof.setLocation(Tok.getLocation()); 153226633Sdim LA->Toks.push_back(Eof); 154226633Sdim } else { 155226633Sdim ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc); 156193326Sed } 157193326Sed } else { 158221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 159221345Sdim 0, SourceLocation(), 0, 0); 160193326Sed } 161193326Sed } 162193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 163193326Sed SkipUntil(tok::r_paren, false); 164199990Srdivacky SourceLocation Loc = Tok.getLocation(); 165193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 166193326Sed SkipUntil(tok::r_paren, false); 167193326Sed } 168218893Sdim if (endLoc) 169218893Sdim *endLoc = Loc; 170193326Sed } 171193326Sed} 172193326Sed 173226633Sdim 174226633Sdim/// Parse the arguments to a parameterized GNU attribute 175226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, 176226633Sdim SourceLocation AttrNameLoc, 177226633Sdim ParsedAttributes &Attrs, 178226633Sdim SourceLocation *EndLoc) { 179226633Sdim 180226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 181226633Sdim 182226633Sdim // Availability attributes have their own grammar. 183226633Sdim if (AttrName->isStr("availability")) { 184226633Sdim ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 185226633Sdim return; 186226633Sdim } 187226633Sdim // Thread safety attributes fit into the FIXME case above, so we 188226633Sdim // just parse the arguments as a list of expressions 189226633Sdim if (IsThreadSafetyAttribute(AttrName->getName())) { 190226633Sdim ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 191226633Sdim return; 192226633Sdim } 193226633Sdim 194226633Sdim ConsumeParen(); // ignore the left paren loc for now 195226633Sdim 196234353Sdim IdentifierInfo *ParmName = 0; 197234353Sdim SourceLocation ParmLoc; 198234353Sdim bool BuiltinType = false; 199226633Sdim 200234353Sdim switch (Tok.getKind()) { 201234353Sdim case tok::kw_char: 202234353Sdim case tok::kw_wchar_t: 203234353Sdim case tok::kw_char16_t: 204234353Sdim case tok::kw_char32_t: 205234353Sdim case tok::kw_bool: 206234353Sdim case tok::kw_short: 207234353Sdim case tok::kw_int: 208234353Sdim case tok::kw_long: 209234353Sdim case tok::kw___int64: 210234353Sdim case tok::kw___int128: 211234353Sdim case tok::kw_signed: 212234353Sdim case tok::kw_unsigned: 213234353Sdim case tok::kw_float: 214234353Sdim case tok::kw_double: 215234353Sdim case tok::kw_void: 216234353Sdim case tok::kw_typeof: 217234353Sdim // __attribute__(( vec_type_hint(char) )) 218234353Sdim // FIXME: Don't just discard the builtin type token. 219234353Sdim ConsumeToken(); 220234353Sdim BuiltinType = true; 221234353Sdim break; 222234353Sdim 223234353Sdim case tok::identifier: 224234353Sdim ParmName = Tok.getIdentifierInfo(); 225234353Sdim ParmLoc = ConsumeToken(); 226234353Sdim break; 227234353Sdim 228234353Sdim default: 229234353Sdim break; 230234353Sdim } 231234353Sdim 232234353Sdim ExprVector ArgExprs(Actions); 233234353Sdim 234234353Sdim if (!BuiltinType && 235234353Sdim (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) { 236234353Sdim // Eat the comma. 237234353Sdim if (ParmLoc.isValid()) 238226633Sdim ConsumeToken(); 239226633Sdim 240234353Sdim // Parse the non-empty comma-separated list of expressions. 241234353Sdim while (1) { 242234353Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 243234353Sdim if (ArgExpr.isInvalid()) { 244234353Sdim SkipUntil(tok::r_paren); 245234353Sdim return; 246226633Sdim } 247234353Sdim ArgExprs.push_back(ArgExpr.release()); 248234353Sdim if (Tok.isNot(tok::comma)) 249234353Sdim break; 250234353Sdim ConsumeToken(); // Eat the comma, move to the next argument 251226633Sdim } 252234353Sdim } 253234353Sdim else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) { 254234353Sdim if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<", 255234353Sdim tok::greater)) { 256234353Sdim while (Tok.is(tok::identifier)) { 257234353Sdim ConsumeToken(); 258234353Sdim if (Tok.is(tok::greater)) 259226633Sdim break; 260234353Sdim if (Tok.is(tok::comma)) { 261234353Sdim ConsumeToken(); 262234353Sdim continue; 263226633Sdim } 264226633Sdim } 265234353Sdim if (Tok.isNot(tok::greater)) 266234353Sdim Diag(Tok, diag::err_iboutletcollection_with_protocol); 267234353Sdim SkipUntil(tok::r_paren, false, true); // skip until ')' 268226633Sdim } 269226633Sdim } 270234353Sdim 271234353Sdim SourceLocation RParen = Tok.getLocation(); 272234353Sdim if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 273234353Sdim AttributeList *attr = 274234353Sdim Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc, 275234353Sdim ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size()); 276234353Sdim if (BuiltinType && attr->getKind() == AttributeList::AT_iboutletcollection) 277234353Sdim Diag(Tok, diag::err_iboutletcollection_builtintype); 278234353Sdim } 279226633Sdim} 280226633Sdim 281226633Sdim 282193725Sed/// ParseMicrosoftDeclSpec - Parse an __declspec construct 283193725Sed/// 284193725Sed/// [MS] decl-specifier: 285193725Sed/// __declspec ( extended-decl-modifier-seq ) 286193725Sed/// 287193725Sed/// [MS] extended-decl-modifier-seq: 288193725Sed/// extended-decl-modifier[opt] 289193725Sed/// extended-decl-modifier extended-decl-modifier-seq 290193725Sed 291218893Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) { 292193326Sed assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); 293193725Sed 294193326Sed ConsumeToken(); 295193725Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 296193725Sed "declspec")) { 297193725Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 298218893Sdim return; 299193725Sed } 300223017Sdim 301194179Sed while (Tok.getIdentifierInfo()) { 302193725Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 303193725Sed SourceLocation AttrNameLoc = ConsumeToken(); 304223017Sdim 305223017Sdim // FIXME: Remove this when we have proper __declspec(property()) support. 306223017Sdim // Just skip everything inside property(). 307223017Sdim if (AttrName->getName() == "property") { 308223017Sdim ConsumeParen(); 309223017Sdim SkipUntil(tok::r_paren); 310223017Sdim } 311193725Sed if (Tok.is(tok::l_paren)) { 312193725Sed ConsumeParen(); 313193725Sed // FIXME: This doesn't parse __declspec(property(get=get_func_name)) 314193725Sed // correctly. 315212904Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 316193725Sed if (!ArgExpr.isInvalid()) { 317212904Sdim Expr *ExprList = ArgExpr.take(); 318221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 319221345Sdim SourceLocation(), &ExprList, 1, true); 320193725Sed } 321193725Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 322193725Sed SkipUntil(tok::r_paren, false); 323193725Sed } else { 324221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 325221345Sdim 0, SourceLocation(), 0, 0, true); 326193725Sed } 327193725Sed } 328193725Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 329193725Sed SkipUntil(tok::r_paren, false); 330218893Sdim return; 331193326Sed} 332193326Sed 333218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { 334194179Sed // Treat these like attributes 335194179Sed // FIXME: Allow Sema to distinguish between these and real attributes! 336194179Sed while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || 337208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || 338226633Sdim Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 339226633Sdim Tok.is(tok::kw___ptr32) || 340226633Sdim Tok.is(tok::kw___unaligned)) { 341194179Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 342194179Sed SourceLocation AttrNameLoc = ConsumeToken(); 343226633Sdim if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 344226633Sdim Tok.is(tok::kw___ptr32)) 345194179Sed // FIXME: Support these properly! 346194179Sed continue; 347221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 348221345Sdim SourceLocation(), 0, 0, true); 349194179Sed } 350194179Sed} 351194179Sed 352218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { 353212904Sdim // Treat these like attributes 354212904Sdim while (Tok.is(tok::kw___pascal)) { 355212904Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 356212904Sdim SourceLocation AttrNameLoc = ConsumeToken(); 357221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 358221345Sdim SourceLocation(), 0, 0, true); 359212904Sdim } 360212904Sdim} 361212904Sdim 362218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { 363218893Sdim // Treat these like attributes 364218893Sdim while (Tok.is(tok::kw___kernel)) { 365218893Sdim SourceLocation AttrNameLoc = ConsumeToken(); 366221345Sdim attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"), 367221345Sdim AttrNameLoc, 0, AttrNameLoc, 0, 368221345Sdim SourceLocation(), 0, 0, false); 369218893Sdim } 370218893Sdim} 371218893Sdim 372221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) { 373221345Sdim SourceLocation Loc = Tok.getLocation(); 374221345Sdim switch(Tok.getKind()) { 375221345Sdim // OpenCL qualifiers: 376221345Sdim case tok::kw___private: 377221345Sdim case tok::kw_private: 378221345Sdim DS.getAttributes().addNewInteger( 379221345Sdim Actions.getASTContext(), 380221345Sdim PP.getIdentifierInfo("address_space"), Loc, 0); 381221345Sdim break; 382221345Sdim 383221345Sdim case tok::kw___global: 384221345Sdim DS.getAttributes().addNewInteger( 385221345Sdim Actions.getASTContext(), 386221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global); 387221345Sdim break; 388221345Sdim 389221345Sdim case tok::kw___local: 390221345Sdim DS.getAttributes().addNewInteger( 391221345Sdim Actions.getASTContext(), 392221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local); 393221345Sdim break; 394221345Sdim 395221345Sdim case tok::kw___constant: 396221345Sdim DS.getAttributes().addNewInteger( 397221345Sdim Actions.getASTContext(), 398221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant); 399221345Sdim break; 400221345Sdim 401221345Sdim case tok::kw___read_only: 402221345Sdim DS.getAttributes().addNewInteger( 403221345Sdim Actions.getASTContext(), 404221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only); 405221345Sdim break; 406221345Sdim 407221345Sdim case tok::kw___write_only: 408221345Sdim DS.getAttributes().addNewInteger( 409221345Sdim Actions.getASTContext(), 410221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only); 411221345Sdim break; 412221345Sdim 413221345Sdim case tok::kw___read_write: 414221345Sdim DS.getAttributes().addNewInteger( 415221345Sdim Actions.getASTContext(), 416221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write); 417221345Sdim break; 418221345Sdim default: break; 419221345Sdim } 420221345Sdim} 421221345Sdim 422221345Sdim/// \brief Parse a version number. 423221345Sdim/// 424221345Sdim/// version: 425221345Sdim/// simple-integer 426221345Sdim/// simple-integer ',' simple-integer 427221345Sdim/// simple-integer ',' simple-integer ',' simple-integer 428221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) { 429221345Sdim Range = Tok.getLocation(); 430221345Sdim 431221345Sdim if (!Tok.is(tok::numeric_constant)) { 432221345Sdim Diag(Tok, diag::err_expected_version); 433221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 434221345Sdim return VersionTuple(); 435221345Sdim } 436221345Sdim 437221345Sdim // Parse the major (and possibly minor and subminor) versions, which 438221345Sdim // are stored in the numeric constant. We utilize a quirk of the 439221345Sdim // lexer, which is that it handles something like 1.2.3 as a single 440221345Sdim // numeric constant, rather than two separate tokens. 441234353Sdim SmallString<512> Buffer; 442221345Sdim Buffer.resize(Tok.getLength()+1); 443221345Sdim const char *ThisTokBegin = &Buffer[0]; 444221345Sdim 445221345Sdim // Get the spelling of the token, which eliminates trigraphs, etc. 446221345Sdim bool Invalid = false; 447221345Sdim unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid); 448221345Sdim if (Invalid) 449221345Sdim return VersionTuple(); 450221345Sdim 451221345Sdim // Parse the major version. 452221345Sdim unsigned AfterMajor = 0; 453221345Sdim unsigned Major = 0; 454221345Sdim while (AfterMajor < ActualLength && isdigit(ThisTokBegin[AfterMajor])) { 455221345Sdim Major = Major * 10 + ThisTokBegin[AfterMajor] - '0'; 456221345Sdim ++AfterMajor; 457221345Sdim } 458221345Sdim 459221345Sdim if (AfterMajor == 0) { 460221345Sdim Diag(Tok, diag::err_expected_version); 461221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 462221345Sdim return VersionTuple(); 463221345Sdim } 464221345Sdim 465221345Sdim if (AfterMajor == ActualLength) { 466221345Sdim ConsumeToken(); 467221345Sdim 468221345Sdim // We only had a single version component. 469221345Sdim if (Major == 0) { 470221345Sdim Diag(Tok, diag::err_zero_version); 471221345Sdim return VersionTuple(); 472221345Sdim } 473221345Sdim 474221345Sdim return VersionTuple(Major); 475221345Sdim } 476221345Sdim 477221345Sdim if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { 478221345Sdim Diag(Tok, diag::err_expected_version); 479221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 480221345Sdim return VersionTuple(); 481221345Sdim } 482221345Sdim 483221345Sdim // Parse the minor version. 484221345Sdim unsigned AfterMinor = AfterMajor + 1; 485221345Sdim unsigned Minor = 0; 486221345Sdim while (AfterMinor < ActualLength && isdigit(ThisTokBegin[AfterMinor])) { 487221345Sdim Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0'; 488221345Sdim ++AfterMinor; 489221345Sdim } 490221345Sdim 491221345Sdim if (AfterMinor == ActualLength) { 492221345Sdim ConsumeToken(); 493221345Sdim 494221345Sdim // We had major.minor. 495221345Sdim if (Major == 0 && Minor == 0) { 496221345Sdim Diag(Tok, diag::err_zero_version); 497221345Sdim return VersionTuple(); 498221345Sdim } 499221345Sdim 500221345Sdim return VersionTuple(Major, Minor); 501221345Sdim } 502221345Sdim 503221345Sdim // If what follows is not a '.', we have a problem. 504221345Sdim if (ThisTokBegin[AfterMinor] != '.') { 505221345Sdim Diag(Tok, diag::err_expected_version); 506221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 507221345Sdim return VersionTuple(); 508221345Sdim } 509221345Sdim 510221345Sdim // Parse the subminor version. 511221345Sdim unsigned AfterSubminor = AfterMinor + 1; 512221345Sdim unsigned Subminor = 0; 513221345Sdim while (AfterSubminor < ActualLength && isdigit(ThisTokBegin[AfterSubminor])) { 514221345Sdim Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0'; 515221345Sdim ++AfterSubminor; 516221345Sdim } 517221345Sdim 518221345Sdim if (AfterSubminor != ActualLength) { 519221345Sdim Diag(Tok, diag::err_expected_version); 520221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 521221345Sdim return VersionTuple(); 522221345Sdim } 523221345Sdim ConsumeToken(); 524221345Sdim return VersionTuple(Major, Minor, Subminor); 525221345Sdim} 526221345Sdim 527221345Sdim/// \brief Parse the contents of the "availability" attribute. 528221345Sdim/// 529221345Sdim/// availability-attribute: 530234353Sdim/// 'availability' '(' platform ',' version-arg-list, opt-message')' 531221345Sdim/// 532221345Sdim/// platform: 533221345Sdim/// identifier 534221345Sdim/// 535221345Sdim/// version-arg-list: 536221345Sdim/// version-arg 537221345Sdim/// version-arg ',' version-arg-list 538221345Sdim/// 539221345Sdim/// version-arg: 540221345Sdim/// 'introduced' '=' version 541221345Sdim/// 'deprecated' '=' version 542234353Sdim/// 'obsoleted' = version 543221345Sdim/// 'unavailable' 544234353Sdim/// opt-message: 545234353Sdim/// 'message' '=' <string> 546221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, 547221345Sdim SourceLocation AvailabilityLoc, 548221345Sdim ParsedAttributes &attrs, 549221345Sdim SourceLocation *endLoc) { 550221345Sdim SourceLocation PlatformLoc; 551221345Sdim IdentifierInfo *Platform = 0; 552221345Sdim 553221345Sdim enum { Introduced, Deprecated, Obsoleted, Unknown }; 554221345Sdim AvailabilityChange Changes[Unknown]; 555234353Sdim ExprResult MessageExpr; 556221345Sdim 557221345Sdim // Opening '('. 558226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 559226633Sdim if (T.consumeOpen()) { 560221345Sdim Diag(Tok, diag::err_expected_lparen); 561221345Sdim return; 562221345Sdim } 563221345Sdim 564221345Sdim // Parse the platform name, 565221345Sdim if (Tok.isNot(tok::identifier)) { 566221345Sdim Diag(Tok, diag::err_availability_expected_platform); 567221345Sdim SkipUntil(tok::r_paren); 568221345Sdim return; 569221345Sdim } 570221345Sdim Platform = Tok.getIdentifierInfo(); 571221345Sdim PlatformLoc = ConsumeToken(); 572221345Sdim 573221345Sdim // Parse the ',' following the platform name. 574221345Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) 575221345Sdim return; 576221345Sdim 577221345Sdim // If we haven't grabbed the pointers for the identifiers 578221345Sdim // "introduced", "deprecated", and "obsoleted", do so now. 579221345Sdim if (!Ident_introduced) { 580221345Sdim Ident_introduced = PP.getIdentifierInfo("introduced"); 581221345Sdim Ident_deprecated = PP.getIdentifierInfo("deprecated"); 582221345Sdim Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); 583221345Sdim Ident_unavailable = PP.getIdentifierInfo("unavailable"); 584234353Sdim Ident_message = PP.getIdentifierInfo("message"); 585221345Sdim } 586221345Sdim 587221345Sdim // Parse the set of introductions/deprecations/removals. 588221345Sdim SourceLocation UnavailableLoc; 589221345Sdim do { 590221345Sdim if (Tok.isNot(tok::identifier)) { 591221345Sdim Diag(Tok, diag::err_availability_expected_change); 592221345Sdim SkipUntil(tok::r_paren); 593221345Sdim return; 594221345Sdim } 595221345Sdim IdentifierInfo *Keyword = Tok.getIdentifierInfo(); 596221345Sdim SourceLocation KeywordLoc = ConsumeToken(); 597221345Sdim 598221345Sdim if (Keyword == Ident_unavailable) { 599221345Sdim if (UnavailableLoc.isValid()) { 600221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 601221345Sdim << Keyword << SourceRange(UnavailableLoc); 602221345Sdim } 603221345Sdim UnavailableLoc = KeywordLoc; 604221345Sdim 605221345Sdim if (Tok.isNot(tok::comma)) 606221345Sdim break; 607221345Sdim 608221345Sdim ConsumeToken(); 609221345Sdim continue; 610221345Sdim } 611234353Sdim 612221345Sdim if (Tok.isNot(tok::equal)) { 613221345Sdim Diag(Tok, diag::err_expected_equal_after) 614221345Sdim << Keyword; 615221345Sdim SkipUntil(tok::r_paren); 616221345Sdim return; 617221345Sdim } 618221345Sdim ConsumeToken(); 619234353Sdim if (Keyword == Ident_message) { 620234353Sdim if (!isTokenStringLiteral()) { 621234353Sdim Diag(Tok, diag::err_expected_string_literal); 622234353Sdim SkipUntil(tok::r_paren); 623234353Sdim return; 624234353Sdim } 625234353Sdim MessageExpr = ParseStringLiteralExpression(); 626234353Sdim break; 627234353Sdim } 628221345Sdim 629221345Sdim SourceRange VersionRange; 630221345Sdim VersionTuple Version = ParseVersionTuple(VersionRange); 631221345Sdim 632221345Sdim if (Version.empty()) { 633221345Sdim SkipUntil(tok::r_paren); 634221345Sdim return; 635221345Sdim } 636221345Sdim 637221345Sdim unsigned Index; 638221345Sdim if (Keyword == Ident_introduced) 639221345Sdim Index = Introduced; 640221345Sdim else if (Keyword == Ident_deprecated) 641221345Sdim Index = Deprecated; 642221345Sdim else if (Keyword == Ident_obsoleted) 643221345Sdim Index = Obsoleted; 644221345Sdim else 645221345Sdim Index = Unknown; 646221345Sdim 647221345Sdim if (Index < Unknown) { 648221345Sdim if (!Changes[Index].KeywordLoc.isInvalid()) { 649221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 650221345Sdim << Keyword 651221345Sdim << SourceRange(Changes[Index].KeywordLoc, 652221345Sdim Changes[Index].VersionRange.getEnd()); 653221345Sdim } 654221345Sdim 655221345Sdim Changes[Index].KeywordLoc = KeywordLoc; 656221345Sdim Changes[Index].Version = Version; 657221345Sdim Changes[Index].VersionRange = VersionRange; 658221345Sdim } else { 659221345Sdim Diag(KeywordLoc, diag::err_availability_unknown_change) 660221345Sdim << Keyword << VersionRange; 661221345Sdim } 662221345Sdim 663221345Sdim if (Tok.isNot(tok::comma)) 664221345Sdim break; 665221345Sdim 666221345Sdim ConsumeToken(); 667221345Sdim } while (true); 668221345Sdim 669221345Sdim // Closing ')'. 670226633Sdim if (T.consumeClose()) 671221345Sdim return; 672221345Sdim 673221345Sdim if (endLoc) 674226633Sdim *endLoc = T.getCloseLocation(); 675221345Sdim 676221345Sdim // The 'unavailable' availability cannot be combined with any other 677221345Sdim // availability changes. Make sure that hasn't happened. 678221345Sdim if (UnavailableLoc.isValid()) { 679221345Sdim bool Complained = false; 680221345Sdim for (unsigned Index = Introduced; Index != Unknown; ++Index) { 681221345Sdim if (Changes[Index].KeywordLoc.isValid()) { 682221345Sdim if (!Complained) { 683221345Sdim Diag(UnavailableLoc, diag::warn_availability_and_unavailable) 684221345Sdim << SourceRange(Changes[Index].KeywordLoc, 685221345Sdim Changes[Index].VersionRange.getEnd()); 686221345Sdim Complained = true; 687221345Sdim } 688221345Sdim 689221345Sdim // Clear out the availability. 690221345Sdim Changes[Index] = AvailabilityChange(); 691221345Sdim } 692221345Sdim } 693221345Sdim } 694221345Sdim 695221345Sdim // Record this attribute 696226633Sdim attrs.addNew(&Availability, 697226633Sdim SourceRange(AvailabilityLoc, T.getCloseLocation()), 698234353Sdim 0, AvailabilityLoc, 699221345Sdim Platform, PlatformLoc, 700221345Sdim Changes[Introduced], 701221345Sdim Changes[Deprecated], 702221345Sdim Changes[Obsoleted], 703234353Sdim UnavailableLoc, MessageExpr.take(), 704234353Sdim false, false); 705221345Sdim} 706221345Sdim 707226633Sdim 708226633Sdim// Late Parsed Attributes: 709226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods 710226633Sdim 711226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {} 712226633Sdim 713226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() { 714226633Sdim Self->ParseLexedAttributes(*Class); 715226633Sdim} 716226633Sdim 717226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() { 718234353Sdim Self->ParseLexedAttribute(*this, true, false); 719226633Sdim} 720226633Sdim 721226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the 722226633Sdim/// scope appropriately. 723226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) { 724226633Sdim // Deal with templates 725226633Sdim // FIXME: Test cases to make sure this does the right thing for templates. 726226633Sdim bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 727226633Sdim ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 728226633Sdim HasTemplateScope); 729226633Sdim if (HasTemplateScope) 730226633Sdim Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 731226633Sdim 732234982Sdim // Set or update the scope flags. 733226633Sdim bool AlreadyHasClassScope = Class.TopLevelClass; 734234982Sdim unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; 735226633Sdim ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 736226633Sdim ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 737226633Sdim 738234353Sdim // Enter the scope of nested classes 739234353Sdim if (!AlreadyHasClassScope) 740234353Sdim Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 741234353Sdim Class.TagOrTemplate); 742234982Sdim { 743234982Sdim // Allow 'this' within late-parsed attributes. 744234982Sdim Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, 745234982Sdim /*TypeQuals=*/0); 746234982Sdim 747234982Sdim for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ 748234982Sdim Class.LateParsedDeclarations[i]->ParseLexedAttributes(); 749234982Sdim } 750226633Sdim } 751234982Sdim 752234353Sdim if (!AlreadyHasClassScope) 753234353Sdim Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 754234353Sdim Class.TagOrTemplate); 755226633Sdim} 756226633Sdim 757234353Sdim 758234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D. 759234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 760234353Sdim bool EnterScope, bool OnDefinition) { 761234353Sdim for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 762234353Sdim LAs[i]->addDecl(D); 763234353Sdim ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 764234982Sdim delete LAs[i]; 765234353Sdim } 766234353Sdim LAs.clear(); 767234353Sdim} 768234353Sdim 769234353Sdim 770226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed. 771226633Sdim/// This will be called at the end of parsing a class declaration 772226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and 773226633Sdim/// create an attribute with the arguments filled in. We add this 774226633Sdim/// to the Attribute list for the decl. 775234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA, 776234353Sdim bool EnterScope, bool OnDefinition) { 777226633Sdim // Save the current token position. 778226633Sdim SourceLocation OrigLoc = Tok.getLocation(); 779226633Sdim 780226633Sdim // Append the current token at the end of the new token stream so that it 781226633Sdim // doesn't get lost. 782226633Sdim LA.Toks.push_back(Tok); 783226633Sdim PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); 784226633Sdim // Consume the previously pushed token. 785226633Sdim ConsumeAnyToken(); 786226633Sdim 787234353Sdim if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) { 788234353Sdim Diag(Tok, diag::warn_attribute_on_function_definition) 789234353Sdim << LA.AttrName.getName(); 790234353Sdim } 791234353Sdim 792226633Sdim ParsedAttributes Attrs(AttrFactory); 793226633Sdim SourceLocation endLoc; 794226633Sdim 795234353Sdim if (LA.Decls.size() == 1) { 796234353Sdim Decl *D = LA.Decls[0]; 797226633Sdim 798234353Sdim // If the Decl is templatized, add template parameters to scope. 799234353Sdim bool HasTemplateScope = EnterScope && D->isTemplateDecl(); 800234353Sdim ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); 801234353Sdim if (HasTemplateScope) 802234353Sdim Actions.ActOnReenterTemplateScope(Actions.CurScope, D); 803226633Sdim 804234353Sdim // If the Decl is on a function, add function parameters to the scope. 805234353Sdim bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate(); 806234353Sdim ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope); 807234353Sdim if (HasFunctionScope) 808234353Sdim Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 809226633Sdim 810234353Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); 811234353Sdim 812234353Sdim if (HasFunctionScope) { 813234353Sdim Actions.ActOnExitFunctionContext(); 814234353Sdim FnScope.Exit(); // Pop scope, and remove Decls from IdResolver 815234353Sdim } 816234353Sdim if (HasTemplateScope) { 817234353Sdim TempScope.Exit(); 818234353Sdim } 819234353Sdim } else if (LA.Decls.size() > 0) { 820234353Sdim // If there are multiple decls, then the decl cannot be within the 821234353Sdim // function scope. 822234353Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); 823234353Sdim } else { 824234353Sdim Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 825226633Sdim } 826234353Sdim 827234353Sdim for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) { 828234353Sdim Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 829226633Sdim } 830226633Sdim 831226633Sdim if (Tok.getLocation() != OrigLoc) { 832226633Sdim // Due to a parsing error, we either went over the cached tokens or 833226633Sdim // there are still cached tokens left, so we skip the leftover tokens. 834226633Sdim // Since this is an uncommon situation that should be avoided, use the 835226633Sdim // expensive isBeforeInTranslationUnit call. 836226633Sdim if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 837226633Sdim OrigLoc)) 838226633Sdim while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 839234353Sdim ConsumeAnyToken(); 840226633Sdim } 841226633Sdim} 842226633Sdim 843226633Sdim/// \brief Wrapper around a case statement checking if AttrName is 844226633Sdim/// one of the thread safety attributes 845226633Sdimbool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){ 846226633Sdim return llvm::StringSwitch<bool>(AttrName) 847226633Sdim .Case("guarded_by", true) 848226633Sdim .Case("guarded_var", true) 849226633Sdim .Case("pt_guarded_by", true) 850226633Sdim .Case("pt_guarded_var", true) 851226633Sdim .Case("lockable", true) 852226633Sdim .Case("scoped_lockable", true) 853226633Sdim .Case("no_thread_safety_analysis", true) 854226633Sdim .Case("acquired_after", true) 855226633Sdim .Case("acquired_before", true) 856226633Sdim .Case("exclusive_lock_function", true) 857226633Sdim .Case("shared_lock_function", true) 858226633Sdim .Case("exclusive_trylock_function", true) 859226633Sdim .Case("shared_trylock_function", true) 860226633Sdim .Case("unlock_function", true) 861226633Sdim .Case("lock_returned", true) 862226633Sdim .Case("locks_excluded", true) 863226633Sdim .Case("exclusive_locks_required", true) 864226633Sdim .Case("shared_locks_required", true) 865226633Sdim .Default(false); 866226633Sdim} 867226633Sdim 868226633Sdim/// \brief Parse the contents of thread safety attributes. These 869226633Sdim/// should always be parsed as an expression list. 870226633Sdim/// 871226633Sdim/// We need to special case the parsing due to the fact that if the first token 872226633Sdim/// of the first argument is an identifier, the main parse loop will store 873226633Sdim/// that token as a "parameter" and the rest of 874226633Sdim/// the arguments will be added to a list of "arguments". However, 875226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each 876226633Sdim/// argument as an expression and add all arguments to the list of "arguments". 877226633Sdim/// In future, we will take advantage of this special case to also 878226633Sdim/// deal with some argument scoping issues here (for example, referring to a 879226633Sdim/// function parameter in the attribute on that function). 880226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, 881226633Sdim SourceLocation AttrNameLoc, 882226633Sdim ParsedAttributes &Attrs, 883226633Sdim SourceLocation *EndLoc) { 884226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 885226633Sdim 886226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 887226633Sdim T.consumeOpen(); 888226633Sdim 889226633Sdim ExprVector ArgExprs(Actions); 890226633Sdim bool ArgExprsOk = true; 891226633Sdim 892226633Sdim // now parse the list of expressions 893234353Sdim while (Tok.isNot(tok::r_paren)) { 894226633Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 895226633Sdim if (ArgExpr.isInvalid()) { 896226633Sdim ArgExprsOk = false; 897226633Sdim T.consumeClose(); 898226633Sdim break; 899226633Sdim } else { 900226633Sdim ArgExprs.push_back(ArgExpr.release()); 901226633Sdim } 902226633Sdim if (Tok.isNot(tok::comma)) 903226633Sdim break; 904226633Sdim ConsumeToken(); // Eat the comma, move to the next argument 905226633Sdim } 906226633Sdim // Match the ')'. 907226633Sdim if (ArgExprsOk && !T.consumeClose()) { 908226633Sdim Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 909226633Sdim ArgExprs.take(), ArgExprs.size()); 910226633Sdim } 911226633Sdim if (EndLoc) 912226633Sdim *EndLoc = T.getCloseLocation(); 913226633Sdim} 914226633Sdim 915234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 916234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not 917234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 918234353Sdim/// situation. 919234353Sdim/// 920234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if 921234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller 922234353Sdim/// should try to parse it. 923234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() { 924234353Sdim assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 925234353Sdim 926234353Sdim switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) { 927234353Sdim case CAK_NotAttributeSpecifier: 928234353Sdim // No diagnostic: we're in Obj-C++11 and this is not actually an attribute. 929234353Sdim return false; 930234353Sdim 931234353Sdim case CAK_InvalidAttributeSpecifier: 932234353Sdim Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute); 933234353Sdim return false; 934234353Sdim 935234353Sdim case CAK_AttributeSpecifier: 936234353Sdim // Parse and discard the attributes. 937234353Sdim SourceLocation BeginLoc = ConsumeBracket(); 938234353Sdim ConsumeBracket(); 939234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/ false); 940234353Sdim assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); 941234353Sdim SourceLocation EndLoc = ConsumeBracket(); 942234353Sdim Diag(BeginLoc, diag::err_attributes_not_allowed) 943234353Sdim << SourceRange(BeginLoc, EndLoc); 944234353Sdim return true; 945234353Sdim } 946234353Sdim llvm_unreachable("All cases handled above."); 947234353Sdim} 948234353Sdim 949218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { 950218893Sdim Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) 951218893Sdim << attrs.Range; 952218893Sdim} 953218893Sdim 954193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of 955193326Sed/// declaration-specifiers, some number of declarators, and a semicolon. 956193326Sed/// 'Context' should be a Declarator::TheContext value. This returns the 957193326Sed/// location of the semicolon in DeclEnd. 958193326Sed/// 959193326Sed/// declaration: [C99 6.7] 960193326Sed/// block-declaration -> 961193326Sed/// simple-declaration 962193326Sed/// others [FIXME] 963193326Sed/// [C++] template-declaration 964193326Sed/// [C++] namespace-definition 965193326Sed/// [C++] using-directive 966194711Sed/// [C++] using-declaration 967234982Sdim/// [C++11/C11] static_assert-declaration 968193326Sed/// others... [FIXME] 969193326Sed/// 970218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, 971218893Sdim unsigned Context, 972199990Srdivacky SourceLocation &DeclEnd, 973218893Sdim ParsedAttributesWithRange &attrs) { 974210299Sed ParenBraceBracketBalancer BalancerRAIIObj(*this); 975226633Sdim // Must temporarily exit the objective-c container scope for 976226633Sdim // parsing c none objective-c decls. 977226633Sdim ObjCDeclContextSwitch ObjCDC(*this); 978210299Sed 979212904Sdim Decl *SingleDecl = 0; 980224145Sdim Decl *OwnedType = 0; 981193326Sed switch (Tok.getKind()) { 982193326Sed case tok::kw_template: 983193326Sed case tok::kw_export: 984218893Sdim ProhibitAttributes(attrs); 985193326Sed SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); 986193326Sed break; 987212904Sdim case tok::kw_inline: 988212904Sdim // Could be the start of an inline namespace. Allowed as an ext in C++03. 989234353Sdim if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { 990218893Sdim ProhibitAttributes(attrs); 991212904Sdim SourceLocation InlineLoc = ConsumeToken(); 992212904Sdim SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); 993212904Sdim break; 994212904Sdim } 995218893Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, 996218893Sdim true); 997193326Sed case tok::kw_namespace: 998218893Sdim ProhibitAttributes(attrs); 999193326Sed SingleDecl = ParseNamespace(Context, DeclEnd); 1000193326Sed break; 1001193326Sed case tok::kw_using: 1002218893Sdim SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), 1003224145Sdim DeclEnd, attrs, &OwnedType); 1004193326Sed break; 1005193326Sed case tok::kw_static_assert: 1006221345Sdim case tok::kw__Static_assert: 1007218893Sdim ProhibitAttributes(attrs); 1008193326Sed SingleDecl = ParseStaticAssertDeclaration(DeclEnd); 1009193326Sed break; 1010193326Sed default: 1011218893Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true); 1012193326Sed } 1013199990Srdivacky 1014193326Sed // This routine returns a DeclGroup, if the thing we parsed only contains a 1015224145Sdim // single decl, convert it now. Alias declarations can also declare a type; 1016224145Sdim // include that too if it is present. 1017224145Sdim return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType); 1018193326Sed} 1019193326Sed 1020193326Sed/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl] 1021193326Sed/// declaration-specifiers init-declarator-list[opt] ';' 1022193326Sed///[C90/C++]init-declarator-list ';' [TODO] 1023193326Sed/// [OMP] threadprivate-directive [TODO] 1024193326Sed/// 1025221345Sdim/// for-range-declaration: [C++0x 6.5p1: stmt.ranged] 1026221345Sdim/// attribute-specifier-seq[opt] type-specifier-seq declarator 1027221345Sdim/// 1028193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the 1029206275Srdivacky/// declaration. If it is true, it checks for and eats it. 1030221345Sdim/// 1031221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead 1032221345Sdim/// of a simple-declaration. If we find that we are, we also parse the 1033221345Sdim/// for-range-initializer, and place it here. 1034218893SdimParser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts, 1035218893Sdim unsigned Context, 1036199990Srdivacky SourceLocation &DeclEnd, 1037218893Sdim ParsedAttributes &attrs, 1038221345Sdim bool RequireSemi, 1039221345Sdim ForRangeInit *FRI) { 1040193326Sed // Parse the common declaration-specifiers piece. 1041198893Srdivacky ParsingDeclSpec DS(*this); 1042218893Sdim DS.takeAttributesFrom(attrs); 1043221345Sdim 1044202379Srdivacky ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, 1045218893Sdim getDeclSpecContextFromDeclaratorContext(Context)); 1046234353Sdim 1047193326Sed // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 1048193326Sed // declaration-specifiers init-declarator-list[opt] ';' 1049193326Sed if (Tok.is(tok::semi)) { 1050206275Srdivacky if (RequireSemi) ConsumeToken(); 1051212904Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 1052221345Sdim DS); 1053198893Srdivacky DS.complete(TheDecl); 1054193326Sed return Actions.ConvertDeclToDeclGroup(TheDecl); 1055193326Sed } 1056221345Sdim 1057221345Sdim return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI); 1058198893Srdivacky} 1059198092Srdivacky 1060234353Sdim/// Returns true if this might be the start of a declarator, or a common typo 1061234353Sdim/// for a declarator. 1062234353Sdimbool Parser::MightBeDeclarator(unsigned Context) { 1063234353Sdim switch (Tok.getKind()) { 1064234353Sdim case tok::annot_cxxscope: 1065234353Sdim case tok::annot_template_id: 1066234353Sdim case tok::caret: 1067234353Sdim case tok::code_completion: 1068234353Sdim case tok::coloncolon: 1069234353Sdim case tok::ellipsis: 1070234353Sdim case tok::kw___attribute: 1071234353Sdim case tok::kw_operator: 1072234353Sdim case tok::l_paren: 1073234353Sdim case tok::star: 1074234353Sdim return true; 1075234353Sdim 1076234353Sdim case tok::amp: 1077234353Sdim case tok::ampamp: 1078234353Sdim return getLangOpts().CPlusPlus; 1079234353Sdim 1080234353Sdim case tok::l_square: // Might be an attribute on an unnamed bit-field. 1081234353Sdim return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x && 1082234353Sdim NextToken().is(tok::l_square); 1083234353Sdim 1084234353Sdim case tok::colon: // Might be a typo for '::' or an unnamed bit-field. 1085234353Sdim return Context == Declarator::MemberContext || getLangOpts().CPlusPlus; 1086234353Sdim 1087234353Sdim case tok::identifier: 1088234353Sdim switch (NextToken().getKind()) { 1089234353Sdim case tok::code_completion: 1090234353Sdim case tok::coloncolon: 1091234353Sdim case tok::comma: 1092234353Sdim case tok::equal: 1093234353Sdim case tok::equalequal: // Might be a typo for '='. 1094234353Sdim case tok::kw_alignas: 1095234353Sdim case tok::kw_asm: 1096234353Sdim case tok::kw___attribute: 1097234353Sdim case tok::l_brace: 1098234353Sdim case tok::l_paren: 1099234353Sdim case tok::l_square: 1100234353Sdim case tok::less: 1101234353Sdim case tok::r_brace: 1102234353Sdim case tok::r_paren: 1103234353Sdim case tok::r_square: 1104234353Sdim case tok::semi: 1105234353Sdim return true; 1106234353Sdim 1107234353Sdim case tok::colon: 1108234353Sdim // At namespace scope, 'identifier:' is probably a typo for 'identifier::' 1109234353Sdim // and in block scope it's probably a label. Inside a class definition, 1110234353Sdim // this is a bit-field. 1111234353Sdim return Context == Declarator::MemberContext || 1112234353Sdim (getLangOpts().CPlusPlus && Context == Declarator::FileContext); 1113234353Sdim 1114234353Sdim case tok::identifier: // Possible virt-specifier. 1115234353Sdim return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken()); 1116234353Sdim 1117234353Sdim default: 1118234353Sdim return false; 1119234353Sdim } 1120234353Sdim 1121234353Sdim default: 1122234353Sdim return false; 1123234353Sdim } 1124234353Sdim} 1125234353Sdim 1126234353Sdim/// Skip until we reach something which seems like a sensible place to pick 1127234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner 1128234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later. 1129234353Sdimvoid Parser::SkipMalformedDecl() { 1130234353Sdim while (true) { 1131234353Sdim switch (Tok.getKind()) { 1132234353Sdim case tok::l_brace: 1133234353Sdim // Skip until matching }, then stop. We've probably skipped over 1134234353Sdim // a malformed class or function definition or similar. 1135234353Sdim ConsumeBrace(); 1136234353Sdim SkipUntil(tok::r_brace, /*StopAtSemi*/false); 1137234353Sdim if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { 1138234353Sdim // This declaration isn't over yet. Keep skipping. 1139234353Sdim continue; 1140234353Sdim } 1141234353Sdim if (Tok.is(tok::semi)) 1142234353Sdim ConsumeToken(); 1143234353Sdim return; 1144234353Sdim 1145234353Sdim case tok::l_square: 1146234353Sdim ConsumeBracket(); 1147234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/false); 1148234353Sdim continue; 1149234353Sdim 1150234353Sdim case tok::l_paren: 1151234353Sdim ConsumeParen(); 1152234353Sdim SkipUntil(tok::r_paren, /*StopAtSemi*/false); 1153234353Sdim continue; 1154234353Sdim 1155234353Sdim case tok::r_brace: 1156234353Sdim return; 1157234353Sdim 1158234353Sdim case tok::semi: 1159234353Sdim ConsumeToken(); 1160234353Sdim return; 1161234353Sdim 1162234353Sdim case tok::kw_inline: 1163234353Sdim // 'inline namespace' at the start of a line is almost certainly 1164234353Sdim // a good place to pick back up parsing. 1165234353Sdim if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace)) 1166234353Sdim return; 1167234353Sdim break; 1168234353Sdim 1169234353Sdim case tok::kw_namespace: 1170234353Sdim // 'namespace' at the start of a line is almost certainly a good 1171234353Sdim // place to pick back up parsing. 1172234353Sdim if (Tok.isAtStartOfLine()) 1173234353Sdim return; 1174234353Sdim break; 1175234353Sdim 1176234353Sdim case tok::eof: 1177234353Sdim return; 1178234353Sdim 1179234353Sdim default: 1180234353Sdim break; 1181234353Sdim } 1182234353Sdim 1183234353Sdim ConsumeAnyToken(); 1184234353Sdim } 1185234353Sdim} 1186234353Sdim 1187198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function 1188198893Srdivacky/// definition or a group of object declarations, actually parse the 1189198893Srdivacky/// result. 1190198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, 1191198893Srdivacky unsigned Context, 1192198893Srdivacky bool AllowFunctionDefinitions, 1193221345Sdim SourceLocation *DeclEnd, 1194221345Sdim ForRangeInit *FRI) { 1195198893Srdivacky // Parse the first declarator. 1196198893Srdivacky ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context)); 1197198893Srdivacky ParseDeclarator(D); 1198193326Sed 1199198893Srdivacky // Bail out if the first declarator didn't seem well-formed. 1200198893Srdivacky if (!D.hasName() && !D.mayOmitIdentifier()) { 1201234353Sdim SkipMalformedDecl(); 1202198893Srdivacky return DeclGroupPtrTy(); 1203198893Srdivacky } 1204198092Srdivacky 1205234353Sdim // Save late-parsed attributes for now; they need to be parsed in the 1206234353Sdim // appropriate function scope after the function Decl has been constructed. 1207234353Sdim LateParsedAttrList LateParsedAttrs; 1208234353Sdim if (D.isFunctionDeclarator()) 1209234353Sdim MaybeParseGNUAttributes(D, &LateParsedAttrs); 1210234353Sdim 1211210299Sed // Check to see if we have a function *definition* which must have a body. 1212210299Sed if (AllowFunctionDefinitions && D.isFunctionDeclarator() && 1213210299Sed // Look at the next token to make sure that this isn't a function 1214210299Sed // declaration. We have to check this because __attribute__ might be the 1215210299Sed // start of a function definition in GCC-extended K&R C. 1216210299Sed !isDeclarationAfterDeclarator()) { 1217210299Sed 1218210299Sed if (isStartOfFunctionDefinition(D)) { 1219198893Srdivacky if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 1220198893Srdivacky Diag(Tok, diag::err_function_declared_typedef); 1221198092Srdivacky 1222198893Srdivacky // Recover by treating the 'typedef' as spurious. 1223198893Srdivacky DS.ClearStorageClassSpecs(); 1224198893Srdivacky } 1225198893Srdivacky 1226234353Sdim Decl *TheDecl = 1227234353Sdim ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); 1228198893Srdivacky return Actions.ConvertDeclToDeclGroup(TheDecl); 1229210299Sed } 1230210299Sed 1231210299Sed if (isDeclarationSpecifier()) { 1232210299Sed // If there is an invalid declaration specifier right after the function 1233210299Sed // prototype, then we must be in a missing semicolon case where this isn't 1234210299Sed // actually a body. Just fall through into the code that handles it as a 1235210299Sed // prototype, and let the top-level code handle the erroneous declspec 1236210299Sed // where it would otherwise expect a comma or semicolon. 1237198893Srdivacky } else { 1238198893Srdivacky Diag(Tok, diag::err_expected_fn_body); 1239198893Srdivacky SkipUntil(tok::semi); 1240198893Srdivacky return DeclGroupPtrTy(); 1241198893Srdivacky } 1242198893Srdivacky } 1243198893Srdivacky 1244234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1245221345Sdim return DeclGroupPtrTy(); 1246221345Sdim 1247221345Sdim // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we 1248221345Sdim // must parse and analyze the for-range-initializer before the declaration is 1249221345Sdim // analyzed. 1250221345Sdim if (FRI && Tok.is(tok::colon)) { 1251221345Sdim FRI->ColonLoc = ConsumeToken(); 1252223017Sdim if (Tok.is(tok::l_brace)) 1253223017Sdim FRI->RangeExpr = ParseBraceInitializer(); 1254223017Sdim else 1255223017Sdim FRI->RangeExpr = ParseExpression(); 1256221345Sdim Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1257221345Sdim Actions.ActOnCXXForRangeDecl(ThisDecl); 1258221345Sdim Actions.FinalizeDeclaration(ThisDecl); 1259234353Sdim D.complete(ThisDecl); 1260221345Sdim return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1); 1261221345Sdim } 1262221345Sdim 1263226633Sdim SmallVector<Decl *, 8> DeclsInGroup; 1264221345Sdim Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D); 1265234353Sdim if (LateParsedAttrs.size() > 0) 1266234353Sdim ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); 1267198893Srdivacky D.complete(FirstDecl); 1268212904Sdim if (FirstDecl) 1269198893Srdivacky DeclsInGroup.push_back(FirstDecl); 1270198893Srdivacky 1271234353Sdim bool ExpectSemi = Context != Declarator::ForContext; 1272234353Sdim 1273198893Srdivacky // If we don't have a comma, it is either the end of the list (a ';') or an 1274198893Srdivacky // error, bail out. 1275198893Srdivacky while (Tok.is(tok::comma)) { 1276234353Sdim SourceLocation CommaLoc = ConsumeToken(); 1277198893Srdivacky 1278234353Sdim if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) { 1279234353Sdim // This comma was followed by a line-break and something which can't be 1280234353Sdim // the start of a declarator. The comma was probably a typo for a 1281234353Sdim // semicolon. 1282234353Sdim Diag(CommaLoc, diag::err_expected_semi_declaration) 1283234353Sdim << FixItHint::CreateReplacement(CommaLoc, ";"); 1284234353Sdim ExpectSemi = false; 1285234353Sdim break; 1286234353Sdim } 1287234353Sdim 1288198893Srdivacky // Parse the next declarator. 1289198893Srdivacky D.clear(); 1290234353Sdim D.setCommaLoc(CommaLoc); 1291198893Srdivacky 1292198893Srdivacky // Accept attributes in an init-declarator. In the first declarator in a 1293198893Srdivacky // declaration, these would be part of the declspec. In subsequent 1294198893Srdivacky // declarators, they become part of the declarator itself, so that they 1295198893Srdivacky // don't apply to declarators after *this* one. Examples: 1296198893Srdivacky // short __attribute__((common)) var; -> declspec 1297198893Srdivacky // short var __attribute__((common)); -> declarator 1298198893Srdivacky // short x, __attribute__((common)) var; -> declarator 1299218893Sdim MaybeParseGNUAttributes(D); 1300198893Srdivacky 1301198893Srdivacky ParseDeclarator(D); 1302234353Sdim if (!D.isInvalidType()) { 1303234353Sdim Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); 1304234353Sdim D.complete(ThisDecl); 1305234353Sdim if (ThisDecl) 1306234353Sdim DeclsInGroup.push_back(ThisDecl); 1307234353Sdim } 1308193326Sed } 1309198092Srdivacky 1310198893Srdivacky if (DeclEnd) 1311198893Srdivacky *DeclEnd = Tok.getLocation(); 1312198893Srdivacky 1313234353Sdim if (ExpectSemi && 1314198893Srdivacky ExpectAndConsume(tok::semi, 1315198893Srdivacky Context == Declarator::FileContext 1316198893Srdivacky ? diag::err_invalid_token_after_toplevel_declarator 1317198893Srdivacky : diag::err_expected_semi_declaration)) { 1318210299Sed // Okay, there was no semicolon and one was expected. If we see a 1319210299Sed // declaration specifier, just assume it was missing and continue parsing. 1320210299Sed // Otherwise things are very confused and we skip to recover. 1321210299Sed if (!isDeclarationSpecifier()) { 1322210299Sed SkipUntil(tok::r_brace, true, true); 1323210299Sed if (Tok.is(tok::semi)) 1324210299Sed ConsumeToken(); 1325210299Sed } 1326198893Srdivacky } 1327198893Srdivacky 1328210299Sed return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, 1329198893Srdivacky DeclsInGroup.data(), 1330198893Srdivacky DeclsInGroup.size()); 1331193326Sed} 1332193326Sed 1333221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a 1334221345Sdim/// declarator. Returns true on an error. 1335234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) { 1336221345Sdim // If a simple-asm-expr is present, parse it. 1337221345Sdim if (Tok.is(tok::kw_asm)) { 1338221345Sdim SourceLocation Loc; 1339221345Sdim ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1340221345Sdim if (AsmLabel.isInvalid()) { 1341221345Sdim SkipUntil(tok::semi, true, true); 1342221345Sdim return true; 1343221345Sdim } 1344221345Sdim 1345221345Sdim D.setAsmLabel(AsmLabel.release()); 1346221345Sdim D.SetRangeEnd(Loc); 1347221345Sdim } 1348221345Sdim 1349221345Sdim MaybeParseGNUAttributes(D); 1350221345Sdim return false; 1351221345Sdim} 1352221345Sdim 1353193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers 1354193326Sed/// declarator'. This method parses the remainder of the declaration 1355193326Sed/// (including any attributes or initializer, among other things) and 1356193326Sed/// finalizes the declaration. 1357193326Sed/// 1358193326Sed/// init-declarator: [C99 6.7] 1359193326Sed/// declarator 1360193326Sed/// declarator '=' initializer 1361193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] 1362193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer 1363193326Sed/// [C++] declarator initializer[opt] 1364193326Sed/// 1365193326Sed/// [C++] initializer: 1366193326Sed/// [C++] '=' initializer-clause 1367193326Sed/// [C++] '(' expression-list ')' 1368193326Sed/// [C++0x] '=' 'default' [TODO] 1369193326Sed/// [C++0x] '=' 'delete' 1370223017Sdim/// [C++0x] braced-init-list 1371193326Sed/// 1372193326Sed/// According to the standard grammar, =default and =delete are function 1373193326Sed/// definitions, but that definitely doesn't fit with the parser here. 1374193326Sed/// 1375212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, 1376195099Sed const ParsedTemplateInfo &TemplateInfo) { 1377234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1378221345Sdim return 0; 1379198092Srdivacky 1380221345Sdim return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo); 1381221345Sdim} 1382198092Srdivacky 1383221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, 1384221345Sdim const ParsedTemplateInfo &TemplateInfo) { 1385193326Sed // Inform the current actions module that we just parsed this declarator. 1386212904Sdim Decl *ThisDecl = 0; 1387198092Srdivacky switch (TemplateInfo.Kind) { 1388198092Srdivacky case ParsedTemplateInfo::NonTemplate: 1389210299Sed ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1390198092Srdivacky break; 1391198092Srdivacky 1392198092Srdivacky case ParsedTemplateInfo::Template: 1393198092Srdivacky case ParsedTemplateInfo::ExplicitSpecialization: 1394210299Sed ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), 1395212904Sdim MultiTemplateParamsArg(Actions, 1396195099Sed TemplateInfo.TemplateParams->data(), 1397195099Sed TemplateInfo.TemplateParams->size()), 1398198092Srdivacky D); 1399198092Srdivacky break; 1400198092Srdivacky 1401198092Srdivacky case ParsedTemplateInfo::ExplicitInstantiation: { 1402212904Sdim DeclResult ThisRes 1403210299Sed = Actions.ActOnExplicitInstantiation(getCurScope(), 1404198092Srdivacky TemplateInfo.ExternLoc, 1405198092Srdivacky TemplateInfo.TemplateLoc, 1406198092Srdivacky D); 1407198092Srdivacky if (ThisRes.isInvalid()) { 1408198092Srdivacky SkipUntil(tok::semi, true, true); 1409212904Sdim return 0; 1410198092Srdivacky } 1411198092Srdivacky 1412198092Srdivacky ThisDecl = ThisRes.get(); 1413198092Srdivacky break; 1414198092Srdivacky } 1415198092Srdivacky } 1416198092Srdivacky 1417218893Sdim bool TypeContainsAuto = 1418218893Sdim D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; 1419218893Sdim 1420193326Sed // Parse declarator '=' initializer. 1421234353Sdim // If a '==' or '+=' is found, suggest a fixit to '='. 1422234353Sdim if (isTokenEqualOrEqualTypo()) { 1423193326Sed ConsumeToken(); 1424218893Sdim if (Tok.is(tok::kw_delete)) { 1425223017Sdim if (D.isFunctionDeclarator()) 1426223017Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1427223017Sdim << 1 /* delete */; 1428223017Sdim else 1429223017Sdim Diag(ConsumeToken(), diag::err_deleted_non_function); 1430223017Sdim } else if (Tok.is(tok::kw_default)) { 1431223017Sdim if (D.isFunctionDeclarator()) 1432234353Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1433234353Sdim << 0 /* default */; 1434223017Sdim else 1435223017Sdim Diag(ConsumeToken(), diag::err_default_special_members); 1436193326Sed } else { 1437234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1438201361Srdivacky EnterScope(0); 1439210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1440201361Srdivacky } 1441194613Sed 1442210299Sed if (Tok.is(tok::code_completion)) { 1443210299Sed Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); 1444226633Sdim cutOffParsing(); 1445226633Sdim return 0; 1446210299Sed } 1447210299Sed 1448212904Sdim ExprResult Init(ParseInitializer()); 1449194613Sed 1450234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1451210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1452201361Srdivacky ExitScope(); 1453201361Srdivacky } 1454194613Sed 1455193326Sed if (Init.isInvalid()) { 1456204643Srdivacky SkipUntil(tok::comma, true, true); 1457204643Srdivacky Actions.ActOnInitializerError(ThisDecl); 1458204643Srdivacky } else 1459218893Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1460218893Sdim /*DirectInit=*/false, TypeContainsAuto); 1461193326Sed } 1462193326Sed } else if (Tok.is(tok::l_paren)) { 1463193326Sed // Parse C++ direct initializer: '(' expression-list ')' 1464226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1465226633Sdim T.consumeOpen(); 1466226633Sdim 1467193326Sed ExprVector Exprs(Actions); 1468193326Sed CommaLocsTy CommaLocs; 1469193326Sed 1470234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1471201361Srdivacky EnterScope(0); 1472210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1473201361Srdivacky } 1474201361Srdivacky 1475193326Sed if (ParseExpressionList(Exprs, CommaLocs)) { 1476193326Sed SkipUntil(tok::r_paren); 1477201361Srdivacky 1478234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1479210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1480201361Srdivacky ExitScope(); 1481201361Srdivacky } 1482193326Sed } else { 1483193326Sed // Match the ')'. 1484226633Sdim T.consumeClose(); 1485193326Sed 1486193326Sed assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && 1487193326Sed "Unexpected number of commas!"); 1488201361Srdivacky 1489234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1490210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1491201361Srdivacky ExitScope(); 1492201361Srdivacky } 1493201361Srdivacky 1494234353Sdim ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), 1495234353Sdim T.getCloseLocation(), 1496234353Sdim move_arg(Exprs)); 1497234353Sdim Actions.AddInitializerToDecl(ThisDecl, Initializer.take(), 1498234353Sdim /*DirectInit=*/true, TypeContainsAuto); 1499193326Sed } 1500234353Sdim } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 1501223017Sdim // Parse C++0x braced-init-list. 1502234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1503234353Sdim 1504223017Sdim if (D.getCXXScopeSpec().isSet()) { 1505223017Sdim EnterScope(0); 1506223017Sdim Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1507223017Sdim } 1508223017Sdim 1509223017Sdim ExprResult Init(ParseBraceInitializer()); 1510223017Sdim 1511223017Sdim if (D.getCXXScopeSpec().isSet()) { 1512223017Sdim Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1513223017Sdim ExitScope(); 1514223017Sdim } 1515223017Sdim 1516223017Sdim if (Init.isInvalid()) { 1517223017Sdim Actions.ActOnInitializerError(ThisDecl); 1518223017Sdim } else 1519223017Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1520223017Sdim /*DirectInit=*/true, TypeContainsAuto); 1521223017Sdim 1522193326Sed } else { 1523218893Sdim Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto); 1524193326Sed } 1525193326Sed 1526219077Sdim Actions.FinalizeDeclaration(ThisDecl); 1527219077Sdim 1528193326Sed return ThisDecl; 1529193326Sed} 1530193326Sed 1531193326Sed/// ParseSpecifierQualifierList 1532193326Sed/// specifier-qualifier-list: 1533193326Sed/// type-specifier specifier-qualifier-list[opt] 1534193326Sed/// type-qualifier specifier-qualifier-list[opt] 1535193326Sed/// [GNU] attributes specifier-qualifier-list[opt] 1536193326Sed/// 1537234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, 1538234353Sdim DeclSpecContext DSC) { 1539193326Sed /// specifier-qualifier-list is a subset of declaration-specifiers. Just 1540193326Sed /// parse declaration-specifiers and complain about extra stuff. 1541226633Sdim /// TODO: diagnose attribute-specifiers and alignment-specifiers. 1542234353Sdim ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC); 1543198092Srdivacky 1544193326Sed // Validate declspec for type-name. 1545193326Sed unsigned Specs = DS.getParsedSpecifiers(); 1546234353Sdim if (DSC == DSC_type_specifier && !DS.hasTypeSpecifier()) { 1547234353Sdim Diag(Tok, diag::err_expected_type); 1548234353Sdim DS.SetTypeSpecError(); 1549234353Sdim } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && 1550234353Sdim !DS.hasAttributes()) { 1551193326Sed Diag(Tok, diag::err_typename_requires_specqual); 1552234353Sdim if (!DS.hasTypeSpecifier()) 1553234353Sdim DS.SetTypeSpecError(); 1554234353Sdim } 1555198092Srdivacky 1556193326Sed // Issue diagnostic and remove storage class if present. 1557193326Sed if (Specs & DeclSpec::PQ_StorageClassSpecifier) { 1558193326Sed if (DS.getStorageClassSpecLoc().isValid()) 1559193326Sed Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); 1560193326Sed else 1561193326Sed Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass); 1562193326Sed DS.ClearStorageClassSpecs(); 1563193326Sed } 1564198092Srdivacky 1565193326Sed // Issue diagnostic and remove function specfier if present. 1566193326Sed if (Specs & DeclSpec::PQ_FunctionSpecifier) { 1567193326Sed if (DS.isInlineSpecified()) 1568193326Sed Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); 1569193326Sed if (DS.isVirtualSpecified()) 1570193326Sed Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); 1571193326Sed if (DS.isExplicitSpecified()) 1572193326Sed Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); 1573193326Sed DS.ClearFunctionSpecs(); 1574193326Sed } 1575234353Sdim 1576234353Sdim // Issue diagnostic and remove constexpr specfier if present. 1577234353Sdim if (DS.isConstexprSpecified()) { 1578234353Sdim Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); 1579234353Sdim DS.ClearConstexprSpec(); 1580234353Sdim } 1581193326Sed} 1582193326Sed 1583193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the 1584193326Sed/// specified token is valid after the identifier in a declarator which 1585193326Sed/// immediately follows the declspec. For example, these things are valid: 1586193326Sed/// 1587193326Sed/// int x [ 4]; // direct-declarator 1588193326Sed/// int x ( int y); // direct-declarator 1589193326Sed/// int(int x ) // direct-declarator 1590193326Sed/// int x ; // simple-declaration 1591193326Sed/// int x = 17; // init-declarator-list 1592193326Sed/// int x , y; // init-declarator-list 1593193326Sed/// int x __asm__ ("foo"); // init-declarator-list 1594193326Sed/// int x : 4; // struct-declarator 1595193326Sed/// int x { 5}; // C++'0x unified initializers 1596193326Sed/// 1597193326Sed/// This is not, because 'x' does not immediately follow the declspec (though 1598193326Sed/// ')' happens to be valid anyway). 1599193326Sed/// int (x) 1600193326Sed/// 1601193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) { 1602193326Sed return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) || 1603193326Sed T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) || 1604193326Sed T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon); 1605193326Sed} 1606193326Sed 1607193326Sed 1608193326Sed/// ParseImplicitInt - This method is called when we have an non-typename 1609193326Sed/// identifier in a declspec (which normally terminates the decl spec) when 1610193326Sed/// the declspec has no type specifier. In this case, the declspec is either 1611193326Sed/// malformed or is "implicit int" (in K&R and C89). 1612193326Sed/// 1613193326Sed/// This method handles diagnosing this prettily and returns false if the 1614193326Sed/// declspec is done being processed. If it recovers and thinks there may be 1615193326Sed/// other pieces of declspec after it, it returns true. 1616193326Sed/// 1617193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, 1618193326Sed const ParsedTemplateInfo &TemplateInfo, 1619234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 1620193326Sed assert(Tok.is(tok::identifier) && "should have identifier"); 1621198092Srdivacky 1622193326Sed SourceLocation Loc = Tok.getLocation(); 1623193326Sed // If we see an identifier that is not a type name, we normally would 1624193326Sed // parse it as the identifer being declared. However, when a typename 1625193326Sed // is typo'd or the definition is not included, this will incorrectly 1626193326Sed // parse the typename as the identifier name and fall over misparsing 1627193326Sed // later parts of the diagnostic. 1628193326Sed // 1629193326Sed // As such, we try to do some look-ahead in cases where this would 1630193326Sed // otherwise be an "implicit-int" case to see if this is invalid. For 1631193326Sed // example: "static foo_t x = 4;" In this case, if we parsed foo_t as 1632193326Sed // an identifier with implicit int, we'd get a parse error because the 1633193326Sed // next token is obviously invalid for a type. Parse these as a case 1634193326Sed // with an invalid type specifier. 1635193326Sed assert(!DS.hasTypeSpecifier() && "Type specifier checked above"); 1636198092Srdivacky 1637193326Sed // Since we know that this either implicit int (which is rare) or an 1638234353Sdim // error, do lookahead to try to do better recovery. This never applies within 1639234353Sdim // a type specifier. 1640234353Sdim // FIXME: Don't bail out here in languages with no implicit int (like 1641234353Sdim // C++ with no -fms-extensions). This is much more likely to be an undeclared 1642234353Sdim // type or typo than a use of implicit int. 1643234353Sdim if (DSC != DSC_type_specifier && 1644234353Sdim isValidAfterIdentifierInDeclarator(NextToken())) { 1645193326Sed // If this token is valid for implicit int, e.g. "static x = 4", then 1646193326Sed // we just avoid eating the identifier, so it will be parsed as the 1647193326Sed // identifier in the declarator. 1648193326Sed return false; 1649193326Sed } 1650198092Srdivacky 1651193326Sed // Otherwise, if we don't consume this token, we are going to emit an 1652193326Sed // error anyway. Try to recover from various common problems. Check 1653193326Sed // to see if this was a reference to a tag name without a tag specified. 1654193326Sed // This is a common problem in C (saying 'foo' instead of 'struct foo'). 1655193326Sed // 1656193326Sed // C++ doesn't need this, and isTagName doesn't take SS. 1657193326Sed if (SS == 0) { 1658221345Sdim const char *TagName = 0, *FixitTagName = 0; 1659193326Sed tok::TokenKind TagKind = tok::unknown; 1660198092Srdivacky 1661210299Sed switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) { 1662193326Sed default: break; 1663221345Sdim case DeclSpec::TST_enum: 1664221345Sdim TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break; 1665221345Sdim case DeclSpec::TST_union: 1666221345Sdim TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break; 1667221345Sdim case DeclSpec::TST_struct: 1668221345Sdim TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break; 1669221345Sdim case DeclSpec::TST_class: 1670221345Sdim TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; 1671193326Sed } 1672198092Srdivacky 1673193326Sed if (TagName) { 1674193326Sed Diag(Loc, diag::err_use_of_tag_name_without_tag) 1675234353Sdim << Tok.getIdentifierInfo() << TagName << getLangOpts().CPlusPlus 1676221345Sdim << FixItHint::CreateInsertion(Tok.getLocation(),FixitTagName); 1677198092Srdivacky 1678193326Sed // Parse this as a tag as if the missing tag were present. 1679193326Sed if (TagKind == tok::kw_enum) 1680234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); 1681193326Sed else 1682234353Sdim ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, 1683234353Sdim /*EnteringContext*/ false, DSC_normal); 1684193326Sed return true; 1685193326Sed } 1686193326Sed } 1687198092Srdivacky 1688198092Srdivacky // This is almost certainly an invalid type name. Let the action emit a 1689198092Srdivacky // diagnostic and attempt to recover. 1690212904Sdim ParsedType T; 1691198092Srdivacky if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc, 1692210299Sed getCurScope(), SS, T)) { 1693198092Srdivacky // The action emitted a diagnostic, so we don't have to. 1694198092Srdivacky if (T) { 1695198092Srdivacky // The action has suggested that the type T could be used. Set that as 1696198092Srdivacky // the type in the declaration specifiers, consume the would-be type 1697198092Srdivacky // name token, and we're done. 1698198092Srdivacky const char *PrevSpec; 1699198092Srdivacky unsigned DiagID; 1700212904Sdim DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); 1701198092Srdivacky DS.SetRangeEnd(Tok.getLocation()); 1702198092Srdivacky ConsumeToken(); 1703198092Srdivacky 1704198092Srdivacky // There may be other declaration specifiers after this. 1705198092Srdivacky return true; 1706198092Srdivacky } 1707198092Srdivacky 1708198092Srdivacky // Fall through; the action had no suggestion for us. 1709198092Srdivacky } else { 1710198092Srdivacky // The action did not emit a diagnostic, so emit one now. 1711198092Srdivacky SourceRange R; 1712198092Srdivacky if (SS) R = SS->getRange(); 1713198092Srdivacky Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R; 1714198092Srdivacky } 1715198092Srdivacky 1716198092Srdivacky // Mark this as an error. 1717234353Sdim DS.SetTypeSpecError(); 1718193326Sed DS.SetRangeEnd(Tok.getLocation()); 1719193326Sed ConsumeToken(); 1720198092Srdivacky 1721193326Sed // TODO: Could inject an invalid typedef decl in an enclosing scope to 1722193326Sed // avoid rippling error messages on subsequent uses of the same type, 1723193326Sed // could be useful if #include was forgotten. 1724193326Sed return false; 1725193326Sed} 1726193326Sed 1727202379Srdivacky/// \brief Determine the declaration specifier context from the declarator 1728202379Srdivacky/// context. 1729202379Srdivacky/// 1730202379Srdivacky/// \param Context the declarator context, which is one of the 1731202379Srdivacky/// Declarator::TheContext enumerator values. 1732202379SrdivackyParser::DeclSpecContext 1733202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { 1734202379Srdivacky if (Context == Declarator::MemberContext) 1735202379Srdivacky return DSC_class; 1736202379Srdivacky if (Context == Declarator::FileContext) 1737202379Srdivacky return DSC_top_level; 1738234353Sdim if (Context == Declarator::TrailingReturnContext) 1739234353Sdim return DSC_trailing; 1740202379Srdivacky return DSC_normal; 1741202379Srdivacky} 1742202379Srdivacky 1743226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier. 1744226633Sdim/// 1745226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a 1746226633Sdim/// type. Ideally, the type should be propagated directly into Sema. 1747226633Sdim/// 1748234353Sdim/// [C11] type-id 1749234353Sdim/// [C11] constant-expression 1750234353Sdim/// [C++0x] type-id ...[opt] 1751234353Sdim/// [C++0x] assignment-expression ...[opt] 1752234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start, 1753234353Sdim SourceLocation &EllipsisLoc) { 1754234353Sdim ExprResult ER; 1755226633Sdim if (isTypeIdInParens()) { 1756226633Sdim SourceLocation TypeLoc = Tok.getLocation(); 1757226633Sdim ParsedType Ty = ParseTypeName().get(); 1758226633Sdim SourceRange TypeRange(Start, Tok.getLocation()); 1759234353Sdim ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true, 1760234353Sdim Ty.getAsOpaquePtr(), TypeRange); 1761226633Sdim } else 1762234353Sdim ER = ParseConstantExpression(); 1763234353Sdim 1764234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis)) 1765234353Sdim EllipsisLoc = ConsumeToken(); 1766234353Sdim 1767234353Sdim return ER; 1768226633Sdim} 1769226633Sdim 1770226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the 1771226633Sdim/// attribute to Attrs. 1772226633Sdim/// 1773226633Sdim/// alignment-specifier: 1774234353Sdim/// [C11] '_Alignas' '(' type-id ')' 1775234353Sdim/// [C11] '_Alignas' '(' constant-expression ')' 1776234353Sdim/// [C++0x] 'alignas' '(' type-id ...[opt] ')' 1777234353Sdim/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')' 1778226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, 1779226633Sdim SourceLocation *endLoc) { 1780226633Sdim assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) && 1781226633Sdim "Not an alignment-specifier!"); 1782226633Sdim 1783226633Sdim SourceLocation KWLoc = Tok.getLocation(); 1784226633Sdim ConsumeToken(); 1785226633Sdim 1786226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1787226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 1788226633Sdim return; 1789226633Sdim 1790234353Sdim SourceLocation EllipsisLoc; 1791234353Sdim ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); 1792226633Sdim if (ArgExpr.isInvalid()) { 1793226633Sdim SkipUntil(tok::r_paren); 1794226633Sdim return; 1795226633Sdim } 1796226633Sdim 1797226633Sdim T.consumeClose(); 1798226633Sdim if (endLoc) 1799226633Sdim *endLoc = T.getCloseLocation(); 1800226633Sdim 1801234353Sdim // FIXME: Handle pack-expansions here. 1802234353Sdim if (EllipsisLoc.isValid()) { 1803234353Sdim Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported); 1804234353Sdim return; 1805234353Sdim } 1806234353Sdim 1807226633Sdim ExprVector ArgExprs(Actions); 1808226633Sdim ArgExprs.push_back(ArgExpr.release()); 1809226633Sdim Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc, 1810226633Sdim 0, T.getOpenLocation(), ArgExprs.take(), 1, false, true); 1811226633Sdim} 1812226633Sdim 1813193326Sed/// ParseDeclarationSpecifiers 1814193326Sed/// declaration-specifiers: [C99 6.7] 1815193326Sed/// storage-class-specifier declaration-specifiers[opt] 1816193326Sed/// type-specifier declaration-specifiers[opt] 1817193326Sed/// [C99] function-specifier declaration-specifiers[opt] 1818234353Sdim/// [C11] alignment-specifier declaration-specifiers[opt] 1819193326Sed/// [GNU] attributes declaration-specifiers[opt] 1820226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt] 1821193326Sed/// 1822193326Sed/// storage-class-specifier: [C99 6.7.1] 1823193326Sed/// 'typedef' 1824193326Sed/// 'extern' 1825193326Sed/// 'static' 1826193326Sed/// 'auto' 1827193326Sed/// 'register' 1828193326Sed/// [C++] 'mutable' 1829193326Sed/// [GNU] '__thread' 1830193326Sed/// function-specifier: [C99 6.7.4] 1831193326Sed/// [C99] 'inline' 1832193326Sed/// [C++] 'virtual' 1833193326Sed/// [C++] 'explicit' 1834218893Sdim/// [OpenCL] '__kernel' 1835193326Sed/// 'friend': [C++ dcl.friend] 1836198954Srdivacky/// 'constexpr': [C++0x dcl.constexpr] 1837193326Sed 1838193326Sed/// 1839193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS, 1840193326Sed const ParsedTemplateInfo &TemplateInfo, 1841198092Srdivacky AccessSpecifier AS, 1842234353Sdim DeclSpecContext DSContext, 1843234353Sdim LateParsedAttrList *LateAttrs) { 1844221345Sdim if (DS.getSourceRange().isInvalid()) { 1845221345Sdim DS.SetRangeStart(Tok.getLocation()); 1846221345Sdim DS.SetRangeEnd(Tok.getLocation()); 1847221345Sdim } 1848221345Sdim 1849234353Sdim bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 1850193326Sed while (1) { 1851198092Srdivacky bool isInvalid = false; 1852193326Sed const char *PrevSpec = 0; 1853198092Srdivacky unsigned DiagID = 0; 1854198092Srdivacky 1855193326Sed SourceLocation Loc = Tok.getLocation(); 1856193326Sed 1857193326Sed switch (Tok.getKind()) { 1858198092Srdivacky default: 1859193326Sed DoneWithDeclSpec: 1860226633Sdim // [C++0x] decl-specifier-seq: decl-specifier attribute-specifier-seq[opt] 1861226633Sdim MaybeParseCXX0XAttributes(DS.getAttributes()); 1862226633Sdim 1863193326Sed // If this is not a declaration specifier token, we're done reading decl 1864193326Sed // specifiers. First verify that DeclSpec's are consistent. 1865193326Sed DS.Finish(Diags, PP); 1866193326Sed return; 1867198092Srdivacky 1868212904Sdim case tok::code_completion: { 1869212904Sdim Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; 1870212904Sdim if (DS.hasTypeSpecifier()) { 1871212904Sdim bool AllowNonIdentifiers 1872212904Sdim = (getCurScope()->getFlags() & (Scope::ControlScope | 1873212904Sdim Scope::BlockScope | 1874212904Sdim Scope::TemplateParamScope | 1875212904Sdim Scope::FunctionPrototypeScope | 1876212904Sdim Scope::AtCatchScope)) == 0; 1877212904Sdim bool AllowNestedNameSpecifiers 1878212904Sdim = DSContext == DSC_top_level || 1879212904Sdim (DSContext == DSC_class && DS.isFriendSpecified()); 1880212904Sdim 1881218893Sdim Actions.CodeCompleteDeclSpec(getCurScope(), DS, 1882218893Sdim AllowNonIdentifiers, 1883218893Sdim AllowNestedNameSpecifiers); 1884226633Sdim return cutOffParsing(); 1885212904Sdim } 1886212904Sdim 1887218893Sdim if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) 1888218893Sdim CCC = Sema::PCC_LocalDeclarationSpecifiers; 1889218893Sdim else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) 1890212904Sdim CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 1891212904Sdim : Sema::PCC_Template; 1892212904Sdim else if (DSContext == DSC_class) 1893212904Sdim CCC = Sema::PCC_Class; 1894234353Sdim else if (CurParsedObjCImpl) 1895212904Sdim CCC = Sema::PCC_ObjCImplementation; 1896212904Sdim 1897212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); 1898226633Sdim return cutOffParsing(); 1899212904Sdim } 1900212904Sdim 1901193326Sed case tok::coloncolon: // ::foo::bar 1902204643Srdivacky // C++ scope specifier. Annotate and loop, or bail out on error. 1903204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 1904204643Srdivacky if (!DS.hasTypeSpecifier()) 1905204643Srdivacky DS.SetTypeSpecError(); 1906204643Srdivacky goto DoneWithDeclSpec; 1907204643Srdivacky } 1908204643Srdivacky if (Tok.is(tok::coloncolon)) // ::new or ::delete 1909204643Srdivacky goto DoneWithDeclSpec; 1910204643Srdivacky continue; 1911193326Sed 1912193326Sed case tok::annot_cxxscope: { 1913193326Sed if (DS.hasTypeSpecifier()) 1914193326Sed goto DoneWithDeclSpec; 1915193326Sed 1916200583Srdivacky CXXScopeSpec SS; 1917219077Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1918219077Sdim Tok.getAnnotationRange(), 1919219077Sdim SS); 1920200583Srdivacky 1921193326Sed // We are looking for a qualified typename. 1922193326Sed Token Next = NextToken(); 1923198092Srdivacky if (Next.is(tok::annot_template_id) && 1924193326Sed static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) 1925193326Sed ->Kind == TNK_Type_template) { 1926193326Sed // We have a qualified template-id, e.g., N::A<int> 1927202379Srdivacky 1928202379Srdivacky // C++ [class.qual]p2: 1929202379Srdivacky // In a lookup in which the constructor is an acceptable lookup 1930202379Srdivacky // result and the nested-name-specifier nominates a class C: 1931202379Srdivacky // 1932202379Srdivacky // - if the name specified after the 1933202379Srdivacky // nested-name-specifier, when looked up in C, is the 1934202379Srdivacky // injected-class-name of C (Clause 9), or 1935202379Srdivacky // 1936202379Srdivacky // - if the name specified after the nested-name-specifier 1937202379Srdivacky // is the same as the identifier or the 1938202379Srdivacky // simple-template-id's template-name in the last 1939202379Srdivacky // component of the nested-name-specifier, 1940202379Srdivacky // 1941202379Srdivacky // the name is instead considered to name the constructor of 1942202379Srdivacky // class C. 1943202379Srdivacky // 1944202379Srdivacky // Thus, if the template-name is actually the constructor 1945202379Srdivacky // name, then the code is ill-formed; this interpretation is 1946202379Srdivacky // reinforced by the NAD status of core issue 635. 1947224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 1948207619Srdivacky if ((DSContext == DSC_top_level || 1949207619Srdivacky (DSContext == DSC_class && DS.isFriendSpecified())) && 1950207619Srdivacky TemplateId->Name && 1951210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 1952202379Srdivacky if (isConstructorDeclarator()) { 1953202379Srdivacky // The user meant this to be an out-of-line constructor 1954202379Srdivacky // definition, but template arguments are not allowed 1955202379Srdivacky // there. Just allow this as a constructor; we'll 1956202379Srdivacky // complain about it later. 1957202379Srdivacky goto DoneWithDeclSpec; 1958202379Srdivacky } 1959202379Srdivacky 1960202379Srdivacky // The user meant this to name a type, but it actually names 1961202379Srdivacky // a constructor with some extraneous template 1962202379Srdivacky // arguments. Complain, then parse it as a type as the user 1963202379Srdivacky // intended. 1964202379Srdivacky Diag(TemplateId->TemplateNameLoc, 1965202379Srdivacky diag::err_out_of_line_template_id_names_constructor) 1966202379Srdivacky << TemplateId->Name; 1967202379Srdivacky } 1968202379Srdivacky 1969200583Srdivacky DS.getTypeSpecScope() = SS; 1970200583Srdivacky ConsumeToken(); // The C++ scope. 1971198092Srdivacky assert(Tok.is(tok::annot_template_id) && 1972193326Sed "ParseOptionalCXXScopeSpecifier not working"); 1973221345Sdim AnnotateTemplateIdTokenAsType(); 1974193326Sed continue; 1975193326Sed } 1976193326Sed 1977198092Srdivacky if (Next.is(tok::annot_typename)) { 1978200583Srdivacky DS.getTypeSpecScope() = SS; 1979200583Srdivacky ConsumeToken(); // The C++ scope. 1980212904Sdim if (Tok.getAnnotationValue()) { 1981212904Sdim ParsedType T = getTypeAnnotation(Tok); 1982218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, 1983218893Sdim Tok.getAnnotationEndLoc(), 1984212904Sdim PrevSpec, DiagID, T); 1985212904Sdim } 1986198092Srdivacky else 1987198092Srdivacky DS.SetTypeSpecError(); 1988198092Srdivacky DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 1989198092Srdivacky ConsumeToken(); // The typename 1990198092Srdivacky } 1991198092Srdivacky 1992193326Sed if (Next.isNot(tok::identifier)) 1993193326Sed goto DoneWithDeclSpec; 1994193326Sed 1995202379Srdivacky // If we're in a context where the identifier could be a class name, 1996202379Srdivacky // check whether this is a constructor declaration. 1997207619Srdivacky if ((DSContext == DSC_top_level || 1998207619Srdivacky (DSContext == DSC_class && DS.isFriendSpecified())) && 1999210299Sed Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 2000202379Srdivacky &SS)) { 2001202379Srdivacky if (isConstructorDeclarator()) 2002202379Srdivacky goto DoneWithDeclSpec; 2003193326Sed 2004202379Srdivacky // As noted in C++ [class.qual]p2 (cited above), when the name 2005202379Srdivacky // of the class is qualified in a context where it could name 2006202379Srdivacky // a constructor, its a constructor name. However, we've 2007202379Srdivacky // looked at the declarator, and the user probably meant this 2008202379Srdivacky // to be a type. Complain that it isn't supposed to be treated 2009202379Srdivacky // as a type, then proceed to parse it as a type. 2010202379Srdivacky Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) 2011202379Srdivacky << Next.getIdentifierInfo(); 2012202379Srdivacky } 2013202379Srdivacky 2014212904Sdim ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), 2015212904Sdim Next.getLocation(), 2016221345Sdim getCurScope(), &SS, 2017221345Sdim false, false, ParsedType(), 2018234353Sdim /*IsCtorOrDtorName=*/false, 2019221345Sdim /*NonTrivialSourceInfo=*/true); 2020193326Sed 2021193326Sed // If the referenced identifier is not a type, then this declspec is 2022193326Sed // erroneous: We already checked about that it has no type specifier, and 2023193326Sed // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the 2024198092Srdivacky // typename. 2025193326Sed if (TypeRep == 0) { 2026193326Sed ConsumeToken(); // Eat the scope spec so the identifier is current. 2027234353Sdim if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue; 2028193326Sed goto DoneWithDeclSpec; 2029193326Sed } 2030198092Srdivacky 2031200583Srdivacky DS.getTypeSpecScope() = SS; 2032193326Sed ConsumeToken(); // The C++ scope. 2033193326Sed 2034193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2035198092Srdivacky DiagID, TypeRep); 2036193326Sed if (isInvalid) 2037193326Sed break; 2038198092Srdivacky 2039193326Sed DS.SetRangeEnd(Tok.getLocation()); 2040193326Sed ConsumeToken(); // The typename. 2041193326Sed 2042193326Sed continue; 2043193326Sed } 2044198092Srdivacky 2045193326Sed case tok::annot_typename: { 2046212904Sdim if (Tok.getAnnotationValue()) { 2047212904Sdim ParsedType T = getTypeAnnotation(Tok); 2048193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2049212904Sdim DiagID, T); 2050212904Sdim } else 2051193326Sed DS.SetTypeSpecError(); 2052206275Srdivacky 2053206275Srdivacky if (isInvalid) 2054206275Srdivacky break; 2055206275Srdivacky 2056193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2057193326Sed ConsumeToken(); // The typename 2058198092Srdivacky 2059193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2060193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2061218893Sdim // Objective-C interface. 2062234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2063218893Sdim ParseObjCProtocolQualifiers(DS); 2064218893Sdim 2065193326Sed continue; 2066193326Sed } 2067198092Srdivacky 2068221345Sdim case tok::kw___is_signed: 2069221345Sdim // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang 2070221345Sdim // typically treats it as a trait. If we see __is_signed as it appears 2071221345Sdim // in libstdc++, e.g., 2072221345Sdim // 2073221345Sdim // static const bool __is_signed; 2074221345Sdim // 2075221345Sdim // then treat __is_signed as an identifier rather than as a keyword. 2076221345Sdim if (DS.getTypeSpecType() == TST_bool && 2077221345Sdim DS.getTypeQualifiers() == DeclSpec::TQ_const && 2078221345Sdim DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2079221345Sdim Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 2080221345Sdim Tok.setKind(tok::identifier); 2081221345Sdim } 2082221345Sdim 2083221345Sdim // We're done with the declaration-specifiers. 2084221345Sdim goto DoneWithDeclSpec; 2085221345Sdim 2086193326Sed // typedef-name 2087234353Sdim case tok::kw_decltype: 2088193326Sed case tok::identifier: { 2089193326Sed // In C++, check to see if this is a scope specifier like foo::bar::, if 2090193326Sed // so handle it as such. This is important for ctor parsing. 2091234353Sdim if (getLangOpts().CPlusPlus) { 2092204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 2093204643Srdivacky if (!DS.hasTypeSpecifier()) 2094204643Srdivacky DS.SetTypeSpecError(); 2095204643Srdivacky goto DoneWithDeclSpec; 2096204643Srdivacky } 2097204643Srdivacky if (!Tok.is(tok::identifier)) 2098204643Srdivacky continue; 2099204643Srdivacky } 2100198092Srdivacky 2101193326Sed // This identifier can only be a typedef name if we haven't already seen 2102193326Sed // a type-specifier. Without this check we misparse: 2103193326Sed // typedef int X; struct Y { short X; }; as 'short int'. 2104193326Sed if (DS.hasTypeSpecifier()) 2105193326Sed goto DoneWithDeclSpec; 2106198092Srdivacky 2107203955Srdivacky // Check for need to substitute AltiVec keyword tokens. 2108203955Srdivacky if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) 2109203955Srdivacky break; 2110203955Srdivacky 2111212904Sdim ParsedType TypeRep = 2112212904Sdim Actions.getTypeName(*Tok.getIdentifierInfo(), 2113212904Sdim Tok.getLocation(), getCurScope()); 2114193326Sed 2115193326Sed // If this is not a typedef name, don't parse it as part of the declspec, 2116193326Sed // it must be an implicit int or an error. 2117212904Sdim if (!TypeRep) { 2118234353Sdim if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue; 2119193326Sed goto DoneWithDeclSpec; 2120193326Sed } 2121193326Sed 2122202379Srdivacky // If we're in a context where the identifier could be a class name, 2123202379Srdivacky // check whether this is a constructor declaration. 2124234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2125210299Sed Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) && 2126202379Srdivacky isConstructorDeclarator()) 2127193326Sed goto DoneWithDeclSpec; 2128193326Sed 2129193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2130198092Srdivacky DiagID, TypeRep); 2131193326Sed if (isInvalid) 2132193326Sed break; 2133198092Srdivacky 2134193326Sed DS.SetRangeEnd(Tok.getLocation()); 2135193326Sed ConsumeToken(); // The identifier 2136193326Sed 2137193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2138193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2139218893Sdim // Objective-C interface. 2140234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2141218893Sdim ParseObjCProtocolQualifiers(DS); 2142218893Sdim 2143193326Sed // Need to support trailing type qualifiers (e.g. "id<p> const"). 2144193326Sed // If a type specifier follows, it will be diagnosed elsewhere. 2145193326Sed continue; 2146193326Sed } 2147193326Sed 2148193326Sed // type-name 2149193326Sed case tok::annot_template_id: { 2150224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2151193326Sed if (TemplateId->Kind != TNK_Type_template) { 2152193326Sed // This template-id does not refer to a type name, so we're 2153193326Sed // done with the type-specifiers. 2154193326Sed goto DoneWithDeclSpec; 2155193326Sed } 2156193326Sed 2157202379Srdivacky // If we're in a context where the template-id could be a 2158202379Srdivacky // constructor name or specialization, check whether this is a 2159202379Srdivacky // constructor declaration. 2160234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2161210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) && 2162202379Srdivacky isConstructorDeclarator()) 2163202379Srdivacky goto DoneWithDeclSpec; 2164202379Srdivacky 2165193326Sed // Turn the template-id annotation token into a type annotation 2166193326Sed // token, then try again to parse it as a type-specifier. 2167193326Sed AnnotateTemplateIdTokenAsType(); 2168193326Sed continue; 2169193326Sed } 2170193326Sed 2171193326Sed // GNU attributes support. 2172193326Sed case tok::kw___attribute: 2173234353Sdim ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs); 2174193326Sed continue; 2175193326Sed 2176193326Sed // Microsoft declspec support. 2177193326Sed case tok::kw___declspec: 2178218893Sdim ParseMicrosoftDeclSpec(DS.getAttributes()); 2179193326Sed continue; 2180198092Srdivacky 2181193326Sed // Microsoft single token adornments. 2182193326Sed case tok::kw___forceinline: 2183194179Sed // FIXME: Add handling here! 2184194179Sed break; 2185194179Sed 2186194179Sed case tok::kw___ptr64: 2187226633Sdim case tok::kw___ptr32: 2188193326Sed case tok::kw___w64: 2189193326Sed case tok::kw___cdecl: 2190193326Sed case tok::kw___stdcall: 2191193326Sed case tok::kw___fastcall: 2192208600Srdivacky case tok::kw___thiscall: 2193226633Sdim case tok::kw___unaligned: 2194218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 2195194179Sed continue; 2196194179Sed 2197212904Sdim // Borland single token adornments. 2198212904Sdim case tok::kw___pascal: 2199218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 2200212904Sdim continue; 2201212904Sdim 2202218893Sdim // OpenCL single token adornments. 2203218893Sdim case tok::kw___kernel: 2204218893Sdim ParseOpenCLAttributes(DS.getAttributes()); 2205218893Sdim continue; 2206218893Sdim 2207193326Sed // storage-class-specifier 2208193326Sed case tok::kw_typedef: 2209226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, 2210226633Sdim PrevSpec, DiagID); 2211193326Sed break; 2212193326Sed case tok::kw_extern: 2213193326Sed if (DS.isThreadSpecified()) 2214193326Sed Diag(Tok, diag::ext_thread_before) << "extern"; 2215226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc, 2216226633Sdim PrevSpec, DiagID); 2217193326Sed break; 2218193326Sed case tok::kw___private_extern__: 2219226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern, 2220226633Sdim Loc, PrevSpec, DiagID); 2221193326Sed break; 2222193326Sed case tok::kw_static: 2223193326Sed if (DS.isThreadSpecified()) 2224193326Sed Diag(Tok, diag::ext_thread_before) << "static"; 2225226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc, 2226226633Sdim PrevSpec, DiagID); 2227193326Sed break; 2228193326Sed case tok::kw_auto: 2229234353Sdim if (getLangOpts().CPlusPlus0x) { 2230219077Sdim if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { 2231226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2232226633Sdim PrevSpec, DiagID); 2233219077Sdim if (!isInvalid) 2234226633Sdim Diag(Tok, diag::ext_auto_storage_class) 2235219077Sdim << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); 2236226633Sdim } else 2237219077Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, 2238219077Sdim DiagID); 2239226633Sdim } else 2240226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2241226633Sdim PrevSpec, DiagID); 2242193326Sed break; 2243193326Sed case tok::kw_register: 2244226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, 2245226633Sdim PrevSpec, DiagID); 2246193326Sed break; 2247193326Sed case tok::kw_mutable: 2248226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc, 2249226633Sdim PrevSpec, DiagID); 2250193326Sed break; 2251193326Sed case tok::kw___thread: 2252198092Srdivacky isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID); 2253193326Sed break; 2254198092Srdivacky 2255193326Sed // function-specifier 2256193326Sed case tok::kw_inline: 2257198092Srdivacky isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID); 2258193326Sed break; 2259193326Sed case tok::kw_virtual: 2260198092Srdivacky isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID); 2261193326Sed break; 2262193326Sed case tok::kw_explicit: 2263198092Srdivacky isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID); 2264193326Sed break; 2265193326Sed 2266226633Sdim // alignment-specifier 2267226633Sdim case tok::kw__Alignas: 2268234353Sdim if (!getLangOpts().C11) 2269234353Sdim Diag(Tok, diag::ext_c11_alignas); 2270226633Sdim ParseAlignmentSpecifier(DS.getAttributes()); 2271226633Sdim continue; 2272226633Sdim 2273193326Sed // friend 2274193326Sed case tok::kw_friend: 2275198092Srdivacky if (DSContext == DSC_class) 2276198092Srdivacky isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); 2277198092Srdivacky else { 2278198092Srdivacky PrevSpec = ""; // not actually used by the diagnostic 2279198092Srdivacky DiagID = diag::err_friend_invalid_in_context; 2280198092Srdivacky isInvalid = true; 2281198092Srdivacky } 2282193326Sed break; 2283198092Srdivacky 2284226633Sdim // Modules 2285226633Sdim case tok::kw___module_private__: 2286226633Sdim isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); 2287226633Sdim break; 2288226633Sdim 2289198954Srdivacky // constexpr 2290198954Srdivacky case tok::kw_constexpr: 2291198954Srdivacky isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); 2292198954Srdivacky break; 2293198954Srdivacky 2294193326Sed // type-specifier 2295193326Sed case tok::kw_short: 2296198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, 2297198092Srdivacky DiagID); 2298193326Sed break; 2299193326Sed case tok::kw_long: 2300193326Sed if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) 2301198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, 2302198092Srdivacky DiagID); 2303193326Sed else 2304198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2305198092Srdivacky DiagID); 2306193326Sed break; 2307221345Sdim case tok::kw___int64: 2308221345Sdim isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2309221345Sdim DiagID); 2310221345Sdim break; 2311193326Sed case tok::kw_signed: 2312198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, 2313198092Srdivacky DiagID); 2314193326Sed break; 2315193326Sed case tok::kw_unsigned: 2316198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, 2317198092Srdivacky DiagID); 2318193326Sed break; 2319193326Sed case tok::kw__Complex: 2320198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec, 2321198092Srdivacky DiagID); 2322193326Sed break; 2323193326Sed case tok::kw__Imaginary: 2324198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec, 2325198092Srdivacky DiagID); 2326193326Sed break; 2327193326Sed case tok::kw_void: 2328198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, 2329198092Srdivacky DiagID); 2330193326Sed break; 2331193326Sed case tok::kw_char: 2332198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, 2333198092Srdivacky DiagID); 2334193326Sed break; 2335193326Sed case tok::kw_int: 2336198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, 2337198092Srdivacky DiagID); 2338193326Sed break; 2339234353Sdim case tok::kw___int128: 2340234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, 2341234353Sdim DiagID); 2342234353Sdim break; 2343234353Sdim case tok::kw_half: 2344234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, 2345234353Sdim DiagID); 2346234353Sdim break; 2347193326Sed case tok::kw_float: 2348198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, 2349198092Srdivacky DiagID); 2350193326Sed break; 2351193326Sed case tok::kw_double: 2352198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, 2353198092Srdivacky DiagID); 2354193326Sed break; 2355193326Sed case tok::kw_wchar_t: 2356198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, 2357198092Srdivacky DiagID); 2358193326Sed break; 2359198092Srdivacky case tok::kw_char16_t: 2360198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, 2361198092Srdivacky DiagID); 2362198092Srdivacky break; 2363198092Srdivacky case tok::kw_char32_t: 2364198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, 2365198092Srdivacky DiagID); 2366198092Srdivacky break; 2367193326Sed case tok::kw_bool: 2368193326Sed case tok::kw__Bool: 2369218893Sdim if (Tok.is(tok::kw_bool) && 2370218893Sdim DS.getTypeSpecType() != DeclSpec::TST_unspecified && 2371218893Sdim DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 2372218893Sdim PrevSpec = ""; // Not used by the diagnostic. 2373218893Sdim DiagID = diag::err_bool_redeclaration; 2374221345Sdim // For better error recovery. 2375221345Sdim Tok.setKind(tok::identifier); 2376218893Sdim isInvalid = true; 2377218893Sdim } else { 2378218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, 2379218893Sdim DiagID); 2380218893Sdim } 2381193326Sed break; 2382193326Sed case tok::kw__Decimal32: 2383198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec, 2384198092Srdivacky DiagID); 2385193326Sed break; 2386193326Sed case tok::kw__Decimal64: 2387198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec, 2388198092Srdivacky DiagID); 2389193326Sed break; 2390193326Sed case tok::kw__Decimal128: 2391198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, 2392198092Srdivacky DiagID); 2393193326Sed break; 2394203955Srdivacky case tok::kw___vector: 2395203955Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 2396203955Srdivacky break; 2397203955Srdivacky case tok::kw___pixel: 2398203955Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 2399203955Srdivacky break; 2400221345Sdim case tok::kw___unknown_anytype: 2401221345Sdim isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, 2402221345Sdim PrevSpec, DiagID); 2403221345Sdim break; 2404193326Sed 2405193326Sed // class-specifier: 2406193326Sed case tok::kw_class: 2407193326Sed case tok::kw_struct: 2408193326Sed case tok::kw_union: { 2409193326Sed tok::TokenKind Kind = Tok.getKind(); 2410193326Sed ConsumeToken(); 2411234353Sdim ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, 2412234353Sdim EnteringContext, DSContext); 2413193326Sed continue; 2414193326Sed } 2415193326Sed 2416193326Sed // enum-specifier: 2417193326Sed case tok::kw_enum: 2418193326Sed ConsumeToken(); 2419234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext); 2420193326Sed continue; 2421193326Sed 2422193326Sed // cv-qualifier: 2423193326Sed case tok::kw_const: 2424198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, 2425234353Sdim getLangOpts()); 2426193326Sed break; 2427193326Sed case tok::kw_volatile: 2428198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 2429234353Sdim getLangOpts()); 2430193326Sed break; 2431193326Sed case tok::kw_restrict: 2432198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 2433234353Sdim getLangOpts()); 2434193326Sed break; 2435193326Sed 2436193326Sed // C++ typename-specifier: 2437193326Sed case tok::kw_typename: 2438204643Srdivacky if (TryAnnotateTypeOrScopeToken()) { 2439204643Srdivacky DS.SetTypeSpecError(); 2440204643Srdivacky goto DoneWithDeclSpec; 2441204643Srdivacky } 2442204643Srdivacky if (!Tok.is(tok::kw_typename)) 2443193326Sed continue; 2444193326Sed break; 2445193326Sed 2446193326Sed // GNU typeof support. 2447193326Sed case tok::kw_typeof: 2448193326Sed ParseTypeofSpecifier(DS); 2449193326Sed continue; 2450193326Sed 2451234353Sdim case tok::annot_decltype: 2452195099Sed ParseDecltypeSpecifier(DS); 2453195099Sed continue; 2454195099Sed 2455223017Sdim case tok::kw___underlying_type: 2456223017Sdim ParseUnderlyingTypeSpecifier(DS); 2457226633Sdim continue; 2458223017Sdim 2459226633Sdim case tok::kw__Atomic: 2460226633Sdim ParseAtomicSpecifier(DS); 2461226633Sdim continue; 2462226633Sdim 2463221345Sdim // OpenCL qualifiers: 2464221345Sdim case tok::kw_private: 2465234353Sdim if (!getLangOpts().OpenCL) 2466221345Sdim goto DoneWithDeclSpec; 2467221345Sdim case tok::kw___private: 2468221345Sdim case tok::kw___global: 2469221345Sdim case tok::kw___local: 2470221345Sdim case tok::kw___constant: 2471221345Sdim case tok::kw___read_only: 2472221345Sdim case tok::kw___write_only: 2473221345Sdim case tok::kw___read_write: 2474221345Sdim ParseOpenCLQualifiers(DS); 2475221345Sdim break; 2476221345Sdim 2477193326Sed case tok::less: 2478193326Sed // GCC ObjC supports types like "<SomeProtocol>" as a synonym for 2479193326Sed // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous, 2480193326Sed // but we support it. 2481234353Sdim if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1) 2482193326Sed goto DoneWithDeclSpec; 2483198092Srdivacky 2484218893Sdim if (!ParseObjCProtocolQualifiers(DS)) 2485193326Sed Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) 2486206084Srdivacky << FixItHint::CreateInsertion(Loc, "id") 2487218893Sdim << SourceRange(Loc, DS.getSourceRange().getEnd()); 2488218893Sdim 2489218893Sdim // Need to support trailing type qualifiers (e.g. "id<p> const"). 2490218893Sdim // If a type specifier follows, it will be diagnosed elsewhere. 2491218893Sdim continue; 2492193326Sed } 2493198092Srdivacky // If the specifier wasn't legal, issue a diagnostic. 2494193326Sed if (isInvalid) { 2495193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 2496198092Srdivacky assert(DiagID); 2497212904Sdim 2498212904Sdim if (DiagID == diag::ext_duplicate_declspec) 2499212904Sdim Diag(Tok, DiagID) 2500212904Sdim << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); 2501212904Sdim else 2502212904Sdim Diag(Tok, DiagID) << PrevSpec; 2503193326Sed } 2504219077Sdim 2505193326Sed DS.SetRangeEnd(Tok.getLocation()); 2506221345Sdim if (DiagID != diag::err_bool_redeclaration) 2507221345Sdim ConsumeToken(); 2508193326Sed } 2509193326Sed} 2510193326Sed 2511193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating 2512193326Sed/// semicolon. 2513193326Sed/// 2514193326Sed/// struct-declaration: 2515193326Sed/// specifier-qualifier-list struct-declarator-list 2516193326Sed/// [GNU] __extension__ struct-declaration 2517193326Sed/// [GNU] specifier-qualifier-list 2518193326Sed/// struct-declarator-list: 2519193326Sed/// struct-declarator 2520193326Sed/// struct-declarator-list ',' struct-declarator 2521193326Sed/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator 2522193326Sed/// struct-declarator: 2523193326Sed/// declarator 2524193326Sed/// [GNU] declarator attributes[opt] 2525193326Sed/// declarator[opt] ':' constant-expression 2526193326Sed/// [GNU] declarator[opt] ':' constant-expression attributes[opt] 2527193326Sed/// 2528193326Sedvoid Parser:: 2529198893SrdivackyParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { 2530226633Sdim 2531193326Sed if (Tok.is(tok::kw___extension__)) { 2532193326Sed // __extension__ silences extension warnings in the subexpression. 2533193326Sed ExtensionRAIIObject O(Diags); // Use RAII to do this. 2534193326Sed ConsumeToken(); 2535193326Sed return ParseStructDeclaration(DS, Fields); 2536193326Sed } 2537198092Srdivacky 2538193326Sed // Parse the common specifier-qualifiers-list piece. 2539193326Sed ParseSpecifierQualifierList(DS); 2540198092Srdivacky 2541193326Sed // If there are no declarators, this is a free-standing declaration 2542193326Sed // specifier. Let the actions module cope with it. 2543193326Sed if (Tok.is(tok::semi)) { 2544210299Sed Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, DS); 2545193326Sed return; 2546193326Sed } 2547193326Sed 2548193326Sed // Read struct-declarators until we find the semicolon. 2549198893Srdivacky bool FirstDeclarator = true; 2550234353Sdim SourceLocation CommaLoc; 2551193326Sed while (1) { 2552198893Srdivacky ParsingDeclRAIIObject PD(*this); 2553198893Srdivacky FieldDeclarator DeclaratorInfo(DS); 2554234353Sdim DeclaratorInfo.D.setCommaLoc(CommaLoc); 2555198092Srdivacky 2556198893Srdivacky // Attributes are only allowed here on successive declarators. 2557218893Sdim if (!FirstDeclarator) 2558218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 2559198893Srdivacky 2560193326Sed /// struct-declarator: declarator 2561193326Sed /// struct-declarator: declarator[opt] ':' constant-expression 2562200583Srdivacky if (Tok.isNot(tok::colon)) { 2563200583Srdivacky // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 2564200583Srdivacky ColonProtectionRAIIObject X(*this); 2565193326Sed ParseDeclarator(DeclaratorInfo.D); 2566200583Srdivacky } 2567198092Srdivacky 2568193326Sed if (Tok.is(tok::colon)) { 2569193326Sed ConsumeToken(); 2570212904Sdim ExprResult Res(ParseConstantExpression()); 2571193326Sed if (Res.isInvalid()) 2572193326Sed SkipUntil(tok::semi, true, true); 2573193326Sed else 2574193326Sed DeclaratorInfo.BitfieldSize = Res.release(); 2575193326Sed } 2576193326Sed 2577193326Sed // If attributes exist after the declarator, parse them. 2578218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 2579193326Sed 2580198893Srdivacky // We're done with this declarator; invoke the callback. 2581212904Sdim Decl *D = Fields.invoke(DeclaratorInfo); 2582198893Srdivacky PD.complete(D); 2583198893Srdivacky 2584193326Sed // If we don't have a comma, it is either the end of the list (a ';') 2585193326Sed // or an error, bail out. 2586193326Sed if (Tok.isNot(tok::comma)) 2587193326Sed return; 2588193326Sed 2589193326Sed // Consume the comma. 2590234353Sdim CommaLoc = ConsumeToken(); 2591193326Sed 2592198893Srdivacky FirstDeclarator = false; 2593193326Sed } 2594193326Sed} 2595193326Sed 2596193326Sed/// ParseStructUnionBody 2597193326Sed/// struct-contents: 2598193326Sed/// struct-declaration-list 2599193326Sed/// [EXT] empty 2600193326Sed/// [GNU] "struct-declaration-list" without terminatoring ';' 2601193326Sed/// struct-declaration-list: 2602193326Sed/// struct-declaration 2603193326Sed/// struct-declaration-list struct-declaration 2604193326Sed/// [OBC] '@' 'defs' '(' class-name ')' 2605193326Sed/// 2606193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc, 2607212904Sdim unsigned TagType, Decl *TagDecl) { 2608212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2609212904Sdim "parsing struct/union body"); 2610198092Srdivacky 2611226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 2612226633Sdim if (T.consumeOpen()) 2613226633Sdim return; 2614198092Srdivacky 2615193326Sed ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); 2616210299Sed Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2617193326Sed 2618193326Sed // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in 2619193326Sed // C++. 2620234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) { 2621234353Sdim Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union); 2622234353Sdim Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union); 2623234353Sdim } 2624193326Sed 2625226633Sdim SmallVector<Decl *, 32> FieldDecls; 2626193326Sed 2627193326Sed // While we still have something to read, read the declarations in the struct. 2628193326Sed while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 2629193326Sed // Each iteration of this loop reads one struct-declaration. 2630198092Srdivacky 2631193326Sed // Check for extraneous top-level semicolon. 2632193326Sed if (Tok.is(tok::semi)) { 2633193326Sed Diag(Tok, diag::ext_extra_struct_semi) 2634210299Sed << DeclSpec::getSpecifierName((DeclSpec::TST)TagType) 2635206084Srdivacky << FixItHint::CreateRemoval(Tok.getLocation()); 2636193326Sed ConsumeToken(); 2637193326Sed continue; 2638193326Sed } 2639193326Sed 2640193326Sed // Parse all the comma separated declarators. 2641221345Sdim DeclSpec DS(AttrFactory); 2642198893Srdivacky 2643193326Sed if (!Tok.is(tok::at)) { 2644198893Srdivacky struct CFieldCallback : FieldCallback { 2645198893Srdivacky Parser &P; 2646212904Sdim Decl *TagDecl; 2647226633Sdim SmallVectorImpl<Decl *> &FieldDecls; 2648198092Srdivacky 2649212904Sdim CFieldCallback(Parser &P, Decl *TagDecl, 2650226633Sdim SmallVectorImpl<Decl *> &FieldDecls) : 2651198893Srdivacky P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} 2652198893Srdivacky 2653212904Sdim virtual Decl *invoke(FieldDeclarator &FD) { 2654198893Srdivacky // Install the declarator into the current TagDecl. 2655212904Sdim Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, 2656198893Srdivacky FD.D.getDeclSpec().getSourceRange().getBegin(), 2657198893Srdivacky FD.D, FD.BitfieldSize); 2658198893Srdivacky FieldDecls.push_back(Field); 2659198893Srdivacky return Field; 2660198092Srdivacky } 2661198893Srdivacky } Callback(*this, TagDecl, FieldDecls); 2662198893Srdivacky 2663198893Srdivacky ParseStructDeclaration(DS, Callback); 2664193326Sed } else { // Handle @defs 2665193326Sed ConsumeToken(); 2666193326Sed if (!Tok.isObjCAtKeyword(tok::objc_defs)) { 2667193326Sed Diag(Tok, diag::err_unexpected_at); 2668203955Srdivacky SkipUntil(tok::semi, true); 2669193326Sed continue; 2670193326Sed } 2671193326Sed ConsumeToken(); 2672193326Sed ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); 2673193326Sed if (!Tok.is(tok::identifier)) { 2674193326Sed Diag(Tok, diag::err_expected_ident); 2675203955Srdivacky SkipUntil(tok::semi, true); 2676193326Sed continue; 2677193326Sed } 2678226633Sdim SmallVector<Decl *, 16> Fields; 2679210299Sed Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), 2680193326Sed Tok.getIdentifierInfo(), Fields); 2681193326Sed FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); 2682193326Sed ConsumeToken(); 2683193326Sed ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); 2684198092Srdivacky } 2685193326Sed 2686193326Sed if (Tok.is(tok::semi)) { 2687193326Sed ConsumeToken(); 2688193326Sed } else if (Tok.is(tok::r_brace)) { 2689203955Srdivacky ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); 2690193326Sed break; 2691193326Sed } else { 2692203955Srdivacky ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 2693203955Srdivacky // Skip to end of block or statement to avoid ext-warning on extra ';'. 2694193326Sed SkipUntil(tok::r_brace, true, true); 2695203955Srdivacky // If we stopped at a ';', eat it. 2696203955Srdivacky if (Tok.is(tok::semi)) ConsumeToken(); 2697193326Sed } 2698193326Sed } 2699198092Srdivacky 2700226633Sdim T.consumeClose(); 2701198092Srdivacky 2702221345Sdim ParsedAttributes attrs(AttrFactory); 2703193326Sed // If attributes exist after struct contents, parse them. 2704218893Sdim MaybeParseGNUAttributes(attrs); 2705193326Sed 2706210299Sed Actions.ActOnFields(getCurScope(), 2707226633Sdim RecordLoc, TagDecl, FieldDecls, 2708226633Sdim T.getOpenLocation(), T.getCloseLocation(), 2709218893Sdim attrs.getList()); 2710193326Sed StructScope.Exit(); 2711226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 2712226633Sdim T.getCloseLocation()); 2713193326Sed} 2714193326Sed 2715193326Sed/// ParseEnumSpecifier 2716193326Sed/// enum-specifier: [C99 6.7.2.2] 2717193326Sed/// 'enum' identifier[opt] '{' enumerator-list '}' 2718193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}' 2719193326Sed/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt] 2720193326Sed/// '}' attributes[opt] 2721234353Sdim/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt] 2722234353Sdim/// '}' 2723193326Sed/// 'enum' identifier 2724193326Sed/// [GNU] 'enum' attributes[opt] identifier 2725193326Sed/// 2726234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}' 2727234353Sdim/// [C++11] enum-head '{' enumerator-list ',' '}' 2728218893Sdim/// 2729234353Sdim/// enum-head: [C++11] 2730234353Sdim/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt] 2731234353Sdim/// enum-key attribute-specifier-seq[opt] nested-name-specifier 2732234353Sdim/// identifier enum-base[opt] 2733218893Sdim/// 2734234353Sdim/// enum-key: [C++11] 2735218893Sdim/// 'enum' 2736218893Sdim/// 'enum' 'class' 2737218893Sdim/// 'enum' 'struct' 2738218893Sdim/// 2739234353Sdim/// enum-base: [C++11] 2740218893Sdim/// ':' type-specifier-seq 2741218893Sdim/// 2742193326Sed/// [C++] elaborated-type-specifier: 2743193326Sed/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier 2744193326Sed/// 2745193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, 2746204643Srdivacky const ParsedTemplateInfo &TemplateInfo, 2747234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 2748193326Sed // Parse the tag portion of this. 2749198092Srdivacky if (Tok.is(tok::code_completion)) { 2750198092Srdivacky // Code completion for an enum name. 2751210299Sed Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); 2752226633Sdim return cutOffParsing(); 2753198092Srdivacky } 2754224145Sdim 2755234353Sdim SourceLocation ScopedEnumKWLoc; 2756224145Sdim bool IsScopedUsingClassTag = false; 2757224145Sdim 2758234353Sdim if (getLangOpts().CPlusPlus0x && 2759224145Sdim (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) { 2760234353Sdim Diag(Tok, diag::warn_cxx98_compat_scoped_enum); 2761224145Sdim IsScopedUsingClassTag = Tok.is(tok::kw_class); 2762234353Sdim ScopedEnumKWLoc = ConsumeToken(); 2763224145Sdim } 2764234353Sdim 2765234353Sdim // C++11 [temp.explicit]p12: The usual access controls do not apply to names 2766234353Sdim // used to specify explicit instantiations. We extend this to also cover 2767234353Sdim // explicit specializations. 2768234353Sdim Sema::SuppressAccessChecksRAII SuppressAccess(Actions, 2769234353Sdim TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 2770234353Sdim TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 2771234353Sdim 2772193326Sed // If attributes exist after tag, parse them. 2773221345Sdim ParsedAttributes attrs(AttrFactory); 2774218893Sdim MaybeParseGNUAttributes(attrs); 2775193326Sed 2776234353Sdim // If declspecs exist after tag, parse them. 2777234353Sdim while (Tok.is(tok::kw___declspec)) 2778234353Sdim ParseMicrosoftDeclSpec(attrs); 2779224145Sdim 2780234353Sdim // Enum definitions should not be parsed in a trailing-return-type. 2781234353Sdim bool AllowDeclaration = DSC != DSC_trailing; 2782234353Sdim 2783234353Sdim bool AllowFixedUnderlyingType = AllowDeclaration && 2784234353Sdim (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt || 2785234353Sdim getLangOpts().ObjC2); 2786234353Sdim 2787208600Srdivacky CXXScopeSpec &SS = DS.getTypeSpecScope(); 2788234353Sdim if (getLangOpts().CPlusPlus) { 2789224145Sdim // "enum foo : bar;" is not a potential typo for "enum foo::bar;" 2790224145Sdim // if a fixed underlying type is allowed. 2791224145Sdim ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); 2792224145Sdim 2793234353Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 2794234353Sdim /*EnteringContext=*/false)) 2795204643Srdivacky return; 2796204643Srdivacky 2797204643Srdivacky if (SS.isSet() && Tok.isNot(tok::identifier)) { 2798193326Sed Diag(Tok, diag::err_expected_ident); 2799193326Sed if (Tok.isNot(tok::l_brace)) { 2800193326Sed // Has no name and is not a definition. 2801193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 2802193326Sed SkipUntil(tok::comma, true); 2803193326Sed return; 2804193326Sed } 2805193326Sed } 2806193326Sed } 2807198092Srdivacky 2808193326Sed // Must have either 'enum name' or 'enum {...}'. 2809219077Sdim if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && 2810234353Sdim !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { 2811193326Sed Diag(Tok, diag::err_expected_ident_lbrace); 2812198092Srdivacky 2813193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 2814193326Sed SkipUntil(tok::comma, true); 2815193326Sed return; 2816193326Sed } 2817198092Srdivacky 2818193326Sed // If an identifier is present, consume and remember it. 2819193326Sed IdentifierInfo *Name = 0; 2820193326Sed SourceLocation NameLoc; 2821193326Sed if (Tok.is(tok::identifier)) { 2822193326Sed Name = Tok.getIdentifierInfo(); 2823193326Sed NameLoc = ConsumeToken(); 2824193326Sed } 2825198092Srdivacky 2826234353Sdim if (!Name && ScopedEnumKWLoc.isValid()) { 2827218893Sdim // C++0x 7.2p2: The optional identifier shall not be omitted in the 2828218893Sdim // declaration of a scoped enumeration. 2829218893Sdim Diag(Tok, diag::err_scoped_enum_missing_identifier); 2830234353Sdim ScopedEnumKWLoc = SourceLocation(); 2831218893Sdim IsScopedUsingClassTag = false; 2832218893Sdim } 2833218893Sdim 2834234353Sdim // Stop suppressing access control now we've parsed the enum name. 2835234353Sdim SuppressAccess.done(); 2836234353Sdim 2837218893Sdim TypeResult BaseType; 2838218893Sdim 2839218893Sdim // Parse the fixed underlying type. 2840219077Sdim if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { 2841218893Sdim bool PossibleBitfield = false; 2842218893Sdim if (getCurScope()->getFlags() & Scope::ClassScope) { 2843218893Sdim // If we're in class scope, this can either be an enum declaration with 2844218893Sdim // an underlying type, or a declaration of a bitfield member. We try to 2845218893Sdim // use a simple disambiguation scheme first to catch the common cases 2846218893Sdim // (integer literal, sizeof); if it's still ambiguous, we then consider 2847218893Sdim // anything that's a simple-type-specifier followed by '(' as an 2848218893Sdim // expression. This suffices because function types are not valid 2849218893Sdim // underlying types anyway. 2850218893Sdim TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind()); 2851218893Sdim // If the next token starts an expression, we know we're parsing a 2852218893Sdim // bit-field. This is the common case. 2853218893Sdim if (TPR == TPResult::True()) 2854218893Sdim PossibleBitfield = true; 2855218893Sdim // If the next token starts a type-specifier-seq, it may be either a 2856218893Sdim // a fixed underlying type or the start of a function-style cast in C++; 2857218893Sdim // lookahead one more token to see if it's obvious that we have a 2858218893Sdim // fixed underlying type. 2859218893Sdim else if (TPR == TPResult::False() && 2860218893Sdim GetLookAheadToken(2).getKind() == tok::semi) { 2861218893Sdim // Consume the ':'. 2862218893Sdim ConsumeToken(); 2863218893Sdim } else { 2864218893Sdim // We have the start of a type-specifier-seq, so we have to perform 2865218893Sdim // tentative parsing to determine whether we have an expression or a 2866218893Sdim // type. 2867218893Sdim TentativeParsingAction TPA(*this); 2868218893Sdim 2869218893Sdim // Consume the ':'. 2870218893Sdim ConsumeToken(); 2871234353Sdim 2872234353Sdim // If we see a type specifier followed by an open-brace, we have an 2873234353Sdim // ambiguity between an underlying type and a C++11 braced 2874234353Sdim // function-style cast. Resolve this by always treating it as an 2875234353Sdim // underlying type. 2876234353Sdim // FIXME: The standard is not entirely clear on how to disambiguate in 2877234353Sdim // this case. 2878234353Sdim if ((getLangOpts().CPlusPlus && 2879234353Sdim isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) || 2880234353Sdim (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) { 2881218893Sdim // We'll parse this as a bitfield later. 2882218893Sdim PossibleBitfield = true; 2883218893Sdim TPA.Revert(); 2884218893Sdim } else { 2885218893Sdim // We have a type-specifier-seq. 2886218893Sdim TPA.Commit(); 2887218893Sdim } 2888218893Sdim } 2889218893Sdim } else { 2890218893Sdim // Consume the ':'. 2891218893Sdim ConsumeToken(); 2892218893Sdim } 2893218893Sdim 2894218893Sdim if (!PossibleBitfield) { 2895218893Sdim SourceRange Range; 2896218893Sdim BaseType = ParseTypeName(&Range); 2897219077Sdim 2898234353Sdim if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2) 2899219077Sdim Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type) 2900219077Sdim << Range; 2901234353Sdim if (getLangOpts().CPlusPlus0x) 2902234353Sdim Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type); 2903218893Sdim } 2904218893Sdim } 2905218893Sdim 2906234353Sdim // There are four options here. If we have 'friend enum foo;' then this is a 2907234353Sdim // friend declaration, and cannot have an accompanying definition. If we have 2908234353Sdim // 'enum foo;', then this is a forward declaration. If we have 2909234353Sdim // 'enum foo {...' then this is a definition. Otherwise we have something 2910234353Sdim // like 'enum foo xyz', a reference. 2911193326Sed // 2912193326Sed // This is needed to handle stuff like this right (C99 6.7.2.3p11): 2913193326Sed // enum foo {..}; void bar() { enum foo; } <- new foo in bar. 2914193326Sed // enum foo {..}; void bar() { enum foo x; } <- use of old foo. 2915193326Sed // 2916212904Sdim Sema::TagUseKind TUK; 2917234353Sdim if (DS.isFriendSpecified()) 2918234353Sdim TUK = Sema::TUK_Friend; 2919234353Sdim else if (!AllowDeclaration) 2920234353Sdim TUK = Sema::TUK_Reference; 2921234353Sdim else if (Tok.is(tok::l_brace)) 2922212904Sdim TUK = Sema::TUK_Definition; 2923234353Sdim else if (Tok.is(tok::semi) && DSC != DSC_type_specifier) 2924212904Sdim TUK = Sema::TUK_Declaration; 2925193326Sed else 2926212904Sdim TUK = Sema::TUK_Reference; 2927234353Sdim 2928234353Sdim MultiTemplateParamsArg TParams; 2929207619Srdivacky if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 2930212904Sdim TUK != Sema::TUK_Reference) { 2931234353Sdim if (!getLangOpts().CPlusPlus0x || !SS.isSet()) { 2932234353Sdim // Skip the rest of this declarator, up until the comma or semicolon. 2933234353Sdim Diag(Tok, diag::err_enum_template); 2934234353Sdim SkipUntil(tok::comma, true); 2935234353Sdim return; 2936234353Sdim } 2937234353Sdim 2938234353Sdim if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 2939234353Sdim // Enumerations can't be explicitly instantiated. 2940234353Sdim DS.SetTypeSpecError(); 2941234353Sdim Diag(StartLoc, diag::err_explicit_instantiation_enum); 2942234353Sdim return; 2943234353Sdim } 2944234353Sdim 2945234353Sdim assert(TemplateInfo.TemplateParams && "no template parameters"); 2946234353Sdim TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(), 2947234353Sdim TemplateInfo.TemplateParams->size()); 2948207619Srdivacky } 2949234353Sdim 2950219077Sdim if (!Name && TUK != Sema::TUK_Definition) { 2951219077Sdim Diag(Tok, diag::err_enumerator_unnamed_no_def); 2952234353Sdim 2953219077Sdim // Skip the rest of this declarator, up until the comma or semicolon. 2954219077Sdim SkipUntil(tok::comma, true); 2955219077Sdim return; 2956219077Sdim } 2957234353Sdim 2958193326Sed bool Owned = false; 2959198092Srdivacky bool IsDependent = false; 2960207619Srdivacky const char *PrevSpec = 0; 2961207619Srdivacky unsigned DiagID; 2962212904Sdim Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, 2963218893Sdim StartLoc, SS, Name, NameLoc, attrs.getList(), 2964234353Sdim AS, DS.getModulePrivateSpecLoc(), TParams, 2965234353Sdim Owned, IsDependent, ScopedEnumKWLoc, 2966218893Sdim IsScopedUsingClassTag, BaseType); 2967218893Sdim 2968207619Srdivacky if (IsDependent) { 2969207619Srdivacky // This enum has a dependent nested-name-specifier. Handle it as a 2970207619Srdivacky // dependent tag. 2971207619Srdivacky if (!Name) { 2972207619Srdivacky DS.SetTypeSpecError(); 2973207619Srdivacky Diag(Tok, diag::err_expected_type_name_after_typename); 2974207619Srdivacky return; 2975207619Srdivacky } 2976207619Srdivacky 2977210299Sed TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum, 2978207619Srdivacky TUK, SS, Name, StartLoc, 2979207619Srdivacky NameLoc); 2980207619Srdivacky if (Type.isInvalid()) { 2981207619Srdivacky DS.SetTypeSpecError(); 2982207619Srdivacky return; 2983207619Srdivacky } 2984207619Srdivacky 2985221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 2986221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 2987221345Sdim PrevSpec, DiagID, Type.get())) 2988207619Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 2989207619Srdivacky 2990207619Srdivacky return; 2991207619Srdivacky } 2992198092Srdivacky 2993212904Sdim if (!TagDecl) { 2994207619Srdivacky // The action failed to produce an enumeration tag. If this is a 2995207619Srdivacky // definition, consume the entire definition. 2996234353Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 2997207619Srdivacky ConsumeBrace(); 2998207619Srdivacky SkipUntil(tok::r_brace); 2999207619Srdivacky } 3000207619Srdivacky 3001207619Srdivacky DS.SetTypeSpecError(); 3002207619Srdivacky return; 3003207619Srdivacky } 3004198092Srdivacky 3005234353Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 3006234353Sdim if (TUK == Sema::TUK_Friend) { 3007234353Sdim Diag(Tok, diag::err_friend_decl_defines_type) 3008234353Sdim << SourceRange(DS.getFriendSpecLoc()); 3009234353Sdim ConsumeBrace(); 3010234353Sdim SkipUntil(tok::r_brace); 3011234353Sdim } else { 3012234353Sdim ParseEnumBody(StartLoc, TagDecl); 3013234353Sdim } 3014234353Sdim } 3015234353Sdim 3016221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, 3017221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3018221345Sdim PrevSpec, DiagID, TagDecl, Owned)) 3019198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3020193326Sed} 3021193326Sed 3022193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list. 3023193326Sed/// enumerator-list: 3024193326Sed/// enumerator 3025193326Sed/// enumerator-list ',' enumerator 3026193326Sed/// enumerator: 3027193326Sed/// enumeration-constant 3028193326Sed/// enumeration-constant '=' constant-expression 3029193326Sed/// enumeration-constant: 3030193326Sed/// identifier 3031193326Sed/// 3032212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { 3033193326Sed // Enter the scope of the enum body and start the definition. 3034193326Sed ParseScope EnumScope(this, Scope::DeclScope); 3035210299Sed Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); 3036193326Sed 3037226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3038226633Sdim T.consumeOpen(); 3039198092Srdivacky 3040193326Sed // C does not allow an empty enumerator-list, C++ does [dcl.enum]. 3041234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) 3042210299Sed Diag(Tok, diag::error_empty_enum); 3043198092Srdivacky 3044226633Sdim SmallVector<Decl *, 32> EnumConstantDecls; 3045193326Sed 3046212904Sdim Decl *LastEnumConstDecl = 0; 3047198092Srdivacky 3048193326Sed // Parse the enumerator-list. 3049193326Sed while (Tok.is(tok::identifier)) { 3050193326Sed IdentifierInfo *Ident = Tok.getIdentifierInfo(); 3051193326Sed SourceLocation IdentLoc = ConsumeToken(); 3052198092Srdivacky 3053218893Sdim // If attributes exist after the enumerator, parse them. 3054221345Sdim ParsedAttributes attrs(AttrFactory); 3055218893Sdim MaybeParseGNUAttributes(attrs); 3056218893Sdim 3057193326Sed SourceLocation EqualLoc; 3058212904Sdim ExprResult AssignedVal; 3059234353Sdim ParsingDeclRAIIObject PD(*this); 3060234353Sdim 3061193326Sed if (Tok.is(tok::equal)) { 3062193326Sed EqualLoc = ConsumeToken(); 3063193326Sed AssignedVal = ParseConstantExpression(); 3064193326Sed if (AssignedVal.isInvalid()) 3065193326Sed SkipUntil(tok::comma, tok::r_brace, true, true); 3066193326Sed } 3067198092Srdivacky 3068193326Sed // Install the enumerator constant into EnumDecl. 3069212904Sdim Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, 3070212904Sdim LastEnumConstDecl, 3071212904Sdim IdentLoc, Ident, 3072218893Sdim attrs.getList(), EqualLoc, 3073212904Sdim AssignedVal.release()); 3074234353Sdim PD.complete(EnumConstDecl); 3075234353Sdim 3076193326Sed EnumConstantDecls.push_back(EnumConstDecl); 3077193326Sed LastEnumConstDecl = EnumConstDecl; 3078198092Srdivacky 3079218893Sdim if (Tok.is(tok::identifier)) { 3080218893Sdim // We're missing a comma between enumerators. 3081218893Sdim SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 3082218893Sdim Diag(Loc, diag::err_enumerator_list_missing_comma) 3083218893Sdim << FixItHint::CreateInsertion(Loc, ", "); 3084218893Sdim continue; 3085218893Sdim } 3086218893Sdim 3087193326Sed if (Tok.isNot(tok::comma)) 3088193326Sed break; 3089193326Sed SourceLocation CommaLoc = ConsumeToken(); 3090198092Srdivacky 3091234353Sdim if (Tok.isNot(tok::identifier)) { 3092234353Sdim if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x) 3093234353Sdim Diag(CommaLoc, diag::ext_enumerator_list_comma) 3094234353Sdim << getLangOpts().CPlusPlus 3095234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3096234353Sdim else if (getLangOpts().CPlusPlus0x) 3097234353Sdim Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma) 3098234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3099234353Sdim } 3100193326Sed } 3101198092Srdivacky 3102193326Sed // Eat the }. 3103226633Sdim T.consumeClose(); 3104193326Sed 3105193326Sed // If attributes exist after the identifier list, parse them. 3106221345Sdim ParsedAttributes attrs(AttrFactory); 3107218893Sdim MaybeParseGNUAttributes(attrs); 3108193326Sed 3109226633Sdim Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), 3110226633Sdim EnumDecl, EnumConstantDecls.data(), 3111226633Sdim EnumConstantDecls.size(), getCurScope(), 3112226633Sdim attrs.getList()); 3113198092Srdivacky 3114193326Sed EnumScope.Exit(); 3115226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, 3116226633Sdim T.getCloseLocation()); 3117193326Sed} 3118193326Sed 3119193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3120193326Sed/// start of a type-qualifier-list. 3121193326Sedbool Parser::isTypeQualifier() const { 3122193326Sed switch (Tok.getKind()) { 3123193326Sed default: return false; 3124221345Sdim 3125221345Sdim // type-qualifier only in OpenCL 3126221345Sdim case tok::kw_private: 3127234353Sdim return getLangOpts().OpenCL; 3128221345Sdim 3129193326Sed // type-qualifier 3130193326Sed case tok::kw_const: 3131193326Sed case tok::kw_volatile: 3132193326Sed case tok::kw_restrict: 3133221345Sdim case tok::kw___private: 3134221345Sdim case tok::kw___local: 3135221345Sdim case tok::kw___global: 3136221345Sdim case tok::kw___constant: 3137221345Sdim case tok::kw___read_only: 3138221345Sdim case tok::kw___read_write: 3139221345Sdim case tok::kw___write_only: 3140193326Sed return true; 3141193326Sed } 3142193326Sed} 3143193326Sed 3144204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token 3145204643Srdivacky/// is definitely a type-specifier. Return false if it isn't part of a type 3146204643Srdivacky/// specifier or if we're not sure. 3147204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { 3148204643Srdivacky switch (Tok.getKind()) { 3149204643Srdivacky default: return false; 3150204643Srdivacky // type-specifiers 3151204643Srdivacky case tok::kw_short: 3152204643Srdivacky case tok::kw_long: 3153221345Sdim case tok::kw___int64: 3154234353Sdim case tok::kw___int128: 3155204643Srdivacky case tok::kw_signed: 3156204643Srdivacky case tok::kw_unsigned: 3157204643Srdivacky case tok::kw__Complex: 3158204643Srdivacky case tok::kw__Imaginary: 3159204643Srdivacky case tok::kw_void: 3160204643Srdivacky case tok::kw_char: 3161204643Srdivacky case tok::kw_wchar_t: 3162204643Srdivacky case tok::kw_char16_t: 3163204643Srdivacky case tok::kw_char32_t: 3164204643Srdivacky case tok::kw_int: 3165226633Sdim case tok::kw_half: 3166204643Srdivacky case tok::kw_float: 3167204643Srdivacky case tok::kw_double: 3168204643Srdivacky case tok::kw_bool: 3169204643Srdivacky case tok::kw__Bool: 3170204643Srdivacky case tok::kw__Decimal32: 3171204643Srdivacky case tok::kw__Decimal64: 3172204643Srdivacky case tok::kw__Decimal128: 3173204643Srdivacky case tok::kw___vector: 3174204643Srdivacky 3175204643Srdivacky // struct-or-union-specifier (C99) or class-specifier (C++) 3176204643Srdivacky case tok::kw_class: 3177204643Srdivacky case tok::kw_struct: 3178204643Srdivacky case tok::kw_union: 3179204643Srdivacky // enum-specifier 3180204643Srdivacky case tok::kw_enum: 3181204643Srdivacky 3182204643Srdivacky // typedef-name 3183204643Srdivacky case tok::annot_typename: 3184204643Srdivacky return true; 3185204643Srdivacky } 3186204643Srdivacky} 3187204643Srdivacky 3188193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3189193326Sed/// start of a specifier-qualifier-list. 3190193326Sedbool Parser::isTypeSpecifierQualifier() { 3191193326Sed switch (Tok.getKind()) { 3192193326Sed default: return false; 3193198092Srdivacky 3194193326Sed case tok::identifier: // foo::bar 3195203955Srdivacky if (TryAltiVecVectorToken()) 3196203955Srdivacky return true; 3197203955Srdivacky // Fall through. 3198193326Sed case tok::kw_typename: // typename T::type 3199193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3200193326Sed // recurse to handle whatever we get. 3201193326Sed if (TryAnnotateTypeOrScopeToken()) 3202204643Srdivacky return true; 3203204643Srdivacky if (Tok.is(tok::identifier)) 3204204643Srdivacky return false; 3205204643Srdivacky return isTypeSpecifierQualifier(); 3206193326Sed 3207193326Sed case tok::coloncolon: // ::foo::bar 3208193326Sed if (NextToken().is(tok::kw_new) || // ::new 3209193326Sed NextToken().is(tok::kw_delete)) // ::delete 3210193326Sed return false; 3211193326Sed 3212193326Sed if (TryAnnotateTypeOrScopeToken()) 3213204643Srdivacky return true; 3214204643Srdivacky return isTypeSpecifierQualifier(); 3215198092Srdivacky 3216193326Sed // GNU attributes support. 3217193326Sed case tok::kw___attribute: 3218193326Sed // GNU typeof support. 3219193326Sed case tok::kw_typeof: 3220198092Srdivacky 3221193326Sed // type-specifiers 3222193326Sed case tok::kw_short: 3223193326Sed case tok::kw_long: 3224221345Sdim case tok::kw___int64: 3225234353Sdim case tok::kw___int128: 3226193326Sed case tok::kw_signed: 3227193326Sed case tok::kw_unsigned: 3228193326Sed case tok::kw__Complex: 3229193326Sed case tok::kw__Imaginary: 3230193326Sed case tok::kw_void: 3231193326Sed case tok::kw_char: 3232193326Sed case tok::kw_wchar_t: 3233198092Srdivacky case tok::kw_char16_t: 3234198092Srdivacky case tok::kw_char32_t: 3235193326Sed case tok::kw_int: 3236226633Sdim case tok::kw_half: 3237193326Sed case tok::kw_float: 3238193326Sed case tok::kw_double: 3239193326Sed case tok::kw_bool: 3240193326Sed case tok::kw__Bool: 3241193326Sed case tok::kw__Decimal32: 3242193326Sed case tok::kw__Decimal64: 3243193326Sed case tok::kw__Decimal128: 3244203955Srdivacky case tok::kw___vector: 3245198092Srdivacky 3246193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 3247193326Sed case tok::kw_class: 3248193326Sed case tok::kw_struct: 3249193326Sed case tok::kw_union: 3250193326Sed // enum-specifier 3251193326Sed case tok::kw_enum: 3252198092Srdivacky 3253193326Sed // type-qualifier 3254193326Sed case tok::kw_const: 3255193326Sed case tok::kw_volatile: 3256193326Sed case tok::kw_restrict: 3257193326Sed 3258193326Sed // typedef-name 3259193326Sed case tok::annot_typename: 3260193326Sed return true; 3261198092Srdivacky 3262193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 3263193326Sed case tok::less: 3264234353Sdim return getLangOpts().ObjC1; 3265198092Srdivacky 3266193326Sed case tok::kw___cdecl: 3267193326Sed case tok::kw___stdcall: 3268193326Sed case tok::kw___fastcall: 3269208600Srdivacky case tok::kw___thiscall: 3270194179Sed case tok::kw___w64: 3271194179Sed case tok::kw___ptr64: 3272226633Sdim case tok::kw___ptr32: 3273212904Sdim case tok::kw___pascal: 3274226633Sdim case tok::kw___unaligned: 3275221345Sdim 3276221345Sdim case tok::kw___private: 3277221345Sdim case tok::kw___local: 3278221345Sdim case tok::kw___global: 3279221345Sdim case tok::kw___constant: 3280221345Sdim case tok::kw___read_only: 3281221345Sdim case tok::kw___read_write: 3282221345Sdim case tok::kw___write_only: 3283221345Sdim 3284194179Sed return true; 3285221345Sdim 3286221345Sdim case tok::kw_private: 3287234353Sdim return getLangOpts().OpenCL; 3288226633Sdim 3289234353Sdim // C11 _Atomic() 3290226633Sdim case tok::kw__Atomic: 3291226633Sdim return true; 3292193326Sed } 3293193326Sed} 3294193326Sed 3295193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a 3296193326Sed/// declaration specifier. 3297218893Sdim/// 3298218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of 3299218893Sdim/// this check is to disambiguate between an expression and a declaration. 3300218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { 3301193326Sed switch (Tok.getKind()) { 3302193326Sed default: return false; 3303198092Srdivacky 3304221345Sdim case tok::kw_private: 3305234353Sdim return getLangOpts().OpenCL; 3306221345Sdim 3307193326Sed case tok::identifier: // foo::bar 3308193326Sed // Unfortunate hack to support "Class.factoryMethod" notation. 3309234353Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::period)) 3310193326Sed return false; 3311203955Srdivacky if (TryAltiVecVectorToken()) 3312203955Srdivacky return true; 3313203955Srdivacky // Fall through. 3314234353Sdim case tok::kw_decltype: // decltype(T())::type 3315193326Sed case tok::kw_typename: // typename T::type 3316193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3317193326Sed // recurse to handle whatever we get. 3318193326Sed if (TryAnnotateTypeOrScopeToken()) 3319204643Srdivacky return true; 3320204643Srdivacky if (Tok.is(tok::identifier)) 3321204643Srdivacky return false; 3322218893Sdim 3323218893Sdim // If we're in Objective-C and we have an Objective-C class type followed 3324218893Sdim // by an identifier and then either ':' or ']', in a place where an 3325218893Sdim // expression is permitted, then this is probably a class message send 3326218893Sdim // missing the initial '['. In this case, we won't consider this to be 3327218893Sdim // the start of a declaration. 3328218893Sdim if (DisambiguatingWithExpression && 3329218893Sdim isStartOfObjCClassMessageMissingOpenBracket()) 3330218893Sdim return false; 3331218893Sdim 3332204643Srdivacky return isDeclarationSpecifier(); 3333204643Srdivacky 3334193326Sed case tok::coloncolon: // ::foo::bar 3335193326Sed if (NextToken().is(tok::kw_new) || // ::new 3336193326Sed NextToken().is(tok::kw_delete)) // ::delete 3337193326Sed return false; 3338198092Srdivacky 3339193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3340193326Sed // recurse to handle whatever we get. 3341193326Sed if (TryAnnotateTypeOrScopeToken()) 3342204643Srdivacky return true; 3343204643Srdivacky return isDeclarationSpecifier(); 3344198092Srdivacky 3345193326Sed // storage-class-specifier 3346193326Sed case tok::kw_typedef: 3347193326Sed case tok::kw_extern: 3348193326Sed case tok::kw___private_extern__: 3349193326Sed case tok::kw_static: 3350193326Sed case tok::kw_auto: 3351193326Sed case tok::kw_register: 3352193326Sed case tok::kw___thread: 3353198092Srdivacky 3354226633Sdim // Modules 3355226633Sdim case tok::kw___module_private__: 3356226633Sdim 3357193326Sed // type-specifiers 3358193326Sed case tok::kw_short: 3359193326Sed case tok::kw_long: 3360221345Sdim case tok::kw___int64: 3361234353Sdim case tok::kw___int128: 3362193326Sed case tok::kw_signed: 3363193326Sed case tok::kw_unsigned: 3364193326Sed case tok::kw__Complex: 3365193326Sed case tok::kw__Imaginary: 3366193326Sed case tok::kw_void: 3367193326Sed case tok::kw_char: 3368193326Sed case tok::kw_wchar_t: 3369198092Srdivacky case tok::kw_char16_t: 3370198092Srdivacky case tok::kw_char32_t: 3371198092Srdivacky 3372193326Sed case tok::kw_int: 3373226633Sdim case tok::kw_half: 3374193326Sed case tok::kw_float: 3375193326Sed case tok::kw_double: 3376193326Sed case tok::kw_bool: 3377193326Sed case tok::kw__Bool: 3378193326Sed case tok::kw__Decimal32: 3379193326Sed case tok::kw__Decimal64: 3380193326Sed case tok::kw__Decimal128: 3381203955Srdivacky case tok::kw___vector: 3382198092Srdivacky 3383193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 3384193326Sed case tok::kw_class: 3385193326Sed case tok::kw_struct: 3386193326Sed case tok::kw_union: 3387193326Sed // enum-specifier 3388193326Sed case tok::kw_enum: 3389198092Srdivacky 3390193326Sed // type-qualifier 3391193326Sed case tok::kw_const: 3392193326Sed case tok::kw_volatile: 3393193326Sed case tok::kw_restrict: 3394193326Sed 3395193326Sed // function-specifier 3396193326Sed case tok::kw_inline: 3397193326Sed case tok::kw_virtual: 3398193326Sed case tok::kw_explicit: 3399193326Sed 3400221345Sdim // static_assert-declaration 3401221345Sdim case tok::kw__Static_assert: 3402193326Sed 3403193326Sed // GNU typeof support. 3404193326Sed case tok::kw_typeof: 3405198092Srdivacky 3406193326Sed // GNU attributes. 3407193326Sed case tok::kw___attribute: 3408193326Sed return true; 3409198092Srdivacky 3410224145Sdim // C++0x decltype. 3411234353Sdim case tok::annot_decltype: 3412224145Sdim return true; 3413224145Sdim 3414234353Sdim // C11 _Atomic() 3415226633Sdim case tok::kw__Atomic: 3416226633Sdim return true; 3417226633Sdim 3418193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 3419193326Sed case tok::less: 3420234353Sdim return getLangOpts().ObjC1; 3421198092Srdivacky 3422221345Sdim // typedef-name 3423221345Sdim case tok::annot_typename: 3424221345Sdim return !DisambiguatingWithExpression || 3425221345Sdim !isStartOfObjCClassMessageMissingOpenBracket(); 3426221345Sdim 3427193326Sed case tok::kw___declspec: 3428193326Sed case tok::kw___cdecl: 3429193326Sed case tok::kw___stdcall: 3430193326Sed case tok::kw___fastcall: 3431208600Srdivacky case tok::kw___thiscall: 3432194179Sed case tok::kw___w64: 3433194179Sed case tok::kw___ptr64: 3434226633Sdim case tok::kw___ptr32: 3435194179Sed case tok::kw___forceinline: 3436212904Sdim case tok::kw___pascal: 3437226633Sdim case tok::kw___unaligned: 3438221345Sdim 3439221345Sdim case tok::kw___private: 3440221345Sdim case tok::kw___local: 3441221345Sdim case tok::kw___global: 3442221345Sdim case tok::kw___constant: 3443221345Sdim case tok::kw___read_only: 3444221345Sdim case tok::kw___read_write: 3445221345Sdim case tok::kw___write_only: 3446221345Sdim 3447194179Sed return true; 3448193326Sed } 3449193326Sed} 3450193326Sed 3451202379Srdivackybool Parser::isConstructorDeclarator() { 3452202379Srdivacky TentativeParsingAction TPA(*this); 3453193326Sed 3454202379Srdivacky // Parse the C++ scope specifier. 3455202379Srdivacky CXXScopeSpec SS; 3456234353Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3457234353Sdim /*EnteringContext=*/true)) { 3458204643Srdivacky TPA.Revert(); 3459204643Srdivacky return false; 3460204643Srdivacky } 3461202379Srdivacky 3462202379Srdivacky // Parse the constructor name. 3463202379Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 3464202379Srdivacky // We already know that we have a constructor name; just consume 3465202379Srdivacky // the token. 3466202379Srdivacky ConsumeToken(); 3467202379Srdivacky } else { 3468202379Srdivacky TPA.Revert(); 3469202379Srdivacky return false; 3470202379Srdivacky } 3471202379Srdivacky 3472234353Sdim // Current class name must be followed by a left parenthesis. 3473202379Srdivacky if (Tok.isNot(tok::l_paren)) { 3474202379Srdivacky TPA.Revert(); 3475202379Srdivacky return false; 3476202379Srdivacky } 3477202379Srdivacky ConsumeParen(); 3478202379Srdivacky 3479234353Sdim // A right parenthesis, or ellipsis followed by a right parenthesis signals 3480234353Sdim // that we have a constructor. 3481234353Sdim if (Tok.is(tok::r_paren) || 3482234353Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) { 3483202379Srdivacky TPA.Revert(); 3484202379Srdivacky return true; 3485202379Srdivacky } 3486202379Srdivacky 3487202379Srdivacky // If we need to, enter the specified scope. 3488202379Srdivacky DeclaratorScopeObj DeclScopeObj(*this, SS); 3489210299Sed if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 3490202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 3491202379Srdivacky 3492218893Sdim // Optionally skip Microsoft attributes. 3493221345Sdim ParsedAttributes Attrs(AttrFactory); 3494218893Sdim MaybeParseMicrosoftAttributes(Attrs); 3495218893Sdim 3496202379Srdivacky // Check whether the next token(s) are part of a declaration 3497202379Srdivacky // specifier, in which case we have the start of a parameter and, 3498202379Srdivacky // therefore, we know that this is a constructor. 3499234353Sdim bool IsConstructor = false; 3500234353Sdim if (isDeclarationSpecifier()) 3501234353Sdim IsConstructor = true; 3502234353Sdim else if (Tok.is(tok::identifier) || 3503234353Sdim (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) { 3504234353Sdim // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type. 3505234353Sdim // This might be a parenthesized member name, but is more likely to 3506234353Sdim // be a constructor declaration with an invalid argument type. Keep 3507234353Sdim // looking. 3508234353Sdim if (Tok.is(tok::annot_cxxscope)) 3509234353Sdim ConsumeToken(); 3510234353Sdim ConsumeToken(); 3511234353Sdim 3512234353Sdim // If this is not a constructor, we must be parsing a declarator, 3513234353Sdim // which must have one of the following syntactic forms (see the 3514234353Sdim // grammar extract at the start of ParseDirectDeclarator): 3515234353Sdim switch (Tok.getKind()) { 3516234353Sdim case tok::l_paren: 3517234353Sdim // C(X ( int)); 3518234353Sdim case tok::l_square: 3519234353Sdim // C(X [ 5]); 3520234353Sdim // C(X [ [attribute]]); 3521234353Sdim case tok::coloncolon: 3522234353Sdim // C(X :: Y); 3523234353Sdim // C(X :: *p); 3524234353Sdim case tok::r_paren: 3525234353Sdim // C(X ) 3526234353Sdim // Assume this isn't a constructor, rather than assuming it's a 3527234353Sdim // constructor with an unnamed parameter of an ill-formed type. 3528234353Sdim break; 3529234353Sdim 3530234353Sdim default: 3531234353Sdim IsConstructor = true; 3532234353Sdim break; 3533234353Sdim } 3534234353Sdim } 3535234353Sdim 3536202379Srdivacky TPA.Revert(); 3537202379Srdivacky return IsConstructor; 3538202379Srdivacky} 3539202379Srdivacky 3540193326Sed/// ParseTypeQualifierListOpt 3541212904Sdim/// type-qualifier-list: [C99 6.7.5] 3542212904Sdim/// type-qualifier 3543212904Sdim/// [vendor] attributes 3544212904Sdim/// [ only if VendorAttributesAllowed=true ] 3545212904Sdim/// type-qualifier-list type-qualifier 3546212904Sdim/// [vendor] type-qualifier-list attributes 3547212904Sdim/// [ only if VendorAttributesAllowed=true ] 3548212904Sdim/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq 3549212904Sdim/// [ only if CXX0XAttributesAllowed=true ] 3550212904Sdim/// Note: vendor can be GNU, MS, etc. 3551193326Sed/// 3552212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS, 3553212904Sdim bool VendorAttributesAllowed, 3554234353Sdim bool CXX11AttributesAllowed) { 3555234353Sdim if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed && 3556234353Sdim isCXX11AttributeSpecifier()) { 3557221345Sdim ParsedAttributesWithRange attrs(AttrFactory); 3558234353Sdim ParseCXX11Attributes(attrs); 3559234353Sdim DS.takeAttributesFrom(attrs); 3560199990Srdivacky } 3561221345Sdim 3562221345Sdim SourceLocation EndLoc; 3563221345Sdim 3564193326Sed while (1) { 3565198092Srdivacky bool isInvalid = false; 3566193326Sed const char *PrevSpec = 0; 3567198092Srdivacky unsigned DiagID = 0; 3568193326Sed SourceLocation Loc = Tok.getLocation(); 3569193326Sed 3570193326Sed switch (Tok.getKind()) { 3571212904Sdim case tok::code_completion: 3572212904Sdim Actions.CodeCompleteTypeQualifiers(DS); 3573226633Sdim return cutOffParsing(); 3574212904Sdim 3575193326Sed case tok::kw_const: 3576198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, 3577234353Sdim getLangOpts()); 3578193326Sed break; 3579193326Sed case tok::kw_volatile: 3580198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 3581234353Sdim getLangOpts()); 3582193326Sed break; 3583193326Sed case tok::kw_restrict: 3584198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 3585234353Sdim getLangOpts()); 3586193326Sed break; 3587221345Sdim 3588221345Sdim // OpenCL qualifiers: 3589221345Sdim case tok::kw_private: 3590234353Sdim if (!getLangOpts().OpenCL) 3591221345Sdim goto DoneWithTypeQuals; 3592221345Sdim case tok::kw___private: 3593221345Sdim case tok::kw___global: 3594221345Sdim case tok::kw___local: 3595221345Sdim case tok::kw___constant: 3596221345Sdim case tok::kw___read_only: 3597221345Sdim case tok::kw___write_only: 3598221345Sdim case tok::kw___read_write: 3599221345Sdim ParseOpenCLQualifiers(DS); 3600221345Sdim break; 3601221345Sdim 3602194179Sed case tok::kw___w64: 3603193326Sed case tok::kw___ptr64: 3604226633Sdim case tok::kw___ptr32: 3605193326Sed case tok::kw___cdecl: 3606193326Sed case tok::kw___stdcall: 3607193326Sed case tok::kw___fastcall: 3608208600Srdivacky case tok::kw___thiscall: 3609226633Sdim case tok::kw___unaligned: 3610212904Sdim if (VendorAttributesAllowed) { 3611218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 3612194179Sed continue; 3613194179Sed } 3614194179Sed goto DoneWithTypeQuals; 3615212904Sdim case tok::kw___pascal: 3616212904Sdim if (VendorAttributesAllowed) { 3617218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 3618212904Sdim continue; 3619212904Sdim } 3620212904Sdim goto DoneWithTypeQuals; 3621193326Sed case tok::kw___attribute: 3622212904Sdim if (VendorAttributesAllowed) { 3623218893Sdim ParseGNUAttributes(DS.getAttributes()); 3624193326Sed continue; // do *not* consume the next token! 3625193326Sed } 3626193326Sed // otherwise, FALL THROUGH! 3627193326Sed default: 3628193326Sed DoneWithTypeQuals: 3629193326Sed // If this is not a type-qualifier token, we're done reading type 3630193326Sed // qualifiers. First verify that DeclSpec's are consistent. 3631193326Sed DS.Finish(Diags, PP); 3632221345Sdim if (EndLoc.isValid()) 3633221345Sdim DS.SetRangeEnd(EndLoc); 3634193326Sed return; 3635193326Sed } 3636193326Sed 3637193326Sed // If the specifier combination wasn't legal, issue a diagnostic. 3638193326Sed if (isInvalid) { 3639193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 3640193326Sed Diag(Tok, DiagID) << PrevSpec; 3641193326Sed } 3642221345Sdim EndLoc = ConsumeToken(); 3643193326Sed } 3644193326Sed} 3645193326Sed 3646193326Sed 3647193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator. 3648193326Sed/// 3649193326Sedvoid Parser::ParseDeclarator(Declarator &D) { 3650193326Sed /// This implements the 'declarator' production in the C grammar, then checks 3651193326Sed /// for well-formedness and issues diagnostics. 3652193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 3653193326Sed} 3654193326Sed 3655234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { 3656234353Sdim if (Kind == tok::star || Kind == tok::caret) 3657234353Sdim return true; 3658234353Sdim 3659234353Sdim // We parse rvalue refs in C++03, because otherwise the errors are scary. 3660234353Sdim if (!Lang.CPlusPlus) 3661234353Sdim return false; 3662234353Sdim 3663234353Sdim return Kind == tok::amp || Kind == tok::ampamp; 3664234353Sdim} 3665234353Sdim 3666193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator 3667193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator 3668193326Sed/// isn't parsed at all, making this function effectively parse the C++ 3669193326Sed/// ptr-operator production. 3670193326Sed/// 3671234353Sdim/// If the grammar of this construct is extended, matching changes must also be 3672234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to 3673234353Sdim/// isConstructorDeclarator. 3674234353Sdim/// 3675193326Sed/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] 3676193326Sed/// [C] pointer[opt] direct-declarator 3677193326Sed/// [C++] direct-declarator 3678193326Sed/// [C++] ptr-operator declarator 3679193326Sed/// 3680193326Sed/// pointer: [C99 6.7.5] 3681193326Sed/// '*' type-qualifier-list[opt] 3682193326Sed/// '*' type-qualifier-list[opt] pointer 3683193326Sed/// 3684193326Sed/// ptr-operator: 3685193326Sed/// '*' cv-qualifier-seq[opt] 3686193326Sed/// '&' 3687193326Sed/// [C++0x] '&&' 3688193326Sed/// [GNU] '&' restrict[opt] attributes[opt] 3689193326Sed/// [GNU?] '&&' restrict[opt] attributes[opt] 3690193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 3691193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D, 3692193326Sed DirectDeclParseFunction DirectDeclParser) { 3693198092Srdivacky if (Diags.hasAllExtensionsSilenced()) 3694198092Srdivacky D.setExtension(); 3695212904Sdim 3696193326Sed // C++ member pointers start with a '::' or a nested-name. 3697193326Sed // Member pointers get special handling, since there's no place for the 3698193326Sed // scope spec in the generic path below. 3699234353Sdim if (getLangOpts().CPlusPlus && 3700193326Sed (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || 3701193326Sed Tok.is(tok::annot_cxxscope))) { 3702234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 3703234353Sdim D.getContext() == Declarator::MemberContext; 3704193326Sed CXXScopeSpec SS; 3705234353Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); 3706204643Srdivacky 3707207619Srdivacky if (SS.isNotEmpty()) { 3708198092Srdivacky if (Tok.isNot(tok::star)) { 3709193326Sed // The scope spec really belongs to the direct-declarator. 3710193326Sed D.getCXXScopeSpec() = SS; 3711193326Sed if (DirectDeclParser) 3712193326Sed (this->*DirectDeclParser)(D); 3713193326Sed return; 3714193326Sed } 3715193326Sed 3716193326Sed SourceLocation Loc = ConsumeToken(); 3717193326Sed D.SetRangeEnd(Loc); 3718221345Sdim DeclSpec DS(AttrFactory); 3719193326Sed ParseTypeQualifierListOpt(DS); 3720193326Sed D.ExtendWithDeclSpec(DS); 3721193326Sed 3722193326Sed // Recurse to parse whatever is left. 3723193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 3724193326Sed 3725193326Sed // Sema will have to catch (syntactically invalid) pointers into global 3726193326Sed // scope. It has to catch pointers into namespace scope anyway. 3727193326Sed D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), 3728221345Sdim Loc), 3729221345Sdim DS.getAttributes(), 3730193326Sed /* Don't replace range end. */SourceLocation()); 3731193326Sed return; 3732193326Sed } 3733193326Sed } 3734193326Sed 3735193326Sed tok::TokenKind Kind = Tok.getKind(); 3736193326Sed // Not a pointer, C++ reference, or block. 3737234353Sdim if (!isPtrOperatorToken(Kind, getLangOpts())) { 3738193326Sed if (DirectDeclParser) 3739193326Sed (this->*DirectDeclParser)(D); 3740193326Sed return; 3741193326Sed } 3742193326Sed 3743193326Sed // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference, 3744193326Sed // '&&' -> rvalue reference 3745193326Sed SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. 3746193326Sed D.SetRangeEnd(Loc); 3747193326Sed 3748193326Sed if (Kind == tok::star || Kind == tok::caret) { 3749193326Sed // Is a pointer. 3750221345Sdim DeclSpec DS(AttrFactory); 3751193326Sed 3752234353Sdim // FIXME: GNU attributes are not allowed here in a new-type-id. 3753193326Sed ParseTypeQualifierListOpt(DS); 3754193326Sed D.ExtendWithDeclSpec(DS); 3755193326Sed 3756193326Sed // Recursively parse the declarator. 3757193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 3758193326Sed if (Kind == tok::star) 3759193326Sed // Remember that we parsed a pointer type, and remember the type-quals. 3760193326Sed D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, 3761219077Sdim DS.getConstSpecLoc(), 3762219077Sdim DS.getVolatileSpecLoc(), 3763221345Sdim DS.getRestrictSpecLoc()), 3764221345Sdim DS.getAttributes(), 3765193326Sed SourceLocation()); 3766193326Sed else 3767193326Sed // Remember that we parsed a Block type, and remember the type-quals. 3768198092Srdivacky D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), 3769221345Sdim Loc), 3770221345Sdim DS.getAttributes(), 3771193326Sed SourceLocation()); 3772193326Sed } else { 3773193326Sed // Is a reference 3774221345Sdim DeclSpec DS(AttrFactory); 3775193326Sed 3776193326Sed // Complain about rvalue references in C++03, but then go on and build 3777193326Sed // the declarator. 3778234353Sdim if (Kind == tok::ampamp) 3779234353Sdim Diag(Loc, getLangOpts().CPlusPlus0x ? 3780234353Sdim diag::warn_cxx98_compat_rvalue_reference : 3781234353Sdim diag::ext_rvalue_reference); 3782193326Sed 3783234353Sdim // GNU-style and C++11 attributes are allowed here, as is restrict. 3784234353Sdim ParseTypeQualifierListOpt(DS); 3785234353Sdim D.ExtendWithDeclSpec(DS); 3786234353Sdim 3787193326Sed // C++ 8.3.2p1: cv-qualified references are ill-formed except when the 3788193326Sed // cv-qualifiers are introduced through the use of a typedef or of a 3789193326Sed // template type argument, in which case the cv-qualifiers are ignored. 3790193326Sed if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { 3791193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 3792193326Sed Diag(DS.getConstSpecLoc(), 3793193326Sed diag::err_invalid_reference_qualifier_application) << "const"; 3794193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) 3795193326Sed Diag(DS.getVolatileSpecLoc(), 3796193326Sed diag::err_invalid_reference_qualifier_application) << "volatile"; 3797193326Sed } 3798193326Sed 3799193326Sed // Recursively parse the declarator. 3800193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 3801193326Sed 3802193326Sed if (D.getNumTypeObjects() > 0) { 3803193326Sed // C++ [dcl.ref]p4: There shall be no references to references. 3804193326Sed DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1); 3805193326Sed if (InnerChunk.Kind == DeclaratorChunk::Reference) { 3806193326Sed if (const IdentifierInfo *II = D.getIdentifier()) 3807193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 3808193326Sed << II; 3809193326Sed else 3810193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 3811193326Sed << "type name"; 3812193326Sed 3813193326Sed // Once we've complained about the reference-to-reference, we 3814193326Sed // can go ahead and build the (technically ill-formed) 3815193326Sed // declarator: reference collapsing will take care of it. 3816193326Sed } 3817193326Sed } 3818193326Sed 3819193326Sed // Remember that we parsed a reference type. It doesn't have type-quals. 3820193326Sed D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, 3821193326Sed Kind == tok::amp), 3822221345Sdim DS.getAttributes(), 3823193326Sed SourceLocation()); 3824193326Sed } 3825193326Sed} 3826193326Sed 3827234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D, 3828234353Sdim SourceLocation EllipsisLoc) { 3829234353Sdim if (EllipsisLoc.isValid()) { 3830234353Sdim FixItHint Insertion; 3831234353Sdim if (!D.getEllipsisLoc().isValid()) { 3832234353Sdim Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "..."); 3833234353Sdim D.setEllipsisLoc(EllipsisLoc); 3834234353Sdim } 3835234353Sdim P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration) 3836234353Sdim << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName(); 3837234353Sdim } 3838234353Sdim} 3839234353Sdim 3840193326Sed/// ParseDirectDeclarator 3841193326Sed/// direct-declarator: [C99 6.7.5] 3842193326Sed/// [C99] identifier 3843193326Sed/// '(' declarator ')' 3844193326Sed/// [GNU] '(' attributes declarator ')' 3845193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 3846193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 3847193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 3848193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 3849193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 3850234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 3851234353Sdim/// attribute-specifier-seq[opt] 3852193326Sed/// direct-declarator '(' parameter-type-list ')' 3853193326Sed/// direct-declarator '(' identifier-list[opt] ')' 3854193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 3855193326Sed/// parameter-type-list[opt] ')' 3856193326Sed/// [C++] direct-declarator '(' parameter-declaration-clause ')' 3857193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 3858234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')' 3859234353Sdim/// attribute-specifier-seq[opt] cv-qualifier-seq[opt] 3860234353Sdim/// ref-qualifier[opt] exception-specification[opt] 3861193326Sed/// [C++] declarator-id 3862234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt] 3863193326Sed/// 3864193326Sed/// declarator-id: [C++ 8] 3865218893Sdim/// '...'[opt] id-expression 3866193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 3867193326Sed/// 3868193326Sed/// id-expression: [C++ 5.1] 3869193326Sed/// unqualified-id 3870198092Srdivacky/// qualified-id 3871193326Sed/// 3872193326Sed/// unqualified-id: [C++ 5.1] 3873198092Srdivacky/// identifier 3874193326Sed/// operator-function-id 3875198092Srdivacky/// conversion-function-id 3876198092Srdivacky/// '~' class-name 3877193326Sed/// template-id 3878193326Sed/// 3879234353Sdim/// Note, any additional constructs added here may need corresponding changes 3880234353Sdim/// in isConstructorDeclarator. 3881193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) { 3882193326Sed DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); 3883193326Sed 3884234353Sdim if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) { 3885198893Srdivacky // ParseDeclaratorInternal might already have parsed the scope. 3886207619Srdivacky if (D.getCXXScopeSpec().isEmpty()) { 3887234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 3888234353Sdim D.getContext() == Declarator::MemberContext; 3889234353Sdim ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), 3890234353Sdim EnteringContext); 3891204643Srdivacky } 3892204643Srdivacky 3893207619Srdivacky if (D.getCXXScopeSpec().isValid()) { 3894210299Sed if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 3895200583Srdivacky // Change the declaration context for name lookup, until this function 3896200583Srdivacky // is exited (and the declarator has been parsed). 3897200583Srdivacky DeclScopeObj.EnterDeclaratorScope(); 3898207619Srdivacky } 3899207619Srdivacky 3900218893Sdim // C++0x [dcl.fct]p14: 3901218893Sdim // There is a syntactic ambiguity when an ellipsis occurs at the end 3902218893Sdim // of a parameter-declaration-clause without a preceding comma. In 3903218893Sdim // this case, the ellipsis is parsed as part of the 3904218893Sdim // abstract-declarator if the type of the parameter names a template 3905218893Sdim // parameter pack that has not been expanded; otherwise, it is parsed 3906218893Sdim // as part of the parameter-declaration-clause. 3907234353Sdim if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && 3908218893Sdim !((D.getContext() == Declarator::PrototypeContext || 3909218893Sdim D.getContext() == Declarator::BlockLiteralContext) && 3910218893Sdim NextToken().is(tok::r_paren) && 3911234353Sdim !Actions.containsUnexpandedParameterPacks(D))) { 3912234353Sdim SourceLocation EllipsisLoc = ConsumeToken(); 3913234353Sdim if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { 3914234353Sdim // The ellipsis was put in the wrong place. Recover, and explain to 3915234353Sdim // the user what they should have done. 3916234353Sdim ParseDeclarator(D); 3917234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 3918234353Sdim return; 3919234353Sdim } else 3920234353Sdim D.setEllipsisLoc(EllipsisLoc); 3921234353Sdim 3922234353Sdim // The ellipsis can't be followed by a parenthesized declarator. We 3923234353Sdim // check for that in ParseParenDeclarator, after we have disambiguated 3924234353Sdim // the l_paren token. 3925234353Sdim } 3926234353Sdim 3927198893Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 3928198893Srdivacky Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { 3929198893Srdivacky // We found something that indicates the start of an unqualified-id. 3930198893Srdivacky // Parse that unqualified-id. 3931207619Srdivacky bool AllowConstructorName; 3932207619Srdivacky if (D.getDeclSpec().hasTypeSpecifier()) 3933207619Srdivacky AllowConstructorName = false; 3934207619Srdivacky else if (D.getCXXScopeSpec().isSet()) 3935207619Srdivacky AllowConstructorName = 3936207619Srdivacky (D.getContext() == Declarator::FileContext || 3937207619Srdivacky (D.getContext() == Declarator::MemberContext && 3938207619Srdivacky D.getDeclSpec().isFriendSpecified())); 3939207619Srdivacky else 3940207619Srdivacky AllowConstructorName = (D.getContext() == Declarator::MemberContext); 3941207619Srdivacky 3942234353Sdim SourceLocation TemplateKWLoc; 3943198893Srdivacky if (ParseUnqualifiedId(D.getCXXScopeSpec(), 3944198893Srdivacky /*EnteringContext=*/true, 3945198893Srdivacky /*AllowDestructorName=*/true, 3946202379Srdivacky AllowConstructorName, 3947212904Sdim ParsedType(), 3948234353Sdim TemplateKWLoc, 3949207619Srdivacky D.getName()) || 3950207619Srdivacky // Once we're past the identifier, if the scope was bad, mark the 3951207619Srdivacky // whole declarator bad. 3952207619Srdivacky D.getCXXScopeSpec().isInvalid()) { 3953193326Sed D.SetIdentifier(0, Tok.getLocation()); 3954193326Sed D.setInvalidType(true); 3955198893Srdivacky } else { 3956198893Srdivacky // Parsed the unqualified-id; update range information and move along. 3957198893Srdivacky if (D.getSourceRange().getBegin().isInvalid()) 3958198893Srdivacky D.SetRangeBegin(D.getName().getSourceRange().getBegin()); 3959198893Srdivacky D.SetRangeEnd(D.getName().getSourceRange().getEnd()); 3960193326Sed } 3961198893Srdivacky goto PastIdentifier; 3962193326Sed } 3963198893Srdivacky } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { 3964234353Sdim assert(!getLangOpts().CPlusPlus && 3965193326Sed "There's a C++-specific check for tok::identifier above"); 3966193326Sed assert(Tok.getIdentifierInfo() && "Not an identifier?"); 3967193326Sed D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 3968193326Sed ConsumeToken(); 3969198893Srdivacky goto PastIdentifier; 3970198893Srdivacky } 3971234353Sdim 3972198893Srdivacky if (Tok.is(tok::l_paren)) { 3973193326Sed // direct-declarator: '(' declarator ')' 3974193326Sed // direct-declarator: '(' attributes declarator ')' 3975193326Sed // Example: 'char (*X)' or 'int (*XX)(void)' 3976193326Sed ParseParenDeclarator(D); 3977202379Srdivacky 3978202379Srdivacky // If the declarator was parenthesized, we entered the declarator 3979202379Srdivacky // scope when parsing the parenthesized declarator, then exited 3980202379Srdivacky // the scope already. Re-enter the scope, if we need to. 3981202379Srdivacky if (D.getCXXScopeSpec().isSet()) { 3982212904Sdim // If there was an error parsing parenthesized declarator, declarator 3983234353Sdim // scope may have been entered before. Don't do it again. 3984212904Sdim if (!D.isInvalidType() && 3985212904Sdim Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 3986202379Srdivacky // Change the declaration context for name lookup, until this function 3987202379Srdivacky // is exited (and the declarator has been parsed). 3988202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 3989202379Srdivacky } 3990193326Sed } else if (D.mayOmitIdentifier()) { 3991193326Sed // This could be something simple like "int" (in which case the declarator 3992193326Sed // portion is empty), if an abstract-declarator is allowed. 3993193326Sed D.SetIdentifier(0, Tok.getLocation()); 3994193326Sed } else { 3995193326Sed if (D.getContext() == Declarator::MemberContext) 3996193326Sed Diag(Tok, diag::err_expected_member_name_or_semi) 3997193326Sed << D.getDeclSpec().getSourceRange(); 3998234353Sdim else if (getLangOpts().CPlusPlus) 3999234353Sdim Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus; 4000193326Sed else 4001193326Sed Diag(Tok, diag::err_expected_ident_lparen); 4002193326Sed D.SetIdentifier(0, Tok.getLocation()); 4003193326Sed D.setInvalidType(true); 4004193326Sed } 4005198092Srdivacky 4006193326Sed PastIdentifier: 4007193326Sed assert(D.isPastIdentifier() && 4008193326Sed "Haven't past the location of the identifier yet?"); 4009198092Srdivacky 4010234353Sdim // Don't parse attributes unless we have parsed an unparenthesized name. 4011234353Sdim if (D.hasName() && !D.getNumTypeObjects()) 4012218893Sdim MaybeParseCXX0XAttributes(D); 4013199990Srdivacky 4014193326Sed while (1) { 4015193326Sed if (Tok.is(tok::l_paren)) { 4016234353Sdim // Enter function-declaration scope, limiting any declarators to the 4017234353Sdim // function prototype scope, including parameter declarators. 4018234353Sdim ParseScope PrototypeScope(this, 4019234353Sdim Scope::FunctionPrototypeScope|Scope::DeclScope); 4020193326Sed // The paren may be part of a C++ direct initializer, eg. "int x(1);". 4021193326Sed // In such a case, check if we actually have a function declarator; if it 4022193326Sed // is not, the declarator has been fully parsed. 4023234353Sdim if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) { 4024193326Sed // When not in file scope, warn for ambiguous function declarators, just 4025193326Sed // in case the author intended it as a variable definition. 4026193326Sed bool warnIfAmbiguous = D.getContext() != Declarator::FileContext; 4027193326Sed if (!isCXXFunctionDeclarator(warnIfAmbiguous)) 4028193326Sed break; 4029193326Sed } 4030221345Sdim ParsedAttributes attrs(AttrFactory); 4031226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4032226633Sdim T.consumeOpen(); 4033226633Sdim ParseFunctionDeclarator(D, attrs, T); 4034234353Sdim PrototypeScope.Exit(); 4035193326Sed } else if (Tok.is(tok::l_square)) { 4036193326Sed ParseBracketDeclarator(D); 4037193326Sed } else { 4038193326Sed break; 4039193326Sed } 4040193326Sed } 4041234353Sdim} 4042193326Sed 4043193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is 4044193326Sed/// only called before the identifier, so these are most likely just grouping 4045198092Srdivacky/// parens for precedence. If we find that these are actually function 4046193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator. 4047193326Sed/// 4048193326Sed/// direct-declarator: 4049193326Sed/// '(' declarator ')' 4050193326Sed/// [GNU] '(' attributes declarator ')' 4051193326Sed/// direct-declarator '(' parameter-type-list ')' 4052193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4053193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4054193326Sed/// parameter-type-list[opt] ')' 4055193326Sed/// 4056193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) { 4057226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4058226633Sdim T.consumeOpen(); 4059226633Sdim 4060193326Sed assert(!D.isPastIdentifier() && "Should be called before passing identifier"); 4061198092Srdivacky 4062193326Sed // Eat any attributes before we look at whether this is a grouping or function 4063193326Sed // declarator paren. If this is a grouping paren, the attribute applies to 4064193326Sed // the type being built up, for example: 4065193326Sed // int (__attribute__(()) *x)(long y) 4066193326Sed // If this ends up not being a grouping paren, the attribute applies to the 4067193326Sed // first argument, for example: 4068193326Sed // int (__attribute__(()) int x) 4069193326Sed // In either case, we need to eat any attributes to be able to determine what 4070193326Sed // sort of paren this is. 4071193326Sed // 4072221345Sdim ParsedAttributes attrs(AttrFactory); 4073193326Sed bool RequiresArg = false; 4074193326Sed if (Tok.is(tok::kw___attribute)) { 4075218893Sdim ParseGNUAttributes(attrs); 4076198092Srdivacky 4077193326Sed // We require that the argument list (if this is a non-grouping paren) be 4078193326Sed // present even if the attribute list was empty. 4079193326Sed RequiresArg = true; 4080193326Sed } 4081193326Sed // Eat any Microsoft extensions. 4082194179Sed if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) || 4083208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) || 4084226633Sdim Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) || 4085226633Sdim Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) { 4086218893Sdim ParseMicrosoftTypeAttributes(attrs); 4087194179Sed } 4088212904Sdim // Eat any Borland extensions. 4089218893Sdim if (Tok.is(tok::kw___pascal)) 4090218893Sdim ParseBorlandTypeAttributes(attrs); 4091198092Srdivacky 4092193326Sed // If we haven't past the identifier yet (or where the identifier would be 4093193326Sed // stored, if this is an abstract declarator), then this is probably just 4094193326Sed // grouping parens. However, if this could be an abstract-declarator, then 4095193326Sed // this could also be the start of function arguments (consider 'void()'). 4096193326Sed bool isGrouping; 4097198092Srdivacky 4098193326Sed if (!D.mayOmitIdentifier()) { 4099193326Sed // If this can't be an abstract-declarator, this *must* be a grouping 4100193326Sed // paren, because we haven't seen the identifier yet. 4101193326Sed isGrouping = true; 4102193326Sed } else if (Tok.is(tok::r_paren) || // 'int()' is a function. 4103234353Sdim (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && 4104234353Sdim NextToken().is(tok::r_paren)) || // C++ int(...) 4105234353Sdim isDeclarationSpecifier() || // 'int(int)' is a function. 4106234353Sdim isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function. 4107193326Sed // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is 4108193326Sed // considered to be a type, not a K&R identifier-list. 4109193326Sed isGrouping = false; 4110193326Sed } else { 4111193326Sed // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'. 4112193326Sed isGrouping = true; 4113193326Sed } 4114198092Srdivacky 4115193326Sed // If this is a grouping paren, handle: 4116193326Sed // direct-declarator: '(' declarator ')' 4117193326Sed // direct-declarator: '(' attributes declarator ')' 4118193326Sed if (isGrouping) { 4119234353Sdim SourceLocation EllipsisLoc = D.getEllipsisLoc(); 4120234353Sdim D.setEllipsisLoc(SourceLocation()); 4121234353Sdim 4122193326Sed bool hadGroupingParens = D.hasGroupingParens(); 4123193326Sed D.setGroupingParens(true); 4124193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4125193326Sed // Match the ')'. 4126226633Sdim T.consumeClose(); 4127226633Sdim D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), 4128226633Sdim T.getCloseLocation()), 4129226633Sdim attrs, T.getCloseLocation()); 4130193326Sed 4131193326Sed D.setGroupingParens(hadGroupingParens); 4132234353Sdim 4133234353Sdim // An ellipsis cannot be placed outside parentheses. 4134234353Sdim if (EllipsisLoc.isValid()) 4135234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4136234353Sdim 4137193326Sed return; 4138193326Sed } 4139198092Srdivacky 4140193326Sed // Okay, if this wasn't a grouping paren, it must be the start of a function 4141193326Sed // argument list. Recognize that this declarator will never have an 4142193326Sed // identifier (and remember where it would have been), then call into 4143193326Sed // ParseFunctionDeclarator to handle of argument list. 4144193326Sed D.SetIdentifier(0, Tok.getLocation()); 4145193326Sed 4146234353Sdim // Enter function-declaration scope, limiting any declarators to the 4147234353Sdim // function prototype scope, including parameter declarators. 4148234353Sdim ParseScope PrototypeScope(this, 4149234353Sdim Scope::FunctionPrototypeScope|Scope::DeclScope); 4150226633Sdim ParseFunctionDeclarator(D, attrs, T, RequiresArg); 4151234353Sdim PrototypeScope.Exit(); 4152193326Sed} 4153193326Sed 4154193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the 4155193326Sed/// declarator D up to a paren, which indicates that we are parsing function 4156193326Sed/// arguments. 4157193326Sed/// 4158234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments 4159234353Sdim/// immediately after the open paren - they should be considered to be the 4160234353Sdim/// first argument of a parameter. 4161193326Sed/// 4162234353Sdim/// If RequiresArg is true, then the first argument of the function is required 4163234353Sdim/// to be present and required to not be an identifier list. 4164193326Sed/// 4165234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt], 4166234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt], 4167234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt]. 4168234353Sdim/// 4169234353Sdim/// [C++11] exception-specification: 4170221345Sdim/// dynamic-exception-specification 4171221345Sdim/// noexcept-specification 4172221345Sdim/// 4173226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D, 4174234353Sdim ParsedAttributes &FirstArgAttrs, 4175226633Sdim BalancedDelimiterTracker &Tracker, 4176193326Sed bool RequiresArg) { 4177234353Sdim assert(getCurScope()->isFunctionPrototypeScope() && 4178234353Sdim "Should call from a Function scope"); 4179193326Sed // lparen is already consumed! 4180193326Sed assert(D.isPastIdentifier() && "Should not call before identifier!"); 4181198092Srdivacky 4182224145Sdim // This should be true when the function has typed arguments. 4183224145Sdim // Otherwise, it is treated as a K&R-style function. 4184224145Sdim bool HasProto = false; 4185224145Sdim // Build up an array of information about the parsed arguments. 4186226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 4187224145Sdim // Remember where we see an ellipsis, if any. 4188224145Sdim SourceLocation EllipsisLoc; 4189224145Sdim 4190224145Sdim DeclSpec DS(AttrFactory); 4191224145Sdim bool RefQualifierIsLValueRef = true; 4192224145Sdim SourceLocation RefQualifierLoc; 4193234353Sdim SourceLocation ConstQualifierLoc; 4194234353Sdim SourceLocation VolatileQualifierLoc; 4195224145Sdim ExceptionSpecificationType ESpecType = EST_None; 4196224145Sdim SourceRange ESpecRange; 4197226633Sdim SmallVector<ParsedType, 2> DynamicExceptions; 4198226633Sdim SmallVector<SourceRange, 2> DynamicExceptionRanges; 4199224145Sdim ExprResult NoexceptExpr; 4200234982Sdim CachedTokens *ExceptionSpecTokens = 0; 4201234353Sdim ParsedAttributes FnAttrs(AttrFactory); 4202218893Sdim ParsedType TrailingReturnType; 4203234353Sdim 4204234353Sdim Actions.ActOnStartFunctionDeclarator(); 4205234353Sdim 4206224145Sdim SourceLocation EndLoc; 4207224145Sdim if (isFunctionDeclaratorIdentifierList()) { 4208218893Sdim if (RequiresArg) 4209193326Sed Diag(Tok, diag::err_argument_required_after_attribute); 4210193326Sed 4211224145Sdim ParseFunctionDeclaratorIdentifierList(D, ParamInfo); 4212193326Sed 4213226633Sdim Tracker.consumeClose(); 4214226633Sdim EndLoc = Tracker.getCloseLocation(); 4215224145Sdim } else { 4216224145Sdim if (Tok.isNot(tok::r_paren)) 4217234353Sdim ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc); 4218224145Sdim else if (RequiresArg) 4219224145Sdim Diag(Tok, diag::err_argument_required_after_attribute); 4220224145Sdim 4221234353Sdim HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; 4222224145Sdim 4223224145Sdim // If we have the closing ')', eat it. 4224226633Sdim Tracker.consumeClose(); 4225226633Sdim EndLoc = Tracker.getCloseLocation(); 4226224145Sdim 4227234353Sdim if (getLangOpts().CPlusPlus) { 4228234353Sdim // FIXME: Accept these components in any order, and produce fixits to 4229234353Sdim // correct the order if the user gets it wrong. Ideally we should deal 4230234353Sdim // with the virt-specifier-seq and pure-specifier in the same way. 4231218893Sdim 4232224145Sdim // Parse cv-qualifier-seq[opt]. 4233234353Sdim ParseTypeQualifierListOpt(DS, false /*no attributes*/, false); 4234234353Sdim if (!DS.getSourceRange().getEnd().isInvalid()) { 4235234353Sdim EndLoc = DS.getSourceRange().getEnd(); 4236234353Sdim ConstQualifierLoc = DS.getConstSpecLoc(); 4237234353Sdim VolatileQualifierLoc = DS.getVolatileSpecLoc(); 4238234353Sdim } 4239193326Sed 4240224145Sdim // Parse ref-qualifier[opt]. 4241218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) { 4242234353Sdim Diag(Tok, getLangOpts().CPlusPlus0x ? 4243234353Sdim diag::warn_cxx98_compat_ref_qualifier : 4244234353Sdim diag::ext_ref_qualifier); 4245234353Sdim 4246218893Sdim RefQualifierIsLValueRef = Tok.is(tok::amp); 4247218893Sdim RefQualifierLoc = ConsumeToken(); 4248218893Sdim EndLoc = RefQualifierLoc; 4249218893Sdim } 4250221345Sdim 4251234982Sdim // C++11 [expr.prim.general]p3: 4252234982Sdim // If a declaration declares a member function or member function 4253234982Sdim // template of a class X, the expression this is a prvalue of type 4254234982Sdim // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 4255234982Sdim // and the end of the function-definition, member-declarator, or 4256234982Sdim // declarator. 4257234982Sdim bool IsCXX11MemberFunction = 4258234982Sdim getLangOpts().CPlusPlus0x && 4259234982Sdim (D.getContext() == Declarator::MemberContext || 4260234982Sdim (D.getContext() == Declarator::FileContext && 4261234982Sdim D.getCXXScopeSpec().isValid() && 4262234982Sdim Actions.CurContext->isRecord())); 4263234982Sdim Sema::CXXThisScopeRAII ThisScope(Actions, 4264234982Sdim dyn_cast<CXXRecordDecl>(Actions.CurContext), 4265234982Sdim DS.getTypeQualifiers(), 4266234982Sdim IsCXX11MemberFunction); 4267234982Sdim 4268193326Sed // Parse exception-specification[opt]. 4269234982Sdim bool Delayed = (D.getContext() == Declarator::MemberContext && 4270234982Sdim D.getDeclSpec().getStorageClassSpec() 4271234982Sdim != DeclSpec::SCS_typedef && 4272234982Sdim !D.getDeclSpec().isFriendSpecified()); 4273234982Sdim ESpecType = tryParseExceptionSpecification(Delayed, 4274234982Sdim ESpecRange, 4275234982Sdim DynamicExceptions, 4276234982Sdim DynamicExceptionRanges, 4277234982Sdim NoexceptExpr, 4278234982Sdim ExceptionSpecTokens); 4279221345Sdim if (ESpecType != EST_None) 4280221345Sdim EndLoc = ESpecRange.getEnd(); 4281218893Sdim 4282234353Sdim // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes 4283234353Sdim // after the exception-specification. 4284234353Sdim MaybeParseCXX0XAttributes(FnAttrs); 4285234353Sdim 4286224145Sdim // Parse trailing-return-type[opt]. 4287234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) { 4288234353Sdim Diag(Tok, diag::warn_cxx98_compat_trailing_return_type); 4289226633Sdim SourceRange Range; 4290226633Sdim TrailingReturnType = ParseTrailingReturnType(Range).get(); 4291226633Sdim if (Range.getEnd().isValid()) 4292226633Sdim EndLoc = Range.getEnd(); 4293218893Sdim } 4294193326Sed } 4295193326Sed } 4296193326Sed 4297224145Sdim // Remember that we parsed a function type, and remember the attributes. 4298224145Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, 4299224145Sdim /*isVariadic=*/EllipsisLoc.isValid(), 4300224145Sdim EllipsisLoc, 4301224145Sdim ParamInfo.data(), ParamInfo.size(), 4302224145Sdim DS.getTypeQualifiers(), 4303224145Sdim RefQualifierIsLValueRef, 4304234353Sdim RefQualifierLoc, ConstQualifierLoc, 4305234353Sdim VolatileQualifierLoc, 4306224145Sdim /*MutableLoc=*/SourceLocation(), 4307224145Sdim ESpecType, ESpecRange.getBegin(), 4308224145Sdim DynamicExceptions.data(), 4309224145Sdim DynamicExceptionRanges.data(), 4310224145Sdim DynamicExceptions.size(), 4311224145Sdim NoexceptExpr.isUsable() ? 4312224145Sdim NoexceptExpr.get() : 0, 4313234982Sdim ExceptionSpecTokens, 4314226633Sdim Tracker.getOpenLocation(), 4315226633Sdim EndLoc, D, 4316224145Sdim TrailingReturnType), 4317234353Sdim FnAttrs, EndLoc); 4318234353Sdim 4319234353Sdim Actions.ActOnEndFunctionDeclarator(); 4320224145Sdim} 4321224145Sdim 4322224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an 4323224145Sdim/// identifier list form for a K&R-style function: void foo(a,b,c) 4324224145Sdim/// 4325224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for 4326224145Sdim/// abstract-declarators. 4327224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() { 4328234353Sdim return !getLangOpts().CPlusPlus 4329224145Sdim && Tok.is(tok::identifier) 4330224145Sdim && !TryAltiVecVectorToken() 4331224145Sdim // K&R identifier lists can't have typedefs as identifiers, per C99 4332224145Sdim // 6.7.5.3p11. 4333224145Sdim && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) 4334224145Sdim // Identifier lists follow a really simple grammar: the identifiers can 4335224145Sdim // be followed *only* by a ", identifier" or ")". However, K&R 4336224145Sdim // identifier lists are really rare in the brave new modern world, and 4337224145Sdim // it is very common for someone to typo a type in a non-K&R style 4338224145Sdim // list. If we are presented with something like: "void foo(intptr x, 4339224145Sdim // float y)", we don't want to start parsing the function declarator as 4340224145Sdim // though it is a K&R style declarator just because intptr is an 4341224145Sdim // invalid type. 4342224145Sdim // 4343224145Sdim // To handle this, we check to see if the token after the first 4344224145Sdim // identifier is a "," or ")". Only then do we parse it as an 4345224145Sdim // identifier list. 4346224145Sdim && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); 4347224145Sdim} 4348224145Sdim 4349224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator 4350224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list. 4351224145Sdim/// 4352224145Sdim/// After returning, ParamInfo will hold the parsed parameters. 4353224145Sdim/// 4354224145Sdim/// identifier-list: [C99 6.7.5] 4355224145Sdim/// identifier 4356224145Sdim/// identifier-list ',' identifier 4357224145Sdim/// 4358224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList( 4359224145Sdim Declarator &D, 4360226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) { 4361224145Sdim // If there was no identifier specified for the declarator, either we are in 4362224145Sdim // an abstract-declarator, or we are in a parameter declarator which was found 4363224145Sdim // to be abstract. In abstract-declarators, identifier lists are not valid: 4364224145Sdim // diagnose this. 4365224145Sdim if (!D.getIdentifier()) 4366224145Sdim Diag(Tok, diag::ext_ident_list_in_param); 4367224145Sdim 4368224145Sdim // Maintain an efficient lookup of params we have seen so far. 4369224145Sdim llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar; 4370224145Sdim 4371224145Sdim while (1) { 4372224145Sdim // If this isn't an identifier, report the error and skip until ')'. 4373224145Sdim if (Tok.isNot(tok::identifier)) { 4374224145Sdim Diag(Tok, diag::err_expected_ident); 4375224145Sdim SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true); 4376224145Sdim // Forget we parsed anything. 4377224145Sdim ParamInfo.clear(); 4378224145Sdim return; 4379193326Sed } 4380198092Srdivacky 4381224145Sdim IdentifierInfo *ParmII = Tok.getIdentifierInfo(); 4382198092Srdivacky 4383224145Sdim // Reject 'typedef int y; int test(x, y)', but continue parsing. 4384224145Sdim if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope())) 4385224145Sdim Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; 4386193326Sed 4387224145Sdim // Verify that the argument identifier has not already been mentioned. 4388224145Sdim if (!ParamsSoFar.insert(ParmII)) { 4389224145Sdim Diag(Tok, diag::err_param_redefinition) << ParmII; 4390224145Sdim } else { 4391224145Sdim // Remember this identifier in ParamInfo. 4392224145Sdim ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 4393224145Sdim Tok.getLocation(), 4394224145Sdim 0)); 4395224145Sdim } 4396198092Srdivacky 4397224145Sdim // Eat the identifier. 4398224145Sdim ConsumeToken(); 4399224145Sdim 4400224145Sdim // The list continues if we see a comma. 4401224145Sdim if (Tok.isNot(tok::comma)) 4402224145Sdim break; 4403224145Sdim ConsumeToken(); 4404224145Sdim } 4405224145Sdim} 4406224145Sdim 4407224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list 4408224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style 4409224145Sdim/// identifier list. 4410224145Sdim/// 4411234353Sdim/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the 4412234353Sdim/// caller parsed those arguments immediately after the open paren - they should 4413234353Sdim/// be considered to be part of the first parameter. 4414224145Sdim/// 4415224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will 4416224145Sdim/// be the location of the ellipsis, if any was parsed. 4417224145Sdim/// 4418224145Sdim/// parameter-type-list: [C99 6.7.5] 4419224145Sdim/// parameter-list 4420224145Sdim/// parameter-list ',' '...' 4421224145Sdim/// [C++] parameter-list '...' 4422224145Sdim/// 4423224145Sdim/// parameter-list: [C99 6.7.5] 4424224145Sdim/// parameter-declaration 4425224145Sdim/// parameter-list ',' parameter-declaration 4426224145Sdim/// 4427224145Sdim/// parameter-declaration: [C99 6.7.5] 4428224145Sdim/// declaration-specifiers declarator 4429224145Sdim/// [C++] declaration-specifiers declarator '=' assignment-expression 4430234353Sdim/// [C++11] initializer-clause 4431224145Sdim/// [GNU] declaration-specifiers declarator attributes 4432224145Sdim/// declaration-specifiers abstract-declarator[opt] 4433224145Sdim/// [C++] declaration-specifiers abstract-declarator[opt] 4434224145Sdim/// '=' assignment-expression 4435224145Sdim/// [GNU] declaration-specifiers abstract-declarator[opt] attributes 4436234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration 4437224145Sdim/// 4438224145Sdimvoid Parser::ParseParameterDeclarationClause( 4439224145Sdim Declarator &D, 4440234353Sdim ParsedAttributes &FirstArgAttrs, 4441226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, 4442224145Sdim SourceLocation &EllipsisLoc) { 4443224145Sdim 4444193326Sed while (1) { 4445193326Sed if (Tok.is(tok::ellipsis)) { 4446234353Sdim // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq 4447234353Sdim // before deciding this was a parameter-declaration-clause. 4448193326Sed EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 4449193326Sed break; 4450193326Sed } 4451198092Srdivacky 4452193326Sed // Parse the declaration-specifiers. 4453198893Srdivacky // Just use the ParsingDeclaration "scope" of the declarator. 4454221345Sdim DeclSpec DS(AttrFactory); 4455226633Sdim 4456234353Sdim // Parse any C++11 attributes. 4457234353Sdim MaybeParseCXX0XAttributes(DS.getAttributes()); 4458234353Sdim 4459218893Sdim // Skip any Microsoft attributes before a param. 4460234353Sdim if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square)) 4461218893Sdim ParseMicrosoftAttributes(DS.getAttributes()); 4462193326Sed 4463218893Sdim SourceLocation DSStart = Tok.getLocation(); 4464218893Sdim 4465193326Sed // If the caller parsed attributes for the first argument, add them now. 4466218893Sdim // Take them so that we only apply the attributes to the first parameter. 4467224145Sdim // FIXME: If we can leave the attributes in the token stream somehow, we can 4468234353Sdim // get rid of a parameter (FirstArgAttrs) and this statement. It might be 4469234353Sdim // too much hassle. 4470234353Sdim DS.takeAttributesFrom(FirstArgAttrs); 4471218893Sdim 4472193326Sed ParseDeclarationSpecifiers(DS); 4473198092Srdivacky 4474193326Sed // Parse the declarator. This is "PrototypeContext", because we must 4475193326Sed // accept either 'declarator' or 'abstract-declarator' here. 4476193326Sed Declarator ParmDecl(DS, Declarator::PrototypeContext); 4477193326Sed ParseDeclarator(ParmDecl); 4478193326Sed 4479193326Sed // Parse GNU attributes, if present. 4480218893Sdim MaybeParseGNUAttributes(ParmDecl); 4481198092Srdivacky 4482193326Sed // Remember this parsed parameter in ParamInfo. 4483193326Sed IdentifierInfo *ParmII = ParmDecl.getIdentifier(); 4484198092Srdivacky 4485193326Sed // DefArgToks is used when the parsing of default arguments needs 4486193326Sed // to be delayed. 4487193326Sed CachedTokens *DefArgToks = 0; 4488193326Sed 4489193326Sed // If no parameter was specified, verify that *something* was specified, 4490193326Sed // otherwise we have a missing type and identifier. 4491193326Sed if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 && 4492193326Sed ParmDecl.getNumTypeObjects() == 0) { 4493193326Sed // Completely missing, emit error. 4494193326Sed Diag(DSStart, diag::err_missing_param); 4495193326Sed } else { 4496193326Sed // Otherwise, we have something. Add it and let semantic analysis try 4497193326Sed // to grok it and add the result to the ParamInfo we are building. 4498198092Srdivacky 4499193326Sed // Inform the actions module about the parameter declarator, so it gets 4500193326Sed // added to the current scope. 4501212904Sdim Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); 4502193326Sed 4503193326Sed // Parse the default argument, if any. We parse the default 4504193326Sed // arguments in all dialects; the semantic analysis in 4505193326Sed // ActOnParamDefaultArgument will reject the default argument in 4506193326Sed // C. 4507193326Sed if (Tok.is(tok::equal)) { 4508193326Sed SourceLocation EqualLoc = Tok.getLocation(); 4509193326Sed 4510193326Sed // Parse the default argument 4511193326Sed if (D.getContext() == Declarator::MemberContext) { 4512193326Sed // If we're inside a class definition, cache the tokens 4513193326Sed // corresponding to the default argument. We'll actually parse 4514193326Sed // them when we see the end of the class definition. 4515193326Sed // FIXME: Can we use a smart pointer for Toks? 4516193326Sed DefArgToks = new CachedTokens; 4517193326Sed 4518198092Srdivacky if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks, 4519207619Srdivacky /*StopAtSemi=*/true, 4520207619Srdivacky /*ConsumeFinalToken=*/false)) { 4521193326Sed delete DefArgToks; 4522193326Sed DefArgToks = 0; 4523193326Sed Actions.ActOnParamDefaultArgumentError(Param); 4524212904Sdim } else { 4525212904Sdim // Mark the end of the default argument so that we know when to 4526212904Sdim // stop when we parse it later on. 4527212904Sdim Token DefArgEnd; 4528212904Sdim DefArgEnd.startToken(); 4529212904Sdim DefArgEnd.setKind(tok::cxx_defaultarg_end); 4530212904Sdim DefArgEnd.setLocation(Tok.getLocation()); 4531212904Sdim DefArgToks->push_back(DefArgEnd); 4532198092Srdivacky Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, 4533194179Sed (*DefArgToks)[1].getLocation()); 4534212904Sdim } 4535193326Sed } else { 4536193326Sed // Consume the '='. 4537193326Sed ConsumeToken(); 4538198092Srdivacky 4539218893Sdim // The argument isn't actually potentially evaluated unless it is 4540218893Sdim // used. 4541218893Sdim EnterExpressionEvaluationContext Eval(Actions, 4542234353Sdim Sema::PotentiallyEvaluatedIfUsed, 4543234353Sdim Param); 4544218893Sdim 4545234353Sdim ExprResult DefArgResult; 4546234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 4547234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 4548234353Sdim DefArgResult = ParseBraceInitializer(); 4549234353Sdim } else 4550234353Sdim DefArgResult = ParseAssignmentExpression(); 4551193326Sed if (DefArgResult.isInvalid()) { 4552193326Sed Actions.ActOnParamDefaultArgumentError(Param); 4553193326Sed SkipUntil(tok::comma, tok::r_paren, true, true); 4554193326Sed } else { 4555193326Sed // Inform the actions module about the default argument 4556193326Sed Actions.ActOnParamDefaultArgument(Param, EqualLoc, 4557212904Sdim DefArgResult.take()); 4558193326Sed } 4559193326Sed } 4560193326Sed } 4561198092Srdivacky 4562198092Srdivacky ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 4563198092Srdivacky ParmDecl.getIdentifierLoc(), Param, 4564193326Sed DefArgToks)); 4565193326Sed } 4566193326Sed 4567193326Sed // If the next token is a comma, consume it and keep reading arguments. 4568198092Srdivacky if (Tok.isNot(tok::comma)) { 4569198092Srdivacky if (Tok.is(tok::ellipsis)) { 4570198092Srdivacky EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 4571198092Srdivacky 4572234353Sdim if (!getLangOpts().CPlusPlus) { 4573198092Srdivacky // We have ellipsis without a preceding ',', which is ill-formed 4574198092Srdivacky // in C. Complain and provide the fix. 4575198092Srdivacky Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis) 4576206084Srdivacky << FixItHint::CreateInsertion(EllipsisLoc, ", "); 4577198092Srdivacky } 4578198092Srdivacky } 4579198092Srdivacky 4580198092Srdivacky break; 4581198092Srdivacky } 4582198092Srdivacky 4583193326Sed // Consume the comma. 4584193326Sed ConsumeToken(); 4585193326Sed } 4586198092Srdivacky 4587193326Sed} 4588193326Sed 4589193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 4590193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4591193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4592193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4593193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4594234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 4595234353Sdim/// attribute-specifier-seq[opt] 4596193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) { 4597234353Sdim if (CheckProhibitedCXX11Attribute()) 4598234353Sdim return; 4599234353Sdim 4600226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 4601226633Sdim T.consumeOpen(); 4602198092Srdivacky 4603193326Sed // C array syntax has many features, but by-far the most common is [] and [4]. 4604193326Sed // This code does a fast path to handle some of the most obvious cases. 4605193326Sed if (Tok.getKind() == tok::r_square) { 4606226633Sdim T.consumeClose(); 4607221345Sdim ParsedAttributes attrs(AttrFactory); 4608218893Sdim MaybeParseCXX0XAttributes(attrs); 4609199990Srdivacky 4610193326Sed // Remember that we parsed the empty array type. 4611212904Sdim ExprResult NumElements; 4612221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, 4613226633Sdim T.getOpenLocation(), 4614226633Sdim T.getCloseLocation()), 4615226633Sdim attrs, T.getCloseLocation()); 4616193326Sed return; 4617193326Sed } else if (Tok.getKind() == tok::numeric_constant && 4618193326Sed GetLookAheadToken(1).is(tok::r_square)) { 4619193326Sed // [4] is very common. Parse the numeric constant expression. 4620234353Sdim ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope())); 4621193326Sed ConsumeToken(); 4622193326Sed 4623226633Sdim T.consumeClose(); 4624221345Sdim ParsedAttributes attrs(AttrFactory); 4625218893Sdim MaybeParseCXX0XAttributes(attrs); 4626193326Sed 4627193326Sed // Remember that we parsed a array type, and remember its features. 4628221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, 4629218893Sdim ExprRes.release(), 4630226633Sdim T.getOpenLocation(), 4631226633Sdim T.getCloseLocation()), 4632226633Sdim attrs, T.getCloseLocation()); 4633193326Sed return; 4634193326Sed } 4635198092Srdivacky 4636193326Sed // If valid, this location is the position where we read the 'static' keyword. 4637193326Sed SourceLocation StaticLoc; 4638193326Sed if (Tok.is(tok::kw_static)) 4639193326Sed StaticLoc = ConsumeToken(); 4640198092Srdivacky 4641193326Sed // If there is a type-qualifier-list, read it now. 4642193326Sed // Type qualifiers in an array subscript are a C99 feature. 4643221345Sdim DeclSpec DS(AttrFactory); 4644193326Sed ParseTypeQualifierListOpt(DS, false /*no attributes*/); 4645198092Srdivacky 4646193326Sed // If we haven't already read 'static', check to see if there is one after the 4647193326Sed // type-qualifier-list. 4648193326Sed if (!StaticLoc.isValid() && Tok.is(tok::kw_static)) 4649193326Sed StaticLoc = ConsumeToken(); 4650198092Srdivacky 4651193326Sed // Handle "direct-declarator [ type-qual-list[opt] * ]". 4652193326Sed bool isStar = false; 4653212904Sdim ExprResult NumElements; 4654198092Srdivacky 4655193326Sed // Handle the case where we have '[*]' as the array size. However, a leading 4656193326Sed // star could be the start of an expression, for example 'X[*p + 4]'. Verify 4657193326Sed // the the token after the star is a ']'. Since stars in arrays are 4658193326Sed // infrequent, use of lookahead is not costly here. 4659193326Sed if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) { 4660193326Sed ConsumeToken(); // Eat the '*'. 4661193326Sed 4662193326Sed if (StaticLoc.isValid()) { 4663193326Sed Diag(StaticLoc, diag::err_unspecified_vla_size_with_static); 4664193326Sed StaticLoc = SourceLocation(); // Drop the static. 4665193326Sed } 4666193326Sed isStar = true; 4667193326Sed } else if (Tok.isNot(tok::r_square)) { 4668193326Sed // Note, in C89, this production uses the constant-expr production instead 4669193326Sed // of assignment-expr. The only difference is that assignment-expr allows 4670193326Sed // things like '=' and '*='. Sema rejects these in C89 mode because they 4671193326Sed // are not i-c-e's, so we don't need to distinguish between the two here. 4672198092Srdivacky 4673194613Sed // Parse the constant-expression or assignment-expression now (depending 4674194613Sed // on dialect). 4675234353Sdim if (getLangOpts().CPlusPlus) { 4676194613Sed NumElements = ParseConstantExpression(); 4677234353Sdim } else { 4678234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 4679234353Sdim Sema::ConstantEvaluated); 4680194613Sed NumElements = ParseAssignmentExpression(); 4681234353Sdim } 4682193326Sed } 4683198092Srdivacky 4684193326Sed // If there was an error parsing the assignment-expression, recover. 4685193326Sed if (NumElements.isInvalid()) { 4686193326Sed D.setInvalidType(true); 4687193326Sed // If the expression was invalid, skip it. 4688193326Sed SkipUntil(tok::r_square); 4689193326Sed return; 4690193326Sed } 4691193326Sed 4692226633Sdim T.consumeClose(); 4693193326Sed 4694221345Sdim ParsedAttributes attrs(AttrFactory); 4695218893Sdim MaybeParseCXX0XAttributes(attrs); 4696199990Srdivacky 4697193326Sed // Remember that we parsed a array type, and remember its features. 4698221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), 4699193326Sed StaticLoc.isValid(), isStar, 4700198092Srdivacky NumElements.release(), 4701226633Sdim T.getOpenLocation(), 4702226633Sdim T.getCloseLocation()), 4703226633Sdim attrs, T.getCloseLocation()); 4704193326Sed} 4705193326Sed 4706193326Sed/// [GNU] typeof-specifier: 4707193326Sed/// typeof ( expressions ) 4708193326Sed/// typeof ( type-name ) 4709193326Sed/// [GNU/C++] typeof unary-expression 4710193326Sed/// 4711193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) { 4712193326Sed assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); 4713193326Sed Token OpTok = Tok; 4714193326Sed SourceLocation StartLoc = ConsumeToken(); 4715193326Sed 4716202379Srdivacky const bool hasParens = Tok.is(tok::l_paren); 4717202379Srdivacky 4718234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 4719234353Sdim 4720193326Sed bool isCastExpr; 4721212904Sdim ParsedType CastTy; 4722193326Sed SourceRange CastRange; 4723221345Sdim ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, 4724221345Sdim CastTy, CastRange); 4725202379Srdivacky if (hasParens) 4726202379Srdivacky DS.setTypeofParensRange(CastRange); 4727193326Sed 4728193326Sed if (CastRange.getEnd().isInvalid()) 4729193326Sed // FIXME: Not accurate, the range gets one token more than it should. 4730193326Sed DS.SetRangeEnd(Tok.getLocation()); 4731193326Sed else 4732193326Sed DS.SetRangeEnd(CastRange.getEnd()); 4733198092Srdivacky 4734193326Sed if (isCastExpr) { 4735193326Sed if (!CastTy) { 4736193326Sed DS.SetTypeSpecError(); 4737193326Sed return; 4738193326Sed } 4739193326Sed 4740193326Sed const char *PrevSpec = 0; 4741198092Srdivacky unsigned DiagID; 4742193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 4743193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 4744198092Srdivacky DiagID, CastTy)) 4745198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 4746193326Sed return; 4747193326Sed } 4748193326Sed 4749193326Sed // If we get here, the operand to the typeof was an expresion. 4750193326Sed if (Operand.isInvalid()) { 4751193326Sed DS.SetTypeSpecError(); 4752193326Sed return; 4753193326Sed } 4754193326Sed 4755234353Sdim // We might need to transform the operand if it is potentially evaluated. 4756234353Sdim Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get()); 4757234353Sdim if (Operand.isInvalid()) { 4758234353Sdim DS.SetTypeSpecError(); 4759234353Sdim return; 4760234353Sdim } 4761234353Sdim 4762193326Sed const char *PrevSpec = 0; 4763198092Srdivacky unsigned DiagID; 4764193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 4765193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 4766212904Sdim DiagID, Operand.get())) 4767198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 4768193326Sed} 4769204643Srdivacky 4770234353Sdim/// [C11] atomic-specifier: 4771226633Sdim/// _Atomic ( type-name ) 4772226633Sdim/// 4773226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) { 4774226633Sdim assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier"); 4775204643Srdivacky 4776226633Sdim SourceLocation StartLoc = ConsumeToken(); 4777226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4778226633Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) { 4779226633Sdim SkipUntil(tok::r_paren); 4780226633Sdim return; 4781226633Sdim } 4782226633Sdim 4783226633Sdim TypeResult Result = ParseTypeName(); 4784226633Sdim if (Result.isInvalid()) { 4785226633Sdim SkipUntil(tok::r_paren); 4786226633Sdim return; 4787226633Sdim } 4788226633Sdim 4789226633Sdim // Match the ')' 4790226633Sdim T.consumeClose(); 4791226633Sdim 4792226633Sdim if (T.getCloseLocation().isInvalid()) 4793226633Sdim return; 4794226633Sdim 4795226633Sdim DS.setTypeofParensRange(T.getRange()); 4796226633Sdim DS.SetRangeEnd(T.getCloseLocation()); 4797226633Sdim 4798226633Sdim const char *PrevSpec = 0; 4799226633Sdim unsigned DiagID; 4800226633Sdim if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec, 4801226633Sdim DiagID, Result.release())) 4802226633Sdim Diag(StartLoc, DiagID) << PrevSpec; 4803226633Sdim} 4804226633Sdim 4805226633Sdim 4806204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called 4807204643Srdivacky/// from TryAltiVecVectorToken. 4808204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() { 4809204643Srdivacky Token Next = NextToken(); 4810204643Srdivacky switch (Next.getKind()) { 4811204643Srdivacky default: return false; 4812204643Srdivacky case tok::kw_short: 4813204643Srdivacky case tok::kw_long: 4814204643Srdivacky case tok::kw_signed: 4815204643Srdivacky case tok::kw_unsigned: 4816204643Srdivacky case tok::kw_void: 4817204643Srdivacky case tok::kw_char: 4818204643Srdivacky case tok::kw_int: 4819204643Srdivacky case tok::kw_float: 4820204643Srdivacky case tok::kw_double: 4821204643Srdivacky case tok::kw_bool: 4822204643Srdivacky case tok::kw___pixel: 4823204643Srdivacky Tok.setKind(tok::kw___vector); 4824204643Srdivacky return true; 4825204643Srdivacky case tok::identifier: 4826204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 4827204643Srdivacky Tok.setKind(tok::kw___vector); 4828204643Srdivacky return true; 4829204643Srdivacky } 4830204643Srdivacky return false; 4831204643Srdivacky } 4832204643Srdivacky} 4833204643Srdivacky 4834204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, 4835204643Srdivacky const char *&PrevSpec, unsigned &DiagID, 4836204643Srdivacky bool &isInvalid) { 4837204643Srdivacky if (Tok.getIdentifierInfo() == Ident_vector) { 4838204643Srdivacky Token Next = NextToken(); 4839204643Srdivacky switch (Next.getKind()) { 4840204643Srdivacky case tok::kw_short: 4841204643Srdivacky case tok::kw_long: 4842204643Srdivacky case tok::kw_signed: 4843204643Srdivacky case tok::kw_unsigned: 4844204643Srdivacky case tok::kw_void: 4845204643Srdivacky case tok::kw_char: 4846204643Srdivacky case tok::kw_int: 4847204643Srdivacky case tok::kw_float: 4848204643Srdivacky case tok::kw_double: 4849204643Srdivacky case tok::kw_bool: 4850204643Srdivacky case tok::kw___pixel: 4851204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 4852204643Srdivacky return true; 4853204643Srdivacky case tok::identifier: 4854204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 4855204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 4856204643Srdivacky return true; 4857204643Srdivacky } 4858204643Srdivacky break; 4859204643Srdivacky default: 4860204643Srdivacky break; 4861204643Srdivacky } 4862210299Sed } else if ((Tok.getIdentifierInfo() == Ident_pixel) && 4863204643Srdivacky DS.isTypeAltiVecVector()) { 4864204643Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 4865204643Srdivacky return true; 4866204643Srdivacky } 4867204643Srdivacky return false; 4868204643Srdivacky} 4869