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" 15249423Sdim#include "RAIIObjectsForParser.h" 16263508Sdim#include "clang/AST/DeclTemplate.h" 17249423Sdim#include "clang/Basic/AddressSpaces.h" 18249423Sdim#include "clang/Basic/CharInfo.h" 19249423Sdim#include "clang/Basic/OpenCL.h" 20193326Sed#include "clang/Parse/ParseDiagnostic.h" 21239462Sdim#include "clang/Sema/Lookup.h" 22212904Sdim#include "clang/Sema/ParsedTemplate.h" 23212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h" 24249423Sdim#include "clang/Sema/Scope.h" 25193326Sed#include "llvm/ADT/SmallSet.h" 26234353Sdim#include "llvm/ADT/SmallString.h" 27226633Sdim#include "llvm/ADT/StringSwitch.h" 28193326Sedusing namespace clang; 29193326Sed 30193326Sed//===----------------------------------------------------------------------===// 31193326Sed// C99 6.7: Declarations. 32193326Sed//===----------------------------------------------------------------------===// 33193326Sed 34193326Sed/// ParseTypeName 35193326Sed/// type-name: [C99 6.7.6] 36193326Sed/// specifier-qualifier-list abstract-declarator[opt] 37193326Sed/// 38193326Sed/// Called type-id in C++. 39218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range, 40224145Sdim Declarator::TheContext Context, 41224145Sdim AccessSpecifier AS, 42249423Sdim Decl **OwnedType, 43249423Sdim ParsedAttributes *Attrs) { 44234353Sdim DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context); 45239462Sdim if (DSC == DSC_normal) 46239462Sdim DSC = DSC_type_specifier; 47234353Sdim 48193326Sed // Parse the common declaration-specifiers piece. 49221345Sdim DeclSpec DS(AttrFactory); 50249423Sdim if (Attrs) 51249423Sdim DS.addAttributes(Attrs->getList()); 52234353Sdim ParseSpecifierQualifierList(DS, AS, DSC); 53224145Sdim if (OwnedType) 54224145Sdim *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; 55193326Sed 56193326Sed // Parse the abstract-declarator, if present. 57218893Sdim Declarator DeclaratorInfo(DS, Context); 58193326Sed ParseDeclarator(DeclaratorInfo); 59193326Sed if (Range) 60193326Sed *Range = DeclaratorInfo.getSourceRange(); 61193326Sed 62193326Sed if (DeclaratorInfo.isInvalidType()) 63193326Sed return true; 64193326Sed 65210299Sed return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 66193326Sed} 67193326Sed 68226633Sdim 69226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that 70226633Sdim/// require late parsing. 71226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) { 72226633Sdim return llvm::StringSwitch<bool>(II.getName()) 73226633Sdim#include "clang/Parse/AttrLateParsed.inc" 74226633Sdim .Default(false); 75226633Sdim} 76226633Sdim 77199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list. 78193326Sed/// 79193326Sed/// [GNU] attributes: 80193326Sed/// attribute 81193326Sed/// attributes attribute 82193326Sed/// 83193326Sed/// [GNU] attribute: 84193326Sed/// '__attribute__' '(' '(' attribute-list ')' ')' 85193326Sed/// 86193326Sed/// [GNU] attribute-list: 87193326Sed/// attrib 88193326Sed/// attribute_list ',' attrib 89193326Sed/// 90193326Sed/// [GNU] attrib: 91193326Sed/// empty 92193326Sed/// attrib-name 93193326Sed/// attrib-name '(' identifier ')' 94193326Sed/// attrib-name '(' identifier ',' nonempty-expr-list ')' 95193326Sed/// attrib-name '(' argument-expression-list [C99 6.5.2] ')' 96193326Sed/// 97193326Sed/// [GNU] attrib-name: 98193326Sed/// identifier 99193326Sed/// typespec 100193326Sed/// typequal 101193326Sed/// storageclass 102198092Srdivacky/// 103263508Sdim/// Whether an attribute takes an 'identifier' is determined by the 104263508Sdim/// attrib-name. GCC's behavior here is not worth imitating: 105193326Sed/// 106263508Sdim/// * In C mode, if the attribute argument list starts with an identifier 107263508Sdim/// followed by a ',' or an ')', and the identifier doesn't resolve to 108263508Sdim/// a type, it is parsed as an identifier. If the attribute actually 109263508Sdim/// wanted an expression, it's out of luck (but it turns out that no 110263508Sdim/// attributes work that way, because C constant expressions are very 111263508Sdim/// limited). 112263508Sdim/// * In C++ mode, if the attribute argument list starts with an identifier, 113263508Sdim/// and the attribute *wants* an identifier, it is parsed as an identifier. 114263508Sdim/// At block scope, any additional tokens between the identifier and the 115263508Sdim/// ',' or ')' are ignored, otherwise they produce a parse error. 116234353Sdim/// 117263508Sdim/// We follow the C++ model, but don't allow junk after the identifier. 118218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs, 119226633Sdim SourceLocation *endLoc, 120226633Sdim LateParsedAttrList *LateAttrs) { 121199990Srdivacky assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); 122198092Srdivacky 123193326Sed while (Tok.is(tok::kw___attribute)) { 124193326Sed ConsumeToken(); 125193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 126193326Sed "attribute")) { 127263508Sdim SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; 128218893Sdim return; 129193326Sed } 130193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { 131263508Sdim SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; 132218893Sdim return; 133193326Sed } 134193326Sed // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) 135193326Sed while (Tok.is(tok::identifier) || isDeclarationSpecifier() || 136193326Sed Tok.is(tok::comma)) { 137198092Srdivacky if (Tok.is(tok::comma)) { 138193326Sed // allows for empty/non-empty attributes. ((__vector_size__(16),,,,)) 139193326Sed ConsumeToken(); 140193326Sed continue; 141193326Sed } 142193326Sed // we have an identifier or declaration specifier (const, int, etc.) 143193326Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 144193326Sed SourceLocation AttrNameLoc = ConsumeToken(); 145198092Srdivacky 146226633Sdim if (Tok.is(tok::l_paren)) { 147226633Sdim // handle "parameterized" attributes 148234353Sdim if (LateAttrs && isAttributeLateParsed(*AttrName)) { 149226633Sdim LateParsedAttribute *LA = 150226633Sdim new LateParsedAttribute(this, *AttrName, AttrNameLoc); 151226633Sdim LateAttrs->push_back(LA); 152198092Srdivacky 153234353Sdim // Attributes in a class are parsed at the end of the class, along 154234353Sdim // with other late-parsed declarations. 155243830Sdim if (!ClassStack.empty() && !LateAttrs->parseSoon()) 156234353Sdim getCurrentClass().LateParsedDeclarations.push_back(LA); 157234353Sdim 158226633Sdim // consume everything up to and including the matching right parens 159226633Sdim ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false); 160198092Srdivacky 161226633Sdim Token Eof; 162226633Sdim Eof.startToken(); 163226633Sdim Eof.setLocation(Tok.getLocation()); 164226633Sdim LA->Toks.push_back(Eof); 165226633Sdim } else { 166243830Sdim ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, 167243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 168193326Sed } 169193326Sed } else { 170263508Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 171263508Sdim AttributeList::AS_GNU); 172193326Sed } 173193326Sed } 174193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 175263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 176199990Srdivacky SourceLocation Loc = Tok.getLocation(); 177263508Sdim if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 178263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 179218893Sdim if (endLoc) 180218893Sdim *endLoc = Loc; 181193326Sed } 182193326Sed} 183193326Sed 184263508Sdim/// \brief Normalizes an attribute name by dropping prefixed and suffixed __. 185263508Sdimstatic StringRef normalizeAttrName(StringRef Name) { 186263508Sdim if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) 187263508Sdim Name = Name.drop_front(2).drop_back(2); 188263508Sdim return Name; 189263508Sdim} 190263508Sdim 191263508Sdim/// \brief Determine whether the given attribute has an identifier argument. 192263508Sdimstatic bool attributeHasIdentifierArg(const IdentifierInfo &II) { 193263508Sdim return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) 194263508Sdim#include "clang/Parse/AttrIdentifierArg.inc" 195251662Sdim .Default(false); 196251662Sdim} 197226633Sdim 198263508Sdim/// \brief Determine whether the given attribute parses a type argument. 199263508Sdimstatic bool attributeIsTypeArgAttr(const IdentifierInfo &II) { 200263508Sdim return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) 201263508Sdim#include "clang/Parse/AttrTypeArg.inc" 202263508Sdim .Default(false); 203263508Sdim} 204263508Sdim 205263508SdimIdentifierLoc *Parser::ParseIdentifierLoc() { 206263508Sdim assert(Tok.is(tok::identifier) && "expected an identifier"); 207263508Sdim IdentifierLoc *IL = IdentifierLoc::create(Actions.Context, 208263508Sdim Tok.getLocation(), 209263508Sdim Tok.getIdentifierInfo()); 210263508Sdim ConsumeToken(); 211263508Sdim return IL; 212263508Sdim} 213263508Sdim 214263508Sdimvoid Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName, 215263508Sdim SourceLocation AttrNameLoc, 216263508Sdim ParsedAttributes &Attrs, 217263508Sdim SourceLocation *EndLoc) { 218263508Sdim BalancedDelimiterTracker Parens(*this, tok::l_paren); 219263508Sdim Parens.consumeOpen(); 220263508Sdim 221263508Sdim TypeResult T; 222263508Sdim if (Tok.isNot(tok::r_paren)) 223263508Sdim T = ParseTypeName(); 224263508Sdim 225263508Sdim if (Parens.consumeClose()) 226263508Sdim return; 227263508Sdim 228263508Sdim if (T.isInvalid()) 229263508Sdim return; 230263508Sdim 231263508Sdim if (T.isUsable()) 232263508Sdim Attrs.addNewTypeAttr(&AttrName, 233263508Sdim SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0, 234263508Sdim AttrNameLoc, T.get(), AttributeList::AS_GNU); 235263508Sdim else 236263508Sdim Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()), 237263508Sdim 0, AttrNameLoc, 0, 0, AttributeList::AS_GNU); 238263508Sdim} 239263508Sdim 240243830Sdim/// Parse the arguments to a parameterized GNU attribute or 241243830Sdim/// a C++11 attribute in "gnu" namespace. 242226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, 243226633Sdim SourceLocation AttrNameLoc, 244226633Sdim ParsedAttributes &Attrs, 245243830Sdim SourceLocation *EndLoc, 246243830Sdim IdentifierInfo *ScopeName, 247243830Sdim SourceLocation ScopeLoc, 248243830Sdim AttributeList::Syntax Syntax) { 249226633Sdim 250226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 251226633Sdim 252263508Sdim AttributeList::Kind AttrKind = 253263508Sdim AttributeList::getKind(AttrName, ScopeName, Syntax); 254263508Sdim 255226633Sdim // Availability attributes have their own grammar. 256263508Sdim // FIXME: All these cases fail to pass in the syntax and scope, and might be 257263508Sdim // written as C++11 gnu:: attributes. 258263508Sdim if (AttrKind == AttributeList::AT_Availability) { 259226633Sdim ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 260226633Sdim return; 261226633Sdim } 262263508Sdim // Thread safety attributes are parsed in an unevaluated context. 263263508Sdim // FIXME: Share the bulk of the parsing code here and just pull out 264263508Sdim // the unevaluated context. 265226633Sdim if (IsThreadSafetyAttribute(AttrName->getName())) { 266226633Sdim ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 267226633Sdim return; 268226633Sdim } 269239462Sdim // Type safety attributes have their own grammar. 270263508Sdim if (AttrKind == AttributeList::AT_TypeTagForDatatype) { 271239462Sdim ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 272239462Sdim return; 273239462Sdim } 274263508Sdim // Some attributes expect solely a type parameter. 275263508Sdim if (attributeIsTypeArgAttr(*AttrName)) { 276263508Sdim ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc); 277263508Sdim return; 278263508Sdim } 279226633Sdim 280263508Sdim // Ignore the left paren location for now. 281263508Sdim ConsumeParen(); 282226633Sdim 283263508Sdim ArgsVector ArgExprs; 284226633Sdim 285263508Sdim if (Tok.is(tok::identifier)) { 286263508Sdim // If this attribute wants an 'identifier' argument, make it so. 287263508Sdim bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName); 288249423Sdim 289263508Sdim // If we don't know how to parse this attribute, but this is the only 290263508Sdim // token in this argument, assume it's meant to be an identifier. 291263508Sdim if (AttrKind == AttributeList::UnknownAttribute || 292263508Sdim AttrKind == AttributeList::IgnoredAttribute) { 293263508Sdim const Token &Next = NextToken(); 294263508Sdim IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma); 295249423Sdim } 296234353Sdim 297263508Sdim if (IsIdentifierArg) 298263508Sdim ArgExprs.push_back(ParseIdentifierLoc()); 299234353Sdim } 300234353Sdim 301263508Sdim if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) { 302234353Sdim // Eat the comma. 303263508Sdim if (!ArgExprs.empty()) 304226633Sdim ConsumeToken(); 305226633Sdim 306234353Sdim // Parse the non-empty comma-separated list of expressions. 307234353Sdim while (1) { 308234353Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 309234353Sdim if (ArgExpr.isInvalid()) { 310263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 311234353Sdim return; 312226633Sdim } 313234353Sdim ArgExprs.push_back(ArgExpr.release()); 314234353Sdim if (Tok.isNot(tok::comma)) 315234353Sdim break; 316234353Sdim ConsumeToken(); // Eat the comma, move to the next argument 317226633Sdim } 318234353Sdim } 319234353Sdim 320234353Sdim SourceLocation RParen = Tok.getLocation(); 321263508Sdim if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 322243830Sdim SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc; 323263508Sdim Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc, 324263508Sdim ArgExprs.data(), ArgExprs.size(), Syntax); 325234353Sdim } 326226633Sdim} 327226633Sdim 328239462Sdim/// \brief Parses a single argument for a declspec, including the 329239462Sdim/// surrounding parens. 330239462Sdimvoid Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, 331239462Sdim SourceLocation AttrNameLoc, 332239462Sdim ParsedAttributes &Attrs) 333239462Sdim{ 334239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 335239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 336239462Sdim AttrName->getNameStart(), tok::r_paren)) 337239462Sdim return; 338226633Sdim 339239462Sdim ExprResult ArgExpr(ParseConstantExpression()); 340239462Sdim if (ArgExpr.isInvalid()) { 341239462Sdim T.skipToEnd(); 342239462Sdim return; 343239462Sdim } 344263508Sdim ArgsUnion ExprList = ArgExpr.take(); 345263508Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1, 346263508Sdim AttributeList::AS_Declspec); 347239462Sdim 348239462Sdim T.consumeClose(); 349239462Sdim} 350239462Sdim 351239462Sdim/// \brief Determines whether a declspec is a "simple" one requiring no 352239462Sdim/// arguments. 353239462Sdimbool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) { 354239462Sdim return llvm::StringSwitch<bool>(Ident->getName()) 355239462Sdim .Case("dllimport", true) 356239462Sdim .Case("dllexport", true) 357239462Sdim .Case("noreturn", true) 358239462Sdim .Case("nothrow", true) 359239462Sdim .Case("noinline", true) 360239462Sdim .Case("naked", true) 361239462Sdim .Case("appdomain", true) 362239462Sdim .Case("process", true) 363239462Sdim .Case("jitintrinsic", true) 364239462Sdim .Case("noalias", true) 365239462Sdim .Case("restrict", true) 366239462Sdim .Case("novtable", true) 367239462Sdim .Case("selectany", true) 368239462Sdim .Case("thread", true) 369251662Sdim .Case("safebuffers", true ) 370239462Sdim .Default(false); 371239462Sdim} 372239462Sdim 373239462Sdim/// \brief Attempts to parse a declspec which is not simple (one that takes 374239462Sdim/// parameters). Will return false if we properly handled the declspec, or 375239462Sdim/// true if it is an unknown declspec. 376239462Sdimvoid Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, 377239462Sdim SourceLocation Loc, 378239462Sdim ParsedAttributes &Attrs) { 379239462Sdim // Try to handle the easy case first -- these declspecs all take a single 380239462Sdim // parameter as their argument. 381239462Sdim if (llvm::StringSwitch<bool>(Ident->getName()) 382239462Sdim .Case("uuid", true) 383239462Sdim .Case("align", true) 384239462Sdim .Case("allocate", true) 385239462Sdim .Default(false)) { 386239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 387239462Sdim } else if (Ident->getName() == "deprecated") { 388239462Sdim // The deprecated declspec has an optional single argument, so we will 389239462Sdim // check for a l-paren to decide whether we should parse an argument or 390239462Sdim // not. 391239462Sdim if (Tok.getKind() == tok::l_paren) 392239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 393239462Sdim else 394263508Sdim Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec); 395239462Sdim } else if (Ident->getName() == "property") { 396239462Sdim // The property declspec is more complex in that it can take one or two 397239462Sdim // assignment expressions as a parameter, but the lhs of the assignment 398239462Sdim // must be named get or put. 399251662Sdim if (Tok.isNot(tok::l_paren)) { 400251662Sdim Diag(Tok.getLocation(), diag::err_expected_lparen_after) 401251662Sdim << Ident->getNameStart(); 402251662Sdim return; 403251662Sdim } 404239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 405251662Sdim T.expectAndConsume(diag::err_expected_lparen_after, 406251662Sdim Ident->getNameStart(), tok::r_paren); 407251662Sdim 408251662Sdim enum AccessorKind { 409251662Sdim AK_Invalid = -1, 410251662Sdim AK_Put = 0, AK_Get = 1 // indices into AccessorNames 411251662Sdim }; 412251662Sdim IdentifierInfo *AccessorNames[] = { 0, 0 }; 413251662Sdim bool HasInvalidAccessor = false; 414251662Sdim 415251662Sdim // Parse the accessor specifications. 416251662Sdim while (true) { 417251662Sdim // Stop if this doesn't look like an accessor spec. 418251662Sdim if (!Tok.is(tok::identifier)) { 419251662Sdim // If the user wrote a completely empty list, use a special diagnostic. 420251662Sdim if (Tok.is(tok::r_paren) && !HasInvalidAccessor && 421251662Sdim AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) { 422251662Sdim Diag(Loc, diag::err_ms_property_no_getter_or_putter); 423251662Sdim break; 424251662Sdim } 425251662Sdim 426251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor); 427251662Sdim break; 428251662Sdim } 429251662Sdim 430251662Sdim AccessorKind Kind; 431251662Sdim SourceLocation KindLoc = Tok.getLocation(); 432251662Sdim StringRef KindStr = Tok.getIdentifierInfo()->getName(); 433251662Sdim if (KindStr == "get") { 434251662Sdim Kind = AK_Get; 435251662Sdim } else if (KindStr == "put") { 436251662Sdim Kind = AK_Put; 437251662Sdim 438251662Sdim // Recover from the common mistake of using 'set' instead of 'put'. 439251662Sdim } else if (KindStr == "set") { 440251662Sdim Diag(KindLoc, diag::err_ms_property_has_set_accessor) 441251662Sdim << FixItHint::CreateReplacement(KindLoc, "put"); 442251662Sdim Kind = AK_Put; 443251662Sdim 444251662Sdim // Handle the mistake of forgetting the accessor kind by skipping 445251662Sdim // this accessor. 446251662Sdim } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) { 447251662Sdim Diag(KindLoc, diag::err_ms_property_missing_accessor_kind); 448251662Sdim ConsumeToken(); 449251662Sdim HasInvalidAccessor = true; 450251662Sdim goto next_property_accessor; 451251662Sdim 452251662Sdim // Otherwise, complain about the unknown accessor kind. 453251662Sdim } else { 454251662Sdim Diag(KindLoc, diag::err_ms_property_unknown_accessor); 455251662Sdim HasInvalidAccessor = true; 456251662Sdim Kind = AK_Invalid; 457251662Sdim 458251662Sdim // Try to keep parsing unless it doesn't look like an accessor spec. 459251662Sdim if (!NextToken().is(tok::equal)) break; 460251662Sdim } 461251662Sdim 462251662Sdim // Consume the identifier. 463251662Sdim ConsumeToken(); 464251662Sdim 465251662Sdim // Consume the '='. 466251662Sdim if (Tok.is(tok::equal)) { 467251662Sdim ConsumeToken(); 468251662Sdim } else { 469251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_equal) 470251662Sdim << KindStr; 471251662Sdim break; 472251662Sdim } 473251662Sdim 474251662Sdim // Expect the method name. 475251662Sdim if (!Tok.is(tok::identifier)) { 476251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name); 477251662Sdim break; 478251662Sdim } 479251662Sdim 480251662Sdim if (Kind == AK_Invalid) { 481251662Sdim // Just drop invalid accessors. 482251662Sdim } else if (AccessorNames[Kind] != NULL) { 483251662Sdim // Complain about the repeated accessor, ignore it, and keep parsing. 484251662Sdim Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr; 485251662Sdim } else { 486251662Sdim AccessorNames[Kind] = Tok.getIdentifierInfo(); 487251662Sdim } 488251662Sdim ConsumeToken(); 489251662Sdim 490251662Sdim next_property_accessor: 491251662Sdim // Keep processing accessors until we run out. 492251662Sdim if (Tok.is(tok::comma)) { 493251662Sdim ConsumeAnyToken(); 494251662Sdim continue; 495251662Sdim 496251662Sdim // If we run into the ')', stop without consuming it. 497251662Sdim } else if (Tok.is(tok::r_paren)) { 498251662Sdim break; 499251662Sdim } else { 500251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen); 501251662Sdim break; 502251662Sdim } 503251662Sdim } 504251662Sdim 505251662Sdim // Only add the property attribute if it was well-formed. 506251662Sdim if (!HasInvalidAccessor) { 507263508Sdim Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(), 508251662Sdim AccessorNames[AK_Get], AccessorNames[AK_Put], 509251662Sdim AttributeList::AS_Declspec); 510251662Sdim } 511239462Sdim T.skipToEnd(); 512239462Sdim } else { 513239462Sdim // We don't recognize this as a valid declspec, but instead of creating the 514239462Sdim // attribute and allowing sema to warn about it, we will warn here instead. 515239462Sdim // This is because some attributes have multiple spellings, but we need to 516239462Sdim // disallow that for declspecs (such as align vs aligned). If we made the 517239462Sdim // attribute, we'd have to split the valid declspec spelling logic into 518239462Sdim // both locations. 519239462Sdim Diag(Loc, diag::warn_ms_declspec_unknown) << Ident; 520239462Sdim 521239462Sdim // If there's an open paren, we should eat the open and close parens under 522239462Sdim // the assumption that this unknown declspec has parameters. 523239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 524239462Sdim if (!T.consumeOpen()) 525239462Sdim T.skipToEnd(); 526239462Sdim } 527239462Sdim} 528239462Sdim 529193725Sed/// [MS] decl-specifier: 530193725Sed/// __declspec ( extended-decl-modifier-seq ) 531193725Sed/// 532193725Sed/// [MS] extended-decl-modifier-seq: 533193725Sed/// extended-decl-modifier[opt] 534193725Sed/// extended-decl-modifier extended-decl-modifier-seq 535239462Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) { 536193326Sed assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); 537193725Sed 538193326Sed ConsumeToken(); 539239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 540239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec", 541239462Sdim tok::r_paren)) 542218893Sdim return; 543223017Sdim 544239462Sdim // An empty declspec is perfectly legal and should not warn. Additionally, 545239462Sdim // you can specify multiple attributes per declspec. 546239462Sdim while (Tok.getKind() != tok::r_paren) { 547239462Sdim // We expect either a well-known identifier or a generic string. Anything 548239462Sdim // else is a malformed declspec. 549239462Sdim bool IsString = Tok.getKind() == tok::string_literal ? true : false; 550239462Sdim if (!IsString && Tok.getKind() != tok::identifier && 551239462Sdim Tok.getKind() != tok::kw_restrict) { 552239462Sdim Diag(Tok, diag::err_ms_declspec_type); 553239462Sdim T.skipToEnd(); 554239462Sdim return; 555223017Sdim } 556239462Sdim 557239462Sdim IdentifierInfo *AttrName; 558239462Sdim SourceLocation AttrNameLoc; 559239462Sdim if (IsString) { 560239462Sdim SmallString<8> StrBuffer; 561239462Sdim bool Invalid = false; 562239462Sdim StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid); 563239462Sdim if (Invalid) { 564239462Sdim T.skipToEnd(); 565239462Sdim return; 566193725Sed } 567239462Sdim AttrName = PP.getIdentifierInfo(Str); 568239462Sdim AttrNameLoc = ConsumeStringToken(); 569193725Sed } else { 570239462Sdim AttrName = Tok.getIdentifierInfo(); 571239462Sdim AttrNameLoc = ConsumeToken(); 572193725Sed } 573239462Sdim 574239462Sdim if (IsString || IsSimpleMicrosoftDeclSpec(AttrName)) 575239462Sdim // If we have a generic string, we will allow it because there is no 576239462Sdim // documented list of allowable string declspecs, but we know they exist 577239462Sdim // (for instance, SAL declspecs in older versions of MSVC). 578239462Sdim // 579239462Sdim // Alternatively, if the identifier is a simple one, then it requires no 580239462Sdim // arguments and can be turned into an attribute directly. 581263508Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 582263508Sdim AttributeList::AS_Declspec); 583239462Sdim else 584239462Sdim ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs); 585193725Sed } 586239462Sdim T.consumeClose(); 587193326Sed} 588193326Sed 589218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { 590194179Sed // Treat these like attributes 591194179Sed while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || 592208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || 593226633Sdim Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 594263508Sdim Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) || 595263508Sdim Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) { 596194179Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 597194179Sed SourceLocation AttrNameLoc = ConsumeToken(); 598263508Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 599263508Sdim AttributeList::AS_Keyword); 600194179Sed } 601194179Sed} 602194179Sed 603218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { 604212904Sdim // Treat these like attributes 605212904Sdim while (Tok.is(tok::kw___pascal)) { 606212904Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 607212904Sdim SourceLocation AttrNameLoc = ConsumeToken(); 608263508Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 609263508Sdim AttributeList::AS_Keyword); 610212904Sdim } 611212904Sdim} 612212904Sdim 613218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { 614218893Sdim // Treat these like attributes 615218893Sdim while (Tok.is(tok::kw___kernel)) { 616249423Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 617218893Sdim SourceLocation AttrNameLoc = ConsumeToken(); 618263508Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 619263508Sdim AttributeList::AS_Keyword); 620218893Sdim } 621218893Sdim} 622218893Sdim 623221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) { 624249423Sdim // FIXME: The mapping from attribute spelling to semantics should be 625249423Sdim // performed in Sema, not here. 626221345Sdim SourceLocation Loc = Tok.getLocation(); 627221345Sdim switch(Tok.getKind()) { 628221345Sdim // OpenCL qualifiers: 629221345Sdim case tok::kw___private: 630239462Sdim case tok::kw_private: 631221345Sdim DS.getAttributes().addNewInteger( 632239462Sdim Actions.getASTContext(), 633221345Sdim PP.getIdentifierInfo("address_space"), Loc, 0); 634221345Sdim break; 635239462Sdim 636221345Sdim case tok::kw___global: 637221345Sdim DS.getAttributes().addNewInteger( 638221345Sdim Actions.getASTContext(), 639221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global); 640221345Sdim break; 641239462Sdim 642221345Sdim case tok::kw___local: 643221345Sdim DS.getAttributes().addNewInteger( 644221345Sdim Actions.getASTContext(), 645221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local); 646221345Sdim break; 647239462Sdim 648221345Sdim case tok::kw___constant: 649221345Sdim DS.getAttributes().addNewInteger( 650221345Sdim Actions.getASTContext(), 651221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant); 652221345Sdim break; 653239462Sdim 654221345Sdim case tok::kw___read_only: 655221345Sdim DS.getAttributes().addNewInteger( 656239462Sdim Actions.getASTContext(), 657221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only); 658221345Sdim break; 659239462Sdim 660221345Sdim case tok::kw___write_only: 661221345Sdim DS.getAttributes().addNewInteger( 662239462Sdim Actions.getASTContext(), 663221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only); 664221345Sdim break; 665239462Sdim 666221345Sdim case tok::kw___read_write: 667221345Sdim DS.getAttributes().addNewInteger( 668221345Sdim Actions.getASTContext(), 669221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write); 670221345Sdim break; 671221345Sdim default: break; 672221345Sdim } 673221345Sdim} 674221345Sdim 675221345Sdim/// \brief Parse a version number. 676221345Sdim/// 677221345Sdim/// version: 678221345Sdim/// simple-integer 679221345Sdim/// simple-integer ',' simple-integer 680221345Sdim/// simple-integer ',' simple-integer ',' simple-integer 681221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) { 682221345Sdim Range = Tok.getLocation(); 683221345Sdim 684221345Sdim if (!Tok.is(tok::numeric_constant)) { 685221345Sdim Diag(Tok, diag::err_expected_version); 686263508Sdim SkipUntil(tok::comma, tok::r_paren, 687263508Sdim StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 688221345Sdim return VersionTuple(); 689221345Sdim } 690221345Sdim 691221345Sdim // Parse the major (and possibly minor and subminor) versions, which 692221345Sdim // are stored in the numeric constant. We utilize a quirk of the 693221345Sdim // lexer, which is that it handles something like 1.2.3 as a single 694221345Sdim // numeric constant, rather than two separate tokens. 695234353Sdim SmallString<512> Buffer; 696221345Sdim Buffer.resize(Tok.getLength()+1); 697221345Sdim const char *ThisTokBegin = &Buffer[0]; 698221345Sdim 699221345Sdim // Get the spelling of the token, which eliminates trigraphs, etc. 700221345Sdim bool Invalid = false; 701221345Sdim unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid); 702221345Sdim if (Invalid) 703221345Sdim return VersionTuple(); 704221345Sdim 705221345Sdim // Parse the major version. 706221345Sdim unsigned AfterMajor = 0; 707221345Sdim unsigned Major = 0; 708249423Sdim while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) { 709221345Sdim Major = Major * 10 + ThisTokBegin[AfterMajor] - '0'; 710221345Sdim ++AfterMajor; 711221345Sdim } 712221345Sdim 713221345Sdim if (AfterMajor == 0) { 714221345Sdim Diag(Tok, diag::err_expected_version); 715263508Sdim SkipUntil(tok::comma, tok::r_paren, 716263508Sdim StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 717221345Sdim return VersionTuple(); 718221345Sdim } 719221345Sdim 720221345Sdim if (AfterMajor == ActualLength) { 721221345Sdim ConsumeToken(); 722221345Sdim 723221345Sdim // We only had a single version component. 724221345Sdim if (Major == 0) { 725221345Sdim Diag(Tok, diag::err_zero_version); 726221345Sdim return VersionTuple(); 727221345Sdim } 728221345Sdim 729221345Sdim return VersionTuple(Major); 730221345Sdim } 731221345Sdim 732221345Sdim if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { 733221345Sdim Diag(Tok, diag::err_expected_version); 734263508Sdim SkipUntil(tok::comma, tok::r_paren, 735263508Sdim StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 736221345Sdim return VersionTuple(); 737221345Sdim } 738221345Sdim 739221345Sdim // Parse the minor version. 740221345Sdim unsigned AfterMinor = AfterMajor + 1; 741221345Sdim unsigned Minor = 0; 742249423Sdim while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) { 743221345Sdim Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0'; 744221345Sdim ++AfterMinor; 745221345Sdim } 746221345Sdim 747221345Sdim if (AfterMinor == ActualLength) { 748221345Sdim ConsumeToken(); 749239462Sdim 750221345Sdim // We had major.minor. 751221345Sdim if (Major == 0 && Minor == 0) { 752221345Sdim Diag(Tok, diag::err_zero_version); 753221345Sdim return VersionTuple(); 754221345Sdim } 755221345Sdim 756239462Sdim return VersionTuple(Major, Minor); 757221345Sdim } 758221345Sdim 759221345Sdim // If what follows is not a '.', we have a problem. 760221345Sdim if (ThisTokBegin[AfterMinor] != '.') { 761221345Sdim Diag(Tok, diag::err_expected_version); 762263508Sdim SkipUntil(tok::comma, tok::r_paren, 763263508Sdim StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 764239462Sdim return VersionTuple(); 765221345Sdim } 766221345Sdim 767221345Sdim // Parse the subminor version. 768221345Sdim unsigned AfterSubminor = AfterMinor + 1; 769221345Sdim unsigned Subminor = 0; 770249423Sdim while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) { 771221345Sdim Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0'; 772221345Sdim ++AfterSubminor; 773221345Sdim } 774221345Sdim 775221345Sdim if (AfterSubminor != ActualLength) { 776221345Sdim Diag(Tok, diag::err_expected_version); 777263508Sdim SkipUntil(tok::comma, tok::r_paren, 778263508Sdim StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 779221345Sdim return VersionTuple(); 780221345Sdim } 781221345Sdim ConsumeToken(); 782221345Sdim return VersionTuple(Major, Minor, Subminor); 783221345Sdim} 784221345Sdim 785221345Sdim/// \brief Parse the contents of the "availability" attribute. 786221345Sdim/// 787221345Sdim/// availability-attribute: 788234353Sdim/// 'availability' '(' platform ',' version-arg-list, opt-message')' 789221345Sdim/// 790221345Sdim/// platform: 791221345Sdim/// identifier 792221345Sdim/// 793221345Sdim/// version-arg-list: 794221345Sdim/// version-arg 795221345Sdim/// version-arg ',' version-arg-list 796221345Sdim/// 797221345Sdim/// version-arg: 798221345Sdim/// 'introduced' '=' version 799221345Sdim/// 'deprecated' '=' version 800234353Sdim/// 'obsoleted' = version 801221345Sdim/// 'unavailable' 802234353Sdim/// opt-message: 803234353Sdim/// 'message' '=' <string> 804221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, 805221345Sdim SourceLocation AvailabilityLoc, 806221345Sdim ParsedAttributes &attrs, 807221345Sdim SourceLocation *endLoc) { 808221345Sdim enum { Introduced, Deprecated, Obsoleted, Unknown }; 809221345Sdim AvailabilityChange Changes[Unknown]; 810234353Sdim ExprResult MessageExpr; 811221345Sdim 812221345Sdim // Opening '('. 813226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 814226633Sdim if (T.consumeOpen()) { 815221345Sdim Diag(Tok, diag::err_expected_lparen); 816221345Sdim return; 817221345Sdim } 818221345Sdim 819221345Sdim // Parse the platform name, 820221345Sdim if (Tok.isNot(tok::identifier)) { 821221345Sdim Diag(Tok, diag::err_availability_expected_platform); 822263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 823221345Sdim return; 824221345Sdim } 825263508Sdim IdentifierLoc *Platform = ParseIdentifierLoc(); 826221345Sdim 827221345Sdim // Parse the ',' following the platform name. 828221345Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) 829221345Sdim return; 830221345Sdim 831221345Sdim // If we haven't grabbed the pointers for the identifiers 832221345Sdim // "introduced", "deprecated", and "obsoleted", do so now. 833221345Sdim if (!Ident_introduced) { 834221345Sdim Ident_introduced = PP.getIdentifierInfo("introduced"); 835221345Sdim Ident_deprecated = PP.getIdentifierInfo("deprecated"); 836221345Sdim Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); 837221345Sdim Ident_unavailable = PP.getIdentifierInfo("unavailable"); 838234353Sdim Ident_message = PP.getIdentifierInfo("message"); 839221345Sdim } 840221345Sdim 841221345Sdim // Parse the set of introductions/deprecations/removals. 842221345Sdim SourceLocation UnavailableLoc; 843221345Sdim do { 844221345Sdim if (Tok.isNot(tok::identifier)) { 845221345Sdim Diag(Tok, diag::err_availability_expected_change); 846263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 847221345Sdim return; 848221345Sdim } 849221345Sdim IdentifierInfo *Keyword = Tok.getIdentifierInfo(); 850221345Sdim SourceLocation KeywordLoc = ConsumeToken(); 851221345Sdim 852221345Sdim if (Keyword == Ident_unavailable) { 853221345Sdim if (UnavailableLoc.isValid()) { 854221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 855221345Sdim << Keyword << SourceRange(UnavailableLoc); 856239462Sdim } 857221345Sdim UnavailableLoc = KeywordLoc; 858221345Sdim 859221345Sdim if (Tok.isNot(tok::comma)) 860221345Sdim break; 861221345Sdim 862221345Sdim ConsumeToken(); 863221345Sdim continue; 864239462Sdim } 865239462Sdim 866221345Sdim if (Tok.isNot(tok::equal)) { 867221345Sdim Diag(Tok, diag::err_expected_equal_after) 868221345Sdim << Keyword; 869263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 870221345Sdim return; 871221345Sdim } 872221345Sdim ConsumeToken(); 873234353Sdim if (Keyword == Ident_message) { 874263508Sdim if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals. 875249423Sdim Diag(Tok, diag::err_expected_string_literal) 876249423Sdim << /*Source='availability attribute'*/2; 877263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 878234353Sdim return; 879234353Sdim } 880234353Sdim MessageExpr = ParseStringLiteralExpression(); 881234353Sdim break; 882234353Sdim } 883239462Sdim 884221345Sdim SourceRange VersionRange; 885221345Sdim VersionTuple Version = ParseVersionTuple(VersionRange); 886239462Sdim 887221345Sdim if (Version.empty()) { 888263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 889221345Sdim return; 890221345Sdim } 891221345Sdim 892221345Sdim unsigned Index; 893221345Sdim if (Keyword == Ident_introduced) 894221345Sdim Index = Introduced; 895221345Sdim else if (Keyword == Ident_deprecated) 896221345Sdim Index = Deprecated; 897221345Sdim else if (Keyword == Ident_obsoleted) 898221345Sdim Index = Obsoleted; 899239462Sdim else 900221345Sdim Index = Unknown; 901221345Sdim 902221345Sdim if (Index < Unknown) { 903221345Sdim if (!Changes[Index].KeywordLoc.isInvalid()) { 904221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 905239462Sdim << Keyword 906221345Sdim << SourceRange(Changes[Index].KeywordLoc, 907221345Sdim Changes[Index].VersionRange.getEnd()); 908221345Sdim } 909221345Sdim 910221345Sdim Changes[Index].KeywordLoc = KeywordLoc; 911221345Sdim Changes[Index].Version = Version; 912221345Sdim Changes[Index].VersionRange = VersionRange; 913221345Sdim } else { 914221345Sdim Diag(KeywordLoc, diag::err_availability_unknown_change) 915221345Sdim << Keyword << VersionRange; 916221345Sdim } 917221345Sdim 918221345Sdim if (Tok.isNot(tok::comma)) 919221345Sdim break; 920221345Sdim 921221345Sdim ConsumeToken(); 922221345Sdim } while (true); 923221345Sdim 924221345Sdim // Closing ')'. 925226633Sdim if (T.consumeClose()) 926221345Sdim return; 927221345Sdim 928221345Sdim if (endLoc) 929226633Sdim *endLoc = T.getCloseLocation(); 930221345Sdim 931221345Sdim // The 'unavailable' availability cannot be combined with any other 932221345Sdim // availability changes. Make sure that hasn't happened. 933221345Sdim if (UnavailableLoc.isValid()) { 934221345Sdim bool Complained = false; 935221345Sdim for (unsigned Index = Introduced; Index != Unknown; ++Index) { 936221345Sdim if (Changes[Index].KeywordLoc.isValid()) { 937221345Sdim if (!Complained) { 938221345Sdim Diag(UnavailableLoc, diag::warn_availability_and_unavailable) 939221345Sdim << SourceRange(Changes[Index].KeywordLoc, 940221345Sdim Changes[Index].VersionRange.getEnd()); 941221345Sdim Complained = true; 942221345Sdim } 943221345Sdim 944221345Sdim // Clear out the availability. 945221345Sdim Changes[Index] = AvailabilityChange(); 946221345Sdim } 947221345Sdim } 948221345Sdim } 949221345Sdim 950221345Sdim // Record this attribute 951239462Sdim attrs.addNew(&Availability, 952239462Sdim SourceRange(AvailabilityLoc, T.getCloseLocation()), 953234353Sdim 0, AvailabilityLoc, 954263508Sdim Platform, 955221345Sdim Changes[Introduced], 956221345Sdim Changes[Deprecated], 957239462Sdim Changes[Obsoleted], 958234353Sdim UnavailableLoc, MessageExpr.take(), 959239462Sdim AttributeList::AS_GNU); 960221345Sdim} 961221345Sdim 962226633Sdim 963226633Sdim// Late Parsed Attributes: 964226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods 965226633Sdim 966226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {} 967226633Sdim 968226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() { 969226633Sdim Self->ParseLexedAttributes(*Class); 970226633Sdim} 971226633Sdim 972226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() { 973234353Sdim Self->ParseLexedAttribute(*this, true, false); 974226633Sdim} 975226633Sdim 976226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the 977226633Sdim/// scope appropriately. 978226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) { 979226633Sdim // Deal with templates 980226633Sdim // FIXME: Test cases to make sure this does the right thing for templates. 981226633Sdim bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 982226633Sdim ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 983226633Sdim HasTemplateScope); 984226633Sdim if (HasTemplateScope) 985226633Sdim Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 986226633Sdim 987234982Sdim // Set or update the scope flags. 988226633Sdim bool AlreadyHasClassScope = Class.TopLevelClass; 989234982Sdim unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; 990226633Sdim ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 991226633Sdim ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 992226633Sdim 993234353Sdim // Enter the scope of nested classes 994234353Sdim if (!AlreadyHasClassScope) 995234353Sdim Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 996234353Sdim Class.TagOrTemplate); 997239462Sdim if (!Class.LateParsedDeclarations.empty()) { 998234982Sdim for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ 999234982Sdim Class.LateParsedDeclarations[i]->ParseLexedAttributes(); 1000234982Sdim } 1001226633Sdim } 1002239462Sdim 1003234353Sdim if (!AlreadyHasClassScope) 1004234353Sdim Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 1005234353Sdim Class.TagOrTemplate); 1006226633Sdim} 1007226633Sdim 1008234353Sdim 1009234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D. 1010234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 1011234353Sdim bool EnterScope, bool OnDefinition) { 1012243830Sdim assert(LAs.parseSoon() && 1013243830Sdim "Attribute list should be marked for immediate parsing."); 1014234353Sdim for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 1015239462Sdim if (D) 1016239462Sdim LAs[i]->addDecl(D); 1017234353Sdim ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 1018234982Sdim delete LAs[i]; 1019234353Sdim } 1020234353Sdim LAs.clear(); 1021234353Sdim} 1022234353Sdim 1023234353Sdim 1024226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed. 1025226633Sdim/// This will be called at the end of parsing a class declaration 1026226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and 1027239462Sdim/// create an attribute with the arguments filled in. We add this 1028226633Sdim/// to the Attribute list for the decl. 1029234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA, 1030234353Sdim bool EnterScope, bool OnDefinition) { 1031226633Sdim // Save the current token position. 1032226633Sdim SourceLocation OrigLoc = Tok.getLocation(); 1033226633Sdim 1034226633Sdim // Append the current token at the end of the new token stream so that it 1035226633Sdim // doesn't get lost. 1036226633Sdim LA.Toks.push_back(Tok); 1037226633Sdim PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); 1038226633Sdim // Consume the previously pushed token. 1039249423Sdim ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 1040226633Sdim 1041234353Sdim if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) { 1042249423Sdim // FIXME: Do not warn on C++11 attributes, once we start supporting 1043249423Sdim // them here. 1044234353Sdim Diag(Tok, diag::warn_attribute_on_function_definition) 1045234353Sdim << LA.AttrName.getName(); 1046234353Sdim } 1047234353Sdim 1048226633Sdim ParsedAttributes Attrs(AttrFactory); 1049226633Sdim SourceLocation endLoc; 1050226633Sdim 1051243830Sdim if (LA.Decls.size() > 0) { 1052234353Sdim Decl *D = LA.Decls[0]; 1053243830Sdim NamedDecl *ND = dyn_cast<NamedDecl>(D); 1054243830Sdim RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 1055226633Sdim 1056243830Sdim // Allow 'this' within late-parsed attributes. 1057263508Sdim Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0, 1058263508Sdim ND && ND->isCXXInstanceMember()); 1059226633Sdim 1060243830Sdim if (LA.Decls.size() == 1) { 1061243830Sdim // If the Decl is templatized, add template parameters to scope. 1062243830Sdim bool HasTemplateScope = EnterScope && D->isTemplateDecl(); 1063243830Sdim ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); 1064243830Sdim if (HasTemplateScope) 1065243830Sdim Actions.ActOnReenterTemplateScope(Actions.CurScope, D); 1066226633Sdim 1067243830Sdim // If the Decl is on a function, add function parameters to the scope. 1068243830Sdim bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); 1069243830Sdim ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); 1070243830Sdim if (HasFunScope) 1071243830Sdim Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 1072234353Sdim 1073243830Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1074243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 1075243830Sdim 1076243830Sdim if (HasFunScope) { 1077243830Sdim Actions.ActOnExitFunctionContext(); 1078243830Sdim FnScope.Exit(); // Pop scope, and remove Decls from IdResolver 1079243830Sdim } 1080243830Sdim if (HasTemplateScope) { 1081243830Sdim TempScope.Exit(); 1082243830Sdim } 1083243830Sdim } else { 1084243830Sdim // If there are multiple decls, then the decl cannot be within the 1085243830Sdim // function scope. 1086243830Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1087243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 1088234353Sdim } 1089234353Sdim } else { 1090234353Sdim Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 1091226633Sdim } 1092234353Sdim 1093234353Sdim for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) { 1094234353Sdim Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 1095226633Sdim } 1096226633Sdim 1097226633Sdim if (Tok.getLocation() != OrigLoc) { 1098226633Sdim // Due to a parsing error, we either went over the cached tokens or 1099226633Sdim // there are still cached tokens left, so we skip the leftover tokens. 1100226633Sdim // Since this is an uncommon situation that should be avoided, use the 1101226633Sdim // expensive isBeforeInTranslationUnit call. 1102226633Sdim if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 1103226633Sdim OrigLoc)) 1104226633Sdim while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 1105234353Sdim ConsumeAnyToken(); 1106226633Sdim } 1107226633Sdim} 1108226633Sdim 1109226633Sdim/// \brief Wrapper around a case statement checking if AttrName is 1110226633Sdim/// one of the thread safety attributes 1111249423Sdimbool Parser::IsThreadSafetyAttribute(StringRef AttrName) { 1112226633Sdim return llvm::StringSwitch<bool>(AttrName) 1113226633Sdim .Case("guarded_by", true) 1114226633Sdim .Case("guarded_var", true) 1115226633Sdim .Case("pt_guarded_by", true) 1116226633Sdim .Case("pt_guarded_var", true) 1117226633Sdim .Case("lockable", true) 1118226633Sdim .Case("scoped_lockable", true) 1119226633Sdim .Case("no_thread_safety_analysis", true) 1120226633Sdim .Case("acquired_after", true) 1121226633Sdim .Case("acquired_before", true) 1122226633Sdim .Case("exclusive_lock_function", true) 1123226633Sdim .Case("shared_lock_function", true) 1124226633Sdim .Case("exclusive_trylock_function", true) 1125226633Sdim .Case("shared_trylock_function", true) 1126226633Sdim .Case("unlock_function", true) 1127226633Sdim .Case("lock_returned", true) 1128226633Sdim .Case("locks_excluded", true) 1129226633Sdim .Case("exclusive_locks_required", true) 1130226633Sdim .Case("shared_locks_required", true) 1131226633Sdim .Default(false); 1132226633Sdim} 1133226633Sdim 1134226633Sdim/// \brief Parse the contents of thread safety attributes. These 1135226633Sdim/// should always be parsed as an expression list. 1136226633Sdim/// 1137226633Sdim/// We need to special case the parsing due to the fact that if the first token 1138226633Sdim/// of the first argument is an identifier, the main parse loop will store 1139226633Sdim/// that token as a "parameter" and the rest of 1140226633Sdim/// the arguments will be added to a list of "arguments". However, 1141226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each 1142226633Sdim/// argument as an expression and add all arguments to the list of "arguments". 1143226633Sdim/// In future, we will take advantage of this special case to also 1144226633Sdim/// deal with some argument scoping issues here (for example, referring to a 1145226633Sdim/// function parameter in the attribute on that function). 1146226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, 1147226633Sdim SourceLocation AttrNameLoc, 1148226633Sdim ParsedAttributes &Attrs, 1149226633Sdim SourceLocation *EndLoc) { 1150226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1151226633Sdim 1152226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1153226633Sdim T.consumeOpen(); 1154239462Sdim 1155263508Sdim ArgsVector ArgExprs; 1156226633Sdim bool ArgExprsOk = true; 1157239462Sdim 1158226633Sdim // now parse the list of expressions 1159234353Sdim while (Tok.isNot(tok::r_paren)) { 1160249423Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 1161226633Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 1162226633Sdim if (ArgExpr.isInvalid()) { 1163226633Sdim ArgExprsOk = false; 1164226633Sdim T.consumeClose(); 1165226633Sdim break; 1166226633Sdim } else { 1167226633Sdim ArgExprs.push_back(ArgExpr.release()); 1168226633Sdim } 1169226633Sdim if (Tok.isNot(tok::comma)) 1170226633Sdim break; 1171226633Sdim ConsumeToken(); // Eat the comma, move to the next argument 1172226633Sdim } 1173226633Sdim // Match the ')'. 1174226633Sdim if (ArgExprsOk && !T.consumeClose()) { 1175263508Sdim Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(), 1176263508Sdim ArgExprs.size(), AttributeList::AS_GNU); 1177226633Sdim } 1178226633Sdim if (EndLoc) 1179226633Sdim *EndLoc = T.getCloseLocation(); 1180226633Sdim} 1181226633Sdim 1182239462Sdimvoid Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 1183239462Sdim SourceLocation AttrNameLoc, 1184239462Sdim ParsedAttributes &Attrs, 1185239462Sdim SourceLocation *EndLoc) { 1186239462Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1187239462Sdim 1188239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1189239462Sdim T.consumeOpen(); 1190239462Sdim 1191239462Sdim if (Tok.isNot(tok::identifier)) { 1192239462Sdim Diag(Tok, diag::err_expected_ident); 1193239462Sdim T.skipToEnd(); 1194239462Sdim return; 1195239462Sdim } 1196263508Sdim IdentifierLoc *ArgumentKind = ParseIdentifierLoc(); 1197239462Sdim 1198239462Sdim if (Tok.isNot(tok::comma)) { 1199239462Sdim Diag(Tok, diag::err_expected_comma); 1200239462Sdim T.skipToEnd(); 1201239462Sdim return; 1202239462Sdim } 1203239462Sdim ConsumeToken(); 1204239462Sdim 1205239462Sdim SourceRange MatchingCTypeRange; 1206239462Sdim TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange); 1207239462Sdim if (MatchingCType.isInvalid()) { 1208239462Sdim T.skipToEnd(); 1209239462Sdim return; 1210239462Sdim } 1211239462Sdim 1212239462Sdim bool LayoutCompatible = false; 1213239462Sdim bool MustBeNull = false; 1214239462Sdim while (Tok.is(tok::comma)) { 1215239462Sdim ConsumeToken(); 1216239462Sdim if (Tok.isNot(tok::identifier)) { 1217239462Sdim Diag(Tok, diag::err_expected_ident); 1218239462Sdim T.skipToEnd(); 1219239462Sdim return; 1220239462Sdim } 1221239462Sdim IdentifierInfo *Flag = Tok.getIdentifierInfo(); 1222239462Sdim if (Flag->isStr("layout_compatible")) 1223239462Sdim LayoutCompatible = true; 1224239462Sdim else if (Flag->isStr("must_be_null")) 1225239462Sdim MustBeNull = true; 1226239462Sdim else { 1227239462Sdim Diag(Tok, diag::err_type_safety_unknown_flag) << Flag; 1228239462Sdim T.skipToEnd(); 1229239462Sdim return; 1230239462Sdim } 1231239462Sdim ConsumeToken(); // consume flag 1232239462Sdim } 1233239462Sdim 1234239462Sdim if (!T.consumeClose()) { 1235239462Sdim Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc, 1236263508Sdim ArgumentKind, MatchingCType.release(), 1237263508Sdim LayoutCompatible, MustBeNull, 1238263508Sdim AttributeList::AS_GNU); 1239239462Sdim } 1240239462Sdim 1241239462Sdim if (EndLoc) 1242239462Sdim *EndLoc = T.getCloseLocation(); 1243239462Sdim} 1244239462Sdim 1245234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 1246234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not 1247234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 1248234353Sdim/// situation. 1249234353Sdim/// 1250234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if 1251234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller 1252234353Sdim/// should try to parse it. 1253234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() { 1254234353Sdim assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 1255234353Sdim 1256234353Sdim switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) { 1257234353Sdim case CAK_NotAttributeSpecifier: 1258234353Sdim // No diagnostic: we're in Obj-C++11 and this is not actually an attribute. 1259234353Sdim return false; 1260234353Sdim 1261234353Sdim case CAK_InvalidAttributeSpecifier: 1262234353Sdim Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute); 1263234353Sdim return false; 1264234353Sdim 1265234353Sdim case CAK_AttributeSpecifier: 1266234353Sdim // Parse and discard the attributes. 1267234353Sdim SourceLocation BeginLoc = ConsumeBracket(); 1268234353Sdim ConsumeBracket(); 1269263508Sdim SkipUntil(tok::r_square); 1270234353Sdim assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); 1271234353Sdim SourceLocation EndLoc = ConsumeBracket(); 1272234353Sdim Diag(BeginLoc, diag::err_attributes_not_allowed) 1273234353Sdim << SourceRange(BeginLoc, EndLoc); 1274234353Sdim return true; 1275234353Sdim } 1276234353Sdim llvm_unreachable("All cases handled above."); 1277234353Sdim} 1278234353Sdim 1279249423Sdim/// \brief We have found the opening square brackets of a C++11 1280249423Sdim/// attribute-specifier in a location where an attribute is not permitted, but 1281249423Sdim/// we know where the attributes ought to be written. Parse them anyway, and 1282249423Sdim/// provide a fixit moving them to the right place. 1283249423Sdimvoid Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, 1284249423Sdim SourceLocation CorrectLocation) { 1285249423Sdim assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) || 1286249423Sdim Tok.is(tok::kw_alignas)); 1287249423Sdim 1288249423Sdim // Consume the attributes. 1289249423Sdim SourceLocation Loc = Tok.getLocation(); 1290249423Sdim ParseCXX11Attributes(Attrs); 1291249423Sdim CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true); 1292249423Sdim 1293249423Sdim Diag(Loc, diag::err_attributes_not_allowed) 1294249423Sdim << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) 1295249423Sdim << FixItHint::CreateRemoval(AttrRange); 1296249423Sdim} 1297249423Sdim 1298218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { 1299218893Sdim Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) 1300218893Sdim << attrs.Range; 1301218893Sdim} 1302218893Sdim 1303243830Sdimvoid Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) { 1304243830Sdim AttributeList *AttrList = attrs.getList(); 1305243830Sdim while (AttrList) { 1306249423Sdim if (AttrList->isCXX11Attribute()) { 1307249423Sdim Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr) 1308243830Sdim << AttrList->getName(); 1309243830Sdim AttrList->setInvalid(); 1310243830Sdim } 1311243830Sdim AttrList = AttrList->getNext(); 1312243830Sdim } 1313243830Sdim} 1314243830Sdim 1315193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of 1316193326Sed/// declaration-specifiers, some number of declarators, and a semicolon. 1317193326Sed/// 'Context' should be a Declarator::TheContext value. This returns the 1318193326Sed/// location of the semicolon in DeclEnd. 1319193326Sed/// 1320193326Sed/// declaration: [C99 6.7] 1321193326Sed/// block-declaration -> 1322193326Sed/// simple-declaration 1323193326Sed/// others [FIXME] 1324193326Sed/// [C++] template-declaration 1325193326Sed/// [C++] namespace-definition 1326193326Sed/// [C++] using-directive 1327194711Sed/// [C++] using-declaration 1328234982Sdim/// [C++11/C11] static_assert-declaration 1329193326Sed/// others... [FIXME] 1330193326Sed/// 1331218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, 1332218893Sdim unsigned Context, 1333199990Srdivacky SourceLocation &DeclEnd, 1334218893Sdim ParsedAttributesWithRange &attrs) { 1335210299Sed ParenBraceBracketBalancer BalancerRAIIObj(*this); 1336226633Sdim // Must temporarily exit the objective-c container scope for 1337226633Sdim // parsing c none objective-c decls. 1338226633Sdim ObjCDeclContextSwitch ObjCDC(*this); 1339239462Sdim 1340212904Sdim Decl *SingleDecl = 0; 1341224145Sdim Decl *OwnedType = 0; 1342193326Sed switch (Tok.getKind()) { 1343193326Sed case tok::kw_template: 1344193326Sed case tok::kw_export: 1345218893Sdim ProhibitAttributes(attrs); 1346193326Sed SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); 1347193326Sed break; 1348212904Sdim case tok::kw_inline: 1349212904Sdim // Could be the start of an inline namespace. Allowed as an ext in C++03. 1350234353Sdim if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { 1351218893Sdim ProhibitAttributes(attrs); 1352212904Sdim SourceLocation InlineLoc = ConsumeToken(); 1353212904Sdim SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); 1354212904Sdim break; 1355212904Sdim } 1356239462Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, 1357218893Sdim true); 1358193326Sed case tok::kw_namespace: 1359218893Sdim ProhibitAttributes(attrs); 1360193326Sed SingleDecl = ParseNamespace(Context, DeclEnd); 1361193326Sed break; 1362193326Sed case tok::kw_using: 1363218893Sdim SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), 1364224145Sdim DeclEnd, attrs, &OwnedType); 1365193326Sed break; 1366193326Sed case tok::kw_static_assert: 1367221345Sdim case tok::kw__Static_assert: 1368218893Sdim ProhibitAttributes(attrs); 1369193326Sed SingleDecl = ParseStaticAssertDeclaration(DeclEnd); 1370193326Sed break; 1371193326Sed default: 1372218893Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true); 1373193326Sed } 1374239462Sdim 1375193326Sed // This routine returns a DeclGroup, if the thing we parsed only contains a 1376224145Sdim // single decl, convert it now. Alias declarations can also declare a type; 1377224145Sdim // include that too if it is present. 1378224145Sdim return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType); 1379193326Sed} 1380193326Sed 1381193326Sed/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl] 1382193326Sed/// declaration-specifiers init-declarator-list[opt] ';' 1383239462Sdim/// [C++11] attribute-specifier-seq decl-specifier-seq[opt] 1384239462Sdim/// init-declarator-list ';' 1385193326Sed///[C90/C++]init-declarator-list ';' [TODO] 1386193326Sed/// [OMP] threadprivate-directive [TODO] 1387193326Sed/// 1388239462Sdim/// for-range-declaration: [C++11 6.5p1: stmt.ranged] 1389221345Sdim/// attribute-specifier-seq[opt] type-specifier-seq declarator 1390221345Sdim/// 1391193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the 1392206275Srdivacky/// declaration. If it is true, it checks for and eats it. 1393221345Sdim/// 1394221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead 1395221345Sdim/// of a simple-declaration. If we find that we are, we also parse the 1396221345Sdim/// for-range-initializer, and place it here. 1397239462SdimParser::DeclGroupPtrTy 1398239462SdimParser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context, 1399239462Sdim SourceLocation &DeclEnd, 1400249423Sdim ParsedAttributesWithRange &Attrs, 1401239462Sdim bool RequireSemi, ForRangeInit *FRI) { 1402193326Sed // Parse the common declaration-specifiers piece. 1403198893Srdivacky ParsingDeclSpec DS(*this); 1404221345Sdim 1405263508Sdim DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context); 1406263508Sdim ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext); 1407234353Sdim 1408263508Sdim // If we had a free-standing type definition with a missing semicolon, we 1409263508Sdim // may get this far before the problem becomes obvious. 1410263508Sdim if (DS.hasTagDefinition() && 1411263508Sdim DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext)) 1412263508Sdim return DeclGroupPtrTy(); 1413263508Sdim 1414193326Sed // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 1415193326Sed // declaration-specifiers init-declarator-list[opt] ';' 1416193326Sed if (Tok.is(tok::semi)) { 1417249423Sdim ProhibitAttributes(Attrs); 1418239462Sdim DeclEnd = Tok.getLocation(); 1419206275Srdivacky if (RequireSemi) ConsumeToken(); 1420212904Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 1421221345Sdim DS); 1422198893Srdivacky DS.complete(TheDecl); 1423193326Sed return Actions.ConvertDeclToDeclGroup(TheDecl); 1424193326Sed } 1425239462Sdim 1426249423Sdim DS.takeAttributesFrom(Attrs); 1427239462Sdim return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI); 1428198893Srdivacky} 1429198092Srdivacky 1430234353Sdim/// Returns true if this might be the start of a declarator, or a common typo 1431234353Sdim/// for a declarator. 1432234353Sdimbool Parser::MightBeDeclarator(unsigned Context) { 1433234353Sdim switch (Tok.getKind()) { 1434234353Sdim case tok::annot_cxxscope: 1435234353Sdim case tok::annot_template_id: 1436234353Sdim case tok::caret: 1437234353Sdim case tok::code_completion: 1438234353Sdim case tok::coloncolon: 1439234353Sdim case tok::ellipsis: 1440234353Sdim case tok::kw___attribute: 1441234353Sdim case tok::kw_operator: 1442234353Sdim case tok::l_paren: 1443234353Sdim case tok::star: 1444234353Sdim return true; 1445234353Sdim 1446234353Sdim case tok::amp: 1447234353Sdim case tok::ampamp: 1448234353Sdim return getLangOpts().CPlusPlus; 1449234353Sdim 1450234353Sdim case tok::l_square: // Might be an attribute on an unnamed bit-field. 1451249423Sdim return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 && 1452234353Sdim NextToken().is(tok::l_square); 1453234353Sdim 1454234353Sdim case tok::colon: // Might be a typo for '::' or an unnamed bit-field. 1455234353Sdim return Context == Declarator::MemberContext || getLangOpts().CPlusPlus; 1456234353Sdim 1457234353Sdim case tok::identifier: 1458234353Sdim switch (NextToken().getKind()) { 1459234353Sdim case tok::code_completion: 1460234353Sdim case tok::coloncolon: 1461234353Sdim case tok::comma: 1462234353Sdim case tok::equal: 1463234353Sdim case tok::equalequal: // Might be a typo for '='. 1464234353Sdim case tok::kw_alignas: 1465234353Sdim case tok::kw_asm: 1466234353Sdim case tok::kw___attribute: 1467234353Sdim case tok::l_brace: 1468234353Sdim case tok::l_paren: 1469234353Sdim case tok::l_square: 1470234353Sdim case tok::less: 1471234353Sdim case tok::r_brace: 1472234353Sdim case tok::r_paren: 1473234353Sdim case tok::r_square: 1474234353Sdim case tok::semi: 1475234353Sdim return true; 1476234353Sdim 1477234353Sdim case tok::colon: 1478234353Sdim // At namespace scope, 'identifier:' is probably a typo for 'identifier::' 1479234353Sdim // and in block scope it's probably a label. Inside a class definition, 1480234353Sdim // this is a bit-field. 1481234353Sdim return Context == Declarator::MemberContext || 1482234353Sdim (getLangOpts().CPlusPlus && Context == Declarator::FileContext); 1483234353Sdim 1484234353Sdim case tok::identifier: // Possible virt-specifier. 1485249423Sdim return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken()); 1486234353Sdim 1487234353Sdim default: 1488234353Sdim return false; 1489234353Sdim } 1490234353Sdim 1491234353Sdim default: 1492234353Sdim return false; 1493234353Sdim } 1494234353Sdim} 1495234353Sdim 1496234353Sdim/// Skip until we reach something which seems like a sensible place to pick 1497234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner 1498234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later. 1499234353Sdimvoid Parser::SkipMalformedDecl() { 1500234353Sdim while (true) { 1501234353Sdim switch (Tok.getKind()) { 1502234353Sdim case tok::l_brace: 1503234353Sdim // Skip until matching }, then stop. We've probably skipped over 1504234353Sdim // a malformed class or function definition or similar. 1505234353Sdim ConsumeBrace(); 1506263508Sdim SkipUntil(tok::r_brace); 1507234353Sdim if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { 1508234353Sdim // This declaration isn't over yet. Keep skipping. 1509234353Sdim continue; 1510234353Sdim } 1511234353Sdim if (Tok.is(tok::semi)) 1512234353Sdim ConsumeToken(); 1513234353Sdim return; 1514234353Sdim 1515234353Sdim case tok::l_square: 1516234353Sdim ConsumeBracket(); 1517263508Sdim SkipUntil(tok::r_square); 1518234353Sdim continue; 1519234353Sdim 1520234353Sdim case tok::l_paren: 1521234353Sdim ConsumeParen(); 1522263508Sdim SkipUntil(tok::r_paren); 1523234353Sdim continue; 1524234353Sdim 1525234353Sdim case tok::r_brace: 1526234353Sdim return; 1527234353Sdim 1528234353Sdim case tok::semi: 1529234353Sdim ConsumeToken(); 1530234353Sdim return; 1531234353Sdim 1532234353Sdim case tok::kw_inline: 1533234353Sdim // 'inline namespace' at the start of a line is almost certainly 1534239462Sdim // a good place to pick back up parsing, except in an Objective-C 1535239462Sdim // @interface context. 1536239462Sdim if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) && 1537239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1538234353Sdim return; 1539234353Sdim break; 1540234353Sdim 1541234353Sdim case tok::kw_namespace: 1542234353Sdim // 'namespace' at the start of a line is almost certainly a good 1543239462Sdim // place to pick back up parsing, except in an Objective-C 1544239462Sdim // @interface context. 1545239462Sdim if (Tok.isAtStartOfLine() && 1546239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1547234353Sdim return; 1548234353Sdim break; 1549234353Sdim 1550239462Sdim case tok::at: 1551239462Sdim // @end is very much like } in Objective-C contexts. 1552239462Sdim if (NextToken().isObjCAtKeyword(tok::objc_end) && 1553239462Sdim ParsingInObjCContainer) 1554239462Sdim return; 1555239462Sdim break; 1556239462Sdim 1557239462Sdim case tok::minus: 1558239462Sdim case tok::plus: 1559239462Sdim // - and + probably start new method declarations in Objective-C contexts. 1560239462Sdim if (Tok.isAtStartOfLine() && ParsingInObjCContainer) 1561239462Sdim return; 1562239462Sdim break; 1563239462Sdim 1564234353Sdim case tok::eof: 1565234353Sdim return; 1566234353Sdim 1567234353Sdim default: 1568234353Sdim break; 1569234353Sdim } 1570234353Sdim 1571234353Sdim ConsumeAnyToken(); 1572234353Sdim } 1573234353Sdim} 1574234353Sdim 1575198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function 1576198893Srdivacky/// definition or a group of object declarations, actually parse the 1577198893Srdivacky/// result. 1578198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, 1579198893Srdivacky unsigned Context, 1580198893Srdivacky bool AllowFunctionDefinitions, 1581221345Sdim SourceLocation *DeclEnd, 1582221345Sdim ForRangeInit *FRI) { 1583198893Srdivacky // Parse the first declarator. 1584198893Srdivacky ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context)); 1585198893Srdivacky ParseDeclarator(D); 1586193326Sed 1587198893Srdivacky // Bail out if the first declarator didn't seem well-formed. 1588198893Srdivacky if (!D.hasName() && !D.mayOmitIdentifier()) { 1589234353Sdim SkipMalformedDecl(); 1590198893Srdivacky return DeclGroupPtrTy(); 1591198893Srdivacky } 1592198092Srdivacky 1593234353Sdim // Save late-parsed attributes for now; they need to be parsed in the 1594234353Sdim // appropriate function scope after the function Decl has been constructed. 1595243830Sdim // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList. 1596243830Sdim LateParsedAttrList LateParsedAttrs(true); 1597234353Sdim if (D.isFunctionDeclarator()) 1598234353Sdim MaybeParseGNUAttributes(D, &LateParsedAttrs); 1599234353Sdim 1600210299Sed // Check to see if we have a function *definition* which must have a body. 1601251662Sdim if (D.isFunctionDeclarator() && 1602210299Sed // Look at the next token to make sure that this isn't a function 1603210299Sed // declaration. We have to check this because __attribute__ might be the 1604210299Sed // start of a function definition in GCC-extended K&R C. 1605210299Sed !isDeclarationAfterDeclarator()) { 1606239462Sdim 1607251662Sdim if (AllowFunctionDefinitions) { 1608251662Sdim if (isStartOfFunctionDefinition(D)) { 1609251662Sdim if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 1610251662Sdim Diag(Tok, diag::err_function_declared_typedef); 1611198092Srdivacky 1612251662Sdim // Recover by treating the 'typedef' as spurious. 1613251662Sdim DS.ClearStorageClassSpecs(); 1614251662Sdim } 1615251662Sdim 1616251662Sdim Decl *TheDecl = 1617251662Sdim ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); 1618251662Sdim return Actions.ConvertDeclToDeclGroup(TheDecl); 1619198893Srdivacky } 1620198893Srdivacky 1621251662Sdim if (isDeclarationSpecifier()) { 1622251662Sdim // If there is an invalid declaration specifier right after the function 1623251662Sdim // prototype, then we must be in a missing semicolon case where this isn't 1624251662Sdim // actually a body. Just fall through into the code that handles it as a 1625251662Sdim // prototype, and let the top-level code handle the erroneous declspec 1626251662Sdim // where it would otherwise expect a comma or semicolon. 1627251662Sdim } else { 1628251662Sdim Diag(Tok, diag::err_expected_fn_body); 1629251662Sdim SkipUntil(tok::semi); 1630251662Sdim return DeclGroupPtrTy(); 1631251662Sdim } 1632198893Srdivacky } else { 1633251662Sdim if (Tok.is(tok::l_brace)) { 1634251662Sdim Diag(Tok, diag::err_function_definition_not_allowed); 1635263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 1636251662Sdim } 1637198893Srdivacky } 1638198893Srdivacky } 1639198893Srdivacky 1640234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1641221345Sdim return DeclGroupPtrTy(); 1642221345Sdim 1643221345Sdim // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we 1644221345Sdim // must parse and analyze the for-range-initializer before the declaration is 1645221345Sdim // analyzed. 1646251662Sdim // 1647251662Sdim // Handle the Objective-C for-in loop variable similarly, although we 1648251662Sdim // don't need to parse the container in advance. 1649251662Sdim if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) { 1650251662Sdim bool IsForRangeLoop = false; 1651251662Sdim if (Tok.is(tok::colon)) { 1652251662Sdim IsForRangeLoop = true; 1653251662Sdim FRI->ColonLoc = ConsumeToken(); 1654251662Sdim if (Tok.is(tok::l_brace)) 1655251662Sdim FRI->RangeExpr = ParseBraceInitializer(); 1656251662Sdim else 1657251662Sdim FRI->RangeExpr = ParseExpression(); 1658251662Sdim } 1659251662Sdim 1660221345Sdim Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1661251662Sdim if (IsForRangeLoop) 1662251662Sdim Actions.ActOnCXXForRangeDecl(ThisDecl); 1663221345Sdim Actions.FinalizeDeclaration(ThisDecl); 1664234353Sdim D.complete(ThisDecl); 1665263508Sdim return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl); 1666221345Sdim } 1667221345Sdim 1668226633Sdim SmallVector<Decl *, 8> DeclsInGroup; 1669221345Sdim Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D); 1670234353Sdim if (LateParsedAttrs.size() > 0) 1671234353Sdim ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); 1672198893Srdivacky D.complete(FirstDecl); 1673212904Sdim if (FirstDecl) 1674198893Srdivacky DeclsInGroup.push_back(FirstDecl); 1675198893Srdivacky 1676234353Sdim bool ExpectSemi = Context != Declarator::ForContext; 1677239462Sdim 1678198893Srdivacky // If we don't have a comma, it is either the end of the list (a ';') or an 1679198893Srdivacky // error, bail out. 1680198893Srdivacky while (Tok.is(tok::comma)) { 1681234353Sdim SourceLocation CommaLoc = ConsumeToken(); 1682198893Srdivacky 1683234353Sdim if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) { 1684234353Sdim // This comma was followed by a line-break and something which can't be 1685234353Sdim // the start of a declarator. The comma was probably a typo for a 1686234353Sdim // semicolon. 1687234353Sdim Diag(CommaLoc, diag::err_expected_semi_declaration) 1688234353Sdim << FixItHint::CreateReplacement(CommaLoc, ";"); 1689234353Sdim ExpectSemi = false; 1690234353Sdim break; 1691234353Sdim } 1692234353Sdim 1693198893Srdivacky // Parse the next declarator. 1694198893Srdivacky D.clear(); 1695234353Sdim D.setCommaLoc(CommaLoc); 1696198893Srdivacky 1697198893Srdivacky // Accept attributes in an init-declarator. In the first declarator in a 1698198893Srdivacky // declaration, these would be part of the declspec. In subsequent 1699198893Srdivacky // declarators, they become part of the declarator itself, so that they 1700198893Srdivacky // don't apply to declarators after *this* one. Examples: 1701198893Srdivacky // short __attribute__((common)) var; -> declspec 1702198893Srdivacky // short var __attribute__((common)); -> declarator 1703198893Srdivacky // short x, __attribute__((common)) var; -> declarator 1704218893Sdim MaybeParseGNUAttributes(D); 1705198893Srdivacky 1706198893Srdivacky ParseDeclarator(D); 1707234353Sdim if (!D.isInvalidType()) { 1708234353Sdim Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); 1709234353Sdim D.complete(ThisDecl); 1710234353Sdim if (ThisDecl) 1711239462Sdim DeclsInGroup.push_back(ThisDecl); 1712234353Sdim } 1713193326Sed } 1714198092Srdivacky 1715198893Srdivacky if (DeclEnd) 1716198893Srdivacky *DeclEnd = Tok.getLocation(); 1717198893Srdivacky 1718234353Sdim if (ExpectSemi && 1719239462Sdim ExpectAndConsumeSemi(Context == Declarator::FileContext 1720239462Sdim ? diag::err_invalid_token_after_toplevel_declarator 1721239462Sdim : diag::err_expected_semi_declaration)) { 1722210299Sed // Okay, there was no semicolon and one was expected. If we see a 1723210299Sed // declaration specifier, just assume it was missing and continue parsing. 1724210299Sed // Otherwise things are very confused and we skip to recover. 1725210299Sed if (!isDeclarationSpecifier()) { 1726263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 1727210299Sed if (Tok.is(tok::semi)) 1728210299Sed ConsumeToken(); 1729210299Sed } 1730198893Srdivacky } 1731198893Srdivacky 1732263508Sdim return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); 1733193326Sed} 1734193326Sed 1735221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a 1736221345Sdim/// declarator. Returns true on an error. 1737234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) { 1738221345Sdim // If a simple-asm-expr is present, parse it. 1739221345Sdim if (Tok.is(tok::kw_asm)) { 1740221345Sdim SourceLocation Loc; 1741221345Sdim ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1742221345Sdim if (AsmLabel.isInvalid()) { 1743263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1744221345Sdim return true; 1745221345Sdim } 1746221345Sdim 1747221345Sdim D.setAsmLabel(AsmLabel.release()); 1748221345Sdim D.SetRangeEnd(Loc); 1749221345Sdim } 1750221345Sdim 1751221345Sdim MaybeParseGNUAttributes(D); 1752221345Sdim return false; 1753221345Sdim} 1754221345Sdim 1755193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers 1756193326Sed/// declarator'. This method parses the remainder of the declaration 1757193326Sed/// (including any attributes or initializer, among other things) and 1758193326Sed/// finalizes the declaration. 1759193326Sed/// 1760193326Sed/// init-declarator: [C99 6.7] 1761193326Sed/// declarator 1762193326Sed/// declarator '=' initializer 1763193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] 1764193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer 1765193326Sed/// [C++] declarator initializer[opt] 1766193326Sed/// 1767193326Sed/// [C++] initializer: 1768193326Sed/// [C++] '=' initializer-clause 1769193326Sed/// [C++] '(' expression-list ')' 1770193326Sed/// [C++0x] '=' 'default' [TODO] 1771193326Sed/// [C++0x] '=' 'delete' 1772223017Sdim/// [C++0x] braced-init-list 1773193326Sed/// 1774193326Sed/// According to the standard grammar, =default and =delete are function 1775193326Sed/// definitions, but that definitely doesn't fit with the parser here. 1776193326Sed/// 1777212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, 1778195099Sed const ParsedTemplateInfo &TemplateInfo) { 1779234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1780221345Sdim return 0; 1781198092Srdivacky 1782221345Sdim return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo); 1783221345Sdim} 1784198092Srdivacky 1785221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, 1786221345Sdim const ParsedTemplateInfo &TemplateInfo) { 1787193326Sed // Inform the current actions module that we just parsed this declarator. 1788212904Sdim Decl *ThisDecl = 0; 1789198092Srdivacky switch (TemplateInfo.Kind) { 1790198092Srdivacky case ParsedTemplateInfo::NonTemplate: 1791210299Sed ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1792198092Srdivacky break; 1793239462Sdim 1794198092Srdivacky case ParsedTemplateInfo::Template: 1795263508Sdim case ParsedTemplateInfo::ExplicitSpecialization: { 1796210299Sed ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), 1797243830Sdim *TemplateInfo.TemplateParams, 1798198092Srdivacky D); 1799263508Sdim if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) 1800263508Sdim // Re-direct this decl to refer to the templated decl so that we can 1801263508Sdim // initialize it. 1802263508Sdim ThisDecl = VT->getTemplatedDecl(); 1803198092Srdivacky break; 1804263508Sdim } 1805263508Sdim case ParsedTemplateInfo::ExplicitInstantiation: { 1806263508Sdim if (Tok.is(tok::semi)) { 1807263508Sdim DeclResult ThisRes = Actions.ActOnExplicitInstantiation( 1808263508Sdim getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D); 1809263508Sdim if (ThisRes.isInvalid()) { 1810263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1811263508Sdim return 0; 1812263508Sdim } 1813263508Sdim ThisDecl = ThisRes.get(); 1814263508Sdim } else { 1815263508Sdim // FIXME: This check should be for a variable template instantiation only. 1816239462Sdim 1817263508Sdim // Check that this is a valid instantiation 1818263508Sdim if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) { 1819263508Sdim // If the declarator-id is not a template-id, issue a diagnostic and 1820263508Sdim // recover by ignoring the 'template' keyword. 1821263508Sdim Diag(Tok, diag::err_template_defn_explicit_instantiation) 1822263508Sdim << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc); 1823263508Sdim ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1824263508Sdim } else { 1825263508Sdim SourceLocation LAngleLoc = 1826263508Sdim PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 1827263508Sdim Diag(D.getIdentifierLoc(), 1828263508Sdim diag::err_explicit_instantiation_with_definition) 1829263508Sdim << SourceRange(TemplateInfo.TemplateLoc) 1830263508Sdim << FixItHint::CreateInsertion(LAngleLoc, "<>"); 1831263508Sdim 1832263508Sdim // Recover as if it were an explicit specialization. 1833263508Sdim TemplateParameterLists FakedParamLists; 1834263508Sdim FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 1835263508Sdim 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0, 1836263508Sdim LAngleLoc)); 1837263508Sdim 1838263508Sdim ThisDecl = 1839263508Sdim Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D); 1840263508Sdim } 1841198092Srdivacky } 1842198092Srdivacky break; 1843198092Srdivacky } 1844198092Srdivacky } 1845198092Srdivacky 1846251662Sdim bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); 1847218893Sdim 1848193326Sed // Parse declarator '=' initializer. 1849234353Sdim // If a '==' or '+=' is found, suggest a fixit to '='. 1850234353Sdim if (isTokenEqualOrEqualTypo()) { 1851193326Sed ConsumeToken(); 1852263508Sdim 1853218893Sdim if (Tok.is(tok::kw_delete)) { 1854223017Sdim if (D.isFunctionDeclarator()) 1855223017Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1856223017Sdim << 1 /* delete */; 1857223017Sdim else 1858223017Sdim Diag(ConsumeToken(), diag::err_deleted_non_function); 1859223017Sdim } else if (Tok.is(tok::kw_default)) { 1860223017Sdim if (D.isFunctionDeclarator()) 1861234353Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1862234353Sdim << 0 /* default */; 1863223017Sdim else 1864223017Sdim Diag(ConsumeToken(), diag::err_default_special_members); 1865193326Sed } else { 1866234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1867201361Srdivacky EnterScope(0); 1868210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1869201361Srdivacky } 1870194613Sed 1871210299Sed if (Tok.is(tok::code_completion)) { 1872210299Sed Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); 1873239462Sdim Actions.FinalizeDeclaration(ThisDecl); 1874226633Sdim cutOffParsing(); 1875226633Sdim return 0; 1876210299Sed } 1877239462Sdim 1878212904Sdim ExprResult Init(ParseInitializer()); 1879194613Sed 1880234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1881210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1882201361Srdivacky ExitScope(); 1883201361Srdivacky } 1884194613Sed 1885193326Sed if (Init.isInvalid()) { 1886263508Sdim SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); 1887204643Srdivacky Actions.ActOnInitializerError(ThisDecl); 1888204643Srdivacky } else 1889218893Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1890218893Sdim /*DirectInit=*/false, TypeContainsAuto); 1891193326Sed } 1892193326Sed } else if (Tok.is(tok::l_paren)) { 1893193326Sed // Parse C++ direct initializer: '(' expression-list ')' 1894226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1895226633Sdim T.consumeOpen(); 1896226633Sdim 1897243830Sdim ExprVector Exprs; 1898193326Sed CommaLocsTy CommaLocs; 1899193326Sed 1900234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1901201361Srdivacky EnterScope(0); 1902210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1903201361Srdivacky } 1904201361Srdivacky 1905193326Sed if (ParseExpressionList(Exprs, CommaLocs)) { 1906243830Sdim Actions.ActOnInitializerError(ThisDecl); 1907263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 1908201361Srdivacky 1909234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1910210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1911201361Srdivacky ExitScope(); 1912201361Srdivacky } 1913193326Sed } else { 1914193326Sed // Match the ')'. 1915226633Sdim T.consumeClose(); 1916193326Sed 1917193326Sed assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && 1918193326Sed "Unexpected number of commas!"); 1919201361Srdivacky 1920234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1921210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1922201361Srdivacky ExitScope(); 1923201361Srdivacky } 1924201361Srdivacky 1925234353Sdim ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), 1926234353Sdim T.getCloseLocation(), 1927243830Sdim Exprs); 1928234353Sdim Actions.AddInitializerToDecl(ThisDecl, Initializer.take(), 1929234353Sdim /*DirectInit=*/true, TypeContainsAuto); 1930193326Sed } 1931249423Sdim } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) && 1932239462Sdim (!CurParsedObjCImpl || !D.isFunctionDeclarator())) { 1933223017Sdim // Parse C++0x braced-init-list. 1934234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1935234353Sdim 1936223017Sdim if (D.getCXXScopeSpec().isSet()) { 1937223017Sdim EnterScope(0); 1938223017Sdim Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1939223017Sdim } 1940223017Sdim 1941223017Sdim ExprResult Init(ParseBraceInitializer()); 1942223017Sdim 1943223017Sdim if (D.getCXXScopeSpec().isSet()) { 1944223017Sdim Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1945223017Sdim ExitScope(); 1946223017Sdim } 1947223017Sdim 1948223017Sdim if (Init.isInvalid()) { 1949223017Sdim Actions.ActOnInitializerError(ThisDecl); 1950223017Sdim } else 1951223017Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1952223017Sdim /*DirectInit=*/true, TypeContainsAuto); 1953223017Sdim 1954193326Sed } else { 1955218893Sdim Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto); 1956193326Sed } 1957193326Sed 1958219077Sdim Actions.FinalizeDeclaration(ThisDecl); 1959219077Sdim 1960193326Sed return ThisDecl; 1961193326Sed} 1962193326Sed 1963193326Sed/// ParseSpecifierQualifierList 1964193326Sed/// specifier-qualifier-list: 1965193326Sed/// type-specifier specifier-qualifier-list[opt] 1966193326Sed/// type-qualifier specifier-qualifier-list[opt] 1967193326Sed/// [GNU] attributes specifier-qualifier-list[opt] 1968193326Sed/// 1969234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, 1970234353Sdim DeclSpecContext DSC) { 1971193326Sed /// specifier-qualifier-list is a subset of declaration-specifiers. Just 1972193326Sed /// parse declaration-specifiers and complain about extra stuff. 1973226633Sdim /// TODO: diagnose attribute-specifiers and alignment-specifiers. 1974234353Sdim ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC); 1975198092Srdivacky 1976193326Sed // Validate declspec for type-name. 1977193326Sed unsigned Specs = DS.getParsedSpecifiers(); 1978239462Sdim if ((DSC == DSC_type_specifier || DSC == DSC_trailing) && 1979239462Sdim !DS.hasTypeSpecifier()) { 1980234353Sdim Diag(Tok, diag::err_expected_type); 1981234353Sdim DS.SetTypeSpecError(); 1982234353Sdim } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && 1983234353Sdim !DS.hasAttributes()) { 1984193326Sed Diag(Tok, diag::err_typename_requires_specqual); 1985234353Sdim if (!DS.hasTypeSpecifier()) 1986234353Sdim DS.SetTypeSpecError(); 1987234353Sdim } 1988198092Srdivacky 1989193326Sed // Issue diagnostic and remove storage class if present. 1990193326Sed if (Specs & DeclSpec::PQ_StorageClassSpecifier) { 1991193326Sed if (DS.getStorageClassSpecLoc().isValid()) 1992193326Sed Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); 1993193326Sed else 1994251662Sdim Diag(DS.getThreadStorageClassSpecLoc(), 1995251662Sdim diag::err_typename_invalid_storageclass); 1996193326Sed DS.ClearStorageClassSpecs(); 1997193326Sed } 1998198092Srdivacky 1999193326Sed // Issue diagnostic and remove function specfier if present. 2000193326Sed if (Specs & DeclSpec::PQ_FunctionSpecifier) { 2001193326Sed if (DS.isInlineSpecified()) 2002193326Sed Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); 2003193326Sed if (DS.isVirtualSpecified()) 2004193326Sed Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); 2005193326Sed if (DS.isExplicitSpecified()) 2006193326Sed Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); 2007193326Sed DS.ClearFunctionSpecs(); 2008193326Sed } 2009234353Sdim 2010234353Sdim // Issue diagnostic and remove constexpr specfier if present. 2011234353Sdim if (DS.isConstexprSpecified()) { 2012234353Sdim Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); 2013234353Sdim DS.ClearConstexprSpec(); 2014234353Sdim } 2015193326Sed} 2016193326Sed 2017193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the 2018193326Sed/// specified token is valid after the identifier in a declarator which 2019193326Sed/// immediately follows the declspec. For example, these things are valid: 2020193326Sed/// 2021193326Sed/// int x [ 4]; // direct-declarator 2022193326Sed/// int x ( int y); // direct-declarator 2023193326Sed/// int(int x ) // direct-declarator 2024193326Sed/// int x ; // simple-declaration 2025193326Sed/// int x = 17; // init-declarator-list 2026193326Sed/// int x , y; // init-declarator-list 2027193326Sed/// int x __asm__ ("foo"); // init-declarator-list 2028193326Sed/// int x : 4; // struct-declarator 2029193326Sed/// int x { 5}; // C++'0x unified initializers 2030193326Sed/// 2031193326Sed/// This is not, because 'x' does not immediately follow the declspec (though 2032193326Sed/// ')' happens to be valid anyway). 2033193326Sed/// int (x) 2034193326Sed/// 2035193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) { 2036193326Sed return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) || 2037193326Sed T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) || 2038193326Sed T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon); 2039193326Sed} 2040193326Sed 2041193326Sed 2042193326Sed/// ParseImplicitInt - This method is called when we have an non-typename 2043193326Sed/// identifier in a declspec (which normally terminates the decl spec) when 2044193326Sed/// the declspec has no type specifier. In this case, the declspec is either 2045193326Sed/// malformed or is "implicit int" (in K&R and C89). 2046193326Sed/// 2047193326Sed/// This method handles diagnosing this prettily and returns false if the 2048193326Sed/// declspec is done being processed. If it recovers and thinks there may be 2049193326Sed/// other pieces of declspec after it, it returns true. 2050193326Sed/// 2051193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, 2052193326Sed const ParsedTemplateInfo &TemplateInfo, 2053249423Sdim AccessSpecifier AS, DeclSpecContext DSC, 2054249423Sdim ParsedAttributesWithRange &Attrs) { 2055193326Sed assert(Tok.is(tok::identifier) && "should have identifier"); 2056198092Srdivacky 2057193326Sed SourceLocation Loc = Tok.getLocation(); 2058193326Sed // If we see an identifier that is not a type name, we normally would 2059193326Sed // parse it as the identifer being declared. However, when a typename 2060193326Sed // is typo'd or the definition is not included, this will incorrectly 2061193326Sed // parse the typename as the identifier name and fall over misparsing 2062193326Sed // later parts of the diagnostic. 2063193326Sed // 2064193326Sed // As such, we try to do some look-ahead in cases where this would 2065193326Sed // otherwise be an "implicit-int" case to see if this is invalid. For 2066193326Sed // example: "static foo_t x = 4;" In this case, if we parsed foo_t as 2067193326Sed // an identifier with implicit int, we'd get a parse error because the 2068193326Sed // next token is obviously invalid for a type. Parse these as a case 2069193326Sed // with an invalid type specifier. 2070193326Sed assert(!DS.hasTypeSpecifier() && "Type specifier checked above"); 2071198092Srdivacky 2072193326Sed // Since we know that this either implicit int (which is rare) or an 2073239462Sdim // error, do lookahead to try to do better recovery. This never applies 2074239462Sdim // within a type specifier. Outside of C++, we allow this even if the 2075239462Sdim // language doesn't "officially" support implicit int -- we support 2076251662Sdim // implicit int as an extension in C99 and C11. 2077239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2078251662Sdim !getLangOpts().CPlusPlus && 2079234353Sdim isValidAfterIdentifierInDeclarator(NextToken())) { 2080193326Sed // If this token is valid for implicit int, e.g. "static x = 4", then 2081193326Sed // we just avoid eating the identifier, so it will be parsed as the 2082193326Sed // identifier in the declarator. 2083193326Sed return false; 2084193326Sed } 2085198092Srdivacky 2086239462Sdim if (getLangOpts().CPlusPlus && 2087239462Sdim DS.getStorageClassSpec() == DeclSpec::SCS_auto) { 2088239462Sdim // Don't require a type specifier if we have the 'auto' storage class 2089239462Sdim // specifier in C++98 -- we'll promote it to a type specifier. 2090263508Sdim if (SS) 2091263508Sdim AnnotateScopeToken(*SS, /*IsNewAnnotation*/false); 2092239462Sdim return false; 2093239462Sdim } 2094239462Sdim 2095193326Sed // Otherwise, if we don't consume this token, we are going to emit an 2096193326Sed // error anyway. Try to recover from various common problems. Check 2097193326Sed // to see if this was a reference to a tag name without a tag specified. 2098193326Sed // This is a common problem in C (saying 'foo' instead of 'struct foo'). 2099193326Sed // 2100193326Sed // C++ doesn't need this, and isTagName doesn't take SS. 2101193326Sed if (SS == 0) { 2102221345Sdim const char *TagName = 0, *FixitTagName = 0; 2103193326Sed tok::TokenKind TagKind = tok::unknown; 2104198092Srdivacky 2105210299Sed switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) { 2106193326Sed default: break; 2107221345Sdim case DeclSpec::TST_enum: 2108221345Sdim TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break; 2109221345Sdim case DeclSpec::TST_union: 2110221345Sdim TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break; 2111221345Sdim case DeclSpec::TST_struct: 2112221345Sdim TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break; 2113243830Sdim case DeclSpec::TST_interface: 2114243830Sdim TagName="__interface"; FixitTagName = "__interface "; 2115243830Sdim TagKind=tok::kw___interface;break; 2116221345Sdim case DeclSpec::TST_class: 2117221345Sdim TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; 2118193326Sed } 2119198092Srdivacky 2120193326Sed if (TagName) { 2121239462Sdim IdentifierInfo *TokenName = Tok.getIdentifierInfo(); 2122239462Sdim LookupResult R(Actions, TokenName, SourceLocation(), 2123239462Sdim Sema::LookupOrdinaryName); 2124239462Sdim 2125193326Sed Diag(Loc, diag::err_use_of_tag_name_without_tag) 2126239462Sdim << TokenName << TagName << getLangOpts().CPlusPlus 2127239462Sdim << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName); 2128198092Srdivacky 2129239462Sdim if (Actions.LookupParsedName(R, getCurScope(), SS)) { 2130239462Sdim for (LookupResult::iterator I = R.begin(), IEnd = R.end(); 2131239462Sdim I != IEnd; ++I) 2132239462Sdim Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type) 2133239462Sdim << TokenName << TagName; 2134239462Sdim } 2135239462Sdim 2136193326Sed // Parse this as a tag as if the missing tag were present. 2137193326Sed if (TagKind == tok::kw_enum) 2138234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); 2139193326Sed else 2140234353Sdim ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, 2141249423Sdim /*EnteringContext*/ false, DSC_normal, Attrs); 2142193326Sed return true; 2143193326Sed } 2144193326Sed } 2145198092Srdivacky 2146239462Sdim // Determine whether this identifier could plausibly be the name of something 2147239462Sdim // being declared (with a missing type). 2148239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2149239462Sdim (!SS || DSC == DSC_top_level || DSC == DSC_class)) { 2150239462Sdim // Look ahead to the next token to try to figure out what this declaration 2151239462Sdim // was supposed to be. 2152239462Sdim switch (NextToken().getKind()) { 2153239462Sdim case tok::l_paren: { 2154239462Sdim // static x(4); // 'x' is not a type 2155239462Sdim // x(int n); // 'x' is not a type 2156239462Sdim // x (*p)[]; // 'x' is a type 2157239462Sdim // 2158239462Sdim // Since we're in an error case (or the rare 'implicit int in C++' MS 2159239462Sdim // extension), we can afford to perform a tentative parse to determine 2160239462Sdim // which case we're in. 2161239462Sdim TentativeParsingAction PA(*this); 2162239462Sdim ConsumeToken(); 2163239462Sdim TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false); 2164239462Sdim PA.Revert(); 2165263508Sdim 2166263508Sdim if (TPR != TPResult::False()) { 2167263508Sdim // The identifier is followed by a parenthesized declarator. 2168263508Sdim // It's supposed to be a type. 2169263508Sdim break; 2170263508Sdim } 2171263508Sdim 2172263508Sdim // If we're in a context where we could be declaring a constructor, 2173263508Sdim // check whether this is a constructor declaration with a bogus name. 2174263508Sdim if (DSC == DSC_class || (DSC == DSC_top_level && SS)) { 2175263508Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 2176263508Sdim if (Actions.isCurrentClassNameTypo(II, SS)) { 2177263508Sdim Diag(Loc, diag::err_constructor_bad_name) 2178263508Sdim << Tok.getIdentifierInfo() << II 2179263508Sdim << FixItHint::CreateReplacement(Tok.getLocation(), II->getName()); 2180263508Sdim Tok.setIdentifierInfo(II); 2181263508Sdim } 2182263508Sdim } 2183263508Sdim // Fall through. 2184239462Sdim } 2185263508Sdim case tok::comma: 2186263508Sdim case tok::equal: 2187263508Sdim case tok::kw_asm: 2188263508Sdim case tok::l_brace: 2189263508Sdim case tok::l_square: 2190263508Sdim case tok::semi: 2191263508Sdim // This looks like a variable or function declaration. The type is 2192263508Sdim // probably missing. We're done parsing decl-specifiers. 2193263508Sdim if (SS) 2194263508Sdim AnnotateScopeToken(*SS, /*IsNewAnnotation*/false); 2195263508Sdim return false; 2196239462Sdim 2197239462Sdim default: 2198239462Sdim // This is probably supposed to be a type. This includes cases like: 2199239462Sdim // int f(itn); 2200239462Sdim // struct S { unsinged : 4; }; 2201239462Sdim break; 2202239462Sdim } 2203239462Sdim } 2204239462Sdim 2205239462Sdim // This is almost certainly an invalid type name. Let the action emit a 2206198092Srdivacky // diagnostic and attempt to recover. 2207212904Sdim ParsedType T; 2208239462Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 2209239462Sdim if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) { 2210198092Srdivacky // The action emitted a diagnostic, so we don't have to. 2211198092Srdivacky if (T) { 2212198092Srdivacky // The action has suggested that the type T could be used. Set that as 2213198092Srdivacky // the type in the declaration specifiers, consume the would-be type 2214198092Srdivacky // name token, and we're done. 2215198092Srdivacky const char *PrevSpec; 2216198092Srdivacky unsigned DiagID; 2217212904Sdim DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); 2218198092Srdivacky DS.SetRangeEnd(Tok.getLocation()); 2219198092Srdivacky ConsumeToken(); 2220198092Srdivacky // There may be other declaration specifiers after this. 2221198092Srdivacky return true; 2222239462Sdim } else if (II != Tok.getIdentifierInfo()) { 2223239462Sdim // If no type was suggested, the correction is to a keyword 2224239462Sdim Tok.setKind(II->getTokenID()); 2225239462Sdim // There may be other declaration specifiers after this. 2226239462Sdim return true; 2227198092Srdivacky } 2228239462Sdim 2229198092Srdivacky // Fall through; the action had no suggestion for us. 2230198092Srdivacky } else { 2231198092Srdivacky // The action did not emit a diagnostic, so emit one now. 2232198092Srdivacky SourceRange R; 2233198092Srdivacky if (SS) R = SS->getRange(); 2234198092Srdivacky Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R; 2235198092Srdivacky } 2236198092Srdivacky 2237198092Srdivacky // Mark this as an error. 2238234353Sdim DS.SetTypeSpecError(); 2239193326Sed DS.SetRangeEnd(Tok.getLocation()); 2240193326Sed ConsumeToken(); 2241198092Srdivacky 2242193326Sed // TODO: Could inject an invalid typedef decl in an enclosing scope to 2243193326Sed // avoid rippling error messages on subsequent uses of the same type, 2244193326Sed // could be useful if #include was forgotten. 2245193326Sed return false; 2246193326Sed} 2247193326Sed 2248202379Srdivacky/// \brief Determine the declaration specifier context from the declarator 2249202379Srdivacky/// context. 2250202379Srdivacky/// 2251202379Srdivacky/// \param Context the declarator context, which is one of the 2252202379Srdivacky/// Declarator::TheContext enumerator values. 2253239462SdimParser::DeclSpecContext 2254202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { 2255202379Srdivacky if (Context == Declarator::MemberContext) 2256202379Srdivacky return DSC_class; 2257202379Srdivacky if (Context == Declarator::FileContext) 2258202379Srdivacky return DSC_top_level; 2259234353Sdim if (Context == Declarator::TrailingReturnContext) 2260234353Sdim return DSC_trailing; 2261202379Srdivacky return DSC_normal; 2262202379Srdivacky} 2263202379Srdivacky 2264226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier. 2265226633Sdim/// 2266226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a 2267226633Sdim/// type. Ideally, the type should be propagated directly into Sema. 2268226633Sdim/// 2269234353Sdim/// [C11] type-id 2270234353Sdim/// [C11] constant-expression 2271234353Sdim/// [C++0x] type-id ...[opt] 2272234353Sdim/// [C++0x] assignment-expression ...[opt] 2273234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start, 2274234353Sdim SourceLocation &EllipsisLoc) { 2275234353Sdim ExprResult ER; 2276226633Sdim if (isTypeIdInParens()) { 2277226633Sdim SourceLocation TypeLoc = Tok.getLocation(); 2278226633Sdim ParsedType Ty = ParseTypeName().get(); 2279226633Sdim SourceRange TypeRange(Start, Tok.getLocation()); 2280234353Sdim ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true, 2281234353Sdim Ty.getAsOpaquePtr(), TypeRange); 2282226633Sdim } else 2283234353Sdim ER = ParseConstantExpression(); 2284234353Sdim 2285249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis)) 2286234353Sdim EllipsisLoc = ConsumeToken(); 2287234353Sdim 2288234353Sdim return ER; 2289226633Sdim} 2290226633Sdim 2291226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the 2292226633Sdim/// attribute to Attrs. 2293226633Sdim/// 2294226633Sdim/// alignment-specifier: 2295234353Sdim/// [C11] '_Alignas' '(' type-id ')' 2296234353Sdim/// [C11] '_Alignas' '(' constant-expression ')' 2297249423Sdim/// [C++11] 'alignas' '(' type-id ...[opt] ')' 2298249423Sdim/// [C++11] 'alignas' '(' assignment-expression ...[opt] ')' 2299226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, 2300249423Sdim SourceLocation *EndLoc) { 2301226633Sdim assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) && 2302226633Sdim "Not an alignment-specifier!"); 2303226633Sdim 2304249423Sdim IdentifierInfo *KWName = Tok.getIdentifierInfo(); 2305249423Sdim SourceLocation KWLoc = ConsumeToken(); 2306226633Sdim 2307226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2308226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2309226633Sdim return; 2310226633Sdim 2311234353Sdim SourceLocation EllipsisLoc; 2312234353Sdim ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); 2313226633Sdim if (ArgExpr.isInvalid()) { 2314263508Sdim T.skipToEnd(); 2315226633Sdim return; 2316226633Sdim } 2317226633Sdim 2318226633Sdim T.consumeClose(); 2319249423Sdim if (EndLoc) 2320249423Sdim *EndLoc = T.getCloseLocation(); 2321226633Sdim 2322263508Sdim ArgsVector ArgExprs; 2323226633Sdim ArgExprs.push_back(ArgExpr.release()); 2324263508Sdim Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1, 2325263508Sdim AttributeList::AS_Keyword, EllipsisLoc); 2326226633Sdim} 2327226633Sdim 2328263508Sdim/// Determine whether we're looking at something that might be a declarator 2329263508Sdim/// in a simple-declaration. If it can't possibly be a declarator, maybe 2330263508Sdim/// diagnose a missing semicolon after a prior tag definition in the decl 2331263508Sdim/// specifier. 2332263508Sdim/// 2333263508Sdim/// \return \c true if an error occurred and this can't be any kind of 2334263508Sdim/// declaration. 2335263508Sdimbool 2336263508SdimParser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, 2337263508Sdim DeclSpecContext DSContext, 2338263508Sdim LateParsedAttrList *LateAttrs) { 2339263508Sdim assert(DS.hasTagDefinition() && "shouldn't call this"); 2340263508Sdim 2341263508Sdim bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2342263508Sdim bool HasMissingSemi = false; 2343263508Sdim 2344263508Sdim if (getLangOpts().CPlusPlus && 2345263508Sdim (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || 2346263508Sdim Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) && 2347263508Sdim TryAnnotateCXXScopeToken(EnteringContext)) { 2348263508Sdim SkipMalformedDecl(); 2349263508Sdim return true; 2350263508Sdim } 2351263508Sdim 2352263508Sdim // Determine whether the following tokens could possibly be a 2353263508Sdim // declarator. 2354263508Sdim if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 2355263508Sdim const Token &Next = NextToken(); 2356263508Sdim // These tokens cannot come after the declarator-id in a 2357263508Sdim // simple-declaration, and are likely to come after a type-specifier. 2358263508Sdim HasMissingSemi = Next.is(tok::star) || Next.is(tok::amp) || 2359263508Sdim Next.is(tok::ampamp) || Next.is(tok::identifier) || 2360263508Sdim Next.is(tok::annot_cxxscope) || 2361263508Sdim Next.is(tok::coloncolon); 2362263508Sdim } else if (Tok.is(tok::annot_cxxscope) && 2363263508Sdim NextToken().is(tok::identifier) && 2364263508Sdim DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { 2365263508Sdim // We almost certainly have a missing semicolon. Look up the name and 2366263508Sdim // check; if it names a type, we're missing a semicolon. 2367263508Sdim CXXScopeSpec SS; 2368263508Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2369263508Sdim Tok.getAnnotationRange(), SS); 2370263508Sdim const Token &Next = NextToken(); 2371263508Sdim IdentifierInfo *Name = Next.getIdentifierInfo(); 2372263508Sdim Sema::NameClassification Classification = 2373263508Sdim Actions.ClassifyName(getCurScope(), SS, Name, Next.getLocation(), 2374263508Sdim NextToken(), /*IsAddressOfOperand*/false); 2375263508Sdim switch (Classification.getKind()) { 2376263508Sdim case Sema::NC_Error: 2377263508Sdim SkipMalformedDecl(); 2378263508Sdim return true; 2379263508Sdim 2380263508Sdim case Sema::NC_Keyword: 2381263508Sdim case Sema::NC_NestedNameSpecifier: 2382263508Sdim llvm_unreachable("typo correction and nested name specifiers not " 2383263508Sdim "possible here"); 2384263508Sdim 2385263508Sdim case Sema::NC_Type: 2386263508Sdim case Sema::NC_TypeTemplate: 2387263508Sdim // Not a previously-declared non-type entity. 2388263508Sdim HasMissingSemi = true; 2389263508Sdim break; 2390263508Sdim 2391263508Sdim case Sema::NC_Unknown: 2392263508Sdim case Sema::NC_Expression: 2393263508Sdim case Sema::NC_VarTemplate: 2394263508Sdim case Sema::NC_FunctionTemplate: 2395263508Sdim // Might be a redeclaration of a prior entity. 2396263508Sdim HasMissingSemi = false; 2397263508Sdim break; 2398263508Sdim } 2399263508Sdim } else if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) { 2400263508Sdim HasMissingSemi = true; 2401263508Sdim } 2402263508Sdim 2403263508Sdim if (!HasMissingSemi) 2404263508Sdim return false; 2405263508Sdim 2406263508Sdim Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()), 2407263508Sdim diag::err_expected_semi_after_tagdecl) 2408263508Sdim << DeclSpec::getSpecifierName(DS.getTypeSpecType()); 2409263508Sdim 2410263508Sdim // Try to recover from the typo, by dropping the tag definition and parsing 2411263508Sdim // the problematic tokens as a type. 2412263508Sdim // 2413263508Sdim // FIXME: Split the DeclSpec into pieces for the standalone 2414263508Sdim // declaration and pieces for the following declaration, instead 2415263508Sdim // of assuming that all the other pieces attach to new declaration, 2416263508Sdim // and call ParsedFreeStandingDeclSpec as appropriate. 2417263508Sdim DS.ClearTypeSpecType(); 2418263508Sdim ParsedTemplateInfo NotATemplate; 2419263508Sdim ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs); 2420263508Sdim return false; 2421263508Sdim} 2422263508Sdim 2423193326Sed/// ParseDeclarationSpecifiers 2424193326Sed/// declaration-specifiers: [C99 6.7] 2425193326Sed/// storage-class-specifier declaration-specifiers[opt] 2426193326Sed/// type-specifier declaration-specifiers[opt] 2427193326Sed/// [C99] function-specifier declaration-specifiers[opt] 2428234353Sdim/// [C11] alignment-specifier declaration-specifiers[opt] 2429193326Sed/// [GNU] attributes declaration-specifiers[opt] 2430226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt] 2431193326Sed/// 2432193326Sed/// storage-class-specifier: [C99 6.7.1] 2433193326Sed/// 'typedef' 2434193326Sed/// 'extern' 2435193326Sed/// 'static' 2436193326Sed/// 'auto' 2437193326Sed/// 'register' 2438193326Sed/// [C++] 'mutable' 2439251662Sdim/// [C++11] 'thread_local' 2440251662Sdim/// [C11] '_Thread_local' 2441193326Sed/// [GNU] '__thread' 2442193326Sed/// function-specifier: [C99 6.7.4] 2443193326Sed/// [C99] 'inline' 2444193326Sed/// [C++] 'virtual' 2445193326Sed/// [C++] 'explicit' 2446218893Sdim/// [OpenCL] '__kernel' 2447193326Sed/// 'friend': [C++ dcl.friend] 2448198954Srdivacky/// 'constexpr': [C++0x dcl.constexpr] 2449193326Sed 2450193326Sed/// 2451193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS, 2452193326Sed const ParsedTemplateInfo &TemplateInfo, 2453198092Srdivacky AccessSpecifier AS, 2454234353Sdim DeclSpecContext DSContext, 2455234353Sdim LateParsedAttrList *LateAttrs) { 2456221345Sdim if (DS.getSourceRange().isInvalid()) { 2457221345Sdim DS.SetRangeStart(Tok.getLocation()); 2458221345Sdim DS.SetRangeEnd(Tok.getLocation()); 2459221345Sdim } 2460239462Sdim 2461234353Sdim bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2462239462Sdim bool AttrsLastTime = false; 2463239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 2464193326Sed while (1) { 2465198092Srdivacky bool isInvalid = false; 2466193326Sed const char *PrevSpec = 0; 2467198092Srdivacky unsigned DiagID = 0; 2468198092Srdivacky 2469193326Sed SourceLocation Loc = Tok.getLocation(); 2470193326Sed 2471193326Sed switch (Tok.getKind()) { 2472198092Srdivacky default: 2473193326Sed DoneWithDeclSpec: 2474239462Sdim if (!AttrsLastTime) 2475239462Sdim ProhibitAttributes(attrs); 2476243830Sdim else { 2477243830Sdim // Reject C++11 attributes that appertain to decl specifiers as 2478243830Sdim // we don't support any C++11 attributes that appertain to decl 2479243830Sdim // specifiers. This also conforms to what g++ 4.8 is doing. 2480243830Sdim ProhibitCXX11Attributes(attrs); 2481243830Sdim 2482239462Sdim DS.takeAttributesFrom(attrs); 2483243830Sdim } 2484226633Sdim 2485193326Sed // If this is not a declaration specifier token, we're done reading decl 2486193326Sed // specifiers. First verify that DeclSpec's are consistent. 2487193326Sed DS.Finish(Diags, PP); 2488193326Sed return; 2489198092Srdivacky 2490239462Sdim case tok::l_square: 2491239462Sdim case tok::kw_alignas: 2492249423Sdim if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier()) 2493239462Sdim goto DoneWithDeclSpec; 2494239462Sdim 2495239462Sdim ProhibitAttributes(attrs); 2496239462Sdim // FIXME: It would be good to recover by accepting the attributes, 2497239462Sdim // but attempting to do that now would cause serious 2498239462Sdim // madness in terms of diagnostics. 2499239462Sdim attrs.clear(); 2500239462Sdim attrs.Range = SourceRange(); 2501239462Sdim 2502239462Sdim ParseCXX11Attributes(attrs); 2503239462Sdim AttrsLastTime = true; 2504239462Sdim continue; 2505239462Sdim 2506212904Sdim case tok::code_completion: { 2507212904Sdim Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; 2508212904Sdim if (DS.hasTypeSpecifier()) { 2509212904Sdim bool AllowNonIdentifiers 2510212904Sdim = (getCurScope()->getFlags() & (Scope::ControlScope | 2511212904Sdim Scope::BlockScope | 2512212904Sdim Scope::TemplateParamScope | 2513212904Sdim Scope::FunctionPrototypeScope | 2514212904Sdim Scope::AtCatchScope)) == 0; 2515212904Sdim bool AllowNestedNameSpecifiers 2516239462Sdim = DSContext == DSC_top_level || 2517212904Sdim (DSContext == DSC_class && DS.isFriendSpecified()); 2518212904Sdim 2519218893Sdim Actions.CodeCompleteDeclSpec(getCurScope(), DS, 2520239462Sdim AllowNonIdentifiers, 2521218893Sdim AllowNestedNameSpecifiers); 2522226633Sdim return cutOffParsing(); 2523239462Sdim } 2524239462Sdim 2525218893Sdim if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) 2526218893Sdim CCC = Sema::PCC_LocalDeclarationSpecifiers; 2527218893Sdim else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) 2528239462Sdim CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 2529212904Sdim : Sema::PCC_Template; 2530212904Sdim else if (DSContext == DSC_class) 2531212904Sdim CCC = Sema::PCC_Class; 2532234353Sdim else if (CurParsedObjCImpl) 2533212904Sdim CCC = Sema::PCC_ObjCImplementation; 2534239462Sdim 2535212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); 2536226633Sdim return cutOffParsing(); 2537212904Sdim } 2538212904Sdim 2539193326Sed case tok::coloncolon: // ::foo::bar 2540204643Srdivacky // C++ scope specifier. Annotate and loop, or bail out on error. 2541263508Sdim if (TryAnnotateCXXScopeToken(EnteringContext)) { 2542204643Srdivacky if (!DS.hasTypeSpecifier()) 2543204643Srdivacky DS.SetTypeSpecError(); 2544204643Srdivacky goto DoneWithDeclSpec; 2545204643Srdivacky } 2546204643Srdivacky if (Tok.is(tok::coloncolon)) // ::new or ::delete 2547204643Srdivacky goto DoneWithDeclSpec; 2548204643Srdivacky continue; 2549193326Sed 2550193326Sed case tok::annot_cxxscope: { 2551239462Sdim if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector()) 2552193326Sed goto DoneWithDeclSpec; 2553193326Sed 2554200583Srdivacky CXXScopeSpec SS; 2555219077Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2556219077Sdim Tok.getAnnotationRange(), 2557219077Sdim SS); 2558200583Srdivacky 2559193326Sed // We are looking for a qualified typename. 2560193326Sed Token Next = NextToken(); 2561198092Srdivacky if (Next.is(tok::annot_template_id) && 2562193326Sed static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) 2563193326Sed ->Kind == TNK_Type_template) { 2564193326Sed // We have a qualified template-id, e.g., N::A<int> 2565202379Srdivacky 2566202379Srdivacky // C++ [class.qual]p2: 2567202379Srdivacky // In a lookup in which the constructor is an acceptable lookup 2568202379Srdivacky // result and the nested-name-specifier nominates a class C: 2569202379Srdivacky // 2570202379Srdivacky // - if the name specified after the 2571202379Srdivacky // nested-name-specifier, when looked up in C, is the 2572202379Srdivacky // injected-class-name of C (Clause 9), or 2573202379Srdivacky // 2574202379Srdivacky // - if the name specified after the nested-name-specifier 2575202379Srdivacky // is the same as the identifier or the 2576202379Srdivacky // simple-template-id's template-name in the last 2577202379Srdivacky // component of the nested-name-specifier, 2578202379Srdivacky // 2579202379Srdivacky // the name is instead considered to name the constructor of 2580202379Srdivacky // class C. 2581239462Sdim // 2582202379Srdivacky // Thus, if the template-name is actually the constructor 2583202379Srdivacky // name, then the code is ill-formed; this interpretation is 2584239462Sdim // reinforced by the NAD status of core issue 635. 2585224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 2586249423Sdim if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2587207619Srdivacky TemplateId->Name && 2588210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 2589202379Srdivacky if (isConstructorDeclarator()) { 2590202379Srdivacky // The user meant this to be an out-of-line constructor 2591202379Srdivacky // definition, but template arguments are not allowed 2592202379Srdivacky // there. Just allow this as a constructor; we'll 2593202379Srdivacky // complain about it later. 2594202379Srdivacky goto DoneWithDeclSpec; 2595202379Srdivacky } 2596202379Srdivacky 2597202379Srdivacky // The user meant this to name a type, but it actually names 2598202379Srdivacky // a constructor with some extraneous template 2599202379Srdivacky // arguments. Complain, then parse it as a type as the user 2600202379Srdivacky // intended. 2601202379Srdivacky Diag(TemplateId->TemplateNameLoc, 2602202379Srdivacky diag::err_out_of_line_template_id_names_constructor) 2603202379Srdivacky << TemplateId->Name; 2604202379Srdivacky } 2605202379Srdivacky 2606200583Srdivacky DS.getTypeSpecScope() = SS; 2607200583Srdivacky ConsumeToken(); // The C++ scope. 2608198092Srdivacky assert(Tok.is(tok::annot_template_id) && 2609193326Sed "ParseOptionalCXXScopeSpecifier not working"); 2610221345Sdim AnnotateTemplateIdTokenAsType(); 2611193326Sed continue; 2612193326Sed } 2613193326Sed 2614198092Srdivacky if (Next.is(tok::annot_typename)) { 2615200583Srdivacky DS.getTypeSpecScope() = SS; 2616200583Srdivacky ConsumeToken(); // The C++ scope. 2617212904Sdim if (Tok.getAnnotationValue()) { 2618212904Sdim ParsedType T = getTypeAnnotation(Tok); 2619218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, 2620239462Sdim Tok.getAnnotationEndLoc(), 2621212904Sdim PrevSpec, DiagID, T); 2622243830Sdim if (isInvalid) 2623243830Sdim break; 2624212904Sdim } 2625198092Srdivacky else 2626198092Srdivacky DS.SetTypeSpecError(); 2627198092Srdivacky DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2628198092Srdivacky ConsumeToken(); // The typename 2629198092Srdivacky } 2630198092Srdivacky 2631193326Sed if (Next.isNot(tok::identifier)) 2632193326Sed goto DoneWithDeclSpec; 2633193326Sed 2634202379Srdivacky // If we're in a context where the identifier could be a class name, 2635202379Srdivacky // check whether this is a constructor declaration. 2636249423Sdim if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2637239462Sdim Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 2638202379Srdivacky &SS)) { 2639202379Srdivacky if (isConstructorDeclarator()) 2640202379Srdivacky goto DoneWithDeclSpec; 2641193326Sed 2642202379Srdivacky // As noted in C++ [class.qual]p2 (cited above), when the name 2643202379Srdivacky // of the class is qualified in a context where it could name 2644202379Srdivacky // a constructor, its a constructor name. However, we've 2645202379Srdivacky // looked at the declarator, and the user probably meant this 2646202379Srdivacky // to be a type. Complain that it isn't supposed to be treated 2647202379Srdivacky // as a type, then proceed to parse it as a type. 2648202379Srdivacky Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) 2649202379Srdivacky << Next.getIdentifierInfo(); 2650202379Srdivacky } 2651202379Srdivacky 2652212904Sdim ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), 2653212904Sdim Next.getLocation(), 2654221345Sdim getCurScope(), &SS, 2655221345Sdim false, false, ParsedType(), 2656234353Sdim /*IsCtorOrDtorName=*/false, 2657221345Sdim /*NonTrivialSourceInfo=*/true); 2658193326Sed 2659193326Sed // If the referenced identifier is not a type, then this declspec is 2660193326Sed // erroneous: We already checked about that it has no type specifier, and 2661193326Sed // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the 2662198092Srdivacky // typename. 2663263508Sdim if (!TypeRep) { 2664193326Sed ConsumeToken(); // Eat the scope spec so the identifier is current. 2665249423Sdim ParsedAttributesWithRange Attrs(AttrFactory); 2666249423Sdim if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) { 2667249423Sdim if (!Attrs.empty()) { 2668249423Sdim AttrsLastTime = true; 2669249423Sdim attrs.takeAllFrom(Attrs); 2670249423Sdim } 2671249423Sdim continue; 2672249423Sdim } 2673193326Sed goto DoneWithDeclSpec; 2674193326Sed } 2675198092Srdivacky 2676200583Srdivacky DS.getTypeSpecScope() = SS; 2677193326Sed ConsumeToken(); // The C++ scope. 2678193326Sed 2679193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2680198092Srdivacky DiagID, TypeRep); 2681193326Sed if (isInvalid) 2682193326Sed break; 2683198092Srdivacky 2684193326Sed DS.SetRangeEnd(Tok.getLocation()); 2685193326Sed ConsumeToken(); // The typename. 2686193326Sed 2687193326Sed continue; 2688193326Sed } 2689198092Srdivacky 2690193326Sed case tok::annot_typename: { 2691263508Sdim // If we've previously seen a tag definition, we were almost surely 2692263508Sdim // missing a semicolon after it. 2693263508Sdim if (DS.hasTypeSpecifier() && DS.hasTagDefinition()) 2694263508Sdim goto DoneWithDeclSpec; 2695263508Sdim 2696212904Sdim if (Tok.getAnnotationValue()) { 2697212904Sdim ParsedType T = getTypeAnnotation(Tok); 2698193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2699212904Sdim DiagID, T); 2700212904Sdim } else 2701193326Sed DS.SetTypeSpecError(); 2702239462Sdim 2703206275Srdivacky if (isInvalid) 2704206275Srdivacky break; 2705206275Srdivacky 2706193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2707193326Sed ConsumeToken(); // The typename 2708198092Srdivacky 2709193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2710193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2711239462Sdim // Objective-C interface. 2712234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2713218893Sdim ParseObjCProtocolQualifiers(DS); 2714239462Sdim 2715193326Sed continue; 2716193326Sed } 2717198092Srdivacky 2718221345Sdim case tok::kw___is_signed: 2719221345Sdim // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang 2720221345Sdim // typically treats it as a trait. If we see __is_signed as it appears 2721221345Sdim // in libstdc++, e.g., 2722221345Sdim // 2723221345Sdim // static const bool __is_signed; 2724221345Sdim // 2725221345Sdim // then treat __is_signed as an identifier rather than as a keyword. 2726221345Sdim if (DS.getTypeSpecType() == TST_bool && 2727221345Sdim DS.getTypeQualifiers() == DeclSpec::TQ_const && 2728263508Sdim DS.getStorageClassSpec() == DeclSpec::SCS_static) 2729263508Sdim TryKeywordIdentFallback(true); 2730221345Sdim 2731221345Sdim // We're done with the declaration-specifiers. 2732221345Sdim goto DoneWithDeclSpec; 2733239462Sdim 2734193326Sed // typedef-name 2735234353Sdim case tok::kw_decltype: 2736193326Sed case tok::identifier: { 2737193326Sed // In C++, check to see if this is a scope specifier like foo::bar::, if 2738193326Sed // so handle it as such. This is important for ctor parsing. 2739234353Sdim if (getLangOpts().CPlusPlus) { 2740263508Sdim if (TryAnnotateCXXScopeToken(EnteringContext)) { 2741204643Srdivacky if (!DS.hasTypeSpecifier()) 2742204643Srdivacky DS.SetTypeSpecError(); 2743204643Srdivacky goto DoneWithDeclSpec; 2744204643Srdivacky } 2745204643Srdivacky if (!Tok.is(tok::identifier)) 2746204643Srdivacky continue; 2747204643Srdivacky } 2748198092Srdivacky 2749193326Sed // This identifier can only be a typedef name if we haven't already seen 2750193326Sed // a type-specifier. Without this check we misparse: 2751193326Sed // typedef int X; struct Y { short X; }; as 'short int'. 2752193326Sed if (DS.hasTypeSpecifier()) 2753193326Sed goto DoneWithDeclSpec; 2754198092Srdivacky 2755203955Srdivacky // Check for need to substitute AltiVec keyword tokens. 2756203955Srdivacky if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) 2757203955Srdivacky break; 2758203955Srdivacky 2759239462Sdim // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not 2760239462Sdim // allow the use of a typedef name as a type specifier. 2761239462Sdim if (DS.isTypeAltiVecVector()) 2762239462Sdim goto DoneWithDeclSpec; 2763239462Sdim 2764212904Sdim ParsedType TypeRep = 2765212904Sdim Actions.getTypeName(*Tok.getIdentifierInfo(), 2766212904Sdim Tok.getLocation(), getCurScope()); 2767193326Sed 2768193326Sed // If this is not a typedef name, don't parse it as part of the declspec, 2769193326Sed // it must be an implicit int or an error. 2770212904Sdim if (!TypeRep) { 2771249423Sdim ParsedAttributesWithRange Attrs(AttrFactory); 2772249423Sdim if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) { 2773249423Sdim if (!Attrs.empty()) { 2774249423Sdim AttrsLastTime = true; 2775249423Sdim attrs.takeAllFrom(Attrs); 2776249423Sdim } 2777249423Sdim continue; 2778249423Sdim } 2779193326Sed goto DoneWithDeclSpec; 2780193326Sed } 2781193326Sed 2782202379Srdivacky // If we're in a context where the identifier could be a class name, 2783202379Srdivacky // check whether this is a constructor declaration. 2784234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2785210299Sed Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) && 2786202379Srdivacky isConstructorDeclarator()) 2787193326Sed goto DoneWithDeclSpec; 2788193326Sed 2789193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2790198092Srdivacky DiagID, TypeRep); 2791193326Sed if (isInvalid) 2792193326Sed break; 2793198092Srdivacky 2794193326Sed DS.SetRangeEnd(Tok.getLocation()); 2795193326Sed ConsumeToken(); // The identifier 2796193326Sed 2797193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2798193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2799239462Sdim // Objective-C interface. 2800234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2801218893Sdim ParseObjCProtocolQualifiers(DS); 2802239462Sdim 2803193326Sed // Need to support trailing type qualifiers (e.g. "id<p> const"). 2804193326Sed // If a type specifier follows, it will be diagnosed elsewhere. 2805193326Sed continue; 2806193326Sed } 2807193326Sed 2808193326Sed // type-name 2809193326Sed case tok::annot_template_id: { 2810224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2811193326Sed if (TemplateId->Kind != TNK_Type_template) { 2812193326Sed // This template-id does not refer to a type name, so we're 2813193326Sed // done with the type-specifiers. 2814193326Sed goto DoneWithDeclSpec; 2815193326Sed } 2816193326Sed 2817202379Srdivacky // If we're in a context where the template-id could be a 2818202379Srdivacky // constructor name or specialization, check whether this is a 2819202379Srdivacky // constructor declaration. 2820234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2821210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) && 2822202379Srdivacky isConstructorDeclarator()) 2823202379Srdivacky goto DoneWithDeclSpec; 2824202379Srdivacky 2825193326Sed // Turn the template-id annotation token into a type annotation 2826193326Sed // token, then try again to parse it as a type-specifier. 2827193326Sed AnnotateTemplateIdTokenAsType(); 2828193326Sed continue; 2829193326Sed } 2830193326Sed 2831193326Sed // GNU attributes support. 2832193326Sed case tok::kw___attribute: 2833234353Sdim ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs); 2834193326Sed continue; 2835193326Sed 2836193326Sed // Microsoft declspec support. 2837193326Sed case tok::kw___declspec: 2838218893Sdim ParseMicrosoftDeclSpec(DS.getAttributes()); 2839193326Sed continue; 2840198092Srdivacky 2841193326Sed // Microsoft single token adornments. 2842239462Sdim case tok::kw___forceinline: { 2843263508Sdim isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID); 2844239462Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 2845243830Sdim SourceLocation AttrNameLoc = Tok.getLocation(); 2846239462Sdim // FIXME: This does not work correctly if it is set to be a declspec 2847239462Sdim // attribute, and a GNU attribute is simply incorrect. 2848263508Sdim DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 2849263508Sdim AttributeList::AS_GNU); 2850243830Sdim break; 2851239462Sdim } 2852194179Sed 2853263508Sdim case tok::kw___sptr: 2854263508Sdim case tok::kw___uptr: 2855194179Sed case tok::kw___ptr64: 2856226633Sdim case tok::kw___ptr32: 2857193326Sed case tok::kw___w64: 2858193326Sed case tok::kw___cdecl: 2859193326Sed case tok::kw___stdcall: 2860193326Sed case tok::kw___fastcall: 2861208600Srdivacky case tok::kw___thiscall: 2862226633Sdim case tok::kw___unaligned: 2863218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 2864194179Sed continue; 2865194179Sed 2866212904Sdim // Borland single token adornments. 2867212904Sdim case tok::kw___pascal: 2868218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 2869212904Sdim continue; 2870212904Sdim 2871218893Sdim // OpenCL single token adornments. 2872218893Sdim case tok::kw___kernel: 2873218893Sdim ParseOpenCLAttributes(DS.getAttributes()); 2874218893Sdim continue; 2875218893Sdim 2876193326Sed // storage-class-specifier 2877193326Sed case tok::kw_typedef: 2878226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, 2879226633Sdim PrevSpec, DiagID); 2880193326Sed break; 2881193326Sed case tok::kw_extern: 2882251662Sdim if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2883193326Sed Diag(Tok, diag::ext_thread_before) << "extern"; 2884226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc, 2885226633Sdim PrevSpec, DiagID); 2886193326Sed break; 2887193326Sed case tok::kw___private_extern__: 2888226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern, 2889226633Sdim Loc, PrevSpec, DiagID); 2890193326Sed break; 2891193326Sed case tok::kw_static: 2892251662Sdim if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2893193326Sed Diag(Tok, diag::ext_thread_before) << "static"; 2894226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc, 2895226633Sdim PrevSpec, DiagID); 2896193326Sed break; 2897193326Sed case tok::kw_auto: 2898249423Sdim if (getLangOpts().CPlusPlus11) { 2899219077Sdim if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { 2900226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2901226633Sdim PrevSpec, DiagID); 2902219077Sdim if (!isInvalid) 2903226633Sdim Diag(Tok, diag::ext_auto_storage_class) 2904219077Sdim << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); 2905226633Sdim } else 2906219077Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, 2907219077Sdim DiagID); 2908226633Sdim } else 2909226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2910226633Sdim PrevSpec, DiagID); 2911193326Sed break; 2912193326Sed case tok::kw_register: 2913226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, 2914226633Sdim PrevSpec, DiagID); 2915193326Sed break; 2916193326Sed case tok::kw_mutable: 2917226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc, 2918226633Sdim PrevSpec, DiagID); 2919193326Sed break; 2920193326Sed case tok::kw___thread: 2921251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc, 2922251662Sdim PrevSpec, DiagID); 2923193326Sed break; 2924251662Sdim case tok::kw_thread_local: 2925251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc, 2926251662Sdim PrevSpec, DiagID); 2927251662Sdim break; 2928251662Sdim case tok::kw__Thread_local: 2929251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local, 2930251662Sdim Loc, PrevSpec, DiagID); 2931251662Sdim break; 2932198092Srdivacky 2933193326Sed // function-specifier 2934193326Sed case tok::kw_inline: 2935263508Sdim isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID); 2936193326Sed break; 2937193326Sed case tok::kw_virtual: 2938263508Sdim isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID); 2939193326Sed break; 2940193326Sed case tok::kw_explicit: 2941263508Sdim isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID); 2942193326Sed break; 2943249423Sdim case tok::kw__Noreturn: 2944249423Sdim if (!getLangOpts().C11) 2945249423Sdim Diag(Loc, diag::ext_c11_noreturn); 2946263508Sdim isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID); 2947249423Sdim break; 2948193326Sed 2949226633Sdim // alignment-specifier 2950226633Sdim case tok::kw__Alignas: 2951234353Sdim if (!getLangOpts().C11) 2952239462Sdim Diag(Tok, diag::ext_c11_alignment) << Tok.getName(); 2953226633Sdim ParseAlignmentSpecifier(DS.getAttributes()); 2954226633Sdim continue; 2955226633Sdim 2956193326Sed // friend 2957193326Sed case tok::kw_friend: 2958198092Srdivacky if (DSContext == DSC_class) 2959198092Srdivacky isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); 2960198092Srdivacky else { 2961198092Srdivacky PrevSpec = ""; // not actually used by the diagnostic 2962198092Srdivacky DiagID = diag::err_friend_invalid_in_context; 2963198092Srdivacky isInvalid = true; 2964198092Srdivacky } 2965193326Sed break; 2966198092Srdivacky 2967226633Sdim // Modules 2968226633Sdim case tok::kw___module_private__: 2969226633Sdim isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); 2970226633Sdim break; 2971239462Sdim 2972198954Srdivacky // constexpr 2973198954Srdivacky case tok::kw_constexpr: 2974198954Srdivacky isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); 2975198954Srdivacky break; 2976198954Srdivacky 2977193326Sed // type-specifier 2978193326Sed case tok::kw_short: 2979198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, 2980198092Srdivacky DiagID); 2981193326Sed break; 2982193326Sed case tok::kw_long: 2983193326Sed if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) 2984198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, 2985198092Srdivacky DiagID); 2986193326Sed else 2987198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2988198092Srdivacky DiagID); 2989193326Sed break; 2990221345Sdim case tok::kw___int64: 2991221345Sdim isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2992221345Sdim DiagID); 2993221345Sdim break; 2994193326Sed case tok::kw_signed: 2995198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, 2996198092Srdivacky DiagID); 2997193326Sed break; 2998193326Sed case tok::kw_unsigned: 2999198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, 3000198092Srdivacky DiagID); 3001193326Sed break; 3002193326Sed case tok::kw__Complex: 3003198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec, 3004198092Srdivacky DiagID); 3005193326Sed break; 3006193326Sed case tok::kw__Imaginary: 3007198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec, 3008198092Srdivacky DiagID); 3009193326Sed break; 3010193326Sed case tok::kw_void: 3011198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, 3012198092Srdivacky DiagID); 3013193326Sed break; 3014193326Sed case tok::kw_char: 3015198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, 3016198092Srdivacky DiagID); 3017193326Sed break; 3018193326Sed case tok::kw_int: 3019198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, 3020198092Srdivacky DiagID); 3021193326Sed break; 3022234353Sdim case tok::kw___int128: 3023234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, 3024234353Sdim DiagID); 3025234353Sdim break; 3026234353Sdim case tok::kw_half: 3027234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, 3028234353Sdim DiagID); 3029234353Sdim break; 3030193326Sed case tok::kw_float: 3031198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, 3032198092Srdivacky DiagID); 3033193326Sed break; 3034193326Sed case tok::kw_double: 3035198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, 3036198092Srdivacky DiagID); 3037193326Sed break; 3038193326Sed case tok::kw_wchar_t: 3039198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, 3040198092Srdivacky DiagID); 3041193326Sed break; 3042198092Srdivacky case tok::kw_char16_t: 3043198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, 3044198092Srdivacky DiagID); 3045198092Srdivacky break; 3046198092Srdivacky case tok::kw_char32_t: 3047198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, 3048198092Srdivacky DiagID); 3049198092Srdivacky break; 3050193326Sed case tok::kw_bool: 3051193326Sed case tok::kw__Bool: 3052218893Sdim if (Tok.is(tok::kw_bool) && 3053218893Sdim DS.getTypeSpecType() != DeclSpec::TST_unspecified && 3054218893Sdim DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 3055218893Sdim PrevSpec = ""; // Not used by the diagnostic. 3056218893Sdim DiagID = diag::err_bool_redeclaration; 3057221345Sdim // For better error recovery. 3058221345Sdim Tok.setKind(tok::identifier); 3059218893Sdim isInvalid = true; 3060218893Sdim } else { 3061218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, 3062218893Sdim DiagID); 3063218893Sdim } 3064193326Sed break; 3065193326Sed case tok::kw__Decimal32: 3066198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec, 3067198092Srdivacky DiagID); 3068193326Sed break; 3069193326Sed case tok::kw__Decimal64: 3070198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec, 3071198092Srdivacky DiagID); 3072193326Sed break; 3073193326Sed case tok::kw__Decimal128: 3074198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, 3075198092Srdivacky DiagID); 3076193326Sed break; 3077203955Srdivacky case tok::kw___vector: 3078203955Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 3079203955Srdivacky break; 3080203955Srdivacky case tok::kw___pixel: 3081203955Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 3082203955Srdivacky break; 3083249423Sdim case tok::kw_image1d_t: 3084249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc, 3085249423Sdim PrevSpec, DiagID); 3086249423Sdim break; 3087249423Sdim case tok::kw_image1d_array_t: 3088249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc, 3089249423Sdim PrevSpec, DiagID); 3090249423Sdim break; 3091249423Sdim case tok::kw_image1d_buffer_t: 3092249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc, 3093249423Sdim PrevSpec, DiagID); 3094249423Sdim break; 3095249423Sdim case tok::kw_image2d_t: 3096249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc, 3097249423Sdim PrevSpec, DiagID); 3098249423Sdim break; 3099249423Sdim case tok::kw_image2d_array_t: 3100249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc, 3101249423Sdim PrevSpec, DiagID); 3102249423Sdim break; 3103249423Sdim case tok::kw_image3d_t: 3104249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc, 3105249423Sdim PrevSpec, DiagID); 3106249423Sdim break; 3107249423Sdim case tok::kw_sampler_t: 3108249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc, 3109249423Sdim PrevSpec, DiagID); 3110249423Sdim break; 3111249423Sdim case tok::kw_event_t: 3112249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc, 3113249423Sdim PrevSpec, DiagID); 3114249423Sdim break; 3115221345Sdim case tok::kw___unknown_anytype: 3116221345Sdim isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, 3117221345Sdim PrevSpec, DiagID); 3118221345Sdim break; 3119193326Sed 3120193326Sed // class-specifier: 3121193326Sed case tok::kw_class: 3122193326Sed case tok::kw_struct: 3123243830Sdim case tok::kw___interface: 3124193326Sed case tok::kw_union: { 3125193326Sed tok::TokenKind Kind = Tok.getKind(); 3126193326Sed ConsumeToken(); 3127249423Sdim 3128249423Sdim // These are attributes following class specifiers. 3129249423Sdim // To produce better diagnostic, we parse them when 3130249423Sdim // parsing class specifier. 3131249423Sdim ParsedAttributesWithRange Attributes(AttrFactory); 3132234353Sdim ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, 3133249423Sdim EnteringContext, DSContext, Attributes); 3134249423Sdim 3135249423Sdim // If there are attributes following class specifier, 3136249423Sdim // take them over and handle them here. 3137249423Sdim if (!Attributes.empty()) { 3138249423Sdim AttrsLastTime = true; 3139249423Sdim attrs.takeAllFrom(Attributes); 3140249423Sdim } 3141193326Sed continue; 3142193326Sed } 3143193326Sed 3144193326Sed // enum-specifier: 3145193326Sed case tok::kw_enum: 3146193326Sed ConsumeToken(); 3147234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext); 3148193326Sed continue; 3149193326Sed 3150193326Sed // cv-qualifier: 3151193326Sed case tok::kw_const: 3152198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, 3153243830Sdim getLangOpts()); 3154193326Sed break; 3155193326Sed case tok::kw_volatile: 3156198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 3157243830Sdim getLangOpts()); 3158193326Sed break; 3159193326Sed case tok::kw_restrict: 3160198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 3161243830Sdim getLangOpts()); 3162193326Sed break; 3163193326Sed 3164193326Sed // C++ typename-specifier: 3165193326Sed case tok::kw_typename: 3166204643Srdivacky if (TryAnnotateTypeOrScopeToken()) { 3167204643Srdivacky DS.SetTypeSpecError(); 3168204643Srdivacky goto DoneWithDeclSpec; 3169204643Srdivacky } 3170204643Srdivacky if (!Tok.is(tok::kw_typename)) 3171193326Sed continue; 3172193326Sed break; 3173193326Sed 3174193326Sed // GNU typeof support. 3175193326Sed case tok::kw_typeof: 3176193326Sed ParseTypeofSpecifier(DS); 3177193326Sed continue; 3178193326Sed 3179234353Sdim case tok::annot_decltype: 3180195099Sed ParseDecltypeSpecifier(DS); 3181195099Sed continue; 3182195099Sed 3183223017Sdim case tok::kw___underlying_type: 3184223017Sdim ParseUnderlyingTypeSpecifier(DS); 3185226633Sdim continue; 3186223017Sdim 3187226633Sdim case tok::kw__Atomic: 3188249423Sdim // C11 6.7.2.4/4: 3189249423Sdim // If the _Atomic keyword is immediately followed by a left parenthesis, 3190249423Sdim // it is interpreted as a type specifier (with a type name), not as a 3191249423Sdim // type qualifier. 3192249423Sdim if (NextToken().is(tok::l_paren)) { 3193249423Sdim ParseAtomicSpecifier(DS); 3194249423Sdim continue; 3195249423Sdim } 3196249423Sdim isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 3197249423Sdim getLangOpts()); 3198249423Sdim break; 3199226633Sdim 3200221345Sdim // OpenCL qualifiers: 3201239462Sdim case tok::kw_private: 3202234353Sdim if (!getLangOpts().OpenCL) 3203221345Sdim goto DoneWithDeclSpec; 3204221345Sdim case tok::kw___private: 3205221345Sdim case tok::kw___global: 3206221345Sdim case tok::kw___local: 3207221345Sdim case tok::kw___constant: 3208221345Sdim case tok::kw___read_only: 3209221345Sdim case tok::kw___write_only: 3210221345Sdim case tok::kw___read_write: 3211221345Sdim ParseOpenCLQualifiers(DS); 3212221345Sdim break; 3213239462Sdim 3214193326Sed case tok::less: 3215193326Sed // GCC ObjC supports types like "<SomeProtocol>" as a synonym for 3216193326Sed // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous, 3217193326Sed // but we support it. 3218234353Sdim if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1) 3219193326Sed goto DoneWithDeclSpec; 3220198092Srdivacky 3221218893Sdim if (!ParseObjCProtocolQualifiers(DS)) 3222193326Sed Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) 3223206084Srdivacky << FixItHint::CreateInsertion(Loc, "id") 3224218893Sdim << SourceRange(Loc, DS.getSourceRange().getEnd()); 3225239462Sdim 3226218893Sdim // Need to support trailing type qualifiers (e.g. "id<p> const"). 3227218893Sdim // If a type specifier follows, it will be diagnosed elsewhere. 3228218893Sdim continue; 3229193326Sed } 3230198092Srdivacky // If the specifier wasn't legal, issue a diagnostic. 3231193326Sed if (isInvalid) { 3232193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 3233198092Srdivacky assert(DiagID); 3234239462Sdim 3235212904Sdim if (DiagID == diag::ext_duplicate_declspec) 3236212904Sdim Diag(Tok, DiagID) 3237212904Sdim << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); 3238212904Sdim else 3239212904Sdim Diag(Tok, DiagID) << PrevSpec; 3240193326Sed } 3241219077Sdim 3242193326Sed DS.SetRangeEnd(Tok.getLocation()); 3243221345Sdim if (DiagID != diag::err_bool_redeclaration) 3244221345Sdim ConsumeToken(); 3245239462Sdim 3246239462Sdim AttrsLastTime = false; 3247193326Sed } 3248193326Sed} 3249193326Sed 3250193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating 3251193326Sed/// semicolon. 3252193326Sed/// 3253193326Sed/// struct-declaration: 3254193326Sed/// specifier-qualifier-list struct-declarator-list 3255193326Sed/// [GNU] __extension__ struct-declaration 3256193326Sed/// [GNU] specifier-qualifier-list 3257193326Sed/// struct-declarator-list: 3258193326Sed/// struct-declarator 3259193326Sed/// struct-declarator-list ',' struct-declarator 3260193326Sed/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator 3261193326Sed/// struct-declarator: 3262193326Sed/// declarator 3263193326Sed/// [GNU] declarator attributes[opt] 3264193326Sed/// declarator[opt] ':' constant-expression 3265193326Sed/// [GNU] declarator[opt] ':' constant-expression attributes[opt] 3266193326Sed/// 3267193326Sedvoid Parser:: 3268239462SdimParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) { 3269239462Sdim 3270193326Sed if (Tok.is(tok::kw___extension__)) { 3271193326Sed // __extension__ silences extension warnings in the subexpression. 3272193326Sed ExtensionRAIIObject O(Diags); // Use RAII to do this. 3273193326Sed ConsumeToken(); 3274193326Sed return ParseStructDeclaration(DS, Fields); 3275193326Sed } 3276198092Srdivacky 3277193326Sed // Parse the common specifier-qualifiers-list piece. 3278193326Sed ParseSpecifierQualifierList(DS); 3279198092Srdivacky 3280193326Sed // If there are no declarators, this is a free-standing declaration 3281193326Sed // specifier. Let the actions module cope with it. 3282193326Sed if (Tok.is(tok::semi)) { 3283239462Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 3284239462Sdim DS); 3285239462Sdim DS.complete(TheDecl); 3286193326Sed return; 3287193326Sed } 3288193326Sed 3289193326Sed // Read struct-declarators until we find the semicolon. 3290198893Srdivacky bool FirstDeclarator = true; 3291234353Sdim SourceLocation CommaLoc; 3292193326Sed while (1) { 3293239462Sdim ParsingFieldDeclarator DeclaratorInfo(*this, DS); 3294234353Sdim DeclaratorInfo.D.setCommaLoc(CommaLoc); 3295198092Srdivacky 3296198893Srdivacky // Attributes are only allowed here on successive declarators. 3297218893Sdim if (!FirstDeclarator) 3298218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 3299198893Srdivacky 3300193326Sed /// struct-declarator: declarator 3301193326Sed /// struct-declarator: declarator[opt] ':' constant-expression 3302200583Srdivacky if (Tok.isNot(tok::colon)) { 3303200583Srdivacky // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 3304200583Srdivacky ColonProtectionRAIIObject X(*this); 3305193326Sed ParseDeclarator(DeclaratorInfo.D); 3306200583Srdivacky } 3307198092Srdivacky 3308193326Sed if (Tok.is(tok::colon)) { 3309193326Sed ConsumeToken(); 3310212904Sdim ExprResult Res(ParseConstantExpression()); 3311193326Sed if (Res.isInvalid()) 3312263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 3313193326Sed else 3314193326Sed DeclaratorInfo.BitfieldSize = Res.release(); 3315193326Sed } 3316193326Sed 3317193326Sed // If attributes exist after the declarator, parse them. 3318218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 3319193326Sed 3320198893Srdivacky // We're done with this declarator; invoke the callback. 3321239462Sdim Fields.invoke(DeclaratorInfo); 3322198893Srdivacky 3323193326Sed // If we don't have a comma, it is either the end of the list (a ';') 3324193326Sed // or an error, bail out. 3325193326Sed if (Tok.isNot(tok::comma)) 3326193326Sed return; 3327193326Sed 3328193326Sed // Consume the comma. 3329234353Sdim CommaLoc = ConsumeToken(); 3330193326Sed 3331198893Srdivacky FirstDeclarator = false; 3332193326Sed } 3333193326Sed} 3334193326Sed 3335193326Sed/// ParseStructUnionBody 3336193326Sed/// struct-contents: 3337193326Sed/// struct-declaration-list 3338193326Sed/// [EXT] empty 3339193326Sed/// [GNU] "struct-declaration-list" without terminatoring ';' 3340193326Sed/// struct-declaration-list: 3341193326Sed/// struct-declaration 3342193326Sed/// struct-declaration-list struct-declaration 3343193326Sed/// [OBC] '@' 'defs' '(' class-name ')' 3344193326Sed/// 3345193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc, 3346212904Sdim unsigned TagType, Decl *TagDecl) { 3347212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 3348212904Sdim "parsing struct/union body"); 3349249423Sdim assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); 3350198092Srdivacky 3351226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3352226633Sdim if (T.consumeOpen()) 3353226633Sdim return; 3354198092Srdivacky 3355193326Sed ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); 3356210299Sed Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 3357193326Sed 3358226633Sdim SmallVector<Decl *, 32> FieldDecls; 3359193326Sed 3360193326Sed // While we still have something to read, read the declarations in the struct. 3361193326Sed while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3362193326Sed // Each iteration of this loop reads one struct-declaration. 3363198092Srdivacky 3364193326Sed // Check for extraneous top-level semicolon. 3365193326Sed if (Tok.is(tok::semi)) { 3366239462Sdim ConsumeExtraSemi(InsideStruct, TagType); 3367193326Sed continue; 3368193326Sed } 3369193326Sed 3370249423Sdim // Parse _Static_assert declaration. 3371249423Sdim if (Tok.is(tok::kw__Static_assert)) { 3372249423Sdim SourceLocation DeclEnd; 3373249423Sdim ParseStaticAssertDeclaration(DeclEnd); 3374249423Sdim continue; 3375249423Sdim } 3376249423Sdim 3377251662Sdim if (Tok.is(tok::annot_pragma_pack)) { 3378251662Sdim HandlePragmaPack(); 3379251662Sdim continue; 3380251662Sdim } 3381251662Sdim 3382251662Sdim if (Tok.is(tok::annot_pragma_align)) { 3383251662Sdim HandlePragmaAlign(); 3384251662Sdim continue; 3385251662Sdim } 3386251662Sdim 3387193326Sed if (!Tok.is(tok::at)) { 3388198893Srdivacky struct CFieldCallback : FieldCallback { 3389198893Srdivacky Parser &P; 3390212904Sdim Decl *TagDecl; 3391226633Sdim SmallVectorImpl<Decl *> &FieldDecls; 3392198092Srdivacky 3393212904Sdim CFieldCallback(Parser &P, Decl *TagDecl, 3394226633Sdim SmallVectorImpl<Decl *> &FieldDecls) : 3395198893Srdivacky P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} 3396198893Srdivacky 3397239462Sdim void invoke(ParsingFieldDeclarator &FD) { 3398198893Srdivacky // Install the declarator into the current TagDecl. 3399212904Sdim Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, 3400198893Srdivacky FD.D.getDeclSpec().getSourceRange().getBegin(), 3401198893Srdivacky FD.D, FD.BitfieldSize); 3402198893Srdivacky FieldDecls.push_back(Field); 3403239462Sdim FD.complete(Field); 3404198092Srdivacky } 3405198893Srdivacky } Callback(*this, TagDecl, FieldDecls); 3406198893Srdivacky 3407239462Sdim // Parse all the comma separated declarators. 3408239462Sdim ParsingDeclSpec DS(*this); 3409198893Srdivacky ParseStructDeclaration(DS, Callback); 3410193326Sed } else { // Handle @defs 3411193326Sed ConsumeToken(); 3412193326Sed if (!Tok.isObjCAtKeyword(tok::objc_defs)) { 3413193326Sed Diag(Tok, diag::err_unexpected_at); 3414263508Sdim SkipUntil(tok::semi); 3415193326Sed continue; 3416193326Sed } 3417193326Sed ConsumeToken(); 3418193326Sed ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); 3419193326Sed if (!Tok.is(tok::identifier)) { 3420193326Sed Diag(Tok, diag::err_expected_ident); 3421263508Sdim SkipUntil(tok::semi); 3422193326Sed continue; 3423193326Sed } 3424226633Sdim SmallVector<Decl *, 16> Fields; 3425210299Sed Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), 3426193326Sed Tok.getIdentifierInfo(), Fields); 3427193326Sed FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); 3428193326Sed ConsumeToken(); 3429193326Sed ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); 3430198092Srdivacky } 3431193326Sed 3432193326Sed if (Tok.is(tok::semi)) { 3433193326Sed ConsumeToken(); 3434193326Sed } else if (Tok.is(tok::r_brace)) { 3435203955Srdivacky ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); 3436193326Sed break; 3437193326Sed } else { 3438203955Srdivacky ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 3439203955Srdivacky // Skip to end of block or statement to avoid ext-warning on extra ';'. 3440263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 3441203955Srdivacky // If we stopped at a ';', eat it. 3442203955Srdivacky if (Tok.is(tok::semi)) ConsumeToken(); 3443193326Sed } 3444193326Sed } 3445198092Srdivacky 3446226633Sdim T.consumeClose(); 3447198092Srdivacky 3448221345Sdim ParsedAttributes attrs(AttrFactory); 3449193326Sed // If attributes exist after struct contents, parse them. 3450218893Sdim MaybeParseGNUAttributes(attrs); 3451193326Sed 3452210299Sed Actions.ActOnFields(getCurScope(), 3453226633Sdim RecordLoc, TagDecl, FieldDecls, 3454226633Sdim T.getOpenLocation(), T.getCloseLocation(), 3455218893Sdim attrs.getList()); 3456193326Sed StructScope.Exit(); 3457226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 3458226633Sdim T.getCloseLocation()); 3459193326Sed} 3460193326Sed 3461193326Sed/// ParseEnumSpecifier 3462193326Sed/// enum-specifier: [C99 6.7.2.2] 3463193326Sed/// 'enum' identifier[opt] '{' enumerator-list '}' 3464193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}' 3465193326Sed/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt] 3466193326Sed/// '}' attributes[opt] 3467234353Sdim/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt] 3468234353Sdim/// '}' 3469193326Sed/// 'enum' identifier 3470193326Sed/// [GNU] 'enum' attributes[opt] identifier 3471193326Sed/// 3472234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}' 3473234353Sdim/// [C++11] enum-head '{' enumerator-list ',' '}' 3474218893Sdim/// 3475234353Sdim/// enum-head: [C++11] 3476234353Sdim/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt] 3477234353Sdim/// enum-key attribute-specifier-seq[opt] nested-name-specifier 3478234353Sdim/// identifier enum-base[opt] 3479218893Sdim/// 3480234353Sdim/// enum-key: [C++11] 3481218893Sdim/// 'enum' 3482218893Sdim/// 'enum' 'class' 3483218893Sdim/// 'enum' 'struct' 3484218893Sdim/// 3485234353Sdim/// enum-base: [C++11] 3486218893Sdim/// ':' type-specifier-seq 3487218893Sdim/// 3488193326Sed/// [C++] elaborated-type-specifier: 3489193326Sed/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier 3490193326Sed/// 3491193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, 3492204643Srdivacky const ParsedTemplateInfo &TemplateInfo, 3493234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 3494193326Sed // Parse the tag portion of this. 3495198092Srdivacky if (Tok.is(tok::code_completion)) { 3496198092Srdivacky // Code completion for an enum name. 3497210299Sed Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); 3498226633Sdim return cutOffParsing(); 3499198092Srdivacky } 3500224145Sdim 3501239462Sdim // If attributes exist after tag, parse them. 3502239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3503239462Sdim MaybeParseGNUAttributes(attrs); 3504249423Sdim MaybeParseCXX11Attributes(attrs); 3505239462Sdim 3506239462Sdim // If declspecs exist after tag, parse them. 3507239462Sdim while (Tok.is(tok::kw___declspec)) 3508239462Sdim ParseMicrosoftDeclSpec(attrs); 3509239462Sdim 3510234353Sdim SourceLocation ScopedEnumKWLoc; 3511224145Sdim bool IsScopedUsingClassTag = false; 3512224145Sdim 3513239462Sdim // In C++11, recognize 'enum class' and 'enum struct'. 3514251662Sdim if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) { 3515251662Sdim Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum 3516251662Sdim : diag::ext_scoped_enum); 3517224145Sdim IsScopedUsingClassTag = Tok.is(tok::kw_class); 3518234353Sdim ScopedEnumKWLoc = ConsumeToken(); 3519234353Sdim 3520239462Sdim // Attributes are not allowed between these keywords. Diagnose, 3521239462Sdim // but then just treat them like they appeared in the right place. 3522239462Sdim ProhibitAttributes(attrs); 3523234353Sdim 3524239462Sdim // They are allowed afterwards, though. 3525239462Sdim MaybeParseGNUAttributes(attrs); 3526249423Sdim MaybeParseCXX11Attributes(attrs); 3527239462Sdim while (Tok.is(tok::kw___declspec)) 3528239462Sdim ParseMicrosoftDeclSpec(attrs); 3529239462Sdim } 3530193326Sed 3531239462Sdim // C++11 [temp.explicit]p12: 3532239462Sdim // The usual access controls do not apply to names used to specify 3533239462Sdim // explicit instantiations. 3534239462Sdim // We extend this to also cover explicit specializations. Note that 3535239462Sdim // we don't suppress if this turns out to be an elaborated type 3536239462Sdim // specifier. 3537239462Sdim bool shouldDelayDiagsInTag = 3538239462Sdim (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 3539239462Sdim TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 3540239462Sdim SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 3541224145Sdim 3542234353Sdim // Enum definitions should not be parsed in a trailing-return-type. 3543234353Sdim bool AllowDeclaration = DSC != DSC_trailing; 3544234353Sdim 3545234353Sdim bool AllowFixedUnderlyingType = AllowDeclaration && 3546249423Sdim (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt || 3547234353Sdim getLangOpts().ObjC2); 3548234353Sdim 3549208600Srdivacky CXXScopeSpec &SS = DS.getTypeSpecScope(); 3550234353Sdim if (getLangOpts().CPlusPlus) { 3551224145Sdim // "enum foo : bar;" is not a potential typo for "enum foo::bar;" 3552224145Sdim // if a fixed underlying type is allowed. 3553224145Sdim ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); 3554239462Sdim 3555239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3556249423Sdim /*EnteringContext=*/true)) 3557204643Srdivacky return; 3558204643Srdivacky 3559204643Srdivacky if (SS.isSet() && Tok.isNot(tok::identifier)) { 3560193326Sed Diag(Tok, diag::err_expected_ident); 3561193326Sed if (Tok.isNot(tok::l_brace)) { 3562193326Sed // Has no name and is not a definition. 3563193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3564263508Sdim SkipUntil(tok::comma, StopAtSemi); 3565193326Sed return; 3566193326Sed } 3567193326Sed } 3568193326Sed } 3569198092Srdivacky 3570193326Sed // Must have either 'enum name' or 'enum {...}'. 3571219077Sdim if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && 3572234353Sdim !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { 3573193326Sed Diag(Tok, diag::err_expected_ident_lbrace); 3574198092Srdivacky 3575193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3576263508Sdim SkipUntil(tok::comma, StopAtSemi); 3577193326Sed return; 3578193326Sed } 3579198092Srdivacky 3580193326Sed // If an identifier is present, consume and remember it. 3581193326Sed IdentifierInfo *Name = 0; 3582193326Sed SourceLocation NameLoc; 3583193326Sed if (Tok.is(tok::identifier)) { 3584193326Sed Name = Tok.getIdentifierInfo(); 3585193326Sed NameLoc = ConsumeToken(); 3586193326Sed } 3587198092Srdivacky 3588234353Sdim if (!Name && ScopedEnumKWLoc.isValid()) { 3589218893Sdim // C++0x 7.2p2: The optional identifier shall not be omitted in the 3590218893Sdim // declaration of a scoped enumeration. 3591218893Sdim Diag(Tok, diag::err_scoped_enum_missing_identifier); 3592234353Sdim ScopedEnumKWLoc = SourceLocation(); 3593218893Sdim IsScopedUsingClassTag = false; 3594218893Sdim } 3595218893Sdim 3596239462Sdim // Okay, end the suppression area. We'll decide whether to emit the 3597239462Sdim // diagnostics in a second. 3598239462Sdim if (shouldDelayDiagsInTag) 3599239462Sdim diagsFromTag.done(); 3600234353Sdim 3601218893Sdim TypeResult BaseType; 3602218893Sdim 3603218893Sdim // Parse the fixed underlying type. 3604239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3605219077Sdim if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { 3606218893Sdim bool PossibleBitfield = false; 3607239462Sdim if (CanBeBitfield) { 3608218893Sdim // If we're in class scope, this can either be an enum declaration with 3609218893Sdim // an underlying type, or a declaration of a bitfield member. We try to 3610218893Sdim // use a simple disambiguation scheme first to catch the common cases 3611239462Sdim // (integer literal, sizeof); if it's still ambiguous, we then consider 3612239462Sdim // anything that's a simple-type-specifier followed by '(' as an 3613239462Sdim // expression. This suffices because function types are not valid 3614218893Sdim // underlying types anyway. 3615243830Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 3616243830Sdim Sema::ConstantEvaluated); 3617218893Sdim TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind()); 3618239462Sdim // If the next token starts an expression, we know we're parsing a 3619218893Sdim // bit-field. This is the common case. 3620218893Sdim if (TPR == TPResult::True()) 3621218893Sdim PossibleBitfield = true; 3622218893Sdim // If the next token starts a type-specifier-seq, it may be either a 3623218893Sdim // a fixed underlying type or the start of a function-style cast in C++; 3624239462Sdim // lookahead one more token to see if it's obvious that we have a 3625218893Sdim // fixed underlying type. 3626239462Sdim else if (TPR == TPResult::False() && 3627218893Sdim GetLookAheadToken(2).getKind() == tok::semi) { 3628218893Sdim // Consume the ':'. 3629218893Sdim ConsumeToken(); 3630218893Sdim } else { 3631218893Sdim // We have the start of a type-specifier-seq, so we have to perform 3632218893Sdim // tentative parsing to determine whether we have an expression or a 3633218893Sdim // type. 3634218893Sdim TentativeParsingAction TPA(*this); 3635218893Sdim 3636218893Sdim // Consume the ':'. 3637218893Sdim ConsumeToken(); 3638234353Sdim 3639234353Sdim // If we see a type specifier followed by an open-brace, we have an 3640234353Sdim // ambiguity between an underlying type and a C++11 braced 3641234353Sdim // function-style cast. Resolve this by always treating it as an 3642234353Sdim // underlying type. 3643234353Sdim // FIXME: The standard is not entirely clear on how to disambiguate in 3644234353Sdim // this case. 3645234353Sdim if ((getLangOpts().CPlusPlus && 3646234353Sdim isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) || 3647234353Sdim (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) { 3648218893Sdim // We'll parse this as a bitfield later. 3649218893Sdim PossibleBitfield = true; 3650218893Sdim TPA.Revert(); 3651218893Sdim } else { 3652218893Sdim // We have a type-specifier-seq. 3653218893Sdim TPA.Commit(); 3654218893Sdim } 3655218893Sdim } 3656218893Sdim } else { 3657218893Sdim // Consume the ':'. 3658218893Sdim ConsumeToken(); 3659218893Sdim } 3660218893Sdim 3661218893Sdim if (!PossibleBitfield) { 3662218893Sdim SourceRange Range; 3663218893Sdim BaseType = ParseTypeName(&Range); 3664239462Sdim 3665249423Sdim if (getLangOpts().CPlusPlus11) { 3666234353Sdim Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type); 3667243830Sdim } else if (!getLangOpts().ObjC2) { 3668243830Sdim if (getLangOpts().CPlusPlus) 3669243830Sdim Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range; 3670243830Sdim else 3671243830Sdim Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range; 3672243830Sdim } 3673218893Sdim } 3674218893Sdim } 3675218893Sdim 3676234353Sdim // There are four options here. If we have 'friend enum foo;' then this is a 3677234353Sdim // friend declaration, and cannot have an accompanying definition. If we have 3678234353Sdim // 'enum foo;', then this is a forward declaration. If we have 3679234353Sdim // 'enum foo {...' then this is a definition. Otherwise we have something 3680234353Sdim // like 'enum foo xyz', a reference. 3681193326Sed // 3682193326Sed // This is needed to handle stuff like this right (C99 6.7.2.3p11): 3683193326Sed // enum foo {..}; void bar() { enum foo; } <- new foo in bar. 3684193326Sed // enum foo {..}; void bar() { enum foo x; } <- use of old foo. 3685193326Sed // 3686212904Sdim Sema::TagUseKind TUK; 3687239462Sdim if (!AllowDeclaration) { 3688234353Sdim TUK = Sema::TUK_Reference; 3689239462Sdim } else if (Tok.is(tok::l_brace)) { 3690239462Sdim if (DS.isFriendSpecified()) { 3691239462Sdim Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 3692239462Sdim << SourceRange(DS.getFriendSpecLoc()); 3693239462Sdim ConsumeBrace(); 3694263508Sdim SkipUntil(tok::r_brace, StopAtSemi); 3695239462Sdim TUK = Sema::TUK_Friend; 3696239462Sdim } else { 3697239462Sdim TUK = Sema::TUK_Definition; 3698239462Sdim } 3699239462Sdim } else if (DSC != DSC_type_specifier && 3700239462Sdim (Tok.is(tok::semi) || 3701239462Sdim (Tok.isAtStartOfLine() && 3702239462Sdim !isValidAfterTypeSpecifier(CanBeBitfield)))) { 3703239462Sdim TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 3704239462Sdim if (Tok.isNot(tok::semi)) { 3705239462Sdim // A semicolon was missing after this declaration. Diagnose and recover. 3706239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 3707239462Sdim "enum"); 3708239462Sdim PP.EnterToken(Tok); 3709239462Sdim Tok.setKind(tok::semi); 3710239462Sdim } 3711239462Sdim } else { 3712212904Sdim TUK = Sema::TUK_Reference; 3713239462Sdim } 3714234353Sdim 3715239462Sdim // If this is an elaborated type specifier, and we delayed 3716239462Sdim // diagnostics before, just merge them into the current pool. 3717239462Sdim if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) { 3718239462Sdim diagsFromTag.redelay(); 3719239462Sdim } 3720239462Sdim 3721234353Sdim MultiTemplateParamsArg TParams; 3722207619Srdivacky if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 3723212904Sdim TUK != Sema::TUK_Reference) { 3724249423Sdim if (!getLangOpts().CPlusPlus11 || !SS.isSet()) { 3725234353Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3726234353Sdim Diag(Tok, diag::err_enum_template); 3727263508Sdim SkipUntil(tok::comma, StopAtSemi); 3728234353Sdim return; 3729234353Sdim } 3730234353Sdim 3731234353Sdim if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 3732234353Sdim // Enumerations can't be explicitly instantiated. 3733234353Sdim DS.SetTypeSpecError(); 3734234353Sdim Diag(StartLoc, diag::err_explicit_instantiation_enum); 3735234353Sdim return; 3736234353Sdim } 3737234353Sdim 3738234353Sdim assert(TemplateInfo.TemplateParams && "no template parameters"); 3739234353Sdim TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(), 3740234353Sdim TemplateInfo.TemplateParams->size()); 3741207619Srdivacky } 3742234353Sdim 3743239462Sdim if (TUK == Sema::TUK_Reference) 3744239462Sdim ProhibitAttributes(attrs); 3745239462Sdim 3746219077Sdim if (!Name && TUK != Sema::TUK_Definition) { 3747219077Sdim Diag(Tok, diag::err_enumerator_unnamed_no_def); 3748234353Sdim 3749219077Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3750263508Sdim SkipUntil(tok::comma, StopAtSemi); 3751219077Sdim return; 3752219077Sdim } 3753234353Sdim 3754193326Sed bool Owned = false; 3755198092Srdivacky bool IsDependent = false; 3756207619Srdivacky const char *PrevSpec = 0; 3757207619Srdivacky unsigned DiagID; 3758212904Sdim Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, 3759218893Sdim StartLoc, SS, Name, NameLoc, attrs.getList(), 3760234353Sdim AS, DS.getModulePrivateSpecLoc(), TParams, 3761234353Sdim Owned, IsDependent, ScopedEnumKWLoc, 3762218893Sdim IsScopedUsingClassTag, BaseType); 3763218893Sdim 3764207619Srdivacky if (IsDependent) { 3765239462Sdim // This enum has a dependent nested-name-specifier. Handle it as a 3766207619Srdivacky // dependent tag. 3767207619Srdivacky if (!Name) { 3768207619Srdivacky DS.SetTypeSpecError(); 3769207619Srdivacky Diag(Tok, diag::err_expected_type_name_after_typename); 3770207619Srdivacky return; 3771207619Srdivacky } 3772239462Sdim 3773210299Sed TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum, 3774239462Sdim TUK, SS, Name, StartLoc, 3775207619Srdivacky NameLoc); 3776207619Srdivacky if (Type.isInvalid()) { 3777207619Srdivacky DS.SetTypeSpecError(); 3778207619Srdivacky return; 3779207619Srdivacky } 3780239462Sdim 3781221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 3782221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3783221345Sdim PrevSpec, DiagID, Type.get())) 3784207619Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3785239462Sdim 3786207619Srdivacky return; 3787207619Srdivacky } 3788198092Srdivacky 3789212904Sdim if (!TagDecl) { 3790239462Sdim // The action failed to produce an enumeration tag. If this is a 3791207619Srdivacky // definition, consume the entire definition. 3792234353Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 3793207619Srdivacky ConsumeBrace(); 3794263508Sdim SkipUntil(tok::r_brace, StopAtSemi); 3795207619Srdivacky } 3796239462Sdim 3797207619Srdivacky DS.SetTypeSpecError(); 3798207619Srdivacky return; 3799207619Srdivacky } 3800198092Srdivacky 3801239462Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) 3802239462Sdim ParseEnumBody(StartLoc, TagDecl); 3803234353Sdim 3804221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, 3805221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3806221345Sdim PrevSpec, DiagID, TagDecl, Owned)) 3807198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3808193326Sed} 3809193326Sed 3810193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list. 3811193326Sed/// enumerator-list: 3812193326Sed/// enumerator 3813193326Sed/// enumerator-list ',' enumerator 3814193326Sed/// enumerator: 3815193326Sed/// enumeration-constant 3816193326Sed/// enumeration-constant '=' constant-expression 3817193326Sed/// enumeration-constant: 3818193326Sed/// identifier 3819193326Sed/// 3820212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { 3821193326Sed // Enter the scope of the enum body and start the definition. 3822193326Sed ParseScope EnumScope(this, Scope::DeclScope); 3823210299Sed Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); 3824193326Sed 3825226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3826226633Sdim T.consumeOpen(); 3827198092Srdivacky 3828193326Sed // C does not allow an empty enumerator-list, C++ does [dcl.enum]. 3829234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) 3830210299Sed Diag(Tok, diag::error_empty_enum); 3831198092Srdivacky 3832226633Sdim SmallVector<Decl *, 32> EnumConstantDecls; 3833193326Sed 3834212904Sdim Decl *LastEnumConstDecl = 0; 3835198092Srdivacky 3836193326Sed // Parse the enumerator-list. 3837193326Sed while (Tok.is(tok::identifier)) { 3838193326Sed IdentifierInfo *Ident = Tok.getIdentifierInfo(); 3839193326Sed SourceLocation IdentLoc = ConsumeToken(); 3840198092Srdivacky 3841218893Sdim // If attributes exist after the enumerator, parse them. 3842239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3843218893Sdim MaybeParseGNUAttributes(attrs); 3844249423Sdim MaybeParseCXX11Attributes(attrs); 3845239462Sdim ProhibitAttributes(attrs); 3846218893Sdim 3847193326Sed SourceLocation EqualLoc; 3848212904Sdim ExprResult AssignedVal; 3849239462Sdim ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); 3850239462Sdim 3851193326Sed if (Tok.is(tok::equal)) { 3852193326Sed EqualLoc = ConsumeToken(); 3853193326Sed AssignedVal = ParseConstantExpression(); 3854193326Sed if (AssignedVal.isInvalid()) 3855263508Sdim SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch); 3856193326Sed } 3857198092Srdivacky 3858193326Sed // Install the enumerator constant into EnumDecl. 3859212904Sdim Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, 3860212904Sdim LastEnumConstDecl, 3861212904Sdim IdentLoc, Ident, 3862218893Sdim attrs.getList(), EqualLoc, 3863212904Sdim AssignedVal.release()); 3864234353Sdim PD.complete(EnumConstDecl); 3865239462Sdim 3866193326Sed EnumConstantDecls.push_back(EnumConstDecl); 3867193326Sed LastEnumConstDecl = EnumConstDecl; 3868198092Srdivacky 3869218893Sdim if (Tok.is(tok::identifier)) { 3870218893Sdim // We're missing a comma between enumerators. 3871218893Sdim SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 3872239462Sdim Diag(Loc, diag::err_enumerator_list_missing_comma) 3873218893Sdim << FixItHint::CreateInsertion(Loc, ", "); 3874218893Sdim continue; 3875218893Sdim } 3876239462Sdim 3877193326Sed if (Tok.isNot(tok::comma)) 3878193326Sed break; 3879193326Sed SourceLocation CommaLoc = ConsumeToken(); 3880198092Srdivacky 3881234353Sdim if (Tok.isNot(tok::identifier)) { 3882249423Sdim if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) 3883239462Sdim Diag(CommaLoc, getLangOpts().CPlusPlus ? 3884239462Sdim diag::ext_enumerator_list_comma_cxx : 3885239462Sdim diag::ext_enumerator_list_comma_c) 3886234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3887249423Sdim else if (getLangOpts().CPlusPlus11) 3888234353Sdim Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma) 3889234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3890234353Sdim } 3891193326Sed } 3892198092Srdivacky 3893193326Sed // Eat the }. 3894226633Sdim T.consumeClose(); 3895193326Sed 3896193326Sed // If attributes exist after the identifier list, parse them. 3897221345Sdim ParsedAttributes attrs(AttrFactory); 3898218893Sdim MaybeParseGNUAttributes(attrs); 3899193326Sed 3900226633Sdim Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), 3901251662Sdim EnumDecl, EnumConstantDecls, 3902251662Sdim getCurScope(), 3903226633Sdim attrs.getList()); 3904198092Srdivacky 3905193326Sed EnumScope.Exit(); 3906226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, 3907226633Sdim T.getCloseLocation()); 3908239462Sdim 3909239462Sdim // The next token must be valid after an enum definition. If not, a ';' 3910239462Sdim // was probably forgotten. 3911239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3912239462Sdim if (!isValidAfterTypeSpecifier(CanBeBitfield)) { 3913239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum"); 3914239462Sdim // Push this token back into the preprocessor and change our current token 3915239462Sdim // to ';' so that the rest of the code recovers as though there were an 3916239462Sdim // ';' after the definition. 3917239462Sdim PP.EnterToken(Tok); 3918239462Sdim Tok.setKind(tok::semi); 3919239462Sdim } 3920193326Sed} 3921193326Sed 3922193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3923193326Sed/// start of a type-qualifier-list. 3924193326Sedbool Parser::isTypeQualifier() const { 3925193326Sed switch (Tok.getKind()) { 3926193326Sed default: return false; 3927221345Sdim 3928221345Sdim // type-qualifier only in OpenCL 3929221345Sdim case tok::kw_private: 3930234353Sdim return getLangOpts().OpenCL; 3931221345Sdim 3932193326Sed // type-qualifier 3933193326Sed case tok::kw_const: 3934193326Sed case tok::kw_volatile: 3935193326Sed case tok::kw_restrict: 3936221345Sdim case tok::kw___private: 3937221345Sdim case tok::kw___local: 3938221345Sdim case tok::kw___global: 3939221345Sdim case tok::kw___constant: 3940221345Sdim case tok::kw___read_only: 3941221345Sdim case tok::kw___read_write: 3942221345Sdim case tok::kw___write_only: 3943193326Sed return true; 3944193326Sed } 3945193326Sed} 3946193326Sed 3947204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token 3948204643Srdivacky/// is definitely a type-specifier. Return false if it isn't part of a type 3949204643Srdivacky/// specifier or if we're not sure. 3950204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { 3951204643Srdivacky switch (Tok.getKind()) { 3952204643Srdivacky default: return false; 3953204643Srdivacky // type-specifiers 3954204643Srdivacky case tok::kw_short: 3955204643Srdivacky case tok::kw_long: 3956221345Sdim case tok::kw___int64: 3957234353Sdim case tok::kw___int128: 3958204643Srdivacky case tok::kw_signed: 3959204643Srdivacky case tok::kw_unsigned: 3960204643Srdivacky case tok::kw__Complex: 3961204643Srdivacky case tok::kw__Imaginary: 3962204643Srdivacky case tok::kw_void: 3963204643Srdivacky case tok::kw_char: 3964204643Srdivacky case tok::kw_wchar_t: 3965204643Srdivacky case tok::kw_char16_t: 3966204643Srdivacky case tok::kw_char32_t: 3967204643Srdivacky case tok::kw_int: 3968226633Sdim case tok::kw_half: 3969204643Srdivacky case tok::kw_float: 3970204643Srdivacky case tok::kw_double: 3971204643Srdivacky case tok::kw_bool: 3972204643Srdivacky case tok::kw__Bool: 3973204643Srdivacky case tok::kw__Decimal32: 3974204643Srdivacky case tok::kw__Decimal64: 3975204643Srdivacky case tok::kw__Decimal128: 3976204643Srdivacky case tok::kw___vector: 3977239462Sdim 3978249423Sdim // OpenCL specific types: 3979249423Sdim case tok::kw_image1d_t: 3980249423Sdim case tok::kw_image1d_array_t: 3981249423Sdim case tok::kw_image1d_buffer_t: 3982249423Sdim case tok::kw_image2d_t: 3983249423Sdim case tok::kw_image2d_array_t: 3984249423Sdim case tok::kw_image3d_t: 3985249423Sdim case tok::kw_sampler_t: 3986249423Sdim case tok::kw_event_t: 3987249423Sdim 3988204643Srdivacky // struct-or-union-specifier (C99) or class-specifier (C++) 3989204643Srdivacky case tok::kw_class: 3990204643Srdivacky case tok::kw_struct: 3991243830Sdim case tok::kw___interface: 3992204643Srdivacky case tok::kw_union: 3993204643Srdivacky // enum-specifier 3994204643Srdivacky case tok::kw_enum: 3995239462Sdim 3996204643Srdivacky // typedef-name 3997204643Srdivacky case tok::annot_typename: 3998204643Srdivacky return true; 3999204643Srdivacky } 4000204643Srdivacky} 4001204643Srdivacky 4002193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 4003193326Sed/// start of a specifier-qualifier-list. 4004193326Sedbool Parser::isTypeSpecifierQualifier() { 4005193326Sed switch (Tok.getKind()) { 4006193326Sed default: return false; 4007198092Srdivacky 4008193326Sed case tok::identifier: // foo::bar 4009203955Srdivacky if (TryAltiVecVectorToken()) 4010203955Srdivacky return true; 4011203955Srdivacky // Fall through. 4012193326Sed case tok::kw_typename: // typename T::type 4013193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 4014193326Sed // recurse to handle whatever we get. 4015193326Sed if (TryAnnotateTypeOrScopeToken()) 4016204643Srdivacky return true; 4017204643Srdivacky if (Tok.is(tok::identifier)) 4018204643Srdivacky return false; 4019204643Srdivacky return isTypeSpecifierQualifier(); 4020193326Sed 4021193326Sed case tok::coloncolon: // ::foo::bar 4022193326Sed if (NextToken().is(tok::kw_new) || // ::new 4023193326Sed NextToken().is(tok::kw_delete)) // ::delete 4024193326Sed return false; 4025193326Sed 4026193326Sed if (TryAnnotateTypeOrScopeToken()) 4027204643Srdivacky return true; 4028204643Srdivacky return isTypeSpecifierQualifier(); 4029198092Srdivacky 4030193326Sed // GNU attributes support. 4031193326Sed case tok::kw___attribute: 4032193326Sed // GNU typeof support. 4033193326Sed case tok::kw_typeof: 4034198092Srdivacky 4035193326Sed // type-specifiers 4036193326Sed case tok::kw_short: 4037193326Sed case tok::kw_long: 4038221345Sdim case tok::kw___int64: 4039234353Sdim case tok::kw___int128: 4040193326Sed case tok::kw_signed: 4041193326Sed case tok::kw_unsigned: 4042193326Sed case tok::kw__Complex: 4043193326Sed case tok::kw__Imaginary: 4044193326Sed case tok::kw_void: 4045193326Sed case tok::kw_char: 4046193326Sed case tok::kw_wchar_t: 4047198092Srdivacky case tok::kw_char16_t: 4048198092Srdivacky case tok::kw_char32_t: 4049193326Sed case tok::kw_int: 4050226633Sdim case tok::kw_half: 4051193326Sed case tok::kw_float: 4052193326Sed case tok::kw_double: 4053193326Sed case tok::kw_bool: 4054193326Sed case tok::kw__Bool: 4055193326Sed case tok::kw__Decimal32: 4056193326Sed case tok::kw__Decimal64: 4057193326Sed case tok::kw__Decimal128: 4058203955Srdivacky case tok::kw___vector: 4059198092Srdivacky 4060249423Sdim // OpenCL specific types: 4061249423Sdim case tok::kw_image1d_t: 4062249423Sdim case tok::kw_image1d_array_t: 4063249423Sdim case tok::kw_image1d_buffer_t: 4064249423Sdim case tok::kw_image2d_t: 4065249423Sdim case tok::kw_image2d_array_t: 4066249423Sdim case tok::kw_image3d_t: 4067249423Sdim case tok::kw_sampler_t: 4068249423Sdim case tok::kw_event_t: 4069249423Sdim 4070193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 4071193326Sed case tok::kw_class: 4072193326Sed case tok::kw_struct: 4073243830Sdim case tok::kw___interface: 4074193326Sed case tok::kw_union: 4075193326Sed // enum-specifier 4076193326Sed case tok::kw_enum: 4077198092Srdivacky 4078193326Sed // type-qualifier 4079193326Sed case tok::kw_const: 4080193326Sed case tok::kw_volatile: 4081193326Sed case tok::kw_restrict: 4082193326Sed 4083249423Sdim // Debugger support. 4084249423Sdim case tok::kw___unknown_anytype: 4085249423Sdim 4086193326Sed // typedef-name 4087193326Sed case tok::annot_typename: 4088193326Sed return true; 4089198092Srdivacky 4090193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 4091193326Sed case tok::less: 4092234353Sdim return getLangOpts().ObjC1; 4093198092Srdivacky 4094193326Sed case tok::kw___cdecl: 4095193326Sed case tok::kw___stdcall: 4096193326Sed case tok::kw___fastcall: 4097208600Srdivacky case tok::kw___thiscall: 4098194179Sed case tok::kw___w64: 4099194179Sed case tok::kw___ptr64: 4100226633Sdim case tok::kw___ptr32: 4101212904Sdim case tok::kw___pascal: 4102226633Sdim case tok::kw___unaligned: 4103221345Sdim 4104221345Sdim case tok::kw___private: 4105221345Sdim case tok::kw___local: 4106221345Sdim case tok::kw___global: 4107221345Sdim case tok::kw___constant: 4108221345Sdim case tok::kw___read_only: 4109221345Sdim case tok::kw___read_write: 4110221345Sdim case tok::kw___write_only: 4111221345Sdim 4112194179Sed return true; 4113221345Sdim 4114221345Sdim case tok::kw_private: 4115234353Sdim return getLangOpts().OpenCL; 4116226633Sdim 4117249423Sdim // C11 _Atomic 4118226633Sdim case tok::kw__Atomic: 4119226633Sdim return true; 4120193326Sed } 4121193326Sed} 4122193326Sed 4123193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a 4124193326Sed/// declaration specifier. 4125218893Sdim/// 4126218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of 4127218893Sdim/// this check is to disambiguate between an expression and a declaration. 4128218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { 4129193326Sed switch (Tok.getKind()) { 4130193326Sed default: return false; 4131198092Srdivacky 4132221345Sdim case tok::kw_private: 4133234353Sdim return getLangOpts().OpenCL; 4134221345Sdim 4135193326Sed case tok::identifier: // foo::bar 4136193326Sed // Unfortunate hack to support "Class.factoryMethod" notation. 4137234353Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::period)) 4138193326Sed return false; 4139203955Srdivacky if (TryAltiVecVectorToken()) 4140203955Srdivacky return true; 4141203955Srdivacky // Fall through. 4142234353Sdim case tok::kw_decltype: // decltype(T())::type 4143193326Sed case tok::kw_typename: // typename T::type 4144193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 4145193326Sed // recurse to handle whatever we get. 4146193326Sed if (TryAnnotateTypeOrScopeToken()) 4147204643Srdivacky return true; 4148204643Srdivacky if (Tok.is(tok::identifier)) 4149204643Srdivacky return false; 4150239462Sdim 4151218893Sdim // If we're in Objective-C and we have an Objective-C class type followed 4152239462Sdim // by an identifier and then either ':' or ']', in a place where an 4153218893Sdim // expression is permitted, then this is probably a class message send 4154218893Sdim // missing the initial '['. In this case, we won't consider this to be 4155218893Sdim // the start of a declaration. 4156239462Sdim if (DisambiguatingWithExpression && 4157218893Sdim isStartOfObjCClassMessageMissingOpenBracket()) 4158218893Sdim return false; 4159239462Sdim 4160204643Srdivacky return isDeclarationSpecifier(); 4161204643Srdivacky 4162193326Sed case tok::coloncolon: // ::foo::bar 4163193326Sed if (NextToken().is(tok::kw_new) || // ::new 4164193326Sed NextToken().is(tok::kw_delete)) // ::delete 4165193326Sed return false; 4166198092Srdivacky 4167193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 4168193326Sed // recurse to handle whatever we get. 4169193326Sed if (TryAnnotateTypeOrScopeToken()) 4170204643Srdivacky return true; 4171204643Srdivacky return isDeclarationSpecifier(); 4172198092Srdivacky 4173193326Sed // storage-class-specifier 4174193326Sed case tok::kw_typedef: 4175193326Sed case tok::kw_extern: 4176193326Sed case tok::kw___private_extern__: 4177193326Sed case tok::kw_static: 4178193326Sed case tok::kw_auto: 4179193326Sed case tok::kw_register: 4180193326Sed case tok::kw___thread: 4181251662Sdim case tok::kw_thread_local: 4182251662Sdim case tok::kw__Thread_local: 4183198092Srdivacky 4184226633Sdim // Modules 4185226633Sdim case tok::kw___module_private__: 4186239462Sdim 4187249423Sdim // Debugger support 4188249423Sdim case tok::kw___unknown_anytype: 4189249423Sdim 4190193326Sed // type-specifiers 4191193326Sed case tok::kw_short: 4192193326Sed case tok::kw_long: 4193221345Sdim case tok::kw___int64: 4194234353Sdim case tok::kw___int128: 4195193326Sed case tok::kw_signed: 4196193326Sed case tok::kw_unsigned: 4197193326Sed case tok::kw__Complex: 4198193326Sed case tok::kw__Imaginary: 4199193326Sed case tok::kw_void: 4200193326Sed case tok::kw_char: 4201193326Sed case tok::kw_wchar_t: 4202198092Srdivacky case tok::kw_char16_t: 4203198092Srdivacky case tok::kw_char32_t: 4204198092Srdivacky 4205193326Sed case tok::kw_int: 4206226633Sdim case tok::kw_half: 4207193326Sed case tok::kw_float: 4208193326Sed case tok::kw_double: 4209193326Sed case tok::kw_bool: 4210193326Sed case tok::kw__Bool: 4211193326Sed case tok::kw__Decimal32: 4212193326Sed case tok::kw__Decimal64: 4213193326Sed case tok::kw__Decimal128: 4214203955Srdivacky case tok::kw___vector: 4215198092Srdivacky 4216249423Sdim // OpenCL specific types: 4217249423Sdim case tok::kw_image1d_t: 4218249423Sdim case tok::kw_image1d_array_t: 4219249423Sdim case tok::kw_image1d_buffer_t: 4220249423Sdim case tok::kw_image2d_t: 4221249423Sdim case tok::kw_image2d_array_t: 4222249423Sdim case tok::kw_image3d_t: 4223249423Sdim case tok::kw_sampler_t: 4224249423Sdim case tok::kw_event_t: 4225249423Sdim 4226193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 4227193326Sed case tok::kw_class: 4228193326Sed case tok::kw_struct: 4229193326Sed case tok::kw_union: 4230243830Sdim case tok::kw___interface: 4231193326Sed // enum-specifier 4232193326Sed case tok::kw_enum: 4233198092Srdivacky 4234193326Sed // type-qualifier 4235193326Sed case tok::kw_const: 4236193326Sed case tok::kw_volatile: 4237193326Sed case tok::kw_restrict: 4238193326Sed 4239193326Sed // function-specifier 4240193326Sed case tok::kw_inline: 4241193326Sed case tok::kw_virtual: 4242193326Sed case tok::kw_explicit: 4243249423Sdim case tok::kw__Noreturn: 4244193326Sed 4245249423Sdim // alignment-specifier 4246249423Sdim case tok::kw__Alignas: 4247249423Sdim 4248243830Sdim // friend keyword. 4249243830Sdim case tok::kw_friend: 4250243830Sdim 4251221345Sdim // static_assert-declaration 4252221345Sdim case tok::kw__Static_assert: 4253193326Sed 4254193326Sed // GNU typeof support. 4255193326Sed case tok::kw_typeof: 4256198092Srdivacky 4257193326Sed // GNU attributes. 4258193326Sed case tok::kw___attribute: 4259198092Srdivacky 4260243830Sdim // C++11 decltype and constexpr. 4261234353Sdim case tok::annot_decltype: 4262243830Sdim case tok::kw_constexpr: 4263224145Sdim 4264249423Sdim // C11 _Atomic 4265226633Sdim case tok::kw__Atomic: 4266226633Sdim return true; 4267226633Sdim 4268193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 4269193326Sed case tok::less: 4270234353Sdim return getLangOpts().ObjC1; 4271198092Srdivacky 4272221345Sdim // typedef-name 4273221345Sdim case tok::annot_typename: 4274221345Sdim return !DisambiguatingWithExpression || 4275221345Sdim !isStartOfObjCClassMessageMissingOpenBracket(); 4276239462Sdim 4277193326Sed case tok::kw___declspec: 4278193326Sed case tok::kw___cdecl: 4279193326Sed case tok::kw___stdcall: 4280193326Sed case tok::kw___fastcall: 4281208600Srdivacky case tok::kw___thiscall: 4282194179Sed case tok::kw___w64: 4283263508Sdim case tok::kw___sptr: 4284263508Sdim case tok::kw___uptr: 4285194179Sed case tok::kw___ptr64: 4286226633Sdim case tok::kw___ptr32: 4287194179Sed case tok::kw___forceinline: 4288212904Sdim case tok::kw___pascal: 4289226633Sdim case tok::kw___unaligned: 4290221345Sdim 4291221345Sdim case tok::kw___private: 4292221345Sdim case tok::kw___local: 4293221345Sdim case tok::kw___global: 4294221345Sdim case tok::kw___constant: 4295221345Sdim case tok::kw___read_only: 4296221345Sdim case tok::kw___read_write: 4297221345Sdim case tok::kw___write_only: 4298221345Sdim 4299194179Sed return true; 4300193326Sed } 4301193326Sed} 4302193326Sed 4303202379Srdivackybool Parser::isConstructorDeclarator() { 4304202379Srdivacky TentativeParsingAction TPA(*this); 4305193326Sed 4306202379Srdivacky // Parse the C++ scope specifier. 4307202379Srdivacky CXXScopeSpec SS; 4308239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 4309234353Sdim /*EnteringContext=*/true)) { 4310204643Srdivacky TPA.Revert(); 4311204643Srdivacky return false; 4312204643Srdivacky } 4313202379Srdivacky 4314202379Srdivacky // Parse the constructor name. 4315202379Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 4316202379Srdivacky // We already know that we have a constructor name; just consume 4317202379Srdivacky // the token. 4318202379Srdivacky ConsumeToken(); 4319202379Srdivacky } else { 4320202379Srdivacky TPA.Revert(); 4321202379Srdivacky return false; 4322202379Srdivacky } 4323202379Srdivacky 4324234353Sdim // Current class name must be followed by a left parenthesis. 4325202379Srdivacky if (Tok.isNot(tok::l_paren)) { 4326202379Srdivacky TPA.Revert(); 4327202379Srdivacky return false; 4328202379Srdivacky } 4329202379Srdivacky ConsumeParen(); 4330202379Srdivacky 4331234353Sdim // A right parenthesis, or ellipsis followed by a right parenthesis signals 4332234353Sdim // that we have a constructor. 4333234353Sdim if (Tok.is(tok::r_paren) || 4334234353Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) { 4335202379Srdivacky TPA.Revert(); 4336202379Srdivacky return true; 4337202379Srdivacky } 4338202379Srdivacky 4339263508Sdim // A C++11 attribute here signals that we have a constructor, and is an 4340263508Sdim // attribute on the first constructor parameter. 4341263508Sdim if (getLangOpts().CPlusPlus11 && 4342263508Sdim isCXX11AttributeSpecifier(/*Disambiguate*/ false, 4343263508Sdim /*OuterMightBeMessageSend*/ true)) { 4344263508Sdim TPA.Revert(); 4345263508Sdim return true; 4346263508Sdim } 4347263508Sdim 4348202379Srdivacky // If we need to, enter the specified scope. 4349202379Srdivacky DeclaratorScopeObj DeclScopeObj(*this, SS); 4350210299Sed if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 4351202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4352202379Srdivacky 4353218893Sdim // Optionally skip Microsoft attributes. 4354221345Sdim ParsedAttributes Attrs(AttrFactory); 4355218893Sdim MaybeParseMicrosoftAttributes(Attrs); 4356218893Sdim 4357202379Srdivacky // Check whether the next token(s) are part of a declaration 4358202379Srdivacky // specifier, in which case we have the start of a parameter and, 4359202379Srdivacky // therefore, we know that this is a constructor. 4360234353Sdim bool IsConstructor = false; 4361234353Sdim if (isDeclarationSpecifier()) 4362234353Sdim IsConstructor = true; 4363234353Sdim else if (Tok.is(tok::identifier) || 4364234353Sdim (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) { 4365234353Sdim // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type. 4366234353Sdim // This might be a parenthesized member name, but is more likely to 4367234353Sdim // be a constructor declaration with an invalid argument type. Keep 4368234353Sdim // looking. 4369234353Sdim if (Tok.is(tok::annot_cxxscope)) 4370234353Sdim ConsumeToken(); 4371234353Sdim ConsumeToken(); 4372234353Sdim 4373234353Sdim // If this is not a constructor, we must be parsing a declarator, 4374234353Sdim // which must have one of the following syntactic forms (see the 4375234353Sdim // grammar extract at the start of ParseDirectDeclarator): 4376234353Sdim switch (Tok.getKind()) { 4377234353Sdim case tok::l_paren: 4378234353Sdim // C(X ( int)); 4379234353Sdim case tok::l_square: 4380234353Sdim // C(X [ 5]); 4381234353Sdim // C(X [ [attribute]]); 4382234353Sdim case tok::coloncolon: 4383234353Sdim // C(X :: Y); 4384234353Sdim // C(X :: *p); 4385234353Sdim case tok::r_paren: 4386234353Sdim // C(X ) 4387234353Sdim // Assume this isn't a constructor, rather than assuming it's a 4388234353Sdim // constructor with an unnamed parameter of an ill-formed type. 4389234353Sdim break; 4390234353Sdim 4391234353Sdim default: 4392234353Sdim IsConstructor = true; 4393234353Sdim break; 4394234353Sdim } 4395234353Sdim } 4396234353Sdim 4397202379Srdivacky TPA.Revert(); 4398202379Srdivacky return IsConstructor; 4399202379Srdivacky} 4400202379Srdivacky 4401193326Sed/// ParseTypeQualifierListOpt 4402212904Sdim/// type-qualifier-list: [C99 6.7.5] 4403212904Sdim/// type-qualifier 4404239462Sdim/// [vendor] attributes 4405212904Sdim/// [ only if VendorAttributesAllowed=true ] 4406212904Sdim/// type-qualifier-list type-qualifier 4407239462Sdim/// [vendor] type-qualifier-list attributes 4408212904Sdim/// [ only if VendorAttributesAllowed=true ] 4409212904Sdim/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq 4410249423Sdim/// [ only if CXX11AttributesAllowed=true ] 4411212904Sdim/// Note: vendor can be GNU, MS, etc. 4412193326Sed/// 4413212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS, 4414212904Sdim bool VendorAttributesAllowed, 4415249423Sdim bool CXX11AttributesAllowed, 4416263508Sdim bool AtomicAllowed, 4417263508Sdim bool IdentifierRequired) { 4418249423Sdim if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && 4419234353Sdim isCXX11AttributeSpecifier()) { 4420221345Sdim ParsedAttributesWithRange attrs(AttrFactory); 4421234353Sdim ParseCXX11Attributes(attrs); 4422234353Sdim DS.takeAttributesFrom(attrs); 4423199990Srdivacky } 4424221345Sdim 4425221345Sdim SourceLocation EndLoc; 4426221345Sdim 4427193326Sed while (1) { 4428198092Srdivacky bool isInvalid = false; 4429193326Sed const char *PrevSpec = 0; 4430198092Srdivacky unsigned DiagID = 0; 4431193326Sed SourceLocation Loc = Tok.getLocation(); 4432193326Sed 4433193326Sed switch (Tok.getKind()) { 4434212904Sdim case tok::code_completion: 4435212904Sdim Actions.CodeCompleteTypeQualifiers(DS); 4436226633Sdim return cutOffParsing(); 4437239462Sdim 4438193326Sed case tok::kw_const: 4439198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, 4440243830Sdim getLangOpts()); 4441193326Sed break; 4442193326Sed case tok::kw_volatile: 4443198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 4444243830Sdim getLangOpts()); 4445193326Sed break; 4446193326Sed case tok::kw_restrict: 4447198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 4448243830Sdim getLangOpts()); 4449193326Sed break; 4450249423Sdim case tok::kw__Atomic: 4451249423Sdim if (!AtomicAllowed) 4452249423Sdim goto DoneWithTypeQuals; 4453249423Sdim isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 4454249423Sdim getLangOpts()); 4455249423Sdim break; 4456221345Sdim 4457221345Sdim // OpenCL qualifiers: 4458239462Sdim case tok::kw_private: 4459234353Sdim if (!getLangOpts().OpenCL) 4460221345Sdim goto DoneWithTypeQuals; 4461221345Sdim case tok::kw___private: 4462221345Sdim case tok::kw___global: 4463221345Sdim case tok::kw___local: 4464221345Sdim case tok::kw___constant: 4465221345Sdim case tok::kw___read_only: 4466221345Sdim case tok::kw___write_only: 4467221345Sdim case tok::kw___read_write: 4468221345Sdim ParseOpenCLQualifiers(DS); 4469221345Sdim break; 4470221345Sdim 4471263508Sdim case tok::kw___uptr: 4472263508Sdim // GNU libc headers in C mode use '__uptr' as an identifer which conflicts 4473263508Sdim // with the MS modifier keyword. 4474263508Sdim if (VendorAttributesAllowed && !getLangOpts().CPlusPlus && 4475263508Sdim IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) { 4476263508Sdim if (TryKeywordIdentFallback(false)) 4477263508Sdim continue; 4478263508Sdim } 4479263508Sdim case tok::kw___sptr: 4480194179Sed case tok::kw___w64: 4481193326Sed case tok::kw___ptr64: 4482226633Sdim case tok::kw___ptr32: 4483193326Sed case tok::kw___cdecl: 4484193326Sed case tok::kw___stdcall: 4485193326Sed case tok::kw___fastcall: 4486208600Srdivacky case tok::kw___thiscall: 4487226633Sdim case tok::kw___unaligned: 4488212904Sdim if (VendorAttributesAllowed) { 4489218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 4490194179Sed continue; 4491194179Sed } 4492194179Sed goto DoneWithTypeQuals; 4493212904Sdim case tok::kw___pascal: 4494212904Sdim if (VendorAttributesAllowed) { 4495218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 4496212904Sdim continue; 4497212904Sdim } 4498212904Sdim goto DoneWithTypeQuals; 4499193326Sed case tok::kw___attribute: 4500212904Sdim if (VendorAttributesAllowed) { 4501218893Sdim ParseGNUAttributes(DS.getAttributes()); 4502193326Sed continue; // do *not* consume the next token! 4503193326Sed } 4504193326Sed // otherwise, FALL THROUGH! 4505193326Sed default: 4506193326Sed DoneWithTypeQuals: 4507193326Sed // If this is not a type-qualifier token, we're done reading type 4508193326Sed // qualifiers. First verify that DeclSpec's are consistent. 4509193326Sed DS.Finish(Diags, PP); 4510221345Sdim if (EndLoc.isValid()) 4511221345Sdim DS.SetRangeEnd(EndLoc); 4512193326Sed return; 4513193326Sed } 4514193326Sed 4515193326Sed // If the specifier combination wasn't legal, issue a diagnostic. 4516193326Sed if (isInvalid) { 4517193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 4518193326Sed Diag(Tok, DiagID) << PrevSpec; 4519193326Sed } 4520221345Sdim EndLoc = ConsumeToken(); 4521193326Sed } 4522193326Sed} 4523193326Sed 4524193326Sed 4525193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator. 4526193326Sed/// 4527193326Sedvoid Parser::ParseDeclarator(Declarator &D) { 4528193326Sed /// This implements the 'declarator' production in the C grammar, then checks 4529193326Sed /// for well-formedness and issues diagnostics. 4530193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4531193326Sed} 4532193326Sed 4533234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { 4534234353Sdim if (Kind == tok::star || Kind == tok::caret) 4535234353Sdim return true; 4536234353Sdim 4537234353Sdim // We parse rvalue refs in C++03, because otherwise the errors are scary. 4538234353Sdim if (!Lang.CPlusPlus) 4539234353Sdim return false; 4540234353Sdim 4541234353Sdim return Kind == tok::amp || Kind == tok::ampamp; 4542234353Sdim} 4543234353Sdim 4544193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator 4545193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator 4546193326Sed/// isn't parsed at all, making this function effectively parse the C++ 4547193326Sed/// ptr-operator production. 4548193326Sed/// 4549234353Sdim/// If the grammar of this construct is extended, matching changes must also be 4550234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to 4551234353Sdim/// isConstructorDeclarator. 4552234353Sdim/// 4553193326Sed/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] 4554193326Sed/// [C] pointer[opt] direct-declarator 4555193326Sed/// [C++] direct-declarator 4556193326Sed/// [C++] ptr-operator declarator 4557193326Sed/// 4558193326Sed/// pointer: [C99 6.7.5] 4559193326Sed/// '*' type-qualifier-list[opt] 4560193326Sed/// '*' type-qualifier-list[opt] pointer 4561193326Sed/// 4562193326Sed/// ptr-operator: 4563193326Sed/// '*' cv-qualifier-seq[opt] 4564193326Sed/// '&' 4565193326Sed/// [C++0x] '&&' 4566193326Sed/// [GNU] '&' restrict[opt] attributes[opt] 4567193326Sed/// [GNU?] '&&' restrict[opt] attributes[opt] 4568193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4569193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D, 4570193326Sed DirectDeclParseFunction DirectDeclParser) { 4571198092Srdivacky if (Diags.hasAllExtensionsSilenced()) 4572198092Srdivacky D.setExtension(); 4573239462Sdim 4574193326Sed // C++ member pointers start with a '::' or a nested-name. 4575193326Sed // Member pointers get special handling, since there's no place for the 4576193326Sed // scope spec in the generic path below. 4577234353Sdim if (getLangOpts().CPlusPlus && 4578193326Sed (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || 4579193326Sed Tok.is(tok::annot_cxxscope))) { 4580234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4581234353Sdim D.getContext() == Declarator::MemberContext; 4582193326Sed CXXScopeSpec SS; 4583234353Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); 4584204643Srdivacky 4585207619Srdivacky if (SS.isNotEmpty()) { 4586198092Srdivacky if (Tok.isNot(tok::star)) { 4587193326Sed // The scope spec really belongs to the direct-declarator. 4588249423Sdim if (D.mayHaveIdentifier()) 4589249423Sdim D.getCXXScopeSpec() = SS; 4590249423Sdim else 4591249423Sdim AnnotateScopeToken(SS, true); 4592249423Sdim 4593193326Sed if (DirectDeclParser) 4594193326Sed (this->*DirectDeclParser)(D); 4595193326Sed return; 4596193326Sed } 4597193326Sed 4598193326Sed SourceLocation Loc = ConsumeToken(); 4599193326Sed D.SetRangeEnd(Loc); 4600221345Sdim DeclSpec DS(AttrFactory); 4601193326Sed ParseTypeQualifierListOpt(DS); 4602193326Sed D.ExtendWithDeclSpec(DS); 4603193326Sed 4604193326Sed // Recurse to parse whatever is left. 4605193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4606193326Sed 4607193326Sed // Sema will have to catch (syntactically invalid) pointers into global 4608193326Sed // scope. It has to catch pointers into namespace scope anyway. 4609193326Sed D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), 4610221345Sdim Loc), 4611221345Sdim DS.getAttributes(), 4612193326Sed /* Don't replace range end. */SourceLocation()); 4613193326Sed return; 4614193326Sed } 4615193326Sed } 4616193326Sed 4617193326Sed tok::TokenKind Kind = Tok.getKind(); 4618193326Sed // Not a pointer, C++ reference, or block. 4619234353Sdim if (!isPtrOperatorToken(Kind, getLangOpts())) { 4620193326Sed if (DirectDeclParser) 4621193326Sed (this->*DirectDeclParser)(D); 4622193326Sed return; 4623193326Sed } 4624193326Sed 4625193326Sed // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference, 4626193326Sed // '&&' -> rvalue reference 4627193326Sed SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. 4628193326Sed D.SetRangeEnd(Loc); 4629193326Sed 4630193326Sed if (Kind == tok::star || Kind == tok::caret) { 4631193326Sed // Is a pointer. 4632221345Sdim DeclSpec DS(AttrFactory); 4633193326Sed 4634234353Sdim // FIXME: GNU attributes are not allowed here in a new-type-id. 4635263508Sdim ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier()); 4636193326Sed D.ExtendWithDeclSpec(DS); 4637193326Sed 4638193326Sed // Recursively parse the declarator. 4639193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4640193326Sed if (Kind == tok::star) 4641193326Sed // Remember that we parsed a pointer type, and remember the type-quals. 4642193326Sed D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, 4643219077Sdim DS.getConstSpecLoc(), 4644219077Sdim DS.getVolatileSpecLoc(), 4645221345Sdim DS.getRestrictSpecLoc()), 4646221345Sdim DS.getAttributes(), 4647193326Sed SourceLocation()); 4648193326Sed else 4649193326Sed // Remember that we parsed a Block type, and remember the type-quals. 4650198092Srdivacky D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), 4651221345Sdim Loc), 4652221345Sdim DS.getAttributes(), 4653193326Sed SourceLocation()); 4654193326Sed } else { 4655193326Sed // Is a reference 4656221345Sdim DeclSpec DS(AttrFactory); 4657193326Sed 4658193326Sed // Complain about rvalue references in C++03, but then go on and build 4659193326Sed // the declarator. 4660234353Sdim if (Kind == tok::ampamp) 4661249423Sdim Diag(Loc, getLangOpts().CPlusPlus11 ? 4662234353Sdim diag::warn_cxx98_compat_rvalue_reference : 4663234353Sdim diag::ext_rvalue_reference); 4664193326Sed 4665234353Sdim // GNU-style and C++11 attributes are allowed here, as is restrict. 4666234353Sdim ParseTypeQualifierListOpt(DS); 4667234353Sdim D.ExtendWithDeclSpec(DS); 4668234353Sdim 4669193326Sed // C++ 8.3.2p1: cv-qualified references are ill-formed except when the 4670193326Sed // cv-qualifiers are introduced through the use of a typedef or of a 4671193326Sed // template type argument, in which case the cv-qualifiers are ignored. 4672193326Sed if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { 4673193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 4674193326Sed Diag(DS.getConstSpecLoc(), 4675193326Sed diag::err_invalid_reference_qualifier_application) << "const"; 4676193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) 4677193326Sed Diag(DS.getVolatileSpecLoc(), 4678193326Sed diag::err_invalid_reference_qualifier_application) << "volatile"; 4679249423Sdim // 'restrict' is permitted as an extension. 4680249423Sdim if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) 4681249423Sdim Diag(DS.getAtomicSpecLoc(), 4682249423Sdim diag::err_invalid_reference_qualifier_application) << "_Atomic"; 4683193326Sed } 4684193326Sed 4685193326Sed // Recursively parse the declarator. 4686193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4687193326Sed 4688193326Sed if (D.getNumTypeObjects() > 0) { 4689193326Sed // C++ [dcl.ref]p4: There shall be no references to references. 4690193326Sed DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1); 4691193326Sed if (InnerChunk.Kind == DeclaratorChunk::Reference) { 4692193326Sed if (const IdentifierInfo *II = D.getIdentifier()) 4693193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4694193326Sed << II; 4695193326Sed else 4696193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4697193326Sed << "type name"; 4698193326Sed 4699193326Sed // Once we've complained about the reference-to-reference, we 4700193326Sed // can go ahead and build the (technically ill-formed) 4701193326Sed // declarator: reference collapsing will take care of it. 4702193326Sed } 4703193326Sed } 4704193326Sed 4705249423Sdim // Remember that we parsed a reference type. 4706193326Sed D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, 4707193326Sed Kind == tok::amp), 4708221345Sdim DS.getAttributes(), 4709193326Sed SourceLocation()); 4710193326Sed } 4711193326Sed} 4712193326Sed 4713234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D, 4714234353Sdim SourceLocation EllipsisLoc) { 4715234353Sdim if (EllipsisLoc.isValid()) { 4716234353Sdim FixItHint Insertion; 4717234353Sdim if (!D.getEllipsisLoc().isValid()) { 4718234353Sdim Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "..."); 4719234353Sdim D.setEllipsisLoc(EllipsisLoc); 4720234353Sdim } 4721234353Sdim P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration) 4722234353Sdim << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName(); 4723234353Sdim } 4724234353Sdim} 4725234353Sdim 4726193326Sed/// ParseDirectDeclarator 4727193326Sed/// direct-declarator: [C99 6.7.5] 4728193326Sed/// [C99] identifier 4729193326Sed/// '(' declarator ')' 4730193326Sed/// [GNU] '(' attributes declarator ')' 4731193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 4732193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4733193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4734193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4735193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4736234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 4737234353Sdim/// attribute-specifier-seq[opt] 4738193326Sed/// direct-declarator '(' parameter-type-list ')' 4739193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4740193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4741193326Sed/// parameter-type-list[opt] ')' 4742193326Sed/// [C++] direct-declarator '(' parameter-declaration-clause ')' 4743193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 4744234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')' 4745234353Sdim/// attribute-specifier-seq[opt] cv-qualifier-seq[opt] 4746234353Sdim/// ref-qualifier[opt] exception-specification[opt] 4747193326Sed/// [C++] declarator-id 4748234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt] 4749193326Sed/// 4750193326Sed/// declarator-id: [C++ 8] 4751218893Sdim/// '...'[opt] id-expression 4752193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 4753193326Sed/// 4754193326Sed/// id-expression: [C++ 5.1] 4755193326Sed/// unqualified-id 4756198092Srdivacky/// qualified-id 4757193326Sed/// 4758193326Sed/// unqualified-id: [C++ 5.1] 4759198092Srdivacky/// identifier 4760193326Sed/// operator-function-id 4761198092Srdivacky/// conversion-function-id 4762198092Srdivacky/// '~' class-name 4763193326Sed/// template-id 4764193326Sed/// 4765234353Sdim/// Note, any additional constructs added here may need corresponding changes 4766234353Sdim/// in isConstructorDeclarator. 4767193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) { 4768193326Sed DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); 4769193326Sed 4770234353Sdim if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) { 4771198893Srdivacky // ParseDeclaratorInternal might already have parsed the scope. 4772207619Srdivacky if (D.getCXXScopeSpec().isEmpty()) { 4773234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4774234353Sdim D.getContext() == Declarator::MemberContext; 4775239462Sdim ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), 4776234353Sdim EnteringContext); 4777204643Srdivacky } 4778204643Srdivacky 4779207619Srdivacky if (D.getCXXScopeSpec().isValid()) { 4780210299Sed if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4781200583Srdivacky // Change the declaration context for name lookup, until this function 4782200583Srdivacky // is exited (and the declarator has been parsed). 4783200583Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4784207619Srdivacky } 4785207619Srdivacky 4786218893Sdim // C++0x [dcl.fct]p14: 4787218893Sdim // There is a syntactic ambiguity when an ellipsis occurs at the end 4788239462Sdim // of a parameter-declaration-clause without a preceding comma. In 4789239462Sdim // this case, the ellipsis is parsed as part of the 4790239462Sdim // abstract-declarator if the type of the parameter names a template 4791218893Sdim // parameter pack that has not been expanded; otherwise, it is parsed 4792218893Sdim // as part of the parameter-declaration-clause. 4793234353Sdim if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && 4794218893Sdim !((D.getContext() == Declarator::PrototypeContext || 4795263508Sdim D.getContext() == Declarator::LambdaExprParameterContext || 4796218893Sdim D.getContext() == Declarator::BlockLiteralContext) && 4797218893Sdim NextToken().is(tok::r_paren) && 4798249423Sdim !D.hasGroupingParens() && 4799234353Sdim !Actions.containsUnexpandedParameterPacks(D))) { 4800234353Sdim SourceLocation EllipsisLoc = ConsumeToken(); 4801234353Sdim if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { 4802234353Sdim // The ellipsis was put in the wrong place. Recover, and explain to 4803234353Sdim // the user what they should have done. 4804234353Sdim ParseDeclarator(D); 4805234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4806234353Sdim return; 4807234353Sdim } else 4808234353Sdim D.setEllipsisLoc(EllipsisLoc); 4809234353Sdim 4810234353Sdim // The ellipsis can't be followed by a parenthesized declarator. We 4811234353Sdim // check for that in ParseParenDeclarator, after we have disambiguated 4812234353Sdim // the l_paren token. 4813234353Sdim } 4814234353Sdim 4815198893Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 4816198893Srdivacky Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { 4817198893Srdivacky // We found something that indicates the start of an unqualified-id. 4818198893Srdivacky // Parse that unqualified-id. 4819207619Srdivacky bool AllowConstructorName; 4820207619Srdivacky if (D.getDeclSpec().hasTypeSpecifier()) 4821207619Srdivacky AllowConstructorName = false; 4822207619Srdivacky else if (D.getCXXScopeSpec().isSet()) 4823207619Srdivacky AllowConstructorName = 4824207619Srdivacky (D.getContext() == Declarator::FileContext || 4825249423Sdim D.getContext() == Declarator::MemberContext); 4826207619Srdivacky else 4827207619Srdivacky AllowConstructorName = (D.getContext() == Declarator::MemberContext); 4828207619Srdivacky 4829234353Sdim SourceLocation TemplateKWLoc; 4830239462Sdim if (ParseUnqualifiedId(D.getCXXScopeSpec(), 4831239462Sdim /*EnteringContext=*/true, 4832239462Sdim /*AllowDestructorName=*/true, 4833202379Srdivacky AllowConstructorName, 4834212904Sdim ParsedType(), 4835234353Sdim TemplateKWLoc, 4836207619Srdivacky D.getName()) || 4837207619Srdivacky // Once we're past the identifier, if the scope was bad, mark the 4838207619Srdivacky // whole declarator bad. 4839207619Srdivacky D.getCXXScopeSpec().isInvalid()) { 4840193326Sed D.SetIdentifier(0, Tok.getLocation()); 4841193326Sed D.setInvalidType(true); 4842198893Srdivacky } else { 4843198893Srdivacky // Parsed the unqualified-id; update range information and move along. 4844198893Srdivacky if (D.getSourceRange().getBegin().isInvalid()) 4845198893Srdivacky D.SetRangeBegin(D.getName().getSourceRange().getBegin()); 4846198893Srdivacky D.SetRangeEnd(D.getName().getSourceRange().getEnd()); 4847193326Sed } 4848198893Srdivacky goto PastIdentifier; 4849193326Sed } 4850198893Srdivacky } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { 4851234353Sdim assert(!getLangOpts().CPlusPlus && 4852193326Sed "There's a C++-specific check for tok::identifier above"); 4853193326Sed assert(Tok.getIdentifierInfo() && "Not an identifier?"); 4854193326Sed D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 4855193326Sed ConsumeToken(); 4856198893Srdivacky goto PastIdentifier; 4857263508Sdim } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) { 4858263508Sdim // A virt-specifier isn't treated as an identifier if it appears after a 4859263508Sdim // trailing-return-type. 4860263508Sdim if (D.getContext() != Declarator::TrailingReturnContext || 4861263508Sdim !isCXX11VirtSpecifier(Tok)) { 4862263508Sdim Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id) 4863263508Sdim << FixItHint::CreateRemoval(Tok.getLocation()); 4864263508Sdim D.SetIdentifier(0, Tok.getLocation()); 4865263508Sdim ConsumeToken(); 4866263508Sdim goto PastIdentifier; 4867263508Sdim } 4868198893Srdivacky } 4869234353Sdim 4870198893Srdivacky if (Tok.is(tok::l_paren)) { 4871193326Sed // direct-declarator: '(' declarator ')' 4872193326Sed // direct-declarator: '(' attributes declarator ')' 4873193326Sed // Example: 'char (*X)' or 'int (*XX)(void)' 4874193326Sed ParseParenDeclarator(D); 4875202379Srdivacky 4876202379Srdivacky // If the declarator was parenthesized, we entered the declarator 4877202379Srdivacky // scope when parsing the parenthesized declarator, then exited 4878202379Srdivacky // the scope already. Re-enter the scope, if we need to. 4879202379Srdivacky if (D.getCXXScopeSpec().isSet()) { 4880212904Sdim // If there was an error parsing parenthesized declarator, declarator 4881234353Sdim // scope may have been entered before. Don't do it again. 4882212904Sdim if (!D.isInvalidType() && 4883212904Sdim Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4884202379Srdivacky // Change the declaration context for name lookup, until this function 4885202379Srdivacky // is exited (and the declarator has been parsed). 4886202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4887202379Srdivacky } 4888193326Sed } else if (D.mayOmitIdentifier()) { 4889193326Sed // This could be something simple like "int" (in which case the declarator 4890193326Sed // portion is empty), if an abstract-declarator is allowed. 4891193326Sed D.SetIdentifier(0, Tok.getLocation()); 4892249423Sdim 4893249423Sdim // The grammar for abstract-pack-declarator does not allow grouping parens. 4894249423Sdim // FIXME: Revisit this once core issue 1488 is resolved. 4895249423Sdim if (D.hasEllipsis() && D.hasGroupingParens()) 4896249423Sdim Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()), 4897249423Sdim diag::ext_abstract_pack_declarator_parens); 4898193326Sed } else { 4899239462Sdim if (Tok.getKind() == tok::annot_pragma_parser_crash) 4900243830Sdim LLVM_BUILTIN_TRAP; 4901193326Sed if (D.getContext() == Declarator::MemberContext) 4902193326Sed Diag(Tok, diag::err_expected_member_name_or_semi) 4903193326Sed << D.getDeclSpec().getSourceRange(); 4904249423Sdim else if (getLangOpts().CPlusPlus) { 4905249423Sdim if (Tok.is(tok::period) || Tok.is(tok::arrow)) 4906249423Sdim Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow); 4907263508Sdim else { 4908263508Sdim SourceLocation Loc = D.getCXXScopeSpec().getEndLoc(); 4909263508Sdim if (Tok.isAtStartOfLine() && Loc.isValid()) 4910263508Sdim Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id) 4911263508Sdim << getLangOpts().CPlusPlus; 4912263508Sdim else 4913263508Sdim Diag(Tok, diag::err_expected_unqualified_id) 4914263508Sdim << getLangOpts().CPlusPlus; 4915263508Sdim } 4916249423Sdim } else 4917193326Sed Diag(Tok, diag::err_expected_ident_lparen); 4918193326Sed D.SetIdentifier(0, Tok.getLocation()); 4919193326Sed D.setInvalidType(true); 4920193326Sed } 4921198092Srdivacky 4922193326Sed PastIdentifier: 4923193326Sed assert(D.isPastIdentifier() && 4924193326Sed "Haven't past the location of the identifier yet?"); 4925198092Srdivacky 4926234353Sdim // Don't parse attributes unless we have parsed an unparenthesized name. 4927234353Sdim if (D.hasName() && !D.getNumTypeObjects()) 4928249423Sdim MaybeParseCXX11Attributes(D); 4929199990Srdivacky 4930193326Sed while (1) { 4931193326Sed if (Tok.is(tok::l_paren)) { 4932234353Sdim // Enter function-declaration scope, limiting any declarators to the 4933234353Sdim // function prototype scope, including parameter declarators. 4934234353Sdim ParseScope PrototypeScope(this, 4935249423Sdim Scope::FunctionPrototypeScope|Scope::DeclScope| 4936249423Sdim (D.isFunctionDeclaratorAFunctionDeclaration() 4937249423Sdim ? Scope::FunctionDeclarationScope : 0)); 4938249423Sdim 4939193326Sed // The paren may be part of a C++ direct initializer, eg. "int x(1);". 4940193326Sed // In such a case, check if we actually have a function declarator; if it 4941193326Sed // is not, the declarator has been fully parsed. 4942239462Sdim bool IsAmbiguous = false; 4943243830Sdim if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) { 4944243830Sdim // The name of the declarator, if any, is tentatively declared within 4945243830Sdim // a possible direct initializer. 4946243830Sdim TentativelyDeclaredIdentifiers.push_back(D.getIdentifier()); 4947243830Sdim bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous); 4948243830Sdim TentativelyDeclaredIdentifiers.pop_back(); 4949243830Sdim if (!IsFunctionDecl) 4950243830Sdim break; 4951243830Sdim } 4952221345Sdim ParsedAttributes attrs(AttrFactory); 4953226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4954226633Sdim T.consumeOpen(); 4955239462Sdim ParseFunctionDeclarator(D, attrs, T, IsAmbiguous); 4956234353Sdim PrototypeScope.Exit(); 4957193326Sed } else if (Tok.is(tok::l_square)) { 4958193326Sed ParseBracketDeclarator(D); 4959193326Sed } else { 4960193326Sed break; 4961193326Sed } 4962193326Sed } 4963239462Sdim} 4964193326Sed 4965193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is 4966193326Sed/// only called before the identifier, so these are most likely just grouping 4967198092Srdivacky/// parens for precedence. If we find that these are actually function 4968193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator. 4969193326Sed/// 4970193326Sed/// direct-declarator: 4971193326Sed/// '(' declarator ')' 4972193326Sed/// [GNU] '(' attributes declarator ')' 4973193326Sed/// direct-declarator '(' parameter-type-list ')' 4974193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4975193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4976193326Sed/// parameter-type-list[opt] ')' 4977193326Sed/// 4978193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) { 4979226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4980226633Sdim T.consumeOpen(); 4981226633Sdim 4982193326Sed assert(!D.isPastIdentifier() && "Should be called before passing identifier"); 4983198092Srdivacky 4984193326Sed // Eat any attributes before we look at whether this is a grouping or function 4985193326Sed // declarator paren. If this is a grouping paren, the attribute applies to 4986193326Sed // the type being built up, for example: 4987193326Sed // int (__attribute__(()) *x)(long y) 4988193326Sed // If this ends up not being a grouping paren, the attribute applies to the 4989193326Sed // first argument, for example: 4990193326Sed // int (__attribute__(()) int x) 4991193326Sed // In either case, we need to eat any attributes to be able to determine what 4992193326Sed // sort of paren this is. 4993193326Sed // 4994221345Sdim ParsedAttributes attrs(AttrFactory); 4995193326Sed bool RequiresArg = false; 4996193326Sed if (Tok.is(tok::kw___attribute)) { 4997218893Sdim ParseGNUAttributes(attrs); 4998198092Srdivacky 4999193326Sed // We require that the argument list (if this is a non-grouping paren) be 5000193326Sed // present even if the attribute list was empty. 5001193326Sed RequiresArg = true; 5002193326Sed } 5003249423Sdim 5004193326Sed // Eat any Microsoft extensions. 5005249423Sdim ParseMicrosoftTypeAttributes(attrs); 5006249423Sdim 5007212904Sdim // Eat any Borland extensions. 5008218893Sdim if (Tok.is(tok::kw___pascal)) 5009218893Sdim ParseBorlandTypeAttributes(attrs); 5010198092Srdivacky 5011193326Sed // If we haven't past the identifier yet (or where the identifier would be 5012193326Sed // stored, if this is an abstract declarator), then this is probably just 5013193326Sed // grouping parens. However, if this could be an abstract-declarator, then 5014193326Sed // this could also be the start of function arguments (consider 'void()'). 5015193326Sed bool isGrouping; 5016198092Srdivacky 5017193326Sed if (!D.mayOmitIdentifier()) { 5018193326Sed // If this can't be an abstract-declarator, this *must* be a grouping 5019193326Sed // paren, because we haven't seen the identifier yet. 5020193326Sed isGrouping = true; 5021193326Sed } else if (Tok.is(tok::r_paren) || // 'int()' is a function. 5022234353Sdim (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && 5023234353Sdim NextToken().is(tok::r_paren)) || // C++ int(...) 5024234353Sdim isDeclarationSpecifier() || // 'int(int)' is a function. 5025234353Sdim isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function. 5026193326Sed // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is 5027193326Sed // considered to be a type, not a K&R identifier-list. 5028193326Sed isGrouping = false; 5029193326Sed } else { 5030193326Sed // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'. 5031193326Sed isGrouping = true; 5032193326Sed } 5033198092Srdivacky 5034193326Sed // If this is a grouping paren, handle: 5035193326Sed // direct-declarator: '(' declarator ')' 5036193326Sed // direct-declarator: '(' attributes declarator ')' 5037193326Sed if (isGrouping) { 5038234353Sdim SourceLocation EllipsisLoc = D.getEllipsisLoc(); 5039234353Sdim D.setEllipsisLoc(SourceLocation()); 5040234353Sdim 5041193326Sed bool hadGroupingParens = D.hasGroupingParens(); 5042193326Sed D.setGroupingParens(true); 5043193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 5044193326Sed // Match the ')'. 5045226633Sdim T.consumeClose(); 5046239462Sdim D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), 5047226633Sdim T.getCloseLocation()), 5048226633Sdim attrs, T.getCloseLocation()); 5049193326Sed 5050193326Sed D.setGroupingParens(hadGroupingParens); 5051234353Sdim 5052234353Sdim // An ellipsis cannot be placed outside parentheses. 5053234353Sdim if (EllipsisLoc.isValid()) 5054234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 5055234353Sdim 5056193326Sed return; 5057193326Sed } 5058198092Srdivacky 5059193326Sed // Okay, if this wasn't a grouping paren, it must be the start of a function 5060193326Sed // argument list. Recognize that this declarator will never have an 5061193326Sed // identifier (and remember where it would have been), then call into 5062193326Sed // ParseFunctionDeclarator to handle of argument list. 5063193326Sed D.SetIdentifier(0, Tok.getLocation()); 5064193326Sed 5065234353Sdim // Enter function-declaration scope, limiting any declarators to the 5066234353Sdim // function prototype scope, including parameter declarators. 5067234353Sdim ParseScope PrototypeScope(this, 5068249423Sdim Scope::FunctionPrototypeScope | Scope::DeclScope | 5069249423Sdim (D.isFunctionDeclaratorAFunctionDeclaration() 5070249423Sdim ? Scope::FunctionDeclarationScope : 0)); 5071239462Sdim ParseFunctionDeclarator(D, attrs, T, false, RequiresArg); 5072234353Sdim PrototypeScope.Exit(); 5073193326Sed} 5074193326Sed 5075193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the 5076193326Sed/// declarator D up to a paren, which indicates that we are parsing function 5077193326Sed/// arguments. 5078193326Sed/// 5079234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments 5080234353Sdim/// immediately after the open paren - they should be considered to be the 5081234353Sdim/// first argument of a parameter. 5082193326Sed/// 5083234353Sdim/// If RequiresArg is true, then the first argument of the function is required 5084234353Sdim/// to be present and required to not be an identifier list. 5085193326Sed/// 5086234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt], 5087234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt], 5088234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt]. 5089234353Sdim/// 5090234353Sdim/// [C++11] exception-specification: 5091221345Sdim/// dynamic-exception-specification 5092221345Sdim/// noexcept-specification 5093221345Sdim/// 5094226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D, 5095234353Sdim ParsedAttributes &FirstArgAttrs, 5096226633Sdim BalancedDelimiterTracker &Tracker, 5097239462Sdim bool IsAmbiguous, 5098193326Sed bool RequiresArg) { 5099239462Sdim assert(getCurScope()->isFunctionPrototypeScope() && 5100234353Sdim "Should call from a Function scope"); 5101193326Sed // lparen is already consumed! 5102193326Sed assert(D.isPastIdentifier() && "Should not call before identifier!"); 5103198092Srdivacky 5104224145Sdim // This should be true when the function has typed arguments. 5105224145Sdim // Otherwise, it is treated as a K&R-style function. 5106224145Sdim bool HasProto = false; 5107224145Sdim // Build up an array of information about the parsed arguments. 5108226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 5109224145Sdim // Remember where we see an ellipsis, if any. 5110224145Sdim SourceLocation EllipsisLoc; 5111224145Sdim 5112224145Sdim DeclSpec DS(AttrFactory); 5113224145Sdim bool RefQualifierIsLValueRef = true; 5114224145Sdim SourceLocation RefQualifierLoc; 5115234353Sdim SourceLocation ConstQualifierLoc; 5116234353Sdim SourceLocation VolatileQualifierLoc; 5117224145Sdim ExceptionSpecificationType ESpecType = EST_None; 5118224145Sdim SourceRange ESpecRange; 5119226633Sdim SmallVector<ParsedType, 2> DynamicExceptions; 5120226633Sdim SmallVector<SourceRange, 2> DynamicExceptionRanges; 5121224145Sdim ExprResult NoexceptExpr; 5122234353Sdim ParsedAttributes FnAttrs(AttrFactory); 5123239462Sdim TypeResult TrailingReturnType; 5124234353Sdim 5125234353Sdim Actions.ActOnStartFunctionDeclarator(); 5126243830Sdim /* LocalEndLoc is the end location for the local FunctionTypeLoc. 5127243830Sdim EndLoc is the end location for the function declarator. 5128243830Sdim They differ for trailing return types. */ 5129243830Sdim SourceLocation StartLoc, LocalEndLoc, EndLoc; 5130243830Sdim SourceLocation LParenLoc, RParenLoc; 5131243830Sdim LParenLoc = Tracker.getOpenLocation(); 5132243830Sdim StartLoc = LParenLoc; 5133243830Sdim 5134224145Sdim if (isFunctionDeclaratorIdentifierList()) { 5135218893Sdim if (RequiresArg) 5136193326Sed Diag(Tok, diag::err_argument_required_after_attribute); 5137193326Sed 5138224145Sdim ParseFunctionDeclaratorIdentifierList(D, ParamInfo); 5139193326Sed 5140226633Sdim Tracker.consumeClose(); 5141243830Sdim RParenLoc = Tracker.getCloseLocation(); 5142243830Sdim LocalEndLoc = RParenLoc; 5143243830Sdim EndLoc = RParenLoc; 5144224145Sdim } else { 5145224145Sdim if (Tok.isNot(tok::r_paren)) 5146263508Sdim ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, 5147263508Sdim EllipsisLoc); 5148224145Sdim else if (RequiresArg) 5149224145Sdim Diag(Tok, diag::err_argument_required_after_attribute); 5150224145Sdim 5151234353Sdim HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; 5152224145Sdim 5153224145Sdim // If we have the closing ')', eat it. 5154226633Sdim Tracker.consumeClose(); 5155243830Sdim RParenLoc = Tracker.getCloseLocation(); 5156243830Sdim LocalEndLoc = RParenLoc; 5157243830Sdim EndLoc = RParenLoc; 5158224145Sdim 5159234353Sdim if (getLangOpts().CPlusPlus) { 5160234353Sdim // FIXME: Accept these components in any order, and produce fixits to 5161234353Sdim // correct the order if the user gets it wrong. Ideally we should deal 5162234353Sdim // with the virt-specifier-seq and pure-specifier in the same way. 5163218893Sdim 5164224145Sdim // Parse cv-qualifier-seq[opt]. 5165249423Sdim ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false, 5166249423Sdim /*CXX11AttributesAllowed*/ false, 5167249423Sdim /*AtomicAllowed*/ false); 5168234353Sdim if (!DS.getSourceRange().getEnd().isInvalid()) { 5169234353Sdim EndLoc = DS.getSourceRange().getEnd(); 5170234353Sdim ConstQualifierLoc = DS.getConstSpecLoc(); 5171234353Sdim VolatileQualifierLoc = DS.getVolatileSpecLoc(); 5172234353Sdim } 5173193326Sed 5174224145Sdim // Parse ref-qualifier[opt]. 5175218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) { 5176249423Sdim Diag(Tok, getLangOpts().CPlusPlus11 ? 5177234353Sdim diag::warn_cxx98_compat_ref_qualifier : 5178234353Sdim diag::ext_ref_qualifier); 5179234353Sdim 5180218893Sdim RefQualifierIsLValueRef = Tok.is(tok::amp); 5181218893Sdim RefQualifierLoc = ConsumeToken(); 5182218893Sdim EndLoc = RefQualifierLoc; 5183218893Sdim } 5184221345Sdim 5185234982Sdim // C++11 [expr.prim.general]p3: 5186239462Sdim // If a declaration declares a member function or member function 5187239462Sdim // template of a class X, the expression this is a prvalue of type 5188234982Sdim // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 5189239462Sdim // and the end of the function-definition, member-declarator, or 5190234982Sdim // declarator. 5191249423Sdim // FIXME: currently, "static" case isn't handled correctly. 5192239462Sdim bool IsCXX11MemberFunction = 5193249423Sdim getLangOpts().CPlusPlus11 && 5194249423Sdim (D.getContext() == Declarator::MemberContext 5195249423Sdim ? !D.getDeclSpec().isFriendSpecified() 5196249423Sdim : D.getContext() == Declarator::FileContext && 5197249423Sdim D.getCXXScopeSpec().isValid() && 5198249423Sdim Actions.CurContext->isRecord()); 5199234982Sdim Sema::CXXThisScopeRAII ThisScope(Actions, 5200234982Sdim dyn_cast<CXXRecordDecl>(Actions.CurContext), 5201249423Sdim DS.getTypeQualifiers() | 5202251662Sdim (D.getDeclSpec().isConstexprSpecified() && 5203251662Sdim !getLangOpts().CPlusPlus1y 5204249423Sdim ? Qualifiers::Const : 0), 5205234982Sdim IsCXX11MemberFunction); 5206235864Sdim 5207193326Sed // Parse exception-specification[opt]. 5208235864Sdim ESpecType = tryParseExceptionSpecification(ESpecRange, 5209234982Sdim DynamicExceptions, 5210234982Sdim DynamicExceptionRanges, 5211235864Sdim NoexceptExpr); 5212221345Sdim if (ESpecType != EST_None) 5213221345Sdim EndLoc = ESpecRange.getEnd(); 5214218893Sdim 5215234353Sdim // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes 5216234353Sdim // after the exception-specification. 5217249423Sdim MaybeParseCXX11Attributes(FnAttrs); 5218234353Sdim 5219224145Sdim // Parse trailing-return-type[opt]. 5220243830Sdim LocalEndLoc = EndLoc; 5221249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) { 5222234353Sdim Diag(Tok, diag::warn_cxx98_compat_trailing_return_type); 5223243830Sdim if (D.getDeclSpec().getTypeSpecType() == TST_auto) 5224243830Sdim StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); 5225243830Sdim LocalEndLoc = Tok.getLocation(); 5226226633Sdim SourceRange Range; 5227239462Sdim TrailingReturnType = ParseTrailingReturnType(Range); 5228243830Sdim EndLoc = Range.getEnd(); 5229218893Sdim } 5230193326Sed } 5231193326Sed } 5232193326Sed 5233224145Sdim // Remember that we parsed a function type, and remember the attributes. 5234224145Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, 5235243830Sdim IsAmbiguous, 5236243830Sdim LParenLoc, 5237224145Sdim ParamInfo.data(), ParamInfo.size(), 5238243830Sdim EllipsisLoc, RParenLoc, 5239224145Sdim DS.getTypeQualifiers(), 5240224145Sdim RefQualifierIsLValueRef, 5241234353Sdim RefQualifierLoc, ConstQualifierLoc, 5242234353Sdim VolatileQualifierLoc, 5243224145Sdim /*MutableLoc=*/SourceLocation(), 5244224145Sdim ESpecType, ESpecRange.getBegin(), 5245224145Sdim DynamicExceptions.data(), 5246224145Sdim DynamicExceptionRanges.data(), 5247224145Sdim DynamicExceptions.size(), 5248224145Sdim NoexceptExpr.isUsable() ? 5249224145Sdim NoexceptExpr.get() : 0, 5250243830Sdim StartLoc, LocalEndLoc, D, 5251224145Sdim TrailingReturnType), 5252234353Sdim FnAttrs, EndLoc); 5253234353Sdim 5254234353Sdim Actions.ActOnEndFunctionDeclarator(); 5255224145Sdim} 5256224145Sdim 5257224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an 5258224145Sdim/// identifier list form for a K&R-style function: void foo(a,b,c) 5259224145Sdim/// 5260224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for 5261224145Sdim/// abstract-declarators. 5262224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() { 5263234353Sdim return !getLangOpts().CPlusPlus 5264224145Sdim && Tok.is(tok::identifier) 5265224145Sdim && !TryAltiVecVectorToken() 5266224145Sdim // K&R identifier lists can't have typedefs as identifiers, per C99 5267224145Sdim // 6.7.5.3p11. 5268224145Sdim && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) 5269224145Sdim // Identifier lists follow a really simple grammar: the identifiers can 5270224145Sdim // be followed *only* by a ", identifier" or ")". However, K&R 5271224145Sdim // identifier lists are really rare in the brave new modern world, and 5272224145Sdim // it is very common for someone to typo a type in a non-K&R style 5273224145Sdim // list. If we are presented with something like: "void foo(intptr x, 5274224145Sdim // float y)", we don't want to start parsing the function declarator as 5275224145Sdim // though it is a K&R style declarator just because intptr is an 5276224145Sdim // invalid type. 5277224145Sdim // 5278224145Sdim // To handle this, we check to see if the token after the first 5279224145Sdim // identifier is a "," or ")". Only then do we parse it as an 5280224145Sdim // identifier list. 5281224145Sdim && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); 5282224145Sdim} 5283224145Sdim 5284224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator 5285224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list. 5286224145Sdim/// 5287224145Sdim/// After returning, ParamInfo will hold the parsed parameters. 5288224145Sdim/// 5289224145Sdim/// identifier-list: [C99 6.7.5] 5290224145Sdim/// identifier 5291224145Sdim/// identifier-list ',' identifier 5292224145Sdim/// 5293224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList( 5294224145Sdim Declarator &D, 5295263508Sdim SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) { 5296224145Sdim // If there was no identifier specified for the declarator, either we are in 5297224145Sdim // an abstract-declarator, or we are in a parameter declarator which was found 5298224145Sdim // to be abstract. In abstract-declarators, identifier lists are not valid: 5299224145Sdim // diagnose this. 5300224145Sdim if (!D.getIdentifier()) 5301224145Sdim Diag(Tok, diag::ext_ident_list_in_param); 5302224145Sdim 5303224145Sdim // Maintain an efficient lookup of params we have seen so far. 5304224145Sdim llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar; 5305224145Sdim 5306224145Sdim while (1) { 5307224145Sdim // If this isn't an identifier, report the error and skip until ')'. 5308224145Sdim if (Tok.isNot(tok::identifier)) { 5309224145Sdim Diag(Tok, diag::err_expected_ident); 5310263508Sdim SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 5311224145Sdim // Forget we parsed anything. 5312224145Sdim ParamInfo.clear(); 5313224145Sdim return; 5314193326Sed } 5315198092Srdivacky 5316224145Sdim IdentifierInfo *ParmII = Tok.getIdentifierInfo(); 5317198092Srdivacky 5318224145Sdim // Reject 'typedef int y; int test(x, y)', but continue parsing. 5319224145Sdim if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope())) 5320224145Sdim Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; 5321193326Sed 5322224145Sdim // Verify that the argument identifier has not already been mentioned. 5323224145Sdim if (!ParamsSoFar.insert(ParmII)) { 5324224145Sdim Diag(Tok, diag::err_param_redefinition) << ParmII; 5325224145Sdim } else { 5326224145Sdim // Remember this identifier in ParamInfo. 5327224145Sdim ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5328224145Sdim Tok.getLocation(), 5329224145Sdim 0)); 5330224145Sdim } 5331198092Srdivacky 5332224145Sdim // Eat the identifier. 5333224145Sdim ConsumeToken(); 5334224145Sdim 5335224145Sdim // The list continues if we see a comma. 5336224145Sdim if (Tok.isNot(tok::comma)) 5337224145Sdim break; 5338224145Sdim ConsumeToken(); 5339224145Sdim } 5340224145Sdim} 5341224145Sdim 5342224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list 5343224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style 5344224145Sdim/// identifier list. 5345224145Sdim/// 5346234353Sdim/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the 5347234353Sdim/// caller parsed those arguments immediately after the open paren - they should 5348234353Sdim/// be considered to be part of the first parameter. 5349224145Sdim/// 5350224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will 5351224145Sdim/// be the location of the ellipsis, if any was parsed. 5352224145Sdim/// 5353224145Sdim/// parameter-type-list: [C99 6.7.5] 5354224145Sdim/// parameter-list 5355224145Sdim/// parameter-list ',' '...' 5356224145Sdim/// [C++] parameter-list '...' 5357224145Sdim/// 5358224145Sdim/// parameter-list: [C99 6.7.5] 5359224145Sdim/// parameter-declaration 5360224145Sdim/// parameter-list ',' parameter-declaration 5361224145Sdim/// 5362224145Sdim/// parameter-declaration: [C99 6.7.5] 5363224145Sdim/// declaration-specifiers declarator 5364224145Sdim/// [C++] declaration-specifiers declarator '=' assignment-expression 5365234353Sdim/// [C++11] initializer-clause 5366224145Sdim/// [GNU] declaration-specifiers declarator attributes 5367224145Sdim/// declaration-specifiers abstract-declarator[opt] 5368224145Sdim/// [C++] declaration-specifiers abstract-declarator[opt] 5369224145Sdim/// '=' assignment-expression 5370224145Sdim/// [GNU] declaration-specifiers abstract-declarator[opt] attributes 5371234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration 5372224145Sdim/// 5373224145Sdimvoid Parser::ParseParameterDeclarationClause( 5374224145Sdim Declarator &D, 5375234353Sdim ParsedAttributes &FirstArgAttrs, 5376263508Sdim SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, 5377224145Sdim SourceLocation &EllipsisLoc) { 5378193326Sed while (1) { 5379193326Sed if (Tok.is(tok::ellipsis)) { 5380234353Sdim // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq 5381234353Sdim // before deciding this was a parameter-declaration-clause. 5382193326Sed EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5383193326Sed break; 5384193326Sed } 5385198092Srdivacky 5386193326Sed // Parse the declaration-specifiers. 5387198893Srdivacky // Just use the ParsingDeclaration "scope" of the declarator. 5388221345Sdim DeclSpec DS(AttrFactory); 5389226633Sdim 5390234353Sdim // Parse any C++11 attributes. 5391249423Sdim MaybeParseCXX11Attributes(DS.getAttributes()); 5392234353Sdim 5393218893Sdim // Skip any Microsoft attributes before a param. 5394249423Sdim MaybeParseMicrosoftAttributes(DS.getAttributes()); 5395193326Sed 5396218893Sdim SourceLocation DSStart = Tok.getLocation(); 5397218893Sdim 5398193326Sed // If the caller parsed attributes for the first argument, add them now. 5399218893Sdim // Take them so that we only apply the attributes to the first parameter. 5400224145Sdim // FIXME: If we can leave the attributes in the token stream somehow, we can 5401234353Sdim // get rid of a parameter (FirstArgAttrs) and this statement. It might be 5402234353Sdim // too much hassle. 5403234353Sdim DS.takeAttributesFrom(FirstArgAttrs); 5404218893Sdim 5405193326Sed ParseDeclarationSpecifiers(DS); 5406198092Srdivacky 5407193326Sed 5408263508Sdim // Parse the declarator. This is "PrototypeContext" or 5409263508Sdim // "LambdaExprParameterContext", because we must accept either 5410263508Sdim // 'declarator' or 'abstract-declarator' here. 5411263508Sdim Declarator ParmDeclarator(DS, 5412263508Sdim D.getContext() == Declarator::LambdaExprContext ? 5413263508Sdim Declarator::LambdaExprParameterContext : 5414263508Sdim Declarator::PrototypeContext); 5415263508Sdim ParseDeclarator(ParmDeclarator); 5416263508Sdim 5417193326Sed // Parse GNU attributes, if present. 5418263508Sdim MaybeParseGNUAttributes(ParmDeclarator); 5419198092Srdivacky 5420193326Sed // Remember this parsed parameter in ParamInfo. 5421263508Sdim IdentifierInfo *ParmII = ParmDeclarator.getIdentifier(); 5422198092Srdivacky 5423193326Sed // DefArgToks is used when the parsing of default arguments needs 5424193326Sed // to be delayed. 5425193326Sed CachedTokens *DefArgToks = 0; 5426193326Sed 5427193326Sed // If no parameter was specified, verify that *something* was specified, 5428193326Sed // otherwise we have a missing type and identifier. 5429263508Sdim if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 && 5430263508Sdim ParmDeclarator.getNumTypeObjects() == 0) { 5431193326Sed // Completely missing, emit error. 5432193326Sed Diag(DSStart, diag::err_missing_param); 5433193326Sed } else { 5434193326Sed // Otherwise, we have something. Add it and let semantic analysis try 5435193326Sed // to grok it and add the result to the ParamInfo we are building. 5436198092Srdivacky 5437193326Sed // Inform the actions module about the parameter declarator, so it gets 5438193326Sed // added to the current scope. 5439263508Sdim Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), 5440263508Sdim ParmDeclarator); 5441193326Sed // Parse the default argument, if any. We parse the default 5442193326Sed // arguments in all dialects; the semantic analysis in 5443193326Sed // ActOnParamDefaultArgument will reject the default argument in 5444193326Sed // C. 5445193326Sed if (Tok.is(tok::equal)) { 5446193326Sed SourceLocation EqualLoc = Tok.getLocation(); 5447193326Sed 5448193326Sed // Parse the default argument 5449193326Sed if (D.getContext() == Declarator::MemberContext) { 5450193326Sed // If we're inside a class definition, cache the tokens 5451193326Sed // corresponding to the default argument. We'll actually parse 5452193326Sed // them when we see the end of the class definition. 5453193326Sed // FIXME: Can we use a smart pointer for Toks? 5454193326Sed DefArgToks = new CachedTokens; 5455193326Sed 5456263508Sdim if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) { 5457193326Sed delete DefArgToks; 5458193326Sed DefArgToks = 0; 5459193326Sed Actions.ActOnParamDefaultArgumentError(Param); 5460212904Sdim } else { 5461212904Sdim // Mark the end of the default argument so that we know when to 5462212904Sdim // stop when we parse it later on. 5463212904Sdim Token DefArgEnd; 5464212904Sdim DefArgEnd.startToken(); 5465212904Sdim DefArgEnd.setKind(tok::cxx_defaultarg_end); 5466212904Sdim DefArgEnd.setLocation(Tok.getLocation()); 5467212904Sdim DefArgToks->push_back(DefArgEnd); 5468198092Srdivacky Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, 5469194179Sed (*DefArgToks)[1].getLocation()); 5470212904Sdim } 5471193326Sed } else { 5472193326Sed // Consume the '='. 5473193326Sed ConsumeToken(); 5474198092Srdivacky 5475239462Sdim // The argument isn't actually potentially evaluated unless it is 5476218893Sdim // used. 5477218893Sdim EnterExpressionEvaluationContext Eval(Actions, 5478234353Sdim Sema::PotentiallyEvaluatedIfUsed, 5479234353Sdim Param); 5480218893Sdim 5481234353Sdim ExprResult DefArgResult; 5482249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5483234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 5484234353Sdim DefArgResult = ParseBraceInitializer(); 5485234353Sdim } else 5486234353Sdim DefArgResult = ParseAssignmentExpression(); 5487193326Sed if (DefArgResult.isInvalid()) { 5488193326Sed Actions.ActOnParamDefaultArgumentError(Param); 5489263508Sdim SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch); 5490193326Sed } else { 5491193326Sed // Inform the actions module about the default argument 5492193326Sed Actions.ActOnParamDefaultArgument(Param, EqualLoc, 5493212904Sdim DefArgResult.take()); 5494193326Sed } 5495193326Sed } 5496193326Sed } 5497198092Srdivacky 5498198092Srdivacky ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5499263508Sdim ParmDeclarator.getIdentifierLoc(), 5500263508Sdim Param, DefArgToks)); 5501193326Sed } 5502193326Sed 5503193326Sed // If the next token is a comma, consume it and keep reading arguments. 5504198092Srdivacky if (Tok.isNot(tok::comma)) { 5505198092Srdivacky if (Tok.is(tok::ellipsis)) { 5506198092Srdivacky EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5507239462Sdim 5508234353Sdim if (!getLangOpts().CPlusPlus) { 5509198092Srdivacky // We have ellipsis without a preceding ',', which is ill-formed 5510198092Srdivacky // in C. Complain and provide the fix. 5511198092Srdivacky Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis) 5512206084Srdivacky << FixItHint::CreateInsertion(EllipsisLoc, ", "); 5513198092Srdivacky } 5514198092Srdivacky } 5515239462Sdim 5516198092Srdivacky break; 5517198092Srdivacky } 5518198092Srdivacky 5519193326Sed // Consume the comma. 5520193326Sed ConsumeToken(); 5521193326Sed } 5522198092Srdivacky 5523193326Sed} 5524193326Sed 5525193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 5526193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 5527193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 5528193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 5529193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 5530234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 5531234353Sdim/// attribute-specifier-seq[opt] 5532193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) { 5533234353Sdim if (CheckProhibitedCXX11Attribute()) 5534234353Sdim return; 5535234353Sdim 5536226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 5537226633Sdim T.consumeOpen(); 5538198092Srdivacky 5539193326Sed // C array syntax has many features, but by-far the most common is [] and [4]. 5540193326Sed // This code does a fast path to handle some of the most obvious cases. 5541193326Sed if (Tok.getKind() == tok::r_square) { 5542226633Sdim T.consumeClose(); 5543221345Sdim ParsedAttributes attrs(AttrFactory); 5544249423Sdim MaybeParseCXX11Attributes(attrs); 5545239462Sdim 5546193326Sed // Remember that we parsed the empty array type. 5547212904Sdim ExprResult NumElements; 5548221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, 5549226633Sdim T.getOpenLocation(), 5550226633Sdim T.getCloseLocation()), 5551226633Sdim attrs, T.getCloseLocation()); 5552193326Sed return; 5553193326Sed } else if (Tok.getKind() == tok::numeric_constant && 5554193326Sed GetLookAheadToken(1).is(tok::r_square)) { 5555193326Sed // [4] is very common. Parse the numeric constant expression. 5556234353Sdim ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope())); 5557193326Sed ConsumeToken(); 5558193326Sed 5559226633Sdim T.consumeClose(); 5560221345Sdim ParsedAttributes attrs(AttrFactory); 5561249423Sdim MaybeParseCXX11Attributes(attrs); 5562193326Sed 5563193326Sed // Remember that we parsed a array type, and remember its features. 5564249423Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 5565218893Sdim ExprRes.release(), 5566226633Sdim T.getOpenLocation(), 5567226633Sdim T.getCloseLocation()), 5568226633Sdim attrs, T.getCloseLocation()); 5569193326Sed return; 5570193326Sed } 5571198092Srdivacky 5572193326Sed // If valid, this location is the position where we read the 'static' keyword. 5573193326Sed SourceLocation StaticLoc; 5574193326Sed if (Tok.is(tok::kw_static)) 5575193326Sed StaticLoc = ConsumeToken(); 5576198092Srdivacky 5577193326Sed // If there is a type-qualifier-list, read it now. 5578193326Sed // Type qualifiers in an array subscript are a C99 feature. 5579221345Sdim DeclSpec DS(AttrFactory); 5580193326Sed ParseTypeQualifierListOpt(DS, false /*no attributes*/); 5581198092Srdivacky 5582193326Sed // If we haven't already read 'static', check to see if there is one after the 5583193326Sed // type-qualifier-list. 5584193326Sed if (!StaticLoc.isValid() && Tok.is(tok::kw_static)) 5585193326Sed StaticLoc = ConsumeToken(); 5586198092Srdivacky 5587193326Sed // Handle "direct-declarator [ type-qual-list[opt] * ]". 5588193326Sed bool isStar = false; 5589212904Sdim ExprResult NumElements; 5590198092Srdivacky 5591193326Sed // Handle the case where we have '[*]' as the array size. However, a leading 5592193326Sed // star could be the start of an expression, for example 'X[*p + 4]'. Verify 5593239462Sdim // the token after the star is a ']'. Since stars in arrays are 5594193326Sed // infrequent, use of lookahead is not costly here. 5595193326Sed if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) { 5596193326Sed ConsumeToken(); // Eat the '*'. 5597193326Sed 5598193326Sed if (StaticLoc.isValid()) { 5599193326Sed Diag(StaticLoc, diag::err_unspecified_vla_size_with_static); 5600193326Sed StaticLoc = SourceLocation(); // Drop the static. 5601193326Sed } 5602193326Sed isStar = true; 5603193326Sed } else if (Tok.isNot(tok::r_square)) { 5604193326Sed // Note, in C89, this production uses the constant-expr production instead 5605193326Sed // of assignment-expr. The only difference is that assignment-expr allows 5606193326Sed // things like '=' and '*='. Sema rejects these in C89 mode because they 5607193326Sed // are not i-c-e's, so we don't need to distinguish between the two here. 5608198092Srdivacky 5609194613Sed // Parse the constant-expression or assignment-expression now (depending 5610194613Sed // on dialect). 5611234353Sdim if (getLangOpts().CPlusPlus) { 5612194613Sed NumElements = ParseConstantExpression(); 5613234353Sdim } else { 5614234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 5615234353Sdim Sema::ConstantEvaluated); 5616194613Sed NumElements = ParseAssignmentExpression(); 5617234353Sdim } 5618193326Sed } 5619198092Srdivacky 5620193326Sed // If there was an error parsing the assignment-expression, recover. 5621193326Sed if (NumElements.isInvalid()) { 5622193326Sed D.setInvalidType(true); 5623193326Sed // If the expression was invalid, skip it. 5624263508Sdim SkipUntil(tok::r_square, StopAtSemi); 5625193326Sed return; 5626193326Sed } 5627193326Sed 5628226633Sdim T.consumeClose(); 5629193326Sed 5630221345Sdim ParsedAttributes attrs(AttrFactory); 5631249423Sdim MaybeParseCXX11Attributes(attrs); 5632199990Srdivacky 5633193326Sed // Remember that we parsed a array type, and remember its features. 5634221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), 5635193326Sed StaticLoc.isValid(), isStar, 5636198092Srdivacky NumElements.release(), 5637226633Sdim T.getOpenLocation(), 5638226633Sdim T.getCloseLocation()), 5639226633Sdim attrs, T.getCloseLocation()); 5640193326Sed} 5641193326Sed 5642193326Sed/// [GNU] typeof-specifier: 5643193326Sed/// typeof ( expressions ) 5644193326Sed/// typeof ( type-name ) 5645193326Sed/// [GNU/C++] typeof unary-expression 5646193326Sed/// 5647193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) { 5648193326Sed assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); 5649193326Sed Token OpTok = Tok; 5650193326Sed SourceLocation StartLoc = ConsumeToken(); 5651193326Sed 5652202379Srdivacky const bool hasParens = Tok.is(tok::l_paren); 5653202379Srdivacky 5654243830Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 5655243830Sdim Sema::ReuseLambdaContextDecl); 5656234353Sdim 5657193326Sed bool isCastExpr; 5658212904Sdim ParsedType CastTy; 5659193326Sed SourceRange CastRange; 5660221345Sdim ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, 5661221345Sdim CastTy, CastRange); 5662202379Srdivacky if (hasParens) 5663202379Srdivacky DS.setTypeofParensRange(CastRange); 5664193326Sed 5665193326Sed if (CastRange.getEnd().isInvalid()) 5666193326Sed // FIXME: Not accurate, the range gets one token more than it should. 5667193326Sed DS.SetRangeEnd(Tok.getLocation()); 5668193326Sed else 5669193326Sed DS.SetRangeEnd(CastRange.getEnd()); 5670198092Srdivacky 5671193326Sed if (isCastExpr) { 5672193326Sed if (!CastTy) { 5673193326Sed DS.SetTypeSpecError(); 5674193326Sed return; 5675193326Sed } 5676193326Sed 5677193326Sed const char *PrevSpec = 0; 5678198092Srdivacky unsigned DiagID; 5679193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5680193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 5681198092Srdivacky DiagID, CastTy)) 5682198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5683193326Sed return; 5684193326Sed } 5685193326Sed 5686193326Sed // If we get here, the operand to the typeof was an expresion. 5687193326Sed if (Operand.isInvalid()) { 5688193326Sed DS.SetTypeSpecError(); 5689193326Sed return; 5690193326Sed } 5691193326Sed 5692234353Sdim // We might need to transform the operand if it is potentially evaluated. 5693234353Sdim Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get()); 5694234353Sdim if (Operand.isInvalid()) { 5695234353Sdim DS.SetTypeSpecError(); 5696234353Sdim return; 5697234353Sdim } 5698234353Sdim 5699193326Sed const char *PrevSpec = 0; 5700198092Srdivacky unsigned DiagID; 5701193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5702193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 5703212904Sdim DiagID, Operand.get())) 5704198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5705193326Sed} 5706204643Srdivacky 5707234353Sdim/// [C11] atomic-specifier: 5708226633Sdim/// _Atomic ( type-name ) 5709226633Sdim/// 5710226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) { 5711249423Sdim assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) && 5712249423Sdim "Not an atomic specifier"); 5713204643Srdivacky 5714226633Sdim SourceLocation StartLoc = ConsumeToken(); 5715226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 5716249423Sdim if (T.consumeOpen()) 5717226633Sdim return; 5718226633Sdim 5719226633Sdim TypeResult Result = ParseTypeName(); 5720226633Sdim if (Result.isInvalid()) { 5721263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 5722226633Sdim return; 5723226633Sdim } 5724226633Sdim 5725226633Sdim // Match the ')' 5726226633Sdim T.consumeClose(); 5727226633Sdim 5728226633Sdim if (T.getCloseLocation().isInvalid()) 5729226633Sdim return; 5730226633Sdim 5731226633Sdim DS.setTypeofParensRange(T.getRange()); 5732226633Sdim DS.SetRangeEnd(T.getCloseLocation()); 5733226633Sdim 5734226633Sdim const char *PrevSpec = 0; 5735226633Sdim unsigned DiagID; 5736226633Sdim if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec, 5737226633Sdim DiagID, Result.release())) 5738226633Sdim Diag(StartLoc, DiagID) << PrevSpec; 5739226633Sdim} 5740226633Sdim 5741226633Sdim 5742204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called 5743204643Srdivacky/// from TryAltiVecVectorToken. 5744204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() { 5745204643Srdivacky Token Next = NextToken(); 5746204643Srdivacky switch (Next.getKind()) { 5747204643Srdivacky default: return false; 5748204643Srdivacky case tok::kw_short: 5749204643Srdivacky case tok::kw_long: 5750204643Srdivacky case tok::kw_signed: 5751204643Srdivacky case tok::kw_unsigned: 5752204643Srdivacky case tok::kw_void: 5753204643Srdivacky case tok::kw_char: 5754204643Srdivacky case tok::kw_int: 5755204643Srdivacky case tok::kw_float: 5756204643Srdivacky case tok::kw_double: 5757204643Srdivacky case tok::kw_bool: 5758204643Srdivacky case tok::kw___pixel: 5759204643Srdivacky Tok.setKind(tok::kw___vector); 5760204643Srdivacky return true; 5761204643Srdivacky case tok::identifier: 5762204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5763204643Srdivacky Tok.setKind(tok::kw___vector); 5764204643Srdivacky return true; 5765204643Srdivacky } 5766263508Sdim if (Next.getIdentifierInfo() == Ident_bool) { 5767263508Sdim Tok.setKind(tok::kw___vector); 5768263508Sdim return true; 5769263508Sdim } 5770204643Srdivacky return false; 5771204643Srdivacky } 5772204643Srdivacky} 5773204643Srdivacky 5774204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, 5775204643Srdivacky const char *&PrevSpec, unsigned &DiagID, 5776204643Srdivacky bool &isInvalid) { 5777204643Srdivacky if (Tok.getIdentifierInfo() == Ident_vector) { 5778204643Srdivacky Token Next = NextToken(); 5779204643Srdivacky switch (Next.getKind()) { 5780204643Srdivacky case tok::kw_short: 5781204643Srdivacky case tok::kw_long: 5782204643Srdivacky case tok::kw_signed: 5783204643Srdivacky case tok::kw_unsigned: 5784204643Srdivacky case tok::kw_void: 5785204643Srdivacky case tok::kw_char: 5786204643Srdivacky case tok::kw_int: 5787204643Srdivacky case tok::kw_float: 5788204643Srdivacky case tok::kw_double: 5789204643Srdivacky case tok::kw_bool: 5790204643Srdivacky case tok::kw___pixel: 5791204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5792204643Srdivacky return true; 5793204643Srdivacky case tok::identifier: 5794204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5795204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5796204643Srdivacky return true; 5797204643Srdivacky } 5798263508Sdim if (Next.getIdentifierInfo() == Ident_bool) { 5799263508Sdim isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5800263508Sdim return true; 5801263508Sdim } 5802204643Srdivacky break; 5803204643Srdivacky default: 5804204643Srdivacky break; 5805204643Srdivacky } 5806210299Sed } else if ((Tok.getIdentifierInfo() == Ident_pixel) && 5807204643Srdivacky DS.isTypeAltiVecVector()) { 5808204643Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 5809204643Srdivacky return true; 5810263508Sdim } else if ((Tok.getIdentifierInfo() == Ident_bool) && 5811263508Sdim DS.isTypeAltiVecVector()) { 5812263508Sdim isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID); 5813263508Sdim return true; 5814204643Srdivacky } 5815204643Srdivacky return false; 5816204643Srdivacky} 5817