1*f4a2713aSLionel Sambuc //===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file implements the Declaration portions of the Parser interfaces. 11*f4a2713aSLionel Sambuc // 12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h" 15*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h" 16*f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h" 17*f4a2713aSLionel Sambuc #include "clang/Basic/AddressSpaces.h" 18*f4a2713aSLionel Sambuc #include "clang/Basic/CharInfo.h" 19*f4a2713aSLionel Sambuc #include "clang/Basic/OpenCL.h" 20*f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h" 21*f4a2713aSLionel Sambuc #include "clang/Sema/Lookup.h" 22*f4a2713aSLionel Sambuc #include "clang/Sema/ParsedTemplate.h" 23*f4a2713aSLionel Sambuc #include "clang/Sema/PrettyDeclStackTrace.h" 24*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h" 25*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallSet.h" 26*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h" 27*f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h" 28*f4a2713aSLionel Sambuc using namespace clang; 29*f4a2713aSLionel Sambuc 30*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 31*f4a2713aSLionel Sambuc // C99 6.7: Declarations. 32*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 33*f4a2713aSLionel Sambuc 34*f4a2713aSLionel Sambuc /// ParseTypeName 35*f4a2713aSLionel Sambuc /// type-name: [C99 6.7.6] 36*f4a2713aSLionel Sambuc /// specifier-qualifier-list abstract-declarator[opt] 37*f4a2713aSLionel Sambuc /// 38*f4a2713aSLionel Sambuc /// Called type-id in C++. 39*f4a2713aSLionel Sambuc TypeResult Parser::ParseTypeName(SourceRange *Range, 40*f4a2713aSLionel Sambuc Declarator::TheContext Context, 41*f4a2713aSLionel Sambuc AccessSpecifier AS, 42*f4a2713aSLionel Sambuc Decl **OwnedType, 43*f4a2713aSLionel Sambuc ParsedAttributes *Attrs) { 44*f4a2713aSLionel Sambuc DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context); 45*f4a2713aSLionel Sambuc if (DSC == DSC_normal) 46*f4a2713aSLionel Sambuc DSC = DSC_type_specifier; 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc // Parse the common declaration-specifiers piece. 49*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 50*f4a2713aSLionel Sambuc if (Attrs) 51*f4a2713aSLionel Sambuc DS.addAttributes(Attrs->getList()); 52*f4a2713aSLionel Sambuc ParseSpecifierQualifierList(DS, AS, DSC); 53*f4a2713aSLionel Sambuc if (OwnedType) 54*f4a2713aSLionel Sambuc *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc // Parse the abstract-declarator, if present. 57*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Context); 58*f4a2713aSLionel Sambuc ParseDeclarator(DeclaratorInfo); 59*f4a2713aSLionel Sambuc if (Range) 60*f4a2713aSLionel Sambuc *Range = DeclaratorInfo.getSourceRange(); 61*f4a2713aSLionel Sambuc 62*f4a2713aSLionel Sambuc if (DeclaratorInfo.isInvalidType()) 63*f4a2713aSLionel Sambuc return true; 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambuc /// isAttributeLateParsed - Return true if the attribute has arguments that 70*f4a2713aSLionel Sambuc /// require late parsing. 71*f4a2713aSLionel Sambuc static bool isAttributeLateParsed(const IdentifierInfo &II) { 72*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(II.getName()) 73*f4a2713aSLionel Sambuc #include "clang/Parse/AttrLateParsed.inc" 74*f4a2713aSLionel Sambuc .Default(false); 75*f4a2713aSLionel Sambuc } 76*f4a2713aSLionel Sambuc 77*f4a2713aSLionel Sambuc /// ParseGNUAttributes - Parse a non-empty attributes list. 78*f4a2713aSLionel Sambuc /// 79*f4a2713aSLionel Sambuc /// [GNU] attributes: 80*f4a2713aSLionel Sambuc /// attribute 81*f4a2713aSLionel Sambuc /// attributes attribute 82*f4a2713aSLionel Sambuc /// 83*f4a2713aSLionel Sambuc /// [GNU] attribute: 84*f4a2713aSLionel Sambuc /// '__attribute__' '(' '(' attribute-list ')' ')' 85*f4a2713aSLionel Sambuc /// 86*f4a2713aSLionel Sambuc /// [GNU] attribute-list: 87*f4a2713aSLionel Sambuc /// attrib 88*f4a2713aSLionel Sambuc /// attribute_list ',' attrib 89*f4a2713aSLionel Sambuc /// 90*f4a2713aSLionel Sambuc /// [GNU] attrib: 91*f4a2713aSLionel Sambuc /// empty 92*f4a2713aSLionel Sambuc /// attrib-name 93*f4a2713aSLionel Sambuc /// attrib-name '(' identifier ')' 94*f4a2713aSLionel Sambuc /// attrib-name '(' identifier ',' nonempty-expr-list ')' 95*f4a2713aSLionel Sambuc /// attrib-name '(' argument-expression-list [C99 6.5.2] ')' 96*f4a2713aSLionel Sambuc /// 97*f4a2713aSLionel Sambuc /// [GNU] attrib-name: 98*f4a2713aSLionel Sambuc /// identifier 99*f4a2713aSLionel Sambuc /// typespec 100*f4a2713aSLionel Sambuc /// typequal 101*f4a2713aSLionel Sambuc /// storageclass 102*f4a2713aSLionel Sambuc /// 103*f4a2713aSLionel Sambuc /// Whether an attribute takes an 'identifier' is determined by the 104*f4a2713aSLionel Sambuc /// attrib-name. GCC's behavior here is not worth imitating: 105*f4a2713aSLionel Sambuc /// 106*f4a2713aSLionel Sambuc /// * In C mode, if the attribute argument list starts with an identifier 107*f4a2713aSLionel Sambuc /// followed by a ',' or an ')', and the identifier doesn't resolve to 108*f4a2713aSLionel Sambuc /// a type, it is parsed as an identifier. If the attribute actually 109*f4a2713aSLionel Sambuc /// wanted an expression, it's out of luck (but it turns out that no 110*f4a2713aSLionel Sambuc /// attributes work that way, because C constant expressions are very 111*f4a2713aSLionel Sambuc /// limited). 112*f4a2713aSLionel Sambuc /// * In C++ mode, if the attribute argument list starts with an identifier, 113*f4a2713aSLionel Sambuc /// and the attribute *wants* an identifier, it is parsed as an identifier. 114*f4a2713aSLionel Sambuc /// At block scope, any additional tokens between the identifier and the 115*f4a2713aSLionel Sambuc /// ',' or ')' are ignored, otherwise they produce a parse error. 116*f4a2713aSLionel Sambuc /// 117*f4a2713aSLionel Sambuc /// We follow the C++ model, but don't allow junk after the identifier. 118*f4a2713aSLionel Sambuc void Parser::ParseGNUAttributes(ParsedAttributes &attrs, 119*f4a2713aSLionel Sambuc SourceLocation *endLoc, 120*f4a2713aSLionel Sambuc LateParsedAttrList *LateAttrs) { 121*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); 122*f4a2713aSLionel Sambuc 123*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___attribute)) { 124*f4a2713aSLionel Sambuc ConsumeToken(); 125*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 126*f4a2713aSLionel Sambuc "attribute")) { 127*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; 128*f4a2713aSLionel Sambuc return; 129*f4a2713aSLionel Sambuc } 130*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { 131*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; 132*f4a2713aSLionel Sambuc return; 133*f4a2713aSLionel Sambuc } 134*f4a2713aSLionel Sambuc // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) 135*f4a2713aSLionel Sambuc while (Tok.is(tok::identifier) || isDeclarationSpecifier() || 136*f4a2713aSLionel Sambuc Tok.is(tok::comma)) { 137*f4a2713aSLionel Sambuc if (Tok.is(tok::comma)) { 138*f4a2713aSLionel Sambuc // allows for empty/non-empty attributes. ((__vector_size__(16),,,,)) 139*f4a2713aSLionel Sambuc ConsumeToken(); 140*f4a2713aSLionel Sambuc continue; 141*f4a2713aSLionel Sambuc } 142*f4a2713aSLionel Sambuc // we have an identifier or declaration specifier (const, int, etc.) 143*f4a2713aSLionel Sambuc IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 144*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc = ConsumeToken(); 145*f4a2713aSLionel Sambuc 146*f4a2713aSLionel Sambuc if (Tok.is(tok::l_paren)) { 147*f4a2713aSLionel Sambuc // handle "parameterized" attributes 148*f4a2713aSLionel Sambuc if (LateAttrs && isAttributeLateParsed(*AttrName)) { 149*f4a2713aSLionel Sambuc LateParsedAttribute *LA = 150*f4a2713aSLionel Sambuc new LateParsedAttribute(this, *AttrName, AttrNameLoc); 151*f4a2713aSLionel Sambuc LateAttrs->push_back(LA); 152*f4a2713aSLionel Sambuc 153*f4a2713aSLionel Sambuc // Attributes in a class are parsed at the end of the class, along 154*f4a2713aSLionel Sambuc // with other late-parsed declarations. 155*f4a2713aSLionel Sambuc if (!ClassStack.empty() && !LateAttrs->parseSoon()) 156*f4a2713aSLionel Sambuc getCurrentClass().LateParsedDeclarations.push_back(LA); 157*f4a2713aSLionel Sambuc 158*f4a2713aSLionel Sambuc // consume everything up to and including the matching right parens 159*f4a2713aSLionel Sambuc ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false); 160*f4a2713aSLionel Sambuc 161*f4a2713aSLionel Sambuc Token Eof; 162*f4a2713aSLionel Sambuc Eof.startToken(); 163*f4a2713aSLionel Sambuc Eof.setLocation(Tok.getLocation()); 164*f4a2713aSLionel Sambuc LA->Toks.push_back(Eof); 165*f4a2713aSLionel Sambuc } else { 166*f4a2713aSLionel Sambuc ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, 167*f4a2713aSLionel Sambuc 0, SourceLocation(), AttributeList::AS_GNU); 168*f4a2713aSLionel Sambuc } 169*f4a2713aSLionel Sambuc } else { 170*f4a2713aSLionel Sambuc attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 171*f4a2713aSLionel Sambuc AttributeList::AS_GNU); 172*f4a2713aSLionel Sambuc } 173*f4a2713aSLionel Sambuc } 174*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 175*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 176*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 177*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 178*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 179*f4a2713aSLionel Sambuc if (endLoc) 180*f4a2713aSLionel Sambuc *endLoc = Loc; 181*f4a2713aSLionel Sambuc } 182*f4a2713aSLionel Sambuc } 183*f4a2713aSLionel Sambuc 184*f4a2713aSLionel Sambuc /// \brief Normalizes an attribute name by dropping prefixed and suffixed __. 185*f4a2713aSLionel Sambuc static StringRef normalizeAttrName(StringRef Name) { 186*f4a2713aSLionel Sambuc if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) 187*f4a2713aSLionel Sambuc Name = Name.drop_front(2).drop_back(2); 188*f4a2713aSLionel Sambuc return Name; 189*f4a2713aSLionel Sambuc } 190*f4a2713aSLionel Sambuc 191*f4a2713aSLionel Sambuc /// \brief Determine whether the given attribute has an identifier argument. 192*f4a2713aSLionel Sambuc static bool attributeHasIdentifierArg(const IdentifierInfo &II) { 193*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) 194*f4a2713aSLionel Sambuc #include "clang/Parse/AttrIdentifierArg.inc" 195*f4a2713aSLionel Sambuc .Default(false); 196*f4a2713aSLionel Sambuc } 197*f4a2713aSLionel Sambuc 198*f4a2713aSLionel Sambuc /// \brief Determine whether the given attribute parses a type argument. 199*f4a2713aSLionel Sambuc static bool attributeIsTypeArgAttr(const IdentifierInfo &II) { 200*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) 201*f4a2713aSLionel Sambuc #include "clang/Parse/AttrTypeArg.inc" 202*f4a2713aSLionel Sambuc .Default(false); 203*f4a2713aSLionel Sambuc } 204*f4a2713aSLionel Sambuc 205*f4a2713aSLionel Sambuc IdentifierLoc *Parser::ParseIdentifierLoc() { 206*f4a2713aSLionel Sambuc assert(Tok.is(tok::identifier) && "expected an identifier"); 207*f4a2713aSLionel Sambuc IdentifierLoc *IL = IdentifierLoc::create(Actions.Context, 208*f4a2713aSLionel Sambuc Tok.getLocation(), 209*f4a2713aSLionel Sambuc Tok.getIdentifierInfo()); 210*f4a2713aSLionel Sambuc ConsumeToken(); 211*f4a2713aSLionel Sambuc return IL; 212*f4a2713aSLionel Sambuc } 213*f4a2713aSLionel Sambuc 214*f4a2713aSLionel Sambuc void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName, 215*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc, 216*f4a2713aSLionel Sambuc ParsedAttributes &Attrs, 217*f4a2713aSLionel Sambuc SourceLocation *EndLoc) { 218*f4a2713aSLionel Sambuc BalancedDelimiterTracker Parens(*this, tok::l_paren); 219*f4a2713aSLionel Sambuc Parens.consumeOpen(); 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel Sambuc TypeResult T; 222*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) 223*f4a2713aSLionel Sambuc T = ParseTypeName(); 224*f4a2713aSLionel Sambuc 225*f4a2713aSLionel Sambuc if (Parens.consumeClose()) 226*f4a2713aSLionel Sambuc return; 227*f4a2713aSLionel Sambuc 228*f4a2713aSLionel Sambuc if (T.isInvalid()) 229*f4a2713aSLionel Sambuc return; 230*f4a2713aSLionel Sambuc 231*f4a2713aSLionel Sambuc if (T.isUsable()) 232*f4a2713aSLionel Sambuc Attrs.addNewTypeAttr(&AttrName, 233*f4a2713aSLionel Sambuc SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0, 234*f4a2713aSLionel Sambuc AttrNameLoc, T.get(), AttributeList::AS_GNU); 235*f4a2713aSLionel Sambuc else 236*f4a2713aSLionel Sambuc Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()), 237*f4a2713aSLionel Sambuc 0, AttrNameLoc, 0, 0, AttributeList::AS_GNU); 238*f4a2713aSLionel Sambuc } 239*f4a2713aSLionel Sambuc 240*f4a2713aSLionel Sambuc /// Parse the arguments to a parameterized GNU attribute or 241*f4a2713aSLionel Sambuc /// a C++11 attribute in "gnu" namespace. 242*f4a2713aSLionel Sambuc void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, 243*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc, 244*f4a2713aSLionel Sambuc ParsedAttributes &Attrs, 245*f4a2713aSLionel Sambuc SourceLocation *EndLoc, 246*f4a2713aSLionel Sambuc IdentifierInfo *ScopeName, 247*f4a2713aSLionel Sambuc SourceLocation ScopeLoc, 248*f4a2713aSLionel Sambuc AttributeList::Syntax Syntax) { 249*f4a2713aSLionel Sambuc 250*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 251*f4a2713aSLionel Sambuc 252*f4a2713aSLionel Sambuc AttributeList::Kind AttrKind = 253*f4a2713aSLionel Sambuc AttributeList::getKind(AttrName, ScopeName, Syntax); 254*f4a2713aSLionel Sambuc 255*f4a2713aSLionel Sambuc // Availability attributes have their own grammar. 256*f4a2713aSLionel Sambuc // FIXME: All these cases fail to pass in the syntax and scope, and might be 257*f4a2713aSLionel Sambuc // written as C++11 gnu:: attributes. 258*f4a2713aSLionel Sambuc if (AttrKind == AttributeList::AT_Availability) { 259*f4a2713aSLionel Sambuc ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 260*f4a2713aSLionel Sambuc return; 261*f4a2713aSLionel Sambuc } 262*f4a2713aSLionel Sambuc // Thread safety attributes are parsed in an unevaluated context. 263*f4a2713aSLionel Sambuc // FIXME: Share the bulk of the parsing code here and just pull out 264*f4a2713aSLionel Sambuc // the unevaluated context. 265*f4a2713aSLionel Sambuc if (IsThreadSafetyAttribute(AttrName->getName())) { 266*f4a2713aSLionel Sambuc ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 267*f4a2713aSLionel Sambuc return; 268*f4a2713aSLionel Sambuc } 269*f4a2713aSLionel Sambuc // Type safety attributes have their own grammar. 270*f4a2713aSLionel Sambuc if (AttrKind == AttributeList::AT_TypeTagForDatatype) { 271*f4a2713aSLionel Sambuc ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 272*f4a2713aSLionel Sambuc return; 273*f4a2713aSLionel Sambuc } 274*f4a2713aSLionel Sambuc // Some attributes expect solely a type parameter. 275*f4a2713aSLionel Sambuc if (attributeIsTypeArgAttr(*AttrName)) { 276*f4a2713aSLionel Sambuc ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc); 277*f4a2713aSLionel Sambuc return; 278*f4a2713aSLionel Sambuc } 279*f4a2713aSLionel Sambuc 280*f4a2713aSLionel Sambuc // Ignore the left paren location for now. 281*f4a2713aSLionel Sambuc ConsumeParen(); 282*f4a2713aSLionel Sambuc 283*f4a2713aSLionel Sambuc ArgsVector ArgExprs; 284*f4a2713aSLionel Sambuc 285*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 286*f4a2713aSLionel Sambuc // If this attribute wants an 'identifier' argument, make it so. 287*f4a2713aSLionel Sambuc bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName); 288*f4a2713aSLionel Sambuc 289*f4a2713aSLionel Sambuc // If we don't know how to parse this attribute, but this is the only 290*f4a2713aSLionel Sambuc // token in this argument, assume it's meant to be an identifier. 291*f4a2713aSLionel Sambuc if (AttrKind == AttributeList::UnknownAttribute) { 292*f4a2713aSLionel Sambuc const Token &Next = NextToken(); 293*f4a2713aSLionel Sambuc IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma); 294*f4a2713aSLionel Sambuc } 295*f4a2713aSLionel Sambuc 296*f4a2713aSLionel Sambuc if (IsIdentifierArg) 297*f4a2713aSLionel Sambuc ArgExprs.push_back(ParseIdentifierLoc()); 298*f4a2713aSLionel Sambuc } 299*f4a2713aSLionel Sambuc 300*f4a2713aSLionel Sambuc if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) { 301*f4a2713aSLionel Sambuc // Eat the comma. 302*f4a2713aSLionel Sambuc if (!ArgExprs.empty()) 303*f4a2713aSLionel Sambuc ConsumeToken(); 304*f4a2713aSLionel Sambuc 305*f4a2713aSLionel Sambuc // Parse the non-empty comma-separated list of expressions. 306*f4a2713aSLionel Sambuc while (1) { 307*f4a2713aSLionel Sambuc ExprResult ArgExpr(ParseAssignmentExpression()); 308*f4a2713aSLionel Sambuc if (ArgExpr.isInvalid()) { 309*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 310*f4a2713aSLionel Sambuc return; 311*f4a2713aSLionel Sambuc } 312*f4a2713aSLionel Sambuc ArgExprs.push_back(ArgExpr.release()); 313*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 314*f4a2713aSLionel Sambuc break; 315*f4a2713aSLionel Sambuc ConsumeToken(); // Eat the comma, move to the next argument 316*f4a2713aSLionel Sambuc } 317*f4a2713aSLionel Sambuc } 318*f4a2713aSLionel Sambuc 319*f4a2713aSLionel Sambuc SourceLocation RParen = Tok.getLocation(); 320*f4a2713aSLionel Sambuc if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 321*f4a2713aSLionel Sambuc SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc; 322*f4a2713aSLionel Sambuc Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc, 323*f4a2713aSLionel Sambuc ArgExprs.data(), ArgExprs.size(), Syntax); 324*f4a2713aSLionel Sambuc } 325*f4a2713aSLionel Sambuc } 326*f4a2713aSLionel Sambuc 327*f4a2713aSLionel Sambuc /// \brief Parses a single argument for a declspec, including the 328*f4a2713aSLionel Sambuc /// surrounding parens. 329*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, 330*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc, 331*f4a2713aSLionel Sambuc ParsedAttributes &Attrs) 332*f4a2713aSLionel Sambuc { 333*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 334*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, 335*f4a2713aSLionel Sambuc AttrName->getNameStart(), tok::r_paren)) 336*f4a2713aSLionel Sambuc return; 337*f4a2713aSLionel Sambuc 338*f4a2713aSLionel Sambuc ExprResult ArgExpr(ParseConstantExpression()); 339*f4a2713aSLionel Sambuc if (ArgExpr.isInvalid()) { 340*f4a2713aSLionel Sambuc T.skipToEnd(); 341*f4a2713aSLionel Sambuc return; 342*f4a2713aSLionel Sambuc } 343*f4a2713aSLionel Sambuc ArgsUnion ExprList = ArgExpr.take(); 344*f4a2713aSLionel Sambuc Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1, 345*f4a2713aSLionel Sambuc AttributeList::AS_Declspec); 346*f4a2713aSLionel Sambuc 347*f4a2713aSLionel Sambuc T.consumeClose(); 348*f4a2713aSLionel Sambuc } 349*f4a2713aSLionel Sambuc 350*f4a2713aSLionel Sambuc /// \brief Determines whether a declspec is a "simple" one requiring no 351*f4a2713aSLionel Sambuc /// arguments. 352*f4a2713aSLionel Sambuc bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) { 353*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(Ident->getName()) 354*f4a2713aSLionel Sambuc .Case("dllimport", true) 355*f4a2713aSLionel Sambuc .Case("dllexport", true) 356*f4a2713aSLionel Sambuc .Case("noreturn", true) 357*f4a2713aSLionel Sambuc .Case("nothrow", true) 358*f4a2713aSLionel Sambuc .Case("noinline", true) 359*f4a2713aSLionel Sambuc .Case("naked", true) 360*f4a2713aSLionel Sambuc .Case("appdomain", true) 361*f4a2713aSLionel Sambuc .Case("process", true) 362*f4a2713aSLionel Sambuc .Case("jitintrinsic", true) 363*f4a2713aSLionel Sambuc .Case("noalias", true) 364*f4a2713aSLionel Sambuc .Case("restrict", true) 365*f4a2713aSLionel Sambuc .Case("novtable", true) 366*f4a2713aSLionel Sambuc .Case("selectany", true) 367*f4a2713aSLionel Sambuc .Case("thread", true) 368*f4a2713aSLionel Sambuc .Case("safebuffers", true ) 369*f4a2713aSLionel Sambuc .Default(false); 370*f4a2713aSLionel Sambuc } 371*f4a2713aSLionel Sambuc 372*f4a2713aSLionel Sambuc /// \brief Attempts to parse a declspec which is not simple (one that takes 373*f4a2713aSLionel Sambuc /// parameters). Will return false if we properly handled the declspec, or 374*f4a2713aSLionel Sambuc /// true if it is an unknown declspec. 375*f4a2713aSLionel Sambuc void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, 376*f4a2713aSLionel Sambuc SourceLocation Loc, 377*f4a2713aSLionel Sambuc ParsedAttributes &Attrs) { 378*f4a2713aSLionel Sambuc // Try to handle the easy case first -- these declspecs all take a single 379*f4a2713aSLionel Sambuc // parameter as their argument. 380*f4a2713aSLionel Sambuc if (llvm::StringSwitch<bool>(Ident->getName()) 381*f4a2713aSLionel Sambuc .Case("uuid", true) 382*f4a2713aSLionel Sambuc .Case("align", true) 383*f4a2713aSLionel Sambuc .Case("allocate", true) 384*f4a2713aSLionel Sambuc .Default(false)) { 385*f4a2713aSLionel Sambuc ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 386*f4a2713aSLionel Sambuc } else if (Ident->getName() == "deprecated") { 387*f4a2713aSLionel Sambuc // The deprecated declspec has an optional single argument, so we will 388*f4a2713aSLionel Sambuc // check for a l-paren to decide whether we should parse an argument or 389*f4a2713aSLionel Sambuc // not. 390*f4a2713aSLionel Sambuc if (Tok.getKind() == tok::l_paren) 391*f4a2713aSLionel Sambuc ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 392*f4a2713aSLionel Sambuc else 393*f4a2713aSLionel Sambuc Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec); 394*f4a2713aSLionel Sambuc } else if (Ident->getName() == "property") { 395*f4a2713aSLionel Sambuc // The property declspec is more complex in that it can take one or two 396*f4a2713aSLionel Sambuc // assignment expressions as a parameter, but the lhs of the assignment 397*f4a2713aSLionel Sambuc // must be named get or put. 398*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 399*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_expected_lparen_after) 400*f4a2713aSLionel Sambuc << Ident->getNameStart(); 401*f4a2713aSLionel Sambuc return; 402*f4a2713aSLionel Sambuc } 403*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 404*f4a2713aSLionel Sambuc T.expectAndConsume(diag::err_expected_lparen_after, 405*f4a2713aSLionel Sambuc Ident->getNameStart(), tok::r_paren); 406*f4a2713aSLionel Sambuc 407*f4a2713aSLionel Sambuc enum AccessorKind { 408*f4a2713aSLionel Sambuc AK_Invalid = -1, 409*f4a2713aSLionel Sambuc AK_Put = 0, AK_Get = 1 // indices into AccessorNames 410*f4a2713aSLionel Sambuc }; 411*f4a2713aSLionel Sambuc IdentifierInfo *AccessorNames[] = { 0, 0 }; 412*f4a2713aSLionel Sambuc bool HasInvalidAccessor = false; 413*f4a2713aSLionel Sambuc 414*f4a2713aSLionel Sambuc // Parse the accessor specifications. 415*f4a2713aSLionel Sambuc while (true) { 416*f4a2713aSLionel Sambuc // Stop if this doesn't look like an accessor spec. 417*f4a2713aSLionel Sambuc if (!Tok.is(tok::identifier)) { 418*f4a2713aSLionel Sambuc // If the user wrote a completely empty list, use a special diagnostic. 419*f4a2713aSLionel Sambuc if (Tok.is(tok::r_paren) && !HasInvalidAccessor && 420*f4a2713aSLionel Sambuc AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) { 421*f4a2713aSLionel Sambuc Diag(Loc, diag::err_ms_property_no_getter_or_putter); 422*f4a2713aSLionel Sambuc break; 423*f4a2713aSLionel Sambuc } 424*f4a2713aSLionel Sambuc 425*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor); 426*f4a2713aSLionel Sambuc break; 427*f4a2713aSLionel Sambuc } 428*f4a2713aSLionel Sambuc 429*f4a2713aSLionel Sambuc AccessorKind Kind; 430*f4a2713aSLionel Sambuc SourceLocation KindLoc = Tok.getLocation(); 431*f4a2713aSLionel Sambuc StringRef KindStr = Tok.getIdentifierInfo()->getName(); 432*f4a2713aSLionel Sambuc if (KindStr == "get") { 433*f4a2713aSLionel Sambuc Kind = AK_Get; 434*f4a2713aSLionel Sambuc } else if (KindStr == "put") { 435*f4a2713aSLionel Sambuc Kind = AK_Put; 436*f4a2713aSLionel Sambuc 437*f4a2713aSLionel Sambuc // Recover from the common mistake of using 'set' instead of 'put'. 438*f4a2713aSLionel Sambuc } else if (KindStr == "set") { 439*f4a2713aSLionel Sambuc Diag(KindLoc, diag::err_ms_property_has_set_accessor) 440*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(KindLoc, "put"); 441*f4a2713aSLionel Sambuc Kind = AK_Put; 442*f4a2713aSLionel Sambuc 443*f4a2713aSLionel Sambuc // Handle the mistake of forgetting the accessor kind by skipping 444*f4a2713aSLionel Sambuc // this accessor. 445*f4a2713aSLionel Sambuc } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) { 446*f4a2713aSLionel Sambuc Diag(KindLoc, diag::err_ms_property_missing_accessor_kind); 447*f4a2713aSLionel Sambuc ConsumeToken(); 448*f4a2713aSLionel Sambuc HasInvalidAccessor = true; 449*f4a2713aSLionel Sambuc goto next_property_accessor; 450*f4a2713aSLionel Sambuc 451*f4a2713aSLionel Sambuc // Otherwise, complain about the unknown accessor kind. 452*f4a2713aSLionel Sambuc } else { 453*f4a2713aSLionel Sambuc Diag(KindLoc, diag::err_ms_property_unknown_accessor); 454*f4a2713aSLionel Sambuc HasInvalidAccessor = true; 455*f4a2713aSLionel Sambuc Kind = AK_Invalid; 456*f4a2713aSLionel Sambuc 457*f4a2713aSLionel Sambuc // Try to keep parsing unless it doesn't look like an accessor spec. 458*f4a2713aSLionel Sambuc if (!NextToken().is(tok::equal)) break; 459*f4a2713aSLionel Sambuc } 460*f4a2713aSLionel Sambuc 461*f4a2713aSLionel Sambuc // Consume the identifier. 462*f4a2713aSLionel Sambuc ConsumeToken(); 463*f4a2713aSLionel Sambuc 464*f4a2713aSLionel Sambuc // Consume the '='. 465*f4a2713aSLionel Sambuc if (Tok.is(tok::equal)) { 466*f4a2713aSLionel Sambuc ConsumeToken(); 467*f4a2713aSLionel Sambuc } else { 468*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_ms_property_expected_equal) 469*f4a2713aSLionel Sambuc << KindStr; 470*f4a2713aSLionel Sambuc break; 471*f4a2713aSLionel Sambuc } 472*f4a2713aSLionel Sambuc 473*f4a2713aSLionel Sambuc // Expect the method name. 474*f4a2713aSLionel Sambuc if (!Tok.is(tok::identifier)) { 475*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name); 476*f4a2713aSLionel Sambuc break; 477*f4a2713aSLionel Sambuc } 478*f4a2713aSLionel Sambuc 479*f4a2713aSLionel Sambuc if (Kind == AK_Invalid) { 480*f4a2713aSLionel Sambuc // Just drop invalid accessors. 481*f4a2713aSLionel Sambuc } else if (AccessorNames[Kind] != NULL) { 482*f4a2713aSLionel Sambuc // Complain about the repeated accessor, ignore it, and keep parsing. 483*f4a2713aSLionel Sambuc Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr; 484*f4a2713aSLionel Sambuc } else { 485*f4a2713aSLionel Sambuc AccessorNames[Kind] = Tok.getIdentifierInfo(); 486*f4a2713aSLionel Sambuc } 487*f4a2713aSLionel Sambuc ConsumeToken(); 488*f4a2713aSLionel Sambuc 489*f4a2713aSLionel Sambuc next_property_accessor: 490*f4a2713aSLionel Sambuc // Keep processing accessors until we run out. 491*f4a2713aSLionel Sambuc if (Tok.is(tok::comma)) { 492*f4a2713aSLionel Sambuc ConsumeAnyToken(); 493*f4a2713aSLionel Sambuc continue; 494*f4a2713aSLionel Sambuc 495*f4a2713aSLionel Sambuc // If we run into the ')', stop without consuming it. 496*f4a2713aSLionel Sambuc } else if (Tok.is(tok::r_paren)) { 497*f4a2713aSLionel Sambuc break; 498*f4a2713aSLionel Sambuc } else { 499*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen); 500*f4a2713aSLionel Sambuc break; 501*f4a2713aSLionel Sambuc } 502*f4a2713aSLionel Sambuc } 503*f4a2713aSLionel Sambuc 504*f4a2713aSLionel Sambuc // Only add the property attribute if it was well-formed. 505*f4a2713aSLionel Sambuc if (!HasInvalidAccessor) { 506*f4a2713aSLionel Sambuc Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(), 507*f4a2713aSLionel Sambuc AccessorNames[AK_Get], AccessorNames[AK_Put], 508*f4a2713aSLionel Sambuc AttributeList::AS_Declspec); 509*f4a2713aSLionel Sambuc } 510*f4a2713aSLionel Sambuc T.skipToEnd(); 511*f4a2713aSLionel Sambuc } else { 512*f4a2713aSLionel Sambuc // We don't recognize this as a valid declspec, but instead of creating the 513*f4a2713aSLionel Sambuc // attribute and allowing sema to warn about it, we will warn here instead. 514*f4a2713aSLionel Sambuc // This is because some attributes have multiple spellings, but we need to 515*f4a2713aSLionel Sambuc // disallow that for declspecs (such as align vs aligned). If we made the 516*f4a2713aSLionel Sambuc // attribute, we'd have to split the valid declspec spelling logic into 517*f4a2713aSLionel Sambuc // both locations. 518*f4a2713aSLionel Sambuc Diag(Loc, diag::warn_ms_declspec_unknown) << Ident; 519*f4a2713aSLionel Sambuc 520*f4a2713aSLionel Sambuc // If there's an open paren, we should eat the open and close parens under 521*f4a2713aSLionel Sambuc // the assumption that this unknown declspec has parameters. 522*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 523*f4a2713aSLionel Sambuc if (!T.consumeOpen()) 524*f4a2713aSLionel Sambuc T.skipToEnd(); 525*f4a2713aSLionel Sambuc } 526*f4a2713aSLionel Sambuc } 527*f4a2713aSLionel Sambuc 528*f4a2713aSLionel Sambuc /// [MS] decl-specifier: 529*f4a2713aSLionel Sambuc /// __declspec ( extended-decl-modifier-seq ) 530*f4a2713aSLionel Sambuc /// 531*f4a2713aSLionel Sambuc /// [MS] extended-decl-modifier-seq: 532*f4a2713aSLionel Sambuc /// extended-decl-modifier[opt] 533*f4a2713aSLionel Sambuc /// extended-decl-modifier extended-decl-modifier-seq 534*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) { 535*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); 536*f4a2713aSLionel Sambuc 537*f4a2713aSLionel Sambuc ConsumeToken(); 538*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 539*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec", 540*f4a2713aSLionel Sambuc tok::r_paren)) 541*f4a2713aSLionel Sambuc return; 542*f4a2713aSLionel Sambuc 543*f4a2713aSLionel Sambuc // An empty declspec is perfectly legal and should not warn. Additionally, 544*f4a2713aSLionel Sambuc // you can specify multiple attributes per declspec. 545*f4a2713aSLionel Sambuc while (Tok.getKind() != tok::r_paren) { 546*f4a2713aSLionel Sambuc // We expect either a well-known identifier or a generic string. Anything 547*f4a2713aSLionel Sambuc // else is a malformed declspec. 548*f4a2713aSLionel Sambuc bool IsString = Tok.getKind() == tok::string_literal ? true : false; 549*f4a2713aSLionel Sambuc if (!IsString && Tok.getKind() != tok::identifier && 550*f4a2713aSLionel Sambuc Tok.getKind() != tok::kw_restrict) { 551*f4a2713aSLionel Sambuc Diag(Tok, diag::err_ms_declspec_type); 552*f4a2713aSLionel Sambuc T.skipToEnd(); 553*f4a2713aSLionel Sambuc return; 554*f4a2713aSLionel Sambuc } 555*f4a2713aSLionel Sambuc 556*f4a2713aSLionel Sambuc IdentifierInfo *AttrName; 557*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc; 558*f4a2713aSLionel Sambuc if (IsString) { 559*f4a2713aSLionel Sambuc SmallString<8> StrBuffer; 560*f4a2713aSLionel Sambuc bool Invalid = false; 561*f4a2713aSLionel Sambuc StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid); 562*f4a2713aSLionel Sambuc if (Invalid) { 563*f4a2713aSLionel Sambuc T.skipToEnd(); 564*f4a2713aSLionel Sambuc return; 565*f4a2713aSLionel Sambuc } 566*f4a2713aSLionel Sambuc AttrName = PP.getIdentifierInfo(Str); 567*f4a2713aSLionel Sambuc AttrNameLoc = ConsumeStringToken(); 568*f4a2713aSLionel Sambuc } else { 569*f4a2713aSLionel Sambuc AttrName = Tok.getIdentifierInfo(); 570*f4a2713aSLionel Sambuc AttrNameLoc = ConsumeToken(); 571*f4a2713aSLionel Sambuc } 572*f4a2713aSLionel Sambuc 573*f4a2713aSLionel Sambuc if (IsString || IsSimpleMicrosoftDeclSpec(AttrName)) 574*f4a2713aSLionel Sambuc // If we have a generic string, we will allow it because there is no 575*f4a2713aSLionel Sambuc // documented list of allowable string declspecs, but we know they exist 576*f4a2713aSLionel Sambuc // (for instance, SAL declspecs in older versions of MSVC). 577*f4a2713aSLionel Sambuc // 578*f4a2713aSLionel Sambuc // Alternatively, if the identifier is a simple one, then it requires no 579*f4a2713aSLionel Sambuc // arguments and can be turned into an attribute directly. 580*f4a2713aSLionel Sambuc Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 581*f4a2713aSLionel Sambuc AttributeList::AS_Declspec); 582*f4a2713aSLionel Sambuc else 583*f4a2713aSLionel Sambuc ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs); 584*f4a2713aSLionel Sambuc } 585*f4a2713aSLionel Sambuc T.consumeClose(); 586*f4a2713aSLionel Sambuc } 587*f4a2713aSLionel Sambuc 588*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { 589*f4a2713aSLionel Sambuc // Treat these like attributes 590*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || 591*f4a2713aSLionel Sambuc Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || 592*f4a2713aSLionel Sambuc Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 593*f4a2713aSLionel Sambuc Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) || 594*f4a2713aSLionel Sambuc Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) { 595*f4a2713aSLionel Sambuc IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 596*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc = ConsumeToken(); 597*f4a2713aSLionel Sambuc attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 598*f4a2713aSLionel Sambuc AttributeList::AS_Keyword); 599*f4a2713aSLionel Sambuc } 600*f4a2713aSLionel Sambuc } 601*f4a2713aSLionel Sambuc 602*f4a2713aSLionel Sambuc void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { 603*f4a2713aSLionel Sambuc // Treat these like attributes 604*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___pascal)) { 605*f4a2713aSLionel Sambuc IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 606*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc = ConsumeToken(); 607*f4a2713aSLionel Sambuc attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 608*f4a2713aSLionel Sambuc AttributeList::AS_Keyword); 609*f4a2713aSLionel Sambuc } 610*f4a2713aSLionel Sambuc } 611*f4a2713aSLionel Sambuc 612*f4a2713aSLionel Sambuc void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { 613*f4a2713aSLionel Sambuc // Treat these like attributes 614*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___kernel)) { 615*f4a2713aSLionel Sambuc IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 616*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc = ConsumeToken(); 617*f4a2713aSLionel Sambuc attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 618*f4a2713aSLionel Sambuc AttributeList::AS_Keyword); 619*f4a2713aSLionel Sambuc } 620*f4a2713aSLionel Sambuc } 621*f4a2713aSLionel Sambuc 622*f4a2713aSLionel Sambuc void Parser::ParseOpenCLQualifiers(DeclSpec &DS) { 623*f4a2713aSLionel Sambuc // FIXME: The mapping from attribute spelling to semantics should be 624*f4a2713aSLionel Sambuc // performed in Sema, not here. 625*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 626*f4a2713aSLionel Sambuc switch(Tok.getKind()) { 627*f4a2713aSLionel Sambuc // OpenCL qualifiers: 628*f4a2713aSLionel Sambuc case tok::kw___private: 629*f4a2713aSLionel Sambuc case tok::kw_private: 630*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 631*f4a2713aSLionel Sambuc Actions.getASTContext(), 632*f4a2713aSLionel Sambuc PP.getIdentifierInfo("address_space"), Loc, 0); 633*f4a2713aSLionel Sambuc break; 634*f4a2713aSLionel Sambuc 635*f4a2713aSLionel Sambuc case tok::kw___global: 636*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 637*f4a2713aSLionel Sambuc Actions.getASTContext(), 638*f4a2713aSLionel Sambuc PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global); 639*f4a2713aSLionel Sambuc break; 640*f4a2713aSLionel Sambuc 641*f4a2713aSLionel Sambuc case tok::kw___local: 642*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 643*f4a2713aSLionel Sambuc Actions.getASTContext(), 644*f4a2713aSLionel Sambuc PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local); 645*f4a2713aSLionel Sambuc break; 646*f4a2713aSLionel Sambuc 647*f4a2713aSLionel Sambuc case tok::kw___constant: 648*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 649*f4a2713aSLionel Sambuc Actions.getASTContext(), 650*f4a2713aSLionel Sambuc PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant); 651*f4a2713aSLionel Sambuc break; 652*f4a2713aSLionel Sambuc 653*f4a2713aSLionel Sambuc case tok::kw___read_only: 654*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 655*f4a2713aSLionel Sambuc Actions.getASTContext(), 656*f4a2713aSLionel Sambuc PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only); 657*f4a2713aSLionel Sambuc break; 658*f4a2713aSLionel Sambuc 659*f4a2713aSLionel Sambuc case tok::kw___write_only: 660*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 661*f4a2713aSLionel Sambuc Actions.getASTContext(), 662*f4a2713aSLionel Sambuc PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only); 663*f4a2713aSLionel Sambuc break; 664*f4a2713aSLionel Sambuc 665*f4a2713aSLionel Sambuc case tok::kw___read_write: 666*f4a2713aSLionel Sambuc DS.getAttributes().addNewInteger( 667*f4a2713aSLionel Sambuc Actions.getASTContext(), 668*f4a2713aSLionel Sambuc PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write); 669*f4a2713aSLionel Sambuc break; 670*f4a2713aSLionel Sambuc default: break; 671*f4a2713aSLionel Sambuc } 672*f4a2713aSLionel Sambuc } 673*f4a2713aSLionel Sambuc 674*f4a2713aSLionel Sambuc /// \brief Parse a version number. 675*f4a2713aSLionel Sambuc /// 676*f4a2713aSLionel Sambuc /// version: 677*f4a2713aSLionel Sambuc /// simple-integer 678*f4a2713aSLionel Sambuc /// simple-integer ',' simple-integer 679*f4a2713aSLionel Sambuc /// simple-integer ',' simple-integer ',' simple-integer 680*f4a2713aSLionel Sambuc VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { 681*f4a2713aSLionel Sambuc Range = Tok.getLocation(); 682*f4a2713aSLionel Sambuc 683*f4a2713aSLionel Sambuc if (!Tok.is(tok::numeric_constant)) { 684*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_version); 685*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, 686*f4a2713aSLionel Sambuc StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 687*f4a2713aSLionel Sambuc return VersionTuple(); 688*f4a2713aSLionel Sambuc } 689*f4a2713aSLionel Sambuc 690*f4a2713aSLionel Sambuc // Parse the major (and possibly minor and subminor) versions, which 691*f4a2713aSLionel Sambuc // are stored in the numeric constant. We utilize a quirk of the 692*f4a2713aSLionel Sambuc // lexer, which is that it handles something like 1.2.3 as a single 693*f4a2713aSLionel Sambuc // numeric constant, rather than two separate tokens. 694*f4a2713aSLionel Sambuc SmallString<512> Buffer; 695*f4a2713aSLionel Sambuc Buffer.resize(Tok.getLength()+1); 696*f4a2713aSLionel Sambuc const char *ThisTokBegin = &Buffer[0]; 697*f4a2713aSLionel Sambuc 698*f4a2713aSLionel Sambuc // Get the spelling of the token, which eliminates trigraphs, etc. 699*f4a2713aSLionel Sambuc bool Invalid = false; 700*f4a2713aSLionel Sambuc unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid); 701*f4a2713aSLionel Sambuc if (Invalid) 702*f4a2713aSLionel Sambuc return VersionTuple(); 703*f4a2713aSLionel Sambuc 704*f4a2713aSLionel Sambuc // Parse the major version. 705*f4a2713aSLionel Sambuc unsigned AfterMajor = 0; 706*f4a2713aSLionel Sambuc unsigned Major = 0; 707*f4a2713aSLionel Sambuc while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) { 708*f4a2713aSLionel Sambuc Major = Major * 10 + ThisTokBegin[AfterMajor] - '0'; 709*f4a2713aSLionel Sambuc ++AfterMajor; 710*f4a2713aSLionel Sambuc } 711*f4a2713aSLionel Sambuc 712*f4a2713aSLionel Sambuc if (AfterMajor == 0) { 713*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_version); 714*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, 715*f4a2713aSLionel Sambuc StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 716*f4a2713aSLionel Sambuc return VersionTuple(); 717*f4a2713aSLionel Sambuc } 718*f4a2713aSLionel Sambuc 719*f4a2713aSLionel Sambuc if (AfterMajor == ActualLength) { 720*f4a2713aSLionel Sambuc ConsumeToken(); 721*f4a2713aSLionel Sambuc 722*f4a2713aSLionel Sambuc // We only had a single version component. 723*f4a2713aSLionel Sambuc if (Major == 0) { 724*f4a2713aSLionel Sambuc Diag(Tok, diag::err_zero_version); 725*f4a2713aSLionel Sambuc return VersionTuple(); 726*f4a2713aSLionel Sambuc } 727*f4a2713aSLionel Sambuc 728*f4a2713aSLionel Sambuc return VersionTuple(Major); 729*f4a2713aSLionel Sambuc } 730*f4a2713aSLionel Sambuc 731*f4a2713aSLionel Sambuc if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { 732*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_version); 733*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, 734*f4a2713aSLionel Sambuc StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 735*f4a2713aSLionel Sambuc return VersionTuple(); 736*f4a2713aSLionel Sambuc } 737*f4a2713aSLionel Sambuc 738*f4a2713aSLionel Sambuc // Parse the minor version. 739*f4a2713aSLionel Sambuc unsigned AfterMinor = AfterMajor + 1; 740*f4a2713aSLionel Sambuc unsigned Minor = 0; 741*f4a2713aSLionel Sambuc while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) { 742*f4a2713aSLionel Sambuc Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0'; 743*f4a2713aSLionel Sambuc ++AfterMinor; 744*f4a2713aSLionel Sambuc } 745*f4a2713aSLionel Sambuc 746*f4a2713aSLionel Sambuc if (AfterMinor == ActualLength) { 747*f4a2713aSLionel Sambuc ConsumeToken(); 748*f4a2713aSLionel Sambuc 749*f4a2713aSLionel Sambuc // We had major.minor. 750*f4a2713aSLionel Sambuc if (Major == 0 && Minor == 0) { 751*f4a2713aSLionel Sambuc Diag(Tok, diag::err_zero_version); 752*f4a2713aSLionel Sambuc return VersionTuple(); 753*f4a2713aSLionel Sambuc } 754*f4a2713aSLionel Sambuc 755*f4a2713aSLionel Sambuc return VersionTuple(Major, Minor); 756*f4a2713aSLionel Sambuc } 757*f4a2713aSLionel Sambuc 758*f4a2713aSLionel Sambuc // If what follows is not a '.', we have a problem. 759*f4a2713aSLionel Sambuc if (ThisTokBegin[AfterMinor] != '.') { 760*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_version); 761*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, 762*f4a2713aSLionel Sambuc StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 763*f4a2713aSLionel Sambuc return VersionTuple(); 764*f4a2713aSLionel Sambuc } 765*f4a2713aSLionel Sambuc 766*f4a2713aSLionel Sambuc // Parse the subminor version. 767*f4a2713aSLionel Sambuc unsigned AfterSubminor = AfterMinor + 1; 768*f4a2713aSLionel Sambuc unsigned Subminor = 0; 769*f4a2713aSLionel Sambuc while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) { 770*f4a2713aSLionel Sambuc Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0'; 771*f4a2713aSLionel Sambuc ++AfterSubminor; 772*f4a2713aSLionel Sambuc } 773*f4a2713aSLionel Sambuc 774*f4a2713aSLionel Sambuc if (AfterSubminor != ActualLength) { 775*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_version); 776*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, 777*f4a2713aSLionel Sambuc StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); 778*f4a2713aSLionel Sambuc return VersionTuple(); 779*f4a2713aSLionel Sambuc } 780*f4a2713aSLionel Sambuc ConsumeToken(); 781*f4a2713aSLionel Sambuc return VersionTuple(Major, Minor, Subminor); 782*f4a2713aSLionel Sambuc } 783*f4a2713aSLionel Sambuc 784*f4a2713aSLionel Sambuc /// \brief Parse the contents of the "availability" attribute. 785*f4a2713aSLionel Sambuc /// 786*f4a2713aSLionel Sambuc /// availability-attribute: 787*f4a2713aSLionel Sambuc /// 'availability' '(' platform ',' version-arg-list, opt-message')' 788*f4a2713aSLionel Sambuc /// 789*f4a2713aSLionel Sambuc /// platform: 790*f4a2713aSLionel Sambuc /// identifier 791*f4a2713aSLionel Sambuc /// 792*f4a2713aSLionel Sambuc /// version-arg-list: 793*f4a2713aSLionel Sambuc /// version-arg 794*f4a2713aSLionel Sambuc /// version-arg ',' version-arg-list 795*f4a2713aSLionel Sambuc /// 796*f4a2713aSLionel Sambuc /// version-arg: 797*f4a2713aSLionel Sambuc /// 'introduced' '=' version 798*f4a2713aSLionel Sambuc /// 'deprecated' '=' version 799*f4a2713aSLionel Sambuc /// 'obsoleted' = version 800*f4a2713aSLionel Sambuc /// 'unavailable' 801*f4a2713aSLionel Sambuc /// opt-message: 802*f4a2713aSLionel Sambuc /// 'message' '=' <string> 803*f4a2713aSLionel Sambuc void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, 804*f4a2713aSLionel Sambuc SourceLocation AvailabilityLoc, 805*f4a2713aSLionel Sambuc ParsedAttributes &attrs, 806*f4a2713aSLionel Sambuc SourceLocation *endLoc) { 807*f4a2713aSLionel Sambuc enum { Introduced, Deprecated, Obsoleted, Unknown }; 808*f4a2713aSLionel Sambuc AvailabilityChange Changes[Unknown]; 809*f4a2713aSLionel Sambuc ExprResult MessageExpr; 810*f4a2713aSLionel Sambuc 811*f4a2713aSLionel Sambuc // Opening '('. 812*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 813*f4a2713aSLionel Sambuc if (T.consumeOpen()) { 814*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen); 815*f4a2713aSLionel Sambuc return; 816*f4a2713aSLionel Sambuc } 817*f4a2713aSLionel Sambuc 818*f4a2713aSLionel Sambuc // Parse the platform name, 819*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 820*f4a2713aSLionel Sambuc Diag(Tok, diag::err_availability_expected_platform); 821*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 822*f4a2713aSLionel Sambuc return; 823*f4a2713aSLionel Sambuc } 824*f4a2713aSLionel Sambuc IdentifierLoc *Platform = ParseIdentifierLoc(); 825*f4a2713aSLionel Sambuc 826*f4a2713aSLionel Sambuc // Parse the ',' following the platform name. 827*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) 828*f4a2713aSLionel Sambuc return; 829*f4a2713aSLionel Sambuc 830*f4a2713aSLionel Sambuc // If we haven't grabbed the pointers for the identifiers 831*f4a2713aSLionel Sambuc // "introduced", "deprecated", and "obsoleted", do so now. 832*f4a2713aSLionel Sambuc if (!Ident_introduced) { 833*f4a2713aSLionel Sambuc Ident_introduced = PP.getIdentifierInfo("introduced"); 834*f4a2713aSLionel Sambuc Ident_deprecated = PP.getIdentifierInfo("deprecated"); 835*f4a2713aSLionel Sambuc Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); 836*f4a2713aSLionel Sambuc Ident_unavailable = PP.getIdentifierInfo("unavailable"); 837*f4a2713aSLionel Sambuc Ident_message = PP.getIdentifierInfo("message"); 838*f4a2713aSLionel Sambuc } 839*f4a2713aSLionel Sambuc 840*f4a2713aSLionel Sambuc // Parse the set of introductions/deprecations/removals. 841*f4a2713aSLionel Sambuc SourceLocation UnavailableLoc; 842*f4a2713aSLionel Sambuc do { 843*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 844*f4a2713aSLionel Sambuc Diag(Tok, diag::err_availability_expected_change); 845*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 846*f4a2713aSLionel Sambuc return; 847*f4a2713aSLionel Sambuc } 848*f4a2713aSLionel Sambuc IdentifierInfo *Keyword = Tok.getIdentifierInfo(); 849*f4a2713aSLionel Sambuc SourceLocation KeywordLoc = ConsumeToken(); 850*f4a2713aSLionel Sambuc 851*f4a2713aSLionel Sambuc if (Keyword == Ident_unavailable) { 852*f4a2713aSLionel Sambuc if (UnavailableLoc.isValid()) { 853*f4a2713aSLionel Sambuc Diag(KeywordLoc, diag::err_availability_redundant) 854*f4a2713aSLionel Sambuc << Keyword << SourceRange(UnavailableLoc); 855*f4a2713aSLionel Sambuc } 856*f4a2713aSLionel Sambuc UnavailableLoc = KeywordLoc; 857*f4a2713aSLionel Sambuc 858*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 859*f4a2713aSLionel Sambuc break; 860*f4a2713aSLionel Sambuc 861*f4a2713aSLionel Sambuc ConsumeToken(); 862*f4a2713aSLionel Sambuc continue; 863*f4a2713aSLionel Sambuc } 864*f4a2713aSLionel Sambuc 865*f4a2713aSLionel Sambuc if (Tok.isNot(tok::equal)) { 866*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_equal_after) 867*f4a2713aSLionel Sambuc << Keyword; 868*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 869*f4a2713aSLionel Sambuc return; 870*f4a2713aSLionel Sambuc } 871*f4a2713aSLionel Sambuc ConsumeToken(); 872*f4a2713aSLionel Sambuc if (Keyword == Ident_message) { 873*f4a2713aSLionel Sambuc if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals. 874*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_string_literal) 875*f4a2713aSLionel Sambuc << /*Source='availability attribute'*/2; 876*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 877*f4a2713aSLionel Sambuc return; 878*f4a2713aSLionel Sambuc } 879*f4a2713aSLionel Sambuc MessageExpr = ParseStringLiteralExpression(); 880*f4a2713aSLionel Sambuc break; 881*f4a2713aSLionel Sambuc } 882*f4a2713aSLionel Sambuc 883*f4a2713aSLionel Sambuc SourceRange VersionRange; 884*f4a2713aSLionel Sambuc VersionTuple Version = ParseVersionTuple(VersionRange); 885*f4a2713aSLionel Sambuc 886*f4a2713aSLionel Sambuc if (Version.empty()) { 887*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 888*f4a2713aSLionel Sambuc return; 889*f4a2713aSLionel Sambuc } 890*f4a2713aSLionel Sambuc 891*f4a2713aSLionel Sambuc unsigned Index; 892*f4a2713aSLionel Sambuc if (Keyword == Ident_introduced) 893*f4a2713aSLionel Sambuc Index = Introduced; 894*f4a2713aSLionel Sambuc else if (Keyword == Ident_deprecated) 895*f4a2713aSLionel Sambuc Index = Deprecated; 896*f4a2713aSLionel Sambuc else if (Keyword == Ident_obsoleted) 897*f4a2713aSLionel Sambuc Index = Obsoleted; 898*f4a2713aSLionel Sambuc else 899*f4a2713aSLionel Sambuc Index = Unknown; 900*f4a2713aSLionel Sambuc 901*f4a2713aSLionel Sambuc if (Index < Unknown) { 902*f4a2713aSLionel Sambuc if (!Changes[Index].KeywordLoc.isInvalid()) { 903*f4a2713aSLionel Sambuc Diag(KeywordLoc, diag::err_availability_redundant) 904*f4a2713aSLionel Sambuc << Keyword 905*f4a2713aSLionel Sambuc << SourceRange(Changes[Index].KeywordLoc, 906*f4a2713aSLionel Sambuc Changes[Index].VersionRange.getEnd()); 907*f4a2713aSLionel Sambuc } 908*f4a2713aSLionel Sambuc 909*f4a2713aSLionel Sambuc Changes[Index].KeywordLoc = KeywordLoc; 910*f4a2713aSLionel Sambuc Changes[Index].Version = Version; 911*f4a2713aSLionel Sambuc Changes[Index].VersionRange = VersionRange; 912*f4a2713aSLionel Sambuc } else { 913*f4a2713aSLionel Sambuc Diag(KeywordLoc, diag::err_availability_unknown_change) 914*f4a2713aSLionel Sambuc << Keyword << VersionRange; 915*f4a2713aSLionel Sambuc } 916*f4a2713aSLionel Sambuc 917*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 918*f4a2713aSLionel Sambuc break; 919*f4a2713aSLionel Sambuc 920*f4a2713aSLionel Sambuc ConsumeToken(); 921*f4a2713aSLionel Sambuc } while (true); 922*f4a2713aSLionel Sambuc 923*f4a2713aSLionel Sambuc // Closing ')'. 924*f4a2713aSLionel Sambuc if (T.consumeClose()) 925*f4a2713aSLionel Sambuc return; 926*f4a2713aSLionel Sambuc 927*f4a2713aSLionel Sambuc if (endLoc) 928*f4a2713aSLionel Sambuc *endLoc = T.getCloseLocation(); 929*f4a2713aSLionel Sambuc 930*f4a2713aSLionel Sambuc // The 'unavailable' availability cannot be combined with any other 931*f4a2713aSLionel Sambuc // availability changes. Make sure that hasn't happened. 932*f4a2713aSLionel Sambuc if (UnavailableLoc.isValid()) { 933*f4a2713aSLionel Sambuc bool Complained = false; 934*f4a2713aSLionel Sambuc for (unsigned Index = Introduced; Index != Unknown; ++Index) { 935*f4a2713aSLionel Sambuc if (Changes[Index].KeywordLoc.isValid()) { 936*f4a2713aSLionel Sambuc if (!Complained) { 937*f4a2713aSLionel Sambuc Diag(UnavailableLoc, diag::warn_availability_and_unavailable) 938*f4a2713aSLionel Sambuc << SourceRange(Changes[Index].KeywordLoc, 939*f4a2713aSLionel Sambuc Changes[Index].VersionRange.getEnd()); 940*f4a2713aSLionel Sambuc Complained = true; 941*f4a2713aSLionel Sambuc } 942*f4a2713aSLionel Sambuc 943*f4a2713aSLionel Sambuc // Clear out the availability. 944*f4a2713aSLionel Sambuc Changes[Index] = AvailabilityChange(); 945*f4a2713aSLionel Sambuc } 946*f4a2713aSLionel Sambuc } 947*f4a2713aSLionel Sambuc } 948*f4a2713aSLionel Sambuc 949*f4a2713aSLionel Sambuc // Record this attribute 950*f4a2713aSLionel Sambuc attrs.addNew(&Availability, 951*f4a2713aSLionel Sambuc SourceRange(AvailabilityLoc, T.getCloseLocation()), 952*f4a2713aSLionel Sambuc 0, AvailabilityLoc, 953*f4a2713aSLionel Sambuc Platform, 954*f4a2713aSLionel Sambuc Changes[Introduced], 955*f4a2713aSLionel Sambuc Changes[Deprecated], 956*f4a2713aSLionel Sambuc Changes[Obsoleted], 957*f4a2713aSLionel Sambuc UnavailableLoc, MessageExpr.take(), 958*f4a2713aSLionel Sambuc AttributeList::AS_GNU); 959*f4a2713aSLionel Sambuc } 960*f4a2713aSLionel Sambuc 961*f4a2713aSLionel Sambuc 962*f4a2713aSLionel Sambuc // Late Parsed Attributes: 963*f4a2713aSLionel Sambuc // See other examples of late parsing in lib/Parse/ParseCXXInlineMethods 964*f4a2713aSLionel Sambuc 965*f4a2713aSLionel Sambuc void Parser::LateParsedDeclaration::ParseLexedAttributes() {} 966*f4a2713aSLionel Sambuc 967*f4a2713aSLionel Sambuc void Parser::LateParsedClass::ParseLexedAttributes() { 968*f4a2713aSLionel Sambuc Self->ParseLexedAttributes(*Class); 969*f4a2713aSLionel Sambuc } 970*f4a2713aSLionel Sambuc 971*f4a2713aSLionel Sambuc void Parser::LateParsedAttribute::ParseLexedAttributes() { 972*f4a2713aSLionel Sambuc Self->ParseLexedAttribute(*this, true, false); 973*f4a2713aSLionel Sambuc } 974*f4a2713aSLionel Sambuc 975*f4a2713aSLionel Sambuc /// Wrapper class which calls ParseLexedAttribute, after setting up the 976*f4a2713aSLionel Sambuc /// scope appropriately. 977*f4a2713aSLionel Sambuc void Parser::ParseLexedAttributes(ParsingClass &Class) { 978*f4a2713aSLionel Sambuc // Deal with templates 979*f4a2713aSLionel Sambuc // FIXME: Test cases to make sure this does the right thing for templates. 980*f4a2713aSLionel Sambuc bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 981*f4a2713aSLionel Sambuc ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 982*f4a2713aSLionel Sambuc HasTemplateScope); 983*f4a2713aSLionel Sambuc if (HasTemplateScope) 984*f4a2713aSLionel Sambuc Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 985*f4a2713aSLionel Sambuc 986*f4a2713aSLionel Sambuc // Set or update the scope flags. 987*f4a2713aSLionel Sambuc bool AlreadyHasClassScope = Class.TopLevelClass; 988*f4a2713aSLionel Sambuc unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; 989*f4a2713aSLionel Sambuc ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 990*f4a2713aSLionel Sambuc ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 991*f4a2713aSLionel Sambuc 992*f4a2713aSLionel Sambuc // Enter the scope of nested classes 993*f4a2713aSLionel Sambuc if (!AlreadyHasClassScope) 994*f4a2713aSLionel Sambuc Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 995*f4a2713aSLionel Sambuc Class.TagOrTemplate); 996*f4a2713aSLionel Sambuc if (!Class.LateParsedDeclarations.empty()) { 997*f4a2713aSLionel Sambuc for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ 998*f4a2713aSLionel Sambuc Class.LateParsedDeclarations[i]->ParseLexedAttributes(); 999*f4a2713aSLionel Sambuc } 1000*f4a2713aSLionel Sambuc } 1001*f4a2713aSLionel Sambuc 1002*f4a2713aSLionel Sambuc if (!AlreadyHasClassScope) 1003*f4a2713aSLionel Sambuc Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 1004*f4a2713aSLionel Sambuc Class.TagOrTemplate); 1005*f4a2713aSLionel Sambuc } 1006*f4a2713aSLionel Sambuc 1007*f4a2713aSLionel Sambuc 1008*f4a2713aSLionel Sambuc /// \brief Parse all attributes in LAs, and attach them to Decl D. 1009*f4a2713aSLionel Sambuc void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 1010*f4a2713aSLionel Sambuc bool EnterScope, bool OnDefinition) { 1011*f4a2713aSLionel Sambuc assert(LAs.parseSoon() && 1012*f4a2713aSLionel Sambuc "Attribute list should be marked for immediate parsing."); 1013*f4a2713aSLionel Sambuc for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 1014*f4a2713aSLionel Sambuc if (D) 1015*f4a2713aSLionel Sambuc LAs[i]->addDecl(D); 1016*f4a2713aSLionel Sambuc ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 1017*f4a2713aSLionel Sambuc delete LAs[i]; 1018*f4a2713aSLionel Sambuc } 1019*f4a2713aSLionel Sambuc LAs.clear(); 1020*f4a2713aSLionel Sambuc } 1021*f4a2713aSLionel Sambuc 1022*f4a2713aSLionel Sambuc 1023*f4a2713aSLionel Sambuc /// \brief Finish parsing an attribute for which parsing was delayed. 1024*f4a2713aSLionel Sambuc /// This will be called at the end of parsing a class declaration 1025*f4a2713aSLionel Sambuc /// for each LateParsedAttribute. We consume the saved tokens and 1026*f4a2713aSLionel Sambuc /// create an attribute with the arguments filled in. We add this 1027*f4a2713aSLionel Sambuc /// to the Attribute list for the decl. 1028*f4a2713aSLionel Sambuc void Parser::ParseLexedAttribute(LateParsedAttribute &LA, 1029*f4a2713aSLionel Sambuc bool EnterScope, bool OnDefinition) { 1030*f4a2713aSLionel Sambuc // Save the current token position. 1031*f4a2713aSLionel Sambuc SourceLocation OrigLoc = Tok.getLocation(); 1032*f4a2713aSLionel Sambuc 1033*f4a2713aSLionel Sambuc // Append the current token at the end of the new token stream so that it 1034*f4a2713aSLionel Sambuc // doesn't get lost. 1035*f4a2713aSLionel Sambuc LA.Toks.push_back(Tok); 1036*f4a2713aSLionel Sambuc PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); 1037*f4a2713aSLionel Sambuc // Consume the previously pushed token. 1038*f4a2713aSLionel Sambuc ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 1039*f4a2713aSLionel Sambuc 1040*f4a2713aSLionel Sambuc if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) { 1041*f4a2713aSLionel Sambuc // FIXME: Do not warn on C++11 attributes, once we start supporting 1042*f4a2713aSLionel Sambuc // them here. 1043*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_attribute_on_function_definition) 1044*f4a2713aSLionel Sambuc << LA.AttrName.getName(); 1045*f4a2713aSLionel Sambuc } 1046*f4a2713aSLionel Sambuc 1047*f4a2713aSLionel Sambuc ParsedAttributes Attrs(AttrFactory); 1048*f4a2713aSLionel Sambuc SourceLocation endLoc; 1049*f4a2713aSLionel Sambuc 1050*f4a2713aSLionel Sambuc if (LA.Decls.size() > 0) { 1051*f4a2713aSLionel Sambuc Decl *D = LA.Decls[0]; 1052*f4a2713aSLionel Sambuc NamedDecl *ND = dyn_cast<NamedDecl>(D); 1053*f4a2713aSLionel Sambuc RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 1054*f4a2713aSLionel Sambuc 1055*f4a2713aSLionel Sambuc // Allow 'this' within late-parsed attributes. 1056*f4a2713aSLionel Sambuc Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0, 1057*f4a2713aSLionel Sambuc ND && ND->isCXXInstanceMember()); 1058*f4a2713aSLionel Sambuc 1059*f4a2713aSLionel Sambuc if (LA.Decls.size() == 1) { 1060*f4a2713aSLionel Sambuc // If the Decl is templatized, add template parameters to scope. 1061*f4a2713aSLionel Sambuc bool HasTemplateScope = EnterScope && D->isTemplateDecl(); 1062*f4a2713aSLionel Sambuc ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); 1063*f4a2713aSLionel Sambuc if (HasTemplateScope) 1064*f4a2713aSLionel Sambuc Actions.ActOnReenterTemplateScope(Actions.CurScope, D); 1065*f4a2713aSLionel Sambuc 1066*f4a2713aSLionel Sambuc // If the Decl is on a function, add function parameters to the scope. 1067*f4a2713aSLionel Sambuc bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); 1068*f4a2713aSLionel Sambuc ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); 1069*f4a2713aSLionel Sambuc if (HasFunScope) 1070*f4a2713aSLionel Sambuc Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 1071*f4a2713aSLionel Sambuc 1072*f4a2713aSLionel Sambuc ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1073*f4a2713aSLionel Sambuc 0, SourceLocation(), AttributeList::AS_GNU); 1074*f4a2713aSLionel Sambuc 1075*f4a2713aSLionel Sambuc if (HasFunScope) { 1076*f4a2713aSLionel Sambuc Actions.ActOnExitFunctionContext(); 1077*f4a2713aSLionel Sambuc FnScope.Exit(); // Pop scope, and remove Decls from IdResolver 1078*f4a2713aSLionel Sambuc } 1079*f4a2713aSLionel Sambuc if (HasTemplateScope) { 1080*f4a2713aSLionel Sambuc TempScope.Exit(); 1081*f4a2713aSLionel Sambuc } 1082*f4a2713aSLionel Sambuc } else { 1083*f4a2713aSLionel Sambuc // If there are multiple decls, then the decl cannot be within the 1084*f4a2713aSLionel Sambuc // function scope. 1085*f4a2713aSLionel Sambuc ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1086*f4a2713aSLionel Sambuc 0, SourceLocation(), AttributeList::AS_GNU); 1087*f4a2713aSLionel Sambuc } 1088*f4a2713aSLionel Sambuc } else { 1089*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 1090*f4a2713aSLionel Sambuc } 1091*f4a2713aSLionel Sambuc 1092*f4a2713aSLionel Sambuc for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) { 1093*f4a2713aSLionel Sambuc Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 1094*f4a2713aSLionel Sambuc } 1095*f4a2713aSLionel Sambuc 1096*f4a2713aSLionel Sambuc if (Tok.getLocation() != OrigLoc) { 1097*f4a2713aSLionel Sambuc // Due to a parsing error, we either went over the cached tokens or 1098*f4a2713aSLionel Sambuc // there are still cached tokens left, so we skip the leftover tokens. 1099*f4a2713aSLionel Sambuc // Since this is an uncommon situation that should be avoided, use the 1100*f4a2713aSLionel Sambuc // expensive isBeforeInTranslationUnit call. 1101*f4a2713aSLionel Sambuc if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 1102*f4a2713aSLionel Sambuc OrigLoc)) 1103*f4a2713aSLionel Sambuc while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 1104*f4a2713aSLionel Sambuc ConsumeAnyToken(); 1105*f4a2713aSLionel Sambuc } 1106*f4a2713aSLionel Sambuc } 1107*f4a2713aSLionel Sambuc 1108*f4a2713aSLionel Sambuc /// \brief Wrapper around a case statement checking if AttrName is 1109*f4a2713aSLionel Sambuc /// one of the thread safety attributes 1110*f4a2713aSLionel Sambuc bool Parser::IsThreadSafetyAttribute(StringRef AttrName) { 1111*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(AttrName) 1112*f4a2713aSLionel Sambuc .Case("guarded_by", true) 1113*f4a2713aSLionel Sambuc .Case("guarded_var", true) 1114*f4a2713aSLionel Sambuc .Case("pt_guarded_by", true) 1115*f4a2713aSLionel Sambuc .Case("pt_guarded_var", true) 1116*f4a2713aSLionel Sambuc .Case("lockable", true) 1117*f4a2713aSLionel Sambuc .Case("scoped_lockable", true) 1118*f4a2713aSLionel Sambuc .Case("no_thread_safety_analysis", true) 1119*f4a2713aSLionel Sambuc .Case("acquired_after", true) 1120*f4a2713aSLionel Sambuc .Case("acquired_before", true) 1121*f4a2713aSLionel Sambuc .Case("exclusive_lock_function", true) 1122*f4a2713aSLionel Sambuc .Case("shared_lock_function", true) 1123*f4a2713aSLionel Sambuc .Case("exclusive_trylock_function", true) 1124*f4a2713aSLionel Sambuc .Case("shared_trylock_function", true) 1125*f4a2713aSLionel Sambuc .Case("unlock_function", true) 1126*f4a2713aSLionel Sambuc .Case("lock_returned", true) 1127*f4a2713aSLionel Sambuc .Case("locks_excluded", true) 1128*f4a2713aSLionel Sambuc .Case("exclusive_locks_required", true) 1129*f4a2713aSLionel Sambuc .Case("shared_locks_required", true) 1130*f4a2713aSLionel Sambuc .Default(false); 1131*f4a2713aSLionel Sambuc } 1132*f4a2713aSLionel Sambuc 1133*f4a2713aSLionel Sambuc /// \brief Parse the contents of thread safety attributes. These 1134*f4a2713aSLionel Sambuc /// should always be parsed as an expression list. 1135*f4a2713aSLionel Sambuc /// 1136*f4a2713aSLionel Sambuc /// We need to special case the parsing due to the fact that if the first token 1137*f4a2713aSLionel Sambuc /// of the first argument is an identifier, the main parse loop will store 1138*f4a2713aSLionel Sambuc /// that token as a "parameter" and the rest of 1139*f4a2713aSLionel Sambuc /// the arguments will be added to a list of "arguments". However, 1140*f4a2713aSLionel Sambuc /// subsequent tokens in the first argument are lost. We instead parse each 1141*f4a2713aSLionel Sambuc /// argument as an expression and add all arguments to the list of "arguments". 1142*f4a2713aSLionel Sambuc /// In future, we will take advantage of this special case to also 1143*f4a2713aSLionel Sambuc /// deal with some argument scoping issues here (for example, referring to a 1144*f4a2713aSLionel Sambuc /// function parameter in the attribute on that function). 1145*f4a2713aSLionel Sambuc void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, 1146*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc, 1147*f4a2713aSLionel Sambuc ParsedAttributes &Attrs, 1148*f4a2713aSLionel Sambuc SourceLocation *EndLoc) { 1149*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1150*f4a2713aSLionel Sambuc 1151*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1152*f4a2713aSLionel Sambuc T.consumeOpen(); 1153*f4a2713aSLionel Sambuc 1154*f4a2713aSLionel Sambuc ArgsVector ArgExprs; 1155*f4a2713aSLionel Sambuc bool ArgExprsOk = true; 1156*f4a2713aSLionel Sambuc 1157*f4a2713aSLionel Sambuc // now parse the list of expressions 1158*f4a2713aSLionel Sambuc while (Tok.isNot(tok::r_paren)) { 1159*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 1160*f4a2713aSLionel Sambuc ExprResult ArgExpr(ParseAssignmentExpression()); 1161*f4a2713aSLionel Sambuc if (ArgExpr.isInvalid()) { 1162*f4a2713aSLionel Sambuc ArgExprsOk = false; 1163*f4a2713aSLionel Sambuc T.consumeClose(); 1164*f4a2713aSLionel Sambuc break; 1165*f4a2713aSLionel Sambuc } else { 1166*f4a2713aSLionel Sambuc ArgExprs.push_back(ArgExpr.release()); 1167*f4a2713aSLionel Sambuc } 1168*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 1169*f4a2713aSLionel Sambuc break; 1170*f4a2713aSLionel Sambuc ConsumeToken(); // Eat the comma, move to the next argument 1171*f4a2713aSLionel Sambuc } 1172*f4a2713aSLionel Sambuc // Match the ')'. 1173*f4a2713aSLionel Sambuc if (ArgExprsOk && !T.consumeClose()) { 1174*f4a2713aSLionel Sambuc Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(), 1175*f4a2713aSLionel Sambuc ArgExprs.size(), AttributeList::AS_GNU); 1176*f4a2713aSLionel Sambuc } 1177*f4a2713aSLionel Sambuc if (EndLoc) 1178*f4a2713aSLionel Sambuc *EndLoc = T.getCloseLocation(); 1179*f4a2713aSLionel Sambuc } 1180*f4a2713aSLionel Sambuc 1181*f4a2713aSLionel Sambuc void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 1182*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc, 1183*f4a2713aSLionel Sambuc ParsedAttributes &Attrs, 1184*f4a2713aSLionel Sambuc SourceLocation *EndLoc) { 1185*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1186*f4a2713aSLionel Sambuc 1187*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1188*f4a2713aSLionel Sambuc T.consumeOpen(); 1189*f4a2713aSLionel Sambuc 1190*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 1191*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 1192*f4a2713aSLionel Sambuc T.skipToEnd(); 1193*f4a2713aSLionel Sambuc return; 1194*f4a2713aSLionel Sambuc } 1195*f4a2713aSLionel Sambuc IdentifierLoc *ArgumentKind = ParseIdentifierLoc(); 1196*f4a2713aSLionel Sambuc 1197*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) { 1198*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_comma); 1199*f4a2713aSLionel Sambuc T.skipToEnd(); 1200*f4a2713aSLionel Sambuc return; 1201*f4a2713aSLionel Sambuc } 1202*f4a2713aSLionel Sambuc ConsumeToken(); 1203*f4a2713aSLionel Sambuc 1204*f4a2713aSLionel Sambuc SourceRange MatchingCTypeRange; 1205*f4a2713aSLionel Sambuc TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange); 1206*f4a2713aSLionel Sambuc if (MatchingCType.isInvalid()) { 1207*f4a2713aSLionel Sambuc T.skipToEnd(); 1208*f4a2713aSLionel Sambuc return; 1209*f4a2713aSLionel Sambuc } 1210*f4a2713aSLionel Sambuc 1211*f4a2713aSLionel Sambuc bool LayoutCompatible = false; 1212*f4a2713aSLionel Sambuc bool MustBeNull = false; 1213*f4a2713aSLionel Sambuc while (Tok.is(tok::comma)) { 1214*f4a2713aSLionel Sambuc ConsumeToken(); 1215*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 1216*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 1217*f4a2713aSLionel Sambuc T.skipToEnd(); 1218*f4a2713aSLionel Sambuc return; 1219*f4a2713aSLionel Sambuc } 1220*f4a2713aSLionel Sambuc IdentifierInfo *Flag = Tok.getIdentifierInfo(); 1221*f4a2713aSLionel Sambuc if (Flag->isStr("layout_compatible")) 1222*f4a2713aSLionel Sambuc LayoutCompatible = true; 1223*f4a2713aSLionel Sambuc else if (Flag->isStr("must_be_null")) 1224*f4a2713aSLionel Sambuc MustBeNull = true; 1225*f4a2713aSLionel Sambuc else { 1226*f4a2713aSLionel Sambuc Diag(Tok, diag::err_type_safety_unknown_flag) << Flag; 1227*f4a2713aSLionel Sambuc T.skipToEnd(); 1228*f4a2713aSLionel Sambuc return; 1229*f4a2713aSLionel Sambuc } 1230*f4a2713aSLionel Sambuc ConsumeToken(); // consume flag 1231*f4a2713aSLionel Sambuc } 1232*f4a2713aSLionel Sambuc 1233*f4a2713aSLionel Sambuc if (!T.consumeClose()) { 1234*f4a2713aSLionel Sambuc Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc, 1235*f4a2713aSLionel Sambuc ArgumentKind, MatchingCType.release(), 1236*f4a2713aSLionel Sambuc LayoutCompatible, MustBeNull, 1237*f4a2713aSLionel Sambuc AttributeList::AS_GNU); 1238*f4a2713aSLionel Sambuc } 1239*f4a2713aSLionel Sambuc 1240*f4a2713aSLionel Sambuc if (EndLoc) 1241*f4a2713aSLionel Sambuc *EndLoc = T.getCloseLocation(); 1242*f4a2713aSLionel Sambuc } 1243*f4a2713aSLionel Sambuc 1244*f4a2713aSLionel Sambuc /// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 1245*f4a2713aSLionel Sambuc /// of a C++11 attribute-specifier in a location where an attribute is not 1246*f4a2713aSLionel Sambuc /// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 1247*f4a2713aSLionel Sambuc /// situation. 1248*f4a2713aSLionel Sambuc /// 1249*f4a2713aSLionel Sambuc /// \return \c true if we skipped an attribute-like chunk of tokens, \c false if 1250*f4a2713aSLionel Sambuc /// this doesn't appear to actually be an attribute-specifier, and the caller 1251*f4a2713aSLionel Sambuc /// should try to parse it. 1252*f4a2713aSLionel Sambuc bool Parser::DiagnoseProhibitedCXX11Attribute() { 1253*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 1254*f4a2713aSLionel Sambuc 1255*f4a2713aSLionel Sambuc switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) { 1256*f4a2713aSLionel Sambuc case CAK_NotAttributeSpecifier: 1257*f4a2713aSLionel Sambuc // No diagnostic: we're in Obj-C++11 and this is not actually an attribute. 1258*f4a2713aSLionel Sambuc return false; 1259*f4a2713aSLionel Sambuc 1260*f4a2713aSLionel Sambuc case CAK_InvalidAttributeSpecifier: 1261*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute); 1262*f4a2713aSLionel Sambuc return false; 1263*f4a2713aSLionel Sambuc 1264*f4a2713aSLionel Sambuc case CAK_AttributeSpecifier: 1265*f4a2713aSLionel Sambuc // Parse and discard the attributes. 1266*f4a2713aSLionel Sambuc SourceLocation BeginLoc = ConsumeBracket(); 1267*f4a2713aSLionel Sambuc ConsumeBracket(); 1268*f4a2713aSLionel Sambuc SkipUntil(tok::r_square); 1269*f4a2713aSLionel Sambuc assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); 1270*f4a2713aSLionel Sambuc SourceLocation EndLoc = ConsumeBracket(); 1271*f4a2713aSLionel Sambuc Diag(BeginLoc, diag::err_attributes_not_allowed) 1272*f4a2713aSLionel Sambuc << SourceRange(BeginLoc, EndLoc); 1273*f4a2713aSLionel Sambuc return true; 1274*f4a2713aSLionel Sambuc } 1275*f4a2713aSLionel Sambuc llvm_unreachable("All cases handled above."); 1276*f4a2713aSLionel Sambuc } 1277*f4a2713aSLionel Sambuc 1278*f4a2713aSLionel Sambuc /// \brief We have found the opening square brackets of a C++11 1279*f4a2713aSLionel Sambuc /// attribute-specifier in a location where an attribute is not permitted, but 1280*f4a2713aSLionel Sambuc /// we know where the attributes ought to be written. Parse them anyway, and 1281*f4a2713aSLionel Sambuc /// provide a fixit moving them to the right place. 1282*f4a2713aSLionel Sambuc void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, 1283*f4a2713aSLionel Sambuc SourceLocation CorrectLocation) { 1284*f4a2713aSLionel Sambuc assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) || 1285*f4a2713aSLionel Sambuc Tok.is(tok::kw_alignas)); 1286*f4a2713aSLionel Sambuc 1287*f4a2713aSLionel Sambuc // Consume the attributes. 1288*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 1289*f4a2713aSLionel Sambuc ParseCXX11Attributes(Attrs); 1290*f4a2713aSLionel Sambuc CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true); 1291*f4a2713aSLionel Sambuc 1292*f4a2713aSLionel Sambuc Diag(Loc, diag::err_attributes_not_allowed) 1293*f4a2713aSLionel Sambuc << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) 1294*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(AttrRange); 1295*f4a2713aSLionel Sambuc } 1296*f4a2713aSLionel Sambuc 1297*f4a2713aSLionel Sambuc void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { 1298*f4a2713aSLionel Sambuc Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) 1299*f4a2713aSLionel Sambuc << attrs.Range; 1300*f4a2713aSLionel Sambuc } 1301*f4a2713aSLionel Sambuc 1302*f4a2713aSLionel Sambuc void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) { 1303*f4a2713aSLionel Sambuc AttributeList *AttrList = attrs.getList(); 1304*f4a2713aSLionel Sambuc while (AttrList) { 1305*f4a2713aSLionel Sambuc if (AttrList->isCXX11Attribute()) { 1306*f4a2713aSLionel Sambuc Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr) 1307*f4a2713aSLionel Sambuc << AttrList->getName(); 1308*f4a2713aSLionel Sambuc AttrList->setInvalid(); 1309*f4a2713aSLionel Sambuc } 1310*f4a2713aSLionel Sambuc AttrList = AttrList->getNext(); 1311*f4a2713aSLionel Sambuc } 1312*f4a2713aSLionel Sambuc } 1313*f4a2713aSLionel Sambuc 1314*f4a2713aSLionel Sambuc /// ParseDeclaration - Parse a full 'declaration', which consists of 1315*f4a2713aSLionel Sambuc /// declaration-specifiers, some number of declarators, and a semicolon. 1316*f4a2713aSLionel Sambuc /// 'Context' should be a Declarator::TheContext value. This returns the 1317*f4a2713aSLionel Sambuc /// location of the semicolon in DeclEnd. 1318*f4a2713aSLionel Sambuc /// 1319*f4a2713aSLionel Sambuc /// declaration: [C99 6.7] 1320*f4a2713aSLionel Sambuc /// block-declaration -> 1321*f4a2713aSLionel Sambuc /// simple-declaration 1322*f4a2713aSLionel Sambuc /// others [FIXME] 1323*f4a2713aSLionel Sambuc /// [C++] template-declaration 1324*f4a2713aSLionel Sambuc /// [C++] namespace-definition 1325*f4a2713aSLionel Sambuc /// [C++] using-directive 1326*f4a2713aSLionel Sambuc /// [C++] using-declaration 1327*f4a2713aSLionel Sambuc /// [C++11/C11] static_assert-declaration 1328*f4a2713aSLionel Sambuc /// others... [FIXME] 1329*f4a2713aSLionel Sambuc /// 1330*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, 1331*f4a2713aSLionel Sambuc unsigned Context, 1332*f4a2713aSLionel Sambuc SourceLocation &DeclEnd, 1333*f4a2713aSLionel Sambuc ParsedAttributesWithRange &attrs) { 1334*f4a2713aSLionel Sambuc ParenBraceBracketBalancer BalancerRAIIObj(*this); 1335*f4a2713aSLionel Sambuc // Must temporarily exit the objective-c container scope for 1336*f4a2713aSLionel Sambuc // parsing c none objective-c decls. 1337*f4a2713aSLionel Sambuc ObjCDeclContextSwitch ObjCDC(*this); 1338*f4a2713aSLionel Sambuc 1339*f4a2713aSLionel Sambuc Decl *SingleDecl = 0; 1340*f4a2713aSLionel Sambuc Decl *OwnedType = 0; 1341*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 1342*f4a2713aSLionel Sambuc case tok::kw_template: 1343*f4a2713aSLionel Sambuc case tok::kw_export: 1344*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1345*f4a2713aSLionel Sambuc SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); 1346*f4a2713aSLionel Sambuc break; 1347*f4a2713aSLionel Sambuc case tok::kw_inline: 1348*f4a2713aSLionel Sambuc // Could be the start of an inline namespace. Allowed as an ext in C++03. 1349*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { 1350*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1351*f4a2713aSLionel Sambuc SourceLocation InlineLoc = ConsumeToken(); 1352*f4a2713aSLionel Sambuc SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); 1353*f4a2713aSLionel Sambuc break; 1354*f4a2713aSLionel Sambuc } 1355*f4a2713aSLionel Sambuc return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, 1356*f4a2713aSLionel Sambuc true); 1357*f4a2713aSLionel Sambuc case tok::kw_namespace: 1358*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1359*f4a2713aSLionel Sambuc SingleDecl = ParseNamespace(Context, DeclEnd); 1360*f4a2713aSLionel Sambuc break; 1361*f4a2713aSLionel Sambuc case tok::kw_using: 1362*f4a2713aSLionel Sambuc SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), 1363*f4a2713aSLionel Sambuc DeclEnd, attrs, &OwnedType); 1364*f4a2713aSLionel Sambuc break; 1365*f4a2713aSLionel Sambuc case tok::kw_static_assert: 1366*f4a2713aSLionel Sambuc case tok::kw__Static_assert: 1367*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1368*f4a2713aSLionel Sambuc SingleDecl = ParseStaticAssertDeclaration(DeclEnd); 1369*f4a2713aSLionel Sambuc break; 1370*f4a2713aSLionel Sambuc default: 1371*f4a2713aSLionel Sambuc return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true); 1372*f4a2713aSLionel Sambuc } 1373*f4a2713aSLionel Sambuc 1374*f4a2713aSLionel Sambuc // This routine returns a DeclGroup, if the thing we parsed only contains a 1375*f4a2713aSLionel Sambuc // single decl, convert it now. Alias declarations can also declare a type; 1376*f4a2713aSLionel Sambuc // include that too if it is present. 1377*f4a2713aSLionel Sambuc return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType); 1378*f4a2713aSLionel Sambuc } 1379*f4a2713aSLionel Sambuc 1380*f4a2713aSLionel Sambuc /// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl] 1381*f4a2713aSLionel Sambuc /// declaration-specifiers init-declarator-list[opt] ';' 1382*f4a2713aSLionel Sambuc /// [C++11] attribute-specifier-seq decl-specifier-seq[opt] 1383*f4a2713aSLionel Sambuc /// init-declarator-list ';' 1384*f4a2713aSLionel Sambuc ///[C90/C++]init-declarator-list ';' [TODO] 1385*f4a2713aSLionel Sambuc /// [OMP] threadprivate-directive [TODO] 1386*f4a2713aSLionel Sambuc /// 1387*f4a2713aSLionel Sambuc /// for-range-declaration: [C++11 6.5p1: stmt.ranged] 1388*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] type-specifier-seq declarator 1389*f4a2713aSLionel Sambuc /// 1390*f4a2713aSLionel Sambuc /// If RequireSemi is false, this does not check for a ';' at the end of the 1391*f4a2713aSLionel Sambuc /// declaration. If it is true, it checks for and eats it. 1392*f4a2713aSLionel Sambuc /// 1393*f4a2713aSLionel Sambuc /// If FRI is non-null, we might be parsing a for-range-declaration instead 1394*f4a2713aSLionel Sambuc /// of a simple-declaration. If we find that we are, we also parse the 1395*f4a2713aSLionel Sambuc /// for-range-initializer, and place it here. 1396*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy 1397*f4a2713aSLionel Sambuc Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context, 1398*f4a2713aSLionel Sambuc SourceLocation &DeclEnd, 1399*f4a2713aSLionel Sambuc ParsedAttributesWithRange &Attrs, 1400*f4a2713aSLionel Sambuc bool RequireSemi, ForRangeInit *FRI) { 1401*f4a2713aSLionel Sambuc // Parse the common declaration-specifiers piece. 1402*f4a2713aSLionel Sambuc ParsingDeclSpec DS(*this); 1403*f4a2713aSLionel Sambuc 1404*f4a2713aSLionel Sambuc DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context); 1405*f4a2713aSLionel Sambuc ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext); 1406*f4a2713aSLionel Sambuc 1407*f4a2713aSLionel Sambuc // If we had a free-standing type definition with a missing semicolon, we 1408*f4a2713aSLionel Sambuc // may get this far before the problem becomes obvious. 1409*f4a2713aSLionel Sambuc if (DS.hasTagDefinition() && 1410*f4a2713aSLionel Sambuc DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext)) 1411*f4a2713aSLionel Sambuc return DeclGroupPtrTy(); 1412*f4a2713aSLionel Sambuc 1413*f4a2713aSLionel Sambuc // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 1414*f4a2713aSLionel Sambuc // declaration-specifiers init-declarator-list[opt] ';' 1415*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 1416*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 1417*f4a2713aSLionel Sambuc DeclEnd = Tok.getLocation(); 1418*f4a2713aSLionel Sambuc if (RequireSemi) ConsumeToken(); 1419*f4a2713aSLionel Sambuc Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 1420*f4a2713aSLionel Sambuc DS); 1421*f4a2713aSLionel Sambuc DS.complete(TheDecl); 1422*f4a2713aSLionel Sambuc return Actions.ConvertDeclToDeclGroup(TheDecl); 1423*f4a2713aSLionel Sambuc } 1424*f4a2713aSLionel Sambuc 1425*f4a2713aSLionel Sambuc DS.takeAttributesFrom(Attrs); 1426*f4a2713aSLionel Sambuc return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI); 1427*f4a2713aSLionel Sambuc } 1428*f4a2713aSLionel Sambuc 1429*f4a2713aSLionel Sambuc /// Returns true if this might be the start of a declarator, or a common typo 1430*f4a2713aSLionel Sambuc /// for a declarator. 1431*f4a2713aSLionel Sambuc bool Parser::MightBeDeclarator(unsigned Context) { 1432*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 1433*f4a2713aSLionel Sambuc case tok::annot_cxxscope: 1434*f4a2713aSLionel Sambuc case tok::annot_template_id: 1435*f4a2713aSLionel Sambuc case tok::caret: 1436*f4a2713aSLionel Sambuc case tok::code_completion: 1437*f4a2713aSLionel Sambuc case tok::coloncolon: 1438*f4a2713aSLionel Sambuc case tok::ellipsis: 1439*f4a2713aSLionel Sambuc case tok::kw___attribute: 1440*f4a2713aSLionel Sambuc case tok::kw_operator: 1441*f4a2713aSLionel Sambuc case tok::l_paren: 1442*f4a2713aSLionel Sambuc case tok::star: 1443*f4a2713aSLionel Sambuc return true; 1444*f4a2713aSLionel Sambuc 1445*f4a2713aSLionel Sambuc case tok::amp: 1446*f4a2713aSLionel Sambuc case tok::ampamp: 1447*f4a2713aSLionel Sambuc return getLangOpts().CPlusPlus; 1448*f4a2713aSLionel Sambuc 1449*f4a2713aSLionel Sambuc case tok::l_square: // Might be an attribute on an unnamed bit-field. 1450*f4a2713aSLionel Sambuc return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 && 1451*f4a2713aSLionel Sambuc NextToken().is(tok::l_square); 1452*f4a2713aSLionel Sambuc 1453*f4a2713aSLionel Sambuc case tok::colon: // Might be a typo for '::' or an unnamed bit-field. 1454*f4a2713aSLionel Sambuc return Context == Declarator::MemberContext || getLangOpts().CPlusPlus; 1455*f4a2713aSLionel Sambuc 1456*f4a2713aSLionel Sambuc case tok::identifier: 1457*f4a2713aSLionel Sambuc switch (NextToken().getKind()) { 1458*f4a2713aSLionel Sambuc case tok::code_completion: 1459*f4a2713aSLionel Sambuc case tok::coloncolon: 1460*f4a2713aSLionel Sambuc case tok::comma: 1461*f4a2713aSLionel Sambuc case tok::equal: 1462*f4a2713aSLionel Sambuc case tok::equalequal: // Might be a typo for '='. 1463*f4a2713aSLionel Sambuc case tok::kw_alignas: 1464*f4a2713aSLionel Sambuc case tok::kw_asm: 1465*f4a2713aSLionel Sambuc case tok::kw___attribute: 1466*f4a2713aSLionel Sambuc case tok::l_brace: 1467*f4a2713aSLionel Sambuc case tok::l_paren: 1468*f4a2713aSLionel Sambuc case tok::l_square: 1469*f4a2713aSLionel Sambuc case tok::less: 1470*f4a2713aSLionel Sambuc case tok::r_brace: 1471*f4a2713aSLionel Sambuc case tok::r_paren: 1472*f4a2713aSLionel Sambuc case tok::r_square: 1473*f4a2713aSLionel Sambuc case tok::semi: 1474*f4a2713aSLionel Sambuc return true; 1475*f4a2713aSLionel Sambuc 1476*f4a2713aSLionel Sambuc case tok::colon: 1477*f4a2713aSLionel Sambuc // At namespace scope, 'identifier:' is probably a typo for 'identifier::' 1478*f4a2713aSLionel Sambuc // and in block scope it's probably a label. Inside a class definition, 1479*f4a2713aSLionel Sambuc // this is a bit-field. 1480*f4a2713aSLionel Sambuc return Context == Declarator::MemberContext || 1481*f4a2713aSLionel Sambuc (getLangOpts().CPlusPlus && Context == Declarator::FileContext); 1482*f4a2713aSLionel Sambuc 1483*f4a2713aSLionel Sambuc case tok::identifier: // Possible virt-specifier. 1484*f4a2713aSLionel Sambuc return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken()); 1485*f4a2713aSLionel Sambuc 1486*f4a2713aSLionel Sambuc default: 1487*f4a2713aSLionel Sambuc return false; 1488*f4a2713aSLionel Sambuc } 1489*f4a2713aSLionel Sambuc 1490*f4a2713aSLionel Sambuc default: 1491*f4a2713aSLionel Sambuc return false; 1492*f4a2713aSLionel Sambuc } 1493*f4a2713aSLionel Sambuc } 1494*f4a2713aSLionel Sambuc 1495*f4a2713aSLionel Sambuc /// Skip until we reach something which seems like a sensible place to pick 1496*f4a2713aSLionel Sambuc /// up parsing after a malformed declaration. This will sometimes stop sooner 1497*f4a2713aSLionel Sambuc /// than SkipUntil(tok::r_brace) would, but will never stop later. 1498*f4a2713aSLionel Sambuc void Parser::SkipMalformedDecl() { 1499*f4a2713aSLionel Sambuc while (true) { 1500*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 1501*f4a2713aSLionel Sambuc case tok::l_brace: 1502*f4a2713aSLionel Sambuc // Skip until matching }, then stop. We've probably skipped over 1503*f4a2713aSLionel Sambuc // a malformed class or function definition or similar. 1504*f4a2713aSLionel Sambuc ConsumeBrace(); 1505*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace); 1506*f4a2713aSLionel Sambuc if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { 1507*f4a2713aSLionel Sambuc // This declaration isn't over yet. Keep skipping. 1508*f4a2713aSLionel Sambuc continue; 1509*f4a2713aSLionel Sambuc } 1510*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) 1511*f4a2713aSLionel Sambuc ConsumeToken(); 1512*f4a2713aSLionel Sambuc return; 1513*f4a2713aSLionel Sambuc 1514*f4a2713aSLionel Sambuc case tok::l_square: 1515*f4a2713aSLionel Sambuc ConsumeBracket(); 1516*f4a2713aSLionel Sambuc SkipUntil(tok::r_square); 1517*f4a2713aSLionel Sambuc continue; 1518*f4a2713aSLionel Sambuc 1519*f4a2713aSLionel Sambuc case tok::l_paren: 1520*f4a2713aSLionel Sambuc ConsumeParen(); 1521*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren); 1522*f4a2713aSLionel Sambuc continue; 1523*f4a2713aSLionel Sambuc 1524*f4a2713aSLionel Sambuc case tok::r_brace: 1525*f4a2713aSLionel Sambuc return; 1526*f4a2713aSLionel Sambuc 1527*f4a2713aSLionel Sambuc case tok::semi: 1528*f4a2713aSLionel Sambuc ConsumeToken(); 1529*f4a2713aSLionel Sambuc return; 1530*f4a2713aSLionel Sambuc 1531*f4a2713aSLionel Sambuc case tok::kw_inline: 1532*f4a2713aSLionel Sambuc // 'inline namespace' at the start of a line is almost certainly 1533*f4a2713aSLionel Sambuc // a good place to pick back up parsing, except in an Objective-C 1534*f4a2713aSLionel Sambuc // @interface context. 1535*f4a2713aSLionel Sambuc if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) && 1536*f4a2713aSLionel Sambuc (!ParsingInObjCContainer || CurParsedObjCImpl)) 1537*f4a2713aSLionel Sambuc return; 1538*f4a2713aSLionel Sambuc break; 1539*f4a2713aSLionel Sambuc 1540*f4a2713aSLionel Sambuc case tok::kw_namespace: 1541*f4a2713aSLionel Sambuc // 'namespace' at the start of a line is almost certainly a good 1542*f4a2713aSLionel Sambuc // place to pick back up parsing, except in an Objective-C 1543*f4a2713aSLionel Sambuc // @interface context. 1544*f4a2713aSLionel Sambuc if (Tok.isAtStartOfLine() && 1545*f4a2713aSLionel Sambuc (!ParsingInObjCContainer || CurParsedObjCImpl)) 1546*f4a2713aSLionel Sambuc return; 1547*f4a2713aSLionel Sambuc break; 1548*f4a2713aSLionel Sambuc 1549*f4a2713aSLionel Sambuc case tok::at: 1550*f4a2713aSLionel Sambuc // @end is very much like } in Objective-C contexts. 1551*f4a2713aSLionel Sambuc if (NextToken().isObjCAtKeyword(tok::objc_end) && 1552*f4a2713aSLionel Sambuc ParsingInObjCContainer) 1553*f4a2713aSLionel Sambuc return; 1554*f4a2713aSLionel Sambuc break; 1555*f4a2713aSLionel Sambuc 1556*f4a2713aSLionel Sambuc case tok::minus: 1557*f4a2713aSLionel Sambuc case tok::plus: 1558*f4a2713aSLionel Sambuc // - and + probably start new method declarations in Objective-C contexts. 1559*f4a2713aSLionel Sambuc if (Tok.isAtStartOfLine() && ParsingInObjCContainer) 1560*f4a2713aSLionel Sambuc return; 1561*f4a2713aSLionel Sambuc break; 1562*f4a2713aSLionel Sambuc 1563*f4a2713aSLionel Sambuc case tok::eof: 1564*f4a2713aSLionel Sambuc return; 1565*f4a2713aSLionel Sambuc 1566*f4a2713aSLionel Sambuc default: 1567*f4a2713aSLionel Sambuc break; 1568*f4a2713aSLionel Sambuc } 1569*f4a2713aSLionel Sambuc 1570*f4a2713aSLionel Sambuc ConsumeAnyToken(); 1571*f4a2713aSLionel Sambuc } 1572*f4a2713aSLionel Sambuc } 1573*f4a2713aSLionel Sambuc 1574*f4a2713aSLionel Sambuc /// ParseDeclGroup - Having concluded that this is either a function 1575*f4a2713aSLionel Sambuc /// definition or a group of object declarations, actually parse the 1576*f4a2713aSLionel Sambuc /// result. 1577*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, 1578*f4a2713aSLionel Sambuc unsigned Context, 1579*f4a2713aSLionel Sambuc bool AllowFunctionDefinitions, 1580*f4a2713aSLionel Sambuc SourceLocation *DeclEnd, 1581*f4a2713aSLionel Sambuc ForRangeInit *FRI) { 1582*f4a2713aSLionel Sambuc // Parse the first declarator. 1583*f4a2713aSLionel Sambuc ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context)); 1584*f4a2713aSLionel Sambuc ParseDeclarator(D); 1585*f4a2713aSLionel Sambuc 1586*f4a2713aSLionel Sambuc // Bail out if the first declarator didn't seem well-formed. 1587*f4a2713aSLionel Sambuc if (!D.hasName() && !D.mayOmitIdentifier()) { 1588*f4a2713aSLionel Sambuc SkipMalformedDecl(); 1589*f4a2713aSLionel Sambuc return DeclGroupPtrTy(); 1590*f4a2713aSLionel Sambuc } 1591*f4a2713aSLionel Sambuc 1592*f4a2713aSLionel Sambuc // Save late-parsed attributes for now; they need to be parsed in the 1593*f4a2713aSLionel Sambuc // appropriate function scope after the function Decl has been constructed. 1594*f4a2713aSLionel Sambuc // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList. 1595*f4a2713aSLionel Sambuc LateParsedAttrList LateParsedAttrs(true); 1596*f4a2713aSLionel Sambuc if (D.isFunctionDeclarator()) 1597*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(D, &LateParsedAttrs); 1598*f4a2713aSLionel Sambuc 1599*f4a2713aSLionel Sambuc // Check to see if we have a function *definition* which must have a body. 1600*f4a2713aSLionel Sambuc if (D.isFunctionDeclarator() && 1601*f4a2713aSLionel Sambuc // Look at the next token to make sure that this isn't a function 1602*f4a2713aSLionel Sambuc // declaration. We have to check this because __attribute__ might be the 1603*f4a2713aSLionel Sambuc // start of a function definition in GCC-extended K&R C. 1604*f4a2713aSLionel Sambuc !isDeclarationAfterDeclarator()) { 1605*f4a2713aSLionel Sambuc 1606*f4a2713aSLionel Sambuc if (AllowFunctionDefinitions) { 1607*f4a2713aSLionel Sambuc if (isStartOfFunctionDefinition(D)) { 1608*f4a2713aSLionel Sambuc if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 1609*f4a2713aSLionel Sambuc Diag(Tok, diag::err_function_declared_typedef); 1610*f4a2713aSLionel Sambuc 1611*f4a2713aSLionel Sambuc // Recover by treating the 'typedef' as spurious. 1612*f4a2713aSLionel Sambuc DS.ClearStorageClassSpecs(); 1613*f4a2713aSLionel Sambuc } 1614*f4a2713aSLionel Sambuc 1615*f4a2713aSLionel Sambuc Decl *TheDecl = 1616*f4a2713aSLionel Sambuc ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); 1617*f4a2713aSLionel Sambuc return Actions.ConvertDeclToDeclGroup(TheDecl); 1618*f4a2713aSLionel Sambuc } 1619*f4a2713aSLionel Sambuc 1620*f4a2713aSLionel Sambuc if (isDeclarationSpecifier()) { 1621*f4a2713aSLionel Sambuc // If there is an invalid declaration specifier right after the function 1622*f4a2713aSLionel Sambuc // prototype, then we must be in a missing semicolon case where this isn't 1623*f4a2713aSLionel Sambuc // actually a body. Just fall through into the code that handles it as a 1624*f4a2713aSLionel Sambuc // prototype, and let the top-level code handle the erroneous declspec 1625*f4a2713aSLionel Sambuc // where it would otherwise expect a comma or semicolon. 1626*f4a2713aSLionel Sambuc } else { 1627*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_fn_body); 1628*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1629*f4a2713aSLionel Sambuc return DeclGroupPtrTy(); 1630*f4a2713aSLionel Sambuc } 1631*f4a2713aSLionel Sambuc } else { 1632*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) { 1633*f4a2713aSLionel Sambuc Diag(Tok, diag::err_function_definition_not_allowed); 1634*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 1635*f4a2713aSLionel Sambuc } 1636*f4a2713aSLionel Sambuc } 1637*f4a2713aSLionel Sambuc } 1638*f4a2713aSLionel Sambuc 1639*f4a2713aSLionel Sambuc if (ParseAsmAttributesAfterDeclarator(D)) 1640*f4a2713aSLionel Sambuc return DeclGroupPtrTy(); 1641*f4a2713aSLionel Sambuc 1642*f4a2713aSLionel Sambuc // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we 1643*f4a2713aSLionel Sambuc // must parse and analyze the for-range-initializer before the declaration is 1644*f4a2713aSLionel Sambuc // analyzed. 1645*f4a2713aSLionel Sambuc // 1646*f4a2713aSLionel Sambuc // Handle the Objective-C for-in loop variable similarly, although we 1647*f4a2713aSLionel Sambuc // don't need to parse the container in advance. 1648*f4a2713aSLionel Sambuc if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) { 1649*f4a2713aSLionel Sambuc bool IsForRangeLoop = false; 1650*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) { 1651*f4a2713aSLionel Sambuc IsForRangeLoop = true; 1652*f4a2713aSLionel Sambuc FRI->ColonLoc = ConsumeToken(); 1653*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) 1654*f4a2713aSLionel Sambuc FRI->RangeExpr = ParseBraceInitializer(); 1655*f4a2713aSLionel Sambuc else 1656*f4a2713aSLionel Sambuc FRI->RangeExpr = ParseExpression(); 1657*f4a2713aSLionel Sambuc } 1658*f4a2713aSLionel Sambuc 1659*f4a2713aSLionel Sambuc Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1660*f4a2713aSLionel Sambuc if (IsForRangeLoop) 1661*f4a2713aSLionel Sambuc Actions.ActOnCXXForRangeDecl(ThisDecl); 1662*f4a2713aSLionel Sambuc Actions.FinalizeDeclaration(ThisDecl); 1663*f4a2713aSLionel Sambuc D.complete(ThisDecl); 1664*f4a2713aSLionel Sambuc return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl); 1665*f4a2713aSLionel Sambuc } 1666*f4a2713aSLionel Sambuc 1667*f4a2713aSLionel Sambuc SmallVector<Decl *, 8> DeclsInGroup; 1668*f4a2713aSLionel Sambuc Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D); 1669*f4a2713aSLionel Sambuc if (LateParsedAttrs.size() > 0) 1670*f4a2713aSLionel Sambuc ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); 1671*f4a2713aSLionel Sambuc D.complete(FirstDecl); 1672*f4a2713aSLionel Sambuc if (FirstDecl) 1673*f4a2713aSLionel Sambuc DeclsInGroup.push_back(FirstDecl); 1674*f4a2713aSLionel Sambuc 1675*f4a2713aSLionel Sambuc bool ExpectSemi = Context != Declarator::ForContext; 1676*f4a2713aSLionel Sambuc 1677*f4a2713aSLionel Sambuc // If we don't have a comma, it is either the end of the list (a ';') or an 1678*f4a2713aSLionel Sambuc // error, bail out. 1679*f4a2713aSLionel Sambuc while (Tok.is(tok::comma)) { 1680*f4a2713aSLionel Sambuc SourceLocation CommaLoc = ConsumeToken(); 1681*f4a2713aSLionel Sambuc 1682*f4a2713aSLionel Sambuc if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) { 1683*f4a2713aSLionel Sambuc // This comma was followed by a line-break and something which can't be 1684*f4a2713aSLionel Sambuc // the start of a declarator. The comma was probably a typo for a 1685*f4a2713aSLionel Sambuc // semicolon. 1686*f4a2713aSLionel Sambuc Diag(CommaLoc, diag::err_expected_semi_declaration) 1687*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(CommaLoc, ";"); 1688*f4a2713aSLionel Sambuc ExpectSemi = false; 1689*f4a2713aSLionel Sambuc break; 1690*f4a2713aSLionel Sambuc } 1691*f4a2713aSLionel Sambuc 1692*f4a2713aSLionel Sambuc // Parse the next declarator. 1693*f4a2713aSLionel Sambuc D.clear(); 1694*f4a2713aSLionel Sambuc D.setCommaLoc(CommaLoc); 1695*f4a2713aSLionel Sambuc 1696*f4a2713aSLionel Sambuc // Accept attributes in an init-declarator. In the first declarator in a 1697*f4a2713aSLionel Sambuc // declaration, these would be part of the declspec. In subsequent 1698*f4a2713aSLionel Sambuc // declarators, they become part of the declarator itself, so that they 1699*f4a2713aSLionel Sambuc // don't apply to declarators after *this* one. Examples: 1700*f4a2713aSLionel Sambuc // short __attribute__((common)) var; -> declspec 1701*f4a2713aSLionel Sambuc // short var __attribute__((common)); -> declarator 1702*f4a2713aSLionel Sambuc // short x, __attribute__((common)) var; -> declarator 1703*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(D); 1704*f4a2713aSLionel Sambuc 1705*f4a2713aSLionel Sambuc ParseDeclarator(D); 1706*f4a2713aSLionel Sambuc if (!D.isInvalidType()) { 1707*f4a2713aSLionel Sambuc Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); 1708*f4a2713aSLionel Sambuc D.complete(ThisDecl); 1709*f4a2713aSLionel Sambuc if (ThisDecl) 1710*f4a2713aSLionel Sambuc DeclsInGroup.push_back(ThisDecl); 1711*f4a2713aSLionel Sambuc } 1712*f4a2713aSLionel Sambuc } 1713*f4a2713aSLionel Sambuc 1714*f4a2713aSLionel Sambuc if (DeclEnd) 1715*f4a2713aSLionel Sambuc *DeclEnd = Tok.getLocation(); 1716*f4a2713aSLionel Sambuc 1717*f4a2713aSLionel Sambuc if (ExpectSemi && 1718*f4a2713aSLionel Sambuc ExpectAndConsumeSemi(Context == Declarator::FileContext 1719*f4a2713aSLionel Sambuc ? diag::err_invalid_token_after_toplevel_declarator 1720*f4a2713aSLionel Sambuc : diag::err_expected_semi_declaration)) { 1721*f4a2713aSLionel Sambuc // Okay, there was no semicolon and one was expected. If we see a 1722*f4a2713aSLionel Sambuc // declaration specifier, just assume it was missing and continue parsing. 1723*f4a2713aSLionel Sambuc // Otherwise things are very confused and we skip to recover. 1724*f4a2713aSLionel Sambuc if (!isDeclarationSpecifier()) { 1725*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 1726*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) 1727*f4a2713aSLionel Sambuc ConsumeToken(); 1728*f4a2713aSLionel Sambuc } 1729*f4a2713aSLionel Sambuc } 1730*f4a2713aSLionel Sambuc 1731*f4a2713aSLionel Sambuc return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); 1732*f4a2713aSLionel Sambuc } 1733*f4a2713aSLionel Sambuc 1734*f4a2713aSLionel Sambuc /// Parse an optional simple-asm-expr and attributes, and attach them to a 1735*f4a2713aSLionel Sambuc /// declarator. Returns true on an error. 1736*f4a2713aSLionel Sambuc bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) { 1737*f4a2713aSLionel Sambuc // If a simple-asm-expr is present, parse it. 1738*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_asm)) { 1739*f4a2713aSLionel Sambuc SourceLocation Loc; 1740*f4a2713aSLionel Sambuc ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1741*f4a2713aSLionel Sambuc if (AsmLabel.isInvalid()) { 1742*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1743*f4a2713aSLionel Sambuc return true; 1744*f4a2713aSLionel Sambuc } 1745*f4a2713aSLionel Sambuc 1746*f4a2713aSLionel Sambuc D.setAsmLabel(AsmLabel.release()); 1747*f4a2713aSLionel Sambuc D.SetRangeEnd(Loc); 1748*f4a2713aSLionel Sambuc } 1749*f4a2713aSLionel Sambuc 1750*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(D); 1751*f4a2713aSLionel Sambuc return false; 1752*f4a2713aSLionel Sambuc } 1753*f4a2713aSLionel Sambuc 1754*f4a2713aSLionel Sambuc /// \brief Parse 'declaration' after parsing 'declaration-specifiers 1755*f4a2713aSLionel Sambuc /// declarator'. This method parses the remainder of the declaration 1756*f4a2713aSLionel Sambuc /// (including any attributes or initializer, among other things) and 1757*f4a2713aSLionel Sambuc /// finalizes the declaration. 1758*f4a2713aSLionel Sambuc /// 1759*f4a2713aSLionel Sambuc /// init-declarator: [C99 6.7] 1760*f4a2713aSLionel Sambuc /// declarator 1761*f4a2713aSLionel Sambuc /// declarator '=' initializer 1762*f4a2713aSLionel Sambuc /// [GNU] declarator simple-asm-expr[opt] attributes[opt] 1763*f4a2713aSLionel Sambuc /// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer 1764*f4a2713aSLionel Sambuc /// [C++] declarator initializer[opt] 1765*f4a2713aSLionel Sambuc /// 1766*f4a2713aSLionel Sambuc /// [C++] initializer: 1767*f4a2713aSLionel Sambuc /// [C++] '=' initializer-clause 1768*f4a2713aSLionel Sambuc /// [C++] '(' expression-list ')' 1769*f4a2713aSLionel Sambuc /// [C++0x] '=' 'default' [TODO] 1770*f4a2713aSLionel Sambuc /// [C++0x] '=' 'delete' 1771*f4a2713aSLionel Sambuc /// [C++0x] braced-init-list 1772*f4a2713aSLionel Sambuc /// 1773*f4a2713aSLionel Sambuc /// According to the standard grammar, =default and =delete are function 1774*f4a2713aSLionel Sambuc /// definitions, but that definitely doesn't fit with the parser here. 1775*f4a2713aSLionel Sambuc /// 1776*f4a2713aSLionel Sambuc Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, 1777*f4a2713aSLionel Sambuc const ParsedTemplateInfo &TemplateInfo) { 1778*f4a2713aSLionel Sambuc if (ParseAsmAttributesAfterDeclarator(D)) 1779*f4a2713aSLionel Sambuc return 0; 1780*f4a2713aSLionel Sambuc 1781*f4a2713aSLionel Sambuc return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo); 1782*f4a2713aSLionel Sambuc } 1783*f4a2713aSLionel Sambuc 1784*f4a2713aSLionel Sambuc Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, 1785*f4a2713aSLionel Sambuc const ParsedTemplateInfo &TemplateInfo) { 1786*f4a2713aSLionel Sambuc // Inform the current actions module that we just parsed this declarator. 1787*f4a2713aSLionel Sambuc Decl *ThisDecl = 0; 1788*f4a2713aSLionel Sambuc switch (TemplateInfo.Kind) { 1789*f4a2713aSLionel Sambuc case ParsedTemplateInfo::NonTemplate: 1790*f4a2713aSLionel Sambuc ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1791*f4a2713aSLionel Sambuc break; 1792*f4a2713aSLionel Sambuc 1793*f4a2713aSLionel Sambuc case ParsedTemplateInfo::Template: 1794*f4a2713aSLionel Sambuc case ParsedTemplateInfo::ExplicitSpecialization: { 1795*f4a2713aSLionel Sambuc ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), 1796*f4a2713aSLionel Sambuc *TemplateInfo.TemplateParams, 1797*f4a2713aSLionel Sambuc D); 1798*f4a2713aSLionel Sambuc if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) 1799*f4a2713aSLionel Sambuc // Re-direct this decl to refer to the templated decl so that we can 1800*f4a2713aSLionel Sambuc // initialize it. 1801*f4a2713aSLionel Sambuc ThisDecl = VT->getTemplatedDecl(); 1802*f4a2713aSLionel Sambuc break; 1803*f4a2713aSLionel Sambuc } 1804*f4a2713aSLionel Sambuc case ParsedTemplateInfo::ExplicitInstantiation: { 1805*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 1806*f4a2713aSLionel Sambuc DeclResult ThisRes = Actions.ActOnExplicitInstantiation( 1807*f4a2713aSLionel Sambuc getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D); 1808*f4a2713aSLionel Sambuc if (ThisRes.isInvalid()) { 1809*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1810*f4a2713aSLionel Sambuc return 0; 1811*f4a2713aSLionel Sambuc } 1812*f4a2713aSLionel Sambuc ThisDecl = ThisRes.get(); 1813*f4a2713aSLionel Sambuc } else { 1814*f4a2713aSLionel Sambuc // FIXME: This check should be for a variable template instantiation only. 1815*f4a2713aSLionel Sambuc 1816*f4a2713aSLionel Sambuc // Check that this is a valid instantiation 1817*f4a2713aSLionel Sambuc if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) { 1818*f4a2713aSLionel Sambuc // If the declarator-id is not a template-id, issue a diagnostic and 1819*f4a2713aSLionel Sambuc // recover by ignoring the 'template' keyword. 1820*f4a2713aSLionel Sambuc Diag(Tok, diag::err_template_defn_explicit_instantiation) 1821*f4a2713aSLionel Sambuc << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc); 1822*f4a2713aSLionel Sambuc ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1823*f4a2713aSLionel Sambuc } else { 1824*f4a2713aSLionel Sambuc SourceLocation LAngleLoc = 1825*f4a2713aSLionel Sambuc PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 1826*f4a2713aSLionel Sambuc Diag(D.getIdentifierLoc(), 1827*f4a2713aSLionel Sambuc diag::err_explicit_instantiation_with_definition) 1828*f4a2713aSLionel Sambuc << SourceRange(TemplateInfo.TemplateLoc) 1829*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(LAngleLoc, "<>"); 1830*f4a2713aSLionel Sambuc 1831*f4a2713aSLionel Sambuc // Recover as if it were an explicit specialization. 1832*f4a2713aSLionel Sambuc TemplateParameterLists FakedParamLists; 1833*f4a2713aSLionel Sambuc FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 1834*f4a2713aSLionel Sambuc 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0, 1835*f4a2713aSLionel Sambuc LAngleLoc)); 1836*f4a2713aSLionel Sambuc 1837*f4a2713aSLionel Sambuc ThisDecl = 1838*f4a2713aSLionel Sambuc Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D); 1839*f4a2713aSLionel Sambuc } 1840*f4a2713aSLionel Sambuc } 1841*f4a2713aSLionel Sambuc break; 1842*f4a2713aSLionel Sambuc } 1843*f4a2713aSLionel Sambuc } 1844*f4a2713aSLionel Sambuc 1845*f4a2713aSLionel Sambuc bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); 1846*f4a2713aSLionel Sambuc 1847*f4a2713aSLionel Sambuc // Parse declarator '=' initializer. 1848*f4a2713aSLionel Sambuc // If a '==' or '+=' is found, suggest a fixit to '='. 1849*f4a2713aSLionel Sambuc if (isTokenEqualOrEqualTypo()) { 1850*f4a2713aSLionel Sambuc ConsumeToken(); 1851*f4a2713aSLionel Sambuc 1852*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_delete)) { 1853*f4a2713aSLionel Sambuc if (D.isFunctionDeclarator()) 1854*f4a2713aSLionel Sambuc Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1855*f4a2713aSLionel Sambuc << 1 /* delete */; 1856*f4a2713aSLionel Sambuc else 1857*f4a2713aSLionel Sambuc Diag(ConsumeToken(), diag::err_deleted_non_function); 1858*f4a2713aSLionel Sambuc } else if (Tok.is(tok::kw_default)) { 1859*f4a2713aSLionel Sambuc if (D.isFunctionDeclarator()) 1860*f4a2713aSLionel Sambuc Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1861*f4a2713aSLionel Sambuc << 0 /* default */; 1862*f4a2713aSLionel Sambuc else 1863*f4a2713aSLionel Sambuc Diag(ConsumeToken(), diag::err_default_special_members); 1864*f4a2713aSLionel Sambuc } else { 1865*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1866*f4a2713aSLionel Sambuc EnterScope(0); 1867*f4a2713aSLionel Sambuc Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1868*f4a2713aSLionel Sambuc } 1869*f4a2713aSLionel Sambuc 1870*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1871*f4a2713aSLionel Sambuc Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); 1872*f4a2713aSLionel Sambuc Actions.FinalizeDeclaration(ThisDecl); 1873*f4a2713aSLionel Sambuc cutOffParsing(); 1874*f4a2713aSLionel Sambuc return 0; 1875*f4a2713aSLionel Sambuc } 1876*f4a2713aSLionel Sambuc 1877*f4a2713aSLionel Sambuc ExprResult Init(ParseInitializer()); 1878*f4a2713aSLionel Sambuc 1879*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1880*f4a2713aSLionel Sambuc Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1881*f4a2713aSLionel Sambuc ExitScope(); 1882*f4a2713aSLionel Sambuc } 1883*f4a2713aSLionel Sambuc 1884*f4a2713aSLionel Sambuc if (Init.isInvalid()) { 1885*f4a2713aSLionel Sambuc SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); 1886*f4a2713aSLionel Sambuc Actions.ActOnInitializerError(ThisDecl); 1887*f4a2713aSLionel Sambuc } else 1888*f4a2713aSLionel Sambuc Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1889*f4a2713aSLionel Sambuc /*DirectInit=*/false, TypeContainsAuto); 1890*f4a2713aSLionel Sambuc } 1891*f4a2713aSLionel Sambuc } else if (Tok.is(tok::l_paren)) { 1892*f4a2713aSLionel Sambuc // Parse C++ direct initializer: '(' expression-list ')' 1893*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1894*f4a2713aSLionel Sambuc T.consumeOpen(); 1895*f4a2713aSLionel Sambuc 1896*f4a2713aSLionel Sambuc ExprVector Exprs; 1897*f4a2713aSLionel Sambuc CommaLocsTy CommaLocs; 1898*f4a2713aSLionel Sambuc 1899*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1900*f4a2713aSLionel Sambuc EnterScope(0); 1901*f4a2713aSLionel Sambuc Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1902*f4a2713aSLionel Sambuc } 1903*f4a2713aSLionel Sambuc 1904*f4a2713aSLionel Sambuc if (ParseExpressionList(Exprs, CommaLocs)) { 1905*f4a2713aSLionel Sambuc Actions.ActOnInitializerError(ThisDecl); 1906*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1907*f4a2713aSLionel Sambuc 1908*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1909*f4a2713aSLionel Sambuc Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1910*f4a2713aSLionel Sambuc ExitScope(); 1911*f4a2713aSLionel Sambuc } 1912*f4a2713aSLionel Sambuc } else { 1913*f4a2713aSLionel Sambuc // Match the ')'. 1914*f4a2713aSLionel Sambuc T.consumeClose(); 1915*f4a2713aSLionel Sambuc 1916*f4a2713aSLionel Sambuc assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && 1917*f4a2713aSLionel Sambuc "Unexpected number of commas!"); 1918*f4a2713aSLionel Sambuc 1919*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1920*f4a2713aSLionel Sambuc Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1921*f4a2713aSLionel Sambuc ExitScope(); 1922*f4a2713aSLionel Sambuc } 1923*f4a2713aSLionel Sambuc 1924*f4a2713aSLionel Sambuc ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), 1925*f4a2713aSLionel Sambuc T.getCloseLocation(), 1926*f4a2713aSLionel Sambuc Exprs); 1927*f4a2713aSLionel Sambuc Actions.AddInitializerToDecl(ThisDecl, Initializer.take(), 1928*f4a2713aSLionel Sambuc /*DirectInit=*/true, TypeContainsAuto); 1929*f4a2713aSLionel Sambuc } 1930*f4a2713aSLionel Sambuc } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) && 1931*f4a2713aSLionel Sambuc (!CurParsedObjCImpl || !D.isFunctionDeclarator())) { 1932*f4a2713aSLionel Sambuc // Parse C++0x braced-init-list. 1933*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1934*f4a2713aSLionel Sambuc 1935*f4a2713aSLionel Sambuc if (D.getCXXScopeSpec().isSet()) { 1936*f4a2713aSLionel Sambuc EnterScope(0); 1937*f4a2713aSLionel Sambuc Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1938*f4a2713aSLionel Sambuc } 1939*f4a2713aSLionel Sambuc 1940*f4a2713aSLionel Sambuc ExprResult Init(ParseBraceInitializer()); 1941*f4a2713aSLionel Sambuc 1942*f4a2713aSLionel Sambuc if (D.getCXXScopeSpec().isSet()) { 1943*f4a2713aSLionel Sambuc Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1944*f4a2713aSLionel Sambuc ExitScope(); 1945*f4a2713aSLionel Sambuc } 1946*f4a2713aSLionel Sambuc 1947*f4a2713aSLionel Sambuc if (Init.isInvalid()) { 1948*f4a2713aSLionel Sambuc Actions.ActOnInitializerError(ThisDecl); 1949*f4a2713aSLionel Sambuc } else 1950*f4a2713aSLionel Sambuc Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1951*f4a2713aSLionel Sambuc /*DirectInit=*/true, TypeContainsAuto); 1952*f4a2713aSLionel Sambuc 1953*f4a2713aSLionel Sambuc } else { 1954*f4a2713aSLionel Sambuc Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto); 1955*f4a2713aSLionel Sambuc } 1956*f4a2713aSLionel Sambuc 1957*f4a2713aSLionel Sambuc Actions.FinalizeDeclaration(ThisDecl); 1958*f4a2713aSLionel Sambuc 1959*f4a2713aSLionel Sambuc return ThisDecl; 1960*f4a2713aSLionel Sambuc } 1961*f4a2713aSLionel Sambuc 1962*f4a2713aSLionel Sambuc /// ParseSpecifierQualifierList 1963*f4a2713aSLionel Sambuc /// specifier-qualifier-list: 1964*f4a2713aSLionel Sambuc /// type-specifier specifier-qualifier-list[opt] 1965*f4a2713aSLionel Sambuc /// type-qualifier specifier-qualifier-list[opt] 1966*f4a2713aSLionel Sambuc /// [GNU] attributes specifier-qualifier-list[opt] 1967*f4a2713aSLionel Sambuc /// 1968*f4a2713aSLionel Sambuc void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, 1969*f4a2713aSLionel Sambuc DeclSpecContext DSC) { 1970*f4a2713aSLionel Sambuc /// specifier-qualifier-list is a subset of declaration-specifiers. Just 1971*f4a2713aSLionel Sambuc /// parse declaration-specifiers and complain about extra stuff. 1972*f4a2713aSLionel Sambuc /// TODO: diagnose attribute-specifiers and alignment-specifiers. 1973*f4a2713aSLionel Sambuc ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC); 1974*f4a2713aSLionel Sambuc 1975*f4a2713aSLionel Sambuc // Validate declspec for type-name. 1976*f4a2713aSLionel Sambuc unsigned Specs = DS.getParsedSpecifiers(); 1977*f4a2713aSLionel Sambuc if ((DSC == DSC_type_specifier || DSC == DSC_trailing) && 1978*f4a2713aSLionel Sambuc !DS.hasTypeSpecifier()) { 1979*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_type); 1980*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 1981*f4a2713aSLionel Sambuc } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && 1982*f4a2713aSLionel Sambuc !DS.hasAttributes()) { 1983*f4a2713aSLionel Sambuc Diag(Tok, diag::err_typename_requires_specqual); 1984*f4a2713aSLionel Sambuc if (!DS.hasTypeSpecifier()) 1985*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 1986*f4a2713aSLionel Sambuc } 1987*f4a2713aSLionel Sambuc 1988*f4a2713aSLionel Sambuc // Issue diagnostic and remove storage class if present. 1989*f4a2713aSLionel Sambuc if (Specs & DeclSpec::PQ_StorageClassSpecifier) { 1990*f4a2713aSLionel Sambuc if (DS.getStorageClassSpecLoc().isValid()) 1991*f4a2713aSLionel Sambuc Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); 1992*f4a2713aSLionel Sambuc else 1993*f4a2713aSLionel Sambuc Diag(DS.getThreadStorageClassSpecLoc(), 1994*f4a2713aSLionel Sambuc diag::err_typename_invalid_storageclass); 1995*f4a2713aSLionel Sambuc DS.ClearStorageClassSpecs(); 1996*f4a2713aSLionel Sambuc } 1997*f4a2713aSLionel Sambuc 1998*f4a2713aSLionel Sambuc // Issue diagnostic and remove function specfier if present. 1999*f4a2713aSLionel Sambuc if (Specs & DeclSpec::PQ_FunctionSpecifier) { 2000*f4a2713aSLionel Sambuc if (DS.isInlineSpecified()) 2001*f4a2713aSLionel Sambuc Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); 2002*f4a2713aSLionel Sambuc if (DS.isVirtualSpecified()) 2003*f4a2713aSLionel Sambuc Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); 2004*f4a2713aSLionel Sambuc if (DS.isExplicitSpecified()) 2005*f4a2713aSLionel Sambuc Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); 2006*f4a2713aSLionel Sambuc DS.ClearFunctionSpecs(); 2007*f4a2713aSLionel Sambuc } 2008*f4a2713aSLionel Sambuc 2009*f4a2713aSLionel Sambuc // Issue diagnostic and remove constexpr specfier if present. 2010*f4a2713aSLionel Sambuc if (DS.isConstexprSpecified()) { 2011*f4a2713aSLionel Sambuc Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); 2012*f4a2713aSLionel Sambuc DS.ClearConstexprSpec(); 2013*f4a2713aSLionel Sambuc } 2014*f4a2713aSLionel Sambuc } 2015*f4a2713aSLionel Sambuc 2016*f4a2713aSLionel Sambuc /// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the 2017*f4a2713aSLionel Sambuc /// specified token is valid after the identifier in a declarator which 2018*f4a2713aSLionel Sambuc /// immediately follows the declspec. For example, these things are valid: 2019*f4a2713aSLionel Sambuc /// 2020*f4a2713aSLionel Sambuc /// int x [ 4]; // direct-declarator 2021*f4a2713aSLionel Sambuc /// int x ( int y); // direct-declarator 2022*f4a2713aSLionel Sambuc /// int(int x ) // direct-declarator 2023*f4a2713aSLionel Sambuc /// int x ; // simple-declaration 2024*f4a2713aSLionel Sambuc /// int x = 17; // init-declarator-list 2025*f4a2713aSLionel Sambuc /// int x , y; // init-declarator-list 2026*f4a2713aSLionel Sambuc /// int x __asm__ ("foo"); // init-declarator-list 2027*f4a2713aSLionel Sambuc /// int x : 4; // struct-declarator 2028*f4a2713aSLionel Sambuc /// int x { 5}; // C++'0x unified initializers 2029*f4a2713aSLionel Sambuc /// 2030*f4a2713aSLionel Sambuc /// This is not, because 'x' does not immediately follow the declspec (though 2031*f4a2713aSLionel Sambuc /// ')' happens to be valid anyway). 2032*f4a2713aSLionel Sambuc /// int (x) 2033*f4a2713aSLionel Sambuc /// 2034*f4a2713aSLionel Sambuc static bool isValidAfterIdentifierInDeclarator(const Token &T) { 2035*f4a2713aSLionel Sambuc return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) || 2036*f4a2713aSLionel Sambuc T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) || 2037*f4a2713aSLionel Sambuc T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon); 2038*f4a2713aSLionel Sambuc } 2039*f4a2713aSLionel Sambuc 2040*f4a2713aSLionel Sambuc 2041*f4a2713aSLionel Sambuc /// ParseImplicitInt - This method is called when we have an non-typename 2042*f4a2713aSLionel Sambuc /// identifier in a declspec (which normally terminates the decl spec) when 2043*f4a2713aSLionel Sambuc /// the declspec has no type specifier. In this case, the declspec is either 2044*f4a2713aSLionel Sambuc /// malformed or is "implicit int" (in K&R and C89). 2045*f4a2713aSLionel Sambuc /// 2046*f4a2713aSLionel Sambuc /// This method handles diagnosing this prettily and returns false if the 2047*f4a2713aSLionel Sambuc /// declspec is done being processed. If it recovers and thinks there may be 2048*f4a2713aSLionel Sambuc /// other pieces of declspec after it, it returns true. 2049*f4a2713aSLionel Sambuc /// 2050*f4a2713aSLionel Sambuc bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, 2051*f4a2713aSLionel Sambuc const ParsedTemplateInfo &TemplateInfo, 2052*f4a2713aSLionel Sambuc AccessSpecifier AS, DeclSpecContext DSC, 2053*f4a2713aSLionel Sambuc ParsedAttributesWithRange &Attrs) { 2054*f4a2713aSLionel Sambuc assert(Tok.is(tok::identifier) && "should have identifier"); 2055*f4a2713aSLionel Sambuc 2056*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 2057*f4a2713aSLionel Sambuc // If we see an identifier that is not a type name, we normally would 2058*f4a2713aSLionel Sambuc // parse it as the identifer being declared. However, when a typename 2059*f4a2713aSLionel Sambuc // is typo'd or the definition is not included, this will incorrectly 2060*f4a2713aSLionel Sambuc // parse the typename as the identifier name and fall over misparsing 2061*f4a2713aSLionel Sambuc // later parts of the diagnostic. 2062*f4a2713aSLionel Sambuc // 2063*f4a2713aSLionel Sambuc // As such, we try to do some look-ahead in cases where this would 2064*f4a2713aSLionel Sambuc // otherwise be an "implicit-int" case to see if this is invalid. For 2065*f4a2713aSLionel Sambuc // example: "static foo_t x = 4;" In this case, if we parsed foo_t as 2066*f4a2713aSLionel Sambuc // an identifier with implicit int, we'd get a parse error because the 2067*f4a2713aSLionel Sambuc // next token is obviously invalid for a type. Parse these as a case 2068*f4a2713aSLionel Sambuc // with an invalid type specifier. 2069*f4a2713aSLionel Sambuc assert(!DS.hasTypeSpecifier() && "Type specifier checked above"); 2070*f4a2713aSLionel Sambuc 2071*f4a2713aSLionel Sambuc // Since we know that this either implicit int (which is rare) or an 2072*f4a2713aSLionel Sambuc // error, do lookahead to try to do better recovery. This never applies 2073*f4a2713aSLionel Sambuc // within a type specifier. Outside of C++, we allow this even if the 2074*f4a2713aSLionel Sambuc // language doesn't "officially" support implicit int -- we support 2075*f4a2713aSLionel Sambuc // implicit int as an extension in C99 and C11. 2076*f4a2713aSLionel Sambuc if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2077*f4a2713aSLionel Sambuc !getLangOpts().CPlusPlus && 2078*f4a2713aSLionel Sambuc isValidAfterIdentifierInDeclarator(NextToken())) { 2079*f4a2713aSLionel Sambuc // If this token is valid for implicit int, e.g. "static x = 4", then 2080*f4a2713aSLionel Sambuc // we just avoid eating the identifier, so it will be parsed as the 2081*f4a2713aSLionel Sambuc // identifier in the declarator. 2082*f4a2713aSLionel Sambuc return false; 2083*f4a2713aSLionel Sambuc } 2084*f4a2713aSLionel Sambuc 2085*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && 2086*f4a2713aSLionel Sambuc DS.getStorageClassSpec() == DeclSpec::SCS_auto) { 2087*f4a2713aSLionel Sambuc // Don't require a type specifier if we have the 'auto' storage class 2088*f4a2713aSLionel Sambuc // specifier in C++98 -- we'll promote it to a type specifier. 2089*f4a2713aSLionel Sambuc if (SS) 2090*f4a2713aSLionel Sambuc AnnotateScopeToken(*SS, /*IsNewAnnotation*/false); 2091*f4a2713aSLionel Sambuc return false; 2092*f4a2713aSLionel Sambuc } 2093*f4a2713aSLionel Sambuc 2094*f4a2713aSLionel Sambuc // Otherwise, if we don't consume this token, we are going to emit an 2095*f4a2713aSLionel Sambuc // error anyway. Try to recover from various common problems. Check 2096*f4a2713aSLionel Sambuc // to see if this was a reference to a tag name without a tag specified. 2097*f4a2713aSLionel Sambuc // This is a common problem in C (saying 'foo' instead of 'struct foo'). 2098*f4a2713aSLionel Sambuc // 2099*f4a2713aSLionel Sambuc // C++ doesn't need this, and isTagName doesn't take SS. 2100*f4a2713aSLionel Sambuc if (SS == 0) { 2101*f4a2713aSLionel Sambuc const char *TagName = 0, *FixitTagName = 0; 2102*f4a2713aSLionel Sambuc tok::TokenKind TagKind = tok::unknown; 2103*f4a2713aSLionel Sambuc 2104*f4a2713aSLionel Sambuc switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) { 2105*f4a2713aSLionel Sambuc default: break; 2106*f4a2713aSLionel Sambuc case DeclSpec::TST_enum: 2107*f4a2713aSLionel Sambuc TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break; 2108*f4a2713aSLionel Sambuc case DeclSpec::TST_union: 2109*f4a2713aSLionel Sambuc TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break; 2110*f4a2713aSLionel Sambuc case DeclSpec::TST_struct: 2111*f4a2713aSLionel Sambuc TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break; 2112*f4a2713aSLionel Sambuc case DeclSpec::TST_interface: 2113*f4a2713aSLionel Sambuc TagName="__interface"; FixitTagName = "__interface "; 2114*f4a2713aSLionel Sambuc TagKind=tok::kw___interface;break; 2115*f4a2713aSLionel Sambuc case DeclSpec::TST_class: 2116*f4a2713aSLionel Sambuc TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; 2117*f4a2713aSLionel Sambuc } 2118*f4a2713aSLionel Sambuc 2119*f4a2713aSLionel Sambuc if (TagName) { 2120*f4a2713aSLionel Sambuc IdentifierInfo *TokenName = Tok.getIdentifierInfo(); 2121*f4a2713aSLionel Sambuc LookupResult R(Actions, TokenName, SourceLocation(), 2122*f4a2713aSLionel Sambuc Sema::LookupOrdinaryName); 2123*f4a2713aSLionel Sambuc 2124*f4a2713aSLionel Sambuc Diag(Loc, diag::err_use_of_tag_name_without_tag) 2125*f4a2713aSLionel Sambuc << TokenName << TagName << getLangOpts().CPlusPlus 2126*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName); 2127*f4a2713aSLionel Sambuc 2128*f4a2713aSLionel Sambuc if (Actions.LookupParsedName(R, getCurScope(), SS)) { 2129*f4a2713aSLionel Sambuc for (LookupResult::iterator I = R.begin(), IEnd = R.end(); 2130*f4a2713aSLionel Sambuc I != IEnd; ++I) 2131*f4a2713aSLionel Sambuc Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type) 2132*f4a2713aSLionel Sambuc << TokenName << TagName; 2133*f4a2713aSLionel Sambuc } 2134*f4a2713aSLionel Sambuc 2135*f4a2713aSLionel Sambuc // Parse this as a tag as if the missing tag were present. 2136*f4a2713aSLionel Sambuc if (TagKind == tok::kw_enum) 2137*f4a2713aSLionel Sambuc ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); 2138*f4a2713aSLionel Sambuc else 2139*f4a2713aSLionel Sambuc ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, 2140*f4a2713aSLionel Sambuc /*EnteringContext*/ false, DSC_normal, Attrs); 2141*f4a2713aSLionel Sambuc return true; 2142*f4a2713aSLionel Sambuc } 2143*f4a2713aSLionel Sambuc } 2144*f4a2713aSLionel Sambuc 2145*f4a2713aSLionel Sambuc // Determine whether this identifier could plausibly be the name of something 2146*f4a2713aSLionel Sambuc // being declared (with a missing type). 2147*f4a2713aSLionel Sambuc if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2148*f4a2713aSLionel Sambuc (!SS || DSC == DSC_top_level || DSC == DSC_class)) { 2149*f4a2713aSLionel Sambuc // Look ahead to the next token to try to figure out what this declaration 2150*f4a2713aSLionel Sambuc // was supposed to be. 2151*f4a2713aSLionel Sambuc switch (NextToken().getKind()) { 2152*f4a2713aSLionel Sambuc case tok::l_paren: { 2153*f4a2713aSLionel Sambuc // static x(4); // 'x' is not a type 2154*f4a2713aSLionel Sambuc // x(int n); // 'x' is not a type 2155*f4a2713aSLionel Sambuc // x (*p)[]; // 'x' is a type 2156*f4a2713aSLionel Sambuc // 2157*f4a2713aSLionel Sambuc // Since we're in an error case (or the rare 'implicit int in C++' MS 2158*f4a2713aSLionel Sambuc // extension), we can afford to perform a tentative parse to determine 2159*f4a2713aSLionel Sambuc // which case we're in. 2160*f4a2713aSLionel Sambuc TentativeParsingAction PA(*this); 2161*f4a2713aSLionel Sambuc ConsumeToken(); 2162*f4a2713aSLionel Sambuc TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false); 2163*f4a2713aSLionel Sambuc PA.Revert(); 2164*f4a2713aSLionel Sambuc 2165*f4a2713aSLionel Sambuc if (TPR != TPResult::False()) { 2166*f4a2713aSLionel Sambuc // The identifier is followed by a parenthesized declarator. 2167*f4a2713aSLionel Sambuc // It's supposed to be a type. 2168*f4a2713aSLionel Sambuc break; 2169*f4a2713aSLionel Sambuc } 2170*f4a2713aSLionel Sambuc 2171*f4a2713aSLionel Sambuc // If we're in a context where we could be declaring a constructor, 2172*f4a2713aSLionel Sambuc // check whether this is a constructor declaration with a bogus name. 2173*f4a2713aSLionel Sambuc if (DSC == DSC_class || (DSC == DSC_top_level && SS)) { 2174*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 2175*f4a2713aSLionel Sambuc if (Actions.isCurrentClassNameTypo(II, SS)) { 2176*f4a2713aSLionel Sambuc Diag(Loc, diag::err_constructor_bad_name) 2177*f4a2713aSLionel Sambuc << Tok.getIdentifierInfo() << II 2178*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(Tok.getLocation(), II->getName()); 2179*f4a2713aSLionel Sambuc Tok.setIdentifierInfo(II); 2180*f4a2713aSLionel Sambuc } 2181*f4a2713aSLionel Sambuc } 2182*f4a2713aSLionel Sambuc // Fall through. 2183*f4a2713aSLionel Sambuc } 2184*f4a2713aSLionel Sambuc case tok::comma: 2185*f4a2713aSLionel Sambuc case tok::equal: 2186*f4a2713aSLionel Sambuc case tok::kw_asm: 2187*f4a2713aSLionel Sambuc case tok::l_brace: 2188*f4a2713aSLionel Sambuc case tok::l_square: 2189*f4a2713aSLionel Sambuc case tok::semi: 2190*f4a2713aSLionel Sambuc // This looks like a variable or function declaration. The type is 2191*f4a2713aSLionel Sambuc // probably missing. We're done parsing decl-specifiers. 2192*f4a2713aSLionel Sambuc if (SS) 2193*f4a2713aSLionel Sambuc AnnotateScopeToken(*SS, /*IsNewAnnotation*/false); 2194*f4a2713aSLionel Sambuc return false; 2195*f4a2713aSLionel Sambuc 2196*f4a2713aSLionel Sambuc default: 2197*f4a2713aSLionel Sambuc // This is probably supposed to be a type. This includes cases like: 2198*f4a2713aSLionel Sambuc // int f(itn); 2199*f4a2713aSLionel Sambuc // struct S { unsinged : 4; }; 2200*f4a2713aSLionel Sambuc break; 2201*f4a2713aSLionel Sambuc } 2202*f4a2713aSLionel Sambuc } 2203*f4a2713aSLionel Sambuc 2204*f4a2713aSLionel Sambuc // This is almost certainly an invalid type name. Let the action emit a 2205*f4a2713aSLionel Sambuc // diagnostic and attempt to recover. 2206*f4a2713aSLionel Sambuc ParsedType T; 2207*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 2208*f4a2713aSLionel Sambuc if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) { 2209*f4a2713aSLionel Sambuc // The action emitted a diagnostic, so we don't have to. 2210*f4a2713aSLionel Sambuc if (T) { 2211*f4a2713aSLionel Sambuc // The action has suggested that the type T could be used. Set that as 2212*f4a2713aSLionel Sambuc // the type in the declaration specifiers, consume the would-be type 2213*f4a2713aSLionel Sambuc // name token, and we're done. 2214*f4a2713aSLionel Sambuc const char *PrevSpec; 2215*f4a2713aSLionel Sambuc unsigned DiagID; 2216*f4a2713aSLionel Sambuc DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); 2217*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 2218*f4a2713aSLionel Sambuc ConsumeToken(); 2219*f4a2713aSLionel Sambuc // There may be other declaration specifiers after this. 2220*f4a2713aSLionel Sambuc return true; 2221*f4a2713aSLionel Sambuc } else if (II != Tok.getIdentifierInfo()) { 2222*f4a2713aSLionel Sambuc // If no type was suggested, the correction is to a keyword 2223*f4a2713aSLionel Sambuc Tok.setKind(II->getTokenID()); 2224*f4a2713aSLionel Sambuc // There may be other declaration specifiers after this. 2225*f4a2713aSLionel Sambuc return true; 2226*f4a2713aSLionel Sambuc } 2227*f4a2713aSLionel Sambuc 2228*f4a2713aSLionel Sambuc // Fall through; the action had no suggestion for us. 2229*f4a2713aSLionel Sambuc } else { 2230*f4a2713aSLionel Sambuc // The action did not emit a diagnostic, so emit one now. 2231*f4a2713aSLionel Sambuc SourceRange R; 2232*f4a2713aSLionel Sambuc if (SS) R = SS->getRange(); 2233*f4a2713aSLionel Sambuc Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R; 2234*f4a2713aSLionel Sambuc } 2235*f4a2713aSLionel Sambuc 2236*f4a2713aSLionel Sambuc // Mark this as an error. 2237*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 2238*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 2239*f4a2713aSLionel Sambuc ConsumeToken(); 2240*f4a2713aSLionel Sambuc 2241*f4a2713aSLionel Sambuc // TODO: Could inject an invalid typedef decl in an enclosing scope to 2242*f4a2713aSLionel Sambuc // avoid rippling error messages on subsequent uses of the same type, 2243*f4a2713aSLionel Sambuc // could be useful if #include was forgotten. 2244*f4a2713aSLionel Sambuc return false; 2245*f4a2713aSLionel Sambuc } 2246*f4a2713aSLionel Sambuc 2247*f4a2713aSLionel Sambuc /// \brief Determine the declaration specifier context from the declarator 2248*f4a2713aSLionel Sambuc /// context. 2249*f4a2713aSLionel Sambuc /// 2250*f4a2713aSLionel Sambuc /// \param Context the declarator context, which is one of the 2251*f4a2713aSLionel Sambuc /// Declarator::TheContext enumerator values. 2252*f4a2713aSLionel Sambuc Parser::DeclSpecContext 2253*f4a2713aSLionel Sambuc Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { 2254*f4a2713aSLionel Sambuc if (Context == Declarator::MemberContext) 2255*f4a2713aSLionel Sambuc return DSC_class; 2256*f4a2713aSLionel Sambuc if (Context == Declarator::FileContext) 2257*f4a2713aSLionel Sambuc return DSC_top_level; 2258*f4a2713aSLionel Sambuc if (Context == Declarator::TrailingReturnContext) 2259*f4a2713aSLionel Sambuc return DSC_trailing; 2260*f4a2713aSLionel Sambuc return DSC_normal; 2261*f4a2713aSLionel Sambuc } 2262*f4a2713aSLionel Sambuc 2263*f4a2713aSLionel Sambuc /// ParseAlignArgument - Parse the argument to an alignment-specifier. 2264*f4a2713aSLionel Sambuc /// 2265*f4a2713aSLionel Sambuc /// FIXME: Simply returns an alignof() expression if the argument is a 2266*f4a2713aSLionel Sambuc /// type. Ideally, the type should be propagated directly into Sema. 2267*f4a2713aSLionel Sambuc /// 2268*f4a2713aSLionel Sambuc /// [C11] type-id 2269*f4a2713aSLionel Sambuc /// [C11] constant-expression 2270*f4a2713aSLionel Sambuc /// [C++0x] type-id ...[opt] 2271*f4a2713aSLionel Sambuc /// [C++0x] assignment-expression ...[opt] 2272*f4a2713aSLionel Sambuc ExprResult Parser::ParseAlignArgument(SourceLocation Start, 2273*f4a2713aSLionel Sambuc SourceLocation &EllipsisLoc) { 2274*f4a2713aSLionel Sambuc ExprResult ER; 2275*f4a2713aSLionel Sambuc if (isTypeIdInParens()) { 2276*f4a2713aSLionel Sambuc SourceLocation TypeLoc = Tok.getLocation(); 2277*f4a2713aSLionel Sambuc ParsedType Ty = ParseTypeName().get(); 2278*f4a2713aSLionel Sambuc SourceRange TypeRange(Start, Tok.getLocation()); 2279*f4a2713aSLionel Sambuc ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true, 2280*f4a2713aSLionel Sambuc Ty.getAsOpaquePtr(), TypeRange); 2281*f4a2713aSLionel Sambuc } else 2282*f4a2713aSLionel Sambuc ER = ParseConstantExpression(); 2283*f4a2713aSLionel Sambuc 2284*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis)) 2285*f4a2713aSLionel Sambuc EllipsisLoc = ConsumeToken(); 2286*f4a2713aSLionel Sambuc 2287*f4a2713aSLionel Sambuc return ER; 2288*f4a2713aSLionel Sambuc } 2289*f4a2713aSLionel Sambuc 2290*f4a2713aSLionel Sambuc /// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the 2291*f4a2713aSLionel Sambuc /// attribute to Attrs. 2292*f4a2713aSLionel Sambuc /// 2293*f4a2713aSLionel Sambuc /// alignment-specifier: 2294*f4a2713aSLionel Sambuc /// [C11] '_Alignas' '(' type-id ')' 2295*f4a2713aSLionel Sambuc /// [C11] '_Alignas' '(' constant-expression ')' 2296*f4a2713aSLionel Sambuc /// [C++11] 'alignas' '(' type-id ...[opt] ')' 2297*f4a2713aSLionel Sambuc /// [C++11] 'alignas' '(' assignment-expression ...[opt] ')' 2298*f4a2713aSLionel Sambuc void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, 2299*f4a2713aSLionel Sambuc SourceLocation *EndLoc) { 2300*f4a2713aSLionel Sambuc assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) && 2301*f4a2713aSLionel Sambuc "Not an alignment-specifier!"); 2302*f4a2713aSLionel Sambuc 2303*f4a2713aSLionel Sambuc IdentifierInfo *KWName = Tok.getIdentifierInfo(); 2304*f4a2713aSLionel Sambuc SourceLocation KWLoc = ConsumeToken(); 2305*f4a2713aSLionel Sambuc 2306*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2307*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen)) 2308*f4a2713aSLionel Sambuc return; 2309*f4a2713aSLionel Sambuc 2310*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc; 2311*f4a2713aSLionel Sambuc ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); 2312*f4a2713aSLionel Sambuc if (ArgExpr.isInvalid()) { 2313*f4a2713aSLionel Sambuc T.skipToEnd(); 2314*f4a2713aSLionel Sambuc return; 2315*f4a2713aSLionel Sambuc } 2316*f4a2713aSLionel Sambuc 2317*f4a2713aSLionel Sambuc T.consumeClose(); 2318*f4a2713aSLionel Sambuc if (EndLoc) 2319*f4a2713aSLionel Sambuc *EndLoc = T.getCloseLocation(); 2320*f4a2713aSLionel Sambuc 2321*f4a2713aSLionel Sambuc ArgsVector ArgExprs; 2322*f4a2713aSLionel Sambuc ArgExprs.push_back(ArgExpr.release()); 2323*f4a2713aSLionel Sambuc Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1, 2324*f4a2713aSLionel Sambuc AttributeList::AS_Keyword, EllipsisLoc); 2325*f4a2713aSLionel Sambuc } 2326*f4a2713aSLionel Sambuc 2327*f4a2713aSLionel Sambuc /// Determine whether we're looking at something that might be a declarator 2328*f4a2713aSLionel Sambuc /// in a simple-declaration. If it can't possibly be a declarator, maybe 2329*f4a2713aSLionel Sambuc /// diagnose a missing semicolon after a prior tag definition in the decl 2330*f4a2713aSLionel Sambuc /// specifier. 2331*f4a2713aSLionel Sambuc /// 2332*f4a2713aSLionel Sambuc /// \return \c true if an error occurred and this can't be any kind of 2333*f4a2713aSLionel Sambuc /// declaration. 2334*f4a2713aSLionel Sambuc bool 2335*f4a2713aSLionel Sambuc Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, 2336*f4a2713aSLionel Sambuc DeclSpecContext DSContext, 2337*f4a2713aSLionel Sambuc LateParsedAttrList *LateAttrs) { 2338*f4a2713aSLionel Sambuc assert(DS.hasTagDefinition() && "shouldn't call this"); 2339*f4a2713aSLionel Sambuc 2340*f4a2713aSLionel Sambuc bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2341*f4a2713aSLionel Sambuc bool HasMissingSemi = false; 2342*f4a2713aSLionel Sambuc 2343*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && 2344*f4a2713aSLionel Sambuc (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || 2345*f4a2713aSLionel Sambuc Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) && 2346*f4a2713aSLionel Sambuc TryAnnotateCXXScopeToken(EnteringContext)) { 2347*f4a2713aSLionel Sambuc SkipMalformedDecl(); 2348*f4a2713aSLionel Sambuc return true; 2349*f4a2713aSLionel Sambuc } 2350*f4a2713aSLionel Sambuc 2351*f4a2713aSLionel Sambuc // Determine whether the following tokens could possibly be a 2352*f4a2713aSLionel Sambuc // declarator. 2353*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 2354*f4a2713aSLionel Sambuc const Token &Next = NextToken(); 2355*f4a2713aSLionel Sambuc // These tokens cannot come after the declarator-id in a 2356*f4a2713aSLionel Sambuc // simple-declaration, and are likely to come after a type-specifier. 2357*f4a2713aSLionel Sambuc HasMissingSemi = Next.is(tok::star) || Next.is(tok::amp) || 2358*f4a2713aSLionel Sambuc Next.is(tok::ampamp) || Next.is(tok::identifier) || 2359*f4a2713aSLionel Sambuc Next.is(tok::annot_cxxscope) || 2360*f4a2713aSLionel Sambuc Next.is(tok::coloncolon); 2361*f4a2713aSLionel Sambuc } else if (Tok.is(tok::annot_cxxscope) && 2362*f4a2713aSLionel Sambuc NextToken().is(tok::identifier) && 2363*f4a2713aSLionel Sambuc DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { 2364*f4a2713aSLionel Sambuc // We almost certainly have a missing semicolon. Look up the name and 2365*f4a2713aSLionel Sambuc // check; if it names a type, we're missing a semicolon. 2366*f4a2713aSLionel Sambuc CXXScopeSpec SS; 2367*f4a2713aSLionel Sambuc Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2368*f4a2713aSLionel Sambuc Tok.getAnnotationRange(), SS); 2369*f4a2713aSLionel Sambuc const Token &Next = NextToken(); 2370*f4a2713aSLionel Sambuc IdentifierInfo *Name = Next.getIdentifierInfo(); 2371*f4a2713aSLionel Sambuc Sema::NameClassification Classification = 2372*f4a2713aSLionel Sambuc Actions.ClassifyName(getCurScope(), SS, Name, Next.getLocation(), 2373*f4a2713aSLionel Sambuc NextToken(), /*IsAddressOfOperand*/false); 2374*f4a2713aSLionel Sambuc switch (Classification.getKind()) { 2375*f4a2713aSLionel Sambuc case Sema::NC_Error: 2376*f4a2713aSLionel Sambuc SkipMalformedDecl(); 2377*f4a2713aSLionel Sambuc return true; 2378*f4a2713aSLionel Sambuc 2379*f4a2713aSLionel Sambuc case Sema::NC_Keyword: 2380*f4a2713aSLionel Sambuc case Sema::NC_NestedNameSpecifier: 2381*f4a2713aSLionel Sambuc llvm_unreachable("typo correction and nested name specifiers not " 2382*f4a2713aSLionel Sambuc "possible here"); 2383*f4a2713aSLionel Sambuc 2384*f4a2713aSLionel Sambuc case Sema::NC_Type: 2385*f4a2713aSLionel Sambuc case Sema::NC_TypeTemplate: 2386*f4a2713aSLionel Sambuc // Not a previously-declared non-type entity. 2387*f4a2713aSLionel Sambuc HasMissingSemi = true; 2388*f4a2713aSLionel Sambuc break; 2389*f4a2713aSLionel Sambuc 2390*f4a2713aSLionel Sambuc case Sema::NC_Unknown: 2391*f4a2713aSLionel Sambuc case Sema::NC_Expression: 2392*f4a2713aSLionel Sambuc case Sema::NC_VarTemplate: 2393*f4a2713aSLionel Sambuc case Sema::NC_FunctionTemplate: 2394*f4a2713aSLionel Sambuc // Might be a redeclaration of a prior entity. 2395*f4a2713aSLionel Sambuc HasMissingSemi = false; 2396*f4a2713aSLionel Sambuc break; 2397*f4a2713aSLionel Sambuc } 2398*f4a2713aSLionel Sambuc } else if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) { 2399*f4a2713aSLionel Sambuc HasMissingSemi = true; 2400*f4a2713aSLionel Sambuc } 2401*f4a2713aSLionel Sambuc 2402*f4a2713aSLionel Sambuc if (!HasMissingSemi) 2403*f4a2713aSLionel Sambuc return false; 2404*f4a2713aSLionel Sambuc 2405*f4a2713aSLionel Sambuc Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()), 2406*f4a2713aSLionel Sambuc diag::err_expected_semi_after_tagdecl) 2407*f4a2713aSLionel Sambuc << DeclSpec::getSpecifierName(DS.getTypeSpecType()); 2408*f4a2713aSLionel Sambuc 2409*f4a2713aSLionel Sambuc // Try to recover from the typo, by dropping the tag definition and parsing 2410*f4a2713aSLionel Sambuc // the problematic tokens as a type. 2411*f4a2713aSLionel Sambuc // 2412*f4a2713aSLionel Sambuc // FIXME: Split the DeclSpec into pieces for the standalone 2413*f4a2713aSLionel Sambuc // declaration and pieces for the following declaration, instead 2414*f4a2713aSLionel Sambuc // of assuming that all the other pieces attach to new declaration, 2415*f4a2713aSLionel Sambuc // and call ParsedFreeStandingDeclSpec as appropriate. 2416*f4a2713aSLionel Sambuc DS.ClearTypeSpecType(); 2417*f4a2713aSLionel Sambuc ParsedTemplateInfo NotATemplate; 2418*f4a2713aSLionel Sambuc ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs); 2419*f4a2713aSLionel Sambuc return false; 2420*f4a2713aSLionel Sambuc } 2421*f4a2713aSLionel Sambuc 2422*f4a2713aSLionel Sambuc /// ParseDeclarationSpecifiers 2423*f4a2713aSLionel Sambuc /// declaration-specifiers: [C99 6.7] 2424*f4a2713aSLionel Sambuc /// storage-class-specifier declaration-specifiers[opt] 2425*f4a2713aSLionel Sambuc /// type-specifier declaration-specifiers[opt] 2426*f4a2713aSLionel Sambuc /// [C99] function-specifier declaration-specifiers[opt] 2427*f4a2713aSLionel Sambuc /// [C11] alignment-specifier declaration-specifiers[opt] 2428*f4a2713aSLionel Sambuc /// [GNU] attributes declaration-specifiers[opt] 2429*f4a2713aSLionel Sambuc /// [Clang] '__module_private__' declaration-specifiers[opt] 2430*f4a2713aSLionel Sambuc /// 2431*f4a2713aSLionel Sambuc /// storage-class-specifier: [C99 6.7.1] 2432*f4a2713aSLionel Sambuc /// 'typedef' 2433*f4a2713aSLionel Sambuc /// 'extern' 2434*f4a2713aSLionel Sambuc /// 'static' 2435*f4a2713aSLionel Sambuc /// 'auto' 2436*f4a2713aSLionel Sambuc /// 'register' 2437*f4a2713aSLionel Sambuc /// [C++] 'mutable' 2438*f4a2713aSLionel Sambuc /// [C++11] 'thread_local' 2439*f4a2713aSLionel Sambuc /// [C11] '_Thread_local' 2440*f4a2713aSLionel Sambuc /// [GNU] '__thread' 2441*f4a2713aSLionel Sambuc /// function-specifier: [C99 6.7.4] 2442*f4a2713aSLionel Sambuc /// [C99] 'inline' 2443*f4a2713aSLionel Sambuc /// [C++] 'virtual' 2444*f4a2713aSLionel Sambuc /// [C++] 'explicit' 2445*f4a2713aSLionel Sambuc /// [OpenCL] '__kernel' 2446*f4a2713aSLionel Sambuc /// 'friend': [C++ dcl.friend] 2447*f4a2713aSLionel Sambuc /// 'constexpr': [C++0x dcl.constexpr] 2448*f4a2713aSLionel Sambuc 2449*f4a2713aSLionel Sambuc /// 2450*f4a2713aSLionel Sambuc void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, 2451*f4a2713aSLionel Sambuc const ParsedTemplateInfo &TemplateInfo, 2452*f4a2713aSLionel Sambuc AccessSpecifier AS, 2453*f4a2713aSLionel Sambuc DeclSpecContext DSContext, 2454*f4a2713aSLionel Sambuc LateParsedAttrList *LateAttrs) { 2455*f4a2713aSLionel Sambuc if (DS.getSourceRange().isInvalid()) { 2456*f4a2713aSLionel Sambuc DS.SetRangeStart(Tok.getLocation()); 2457*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 2458*f4a2713aSLionel Sambuc } 2459*f4a2713aSLionel Sambuc 2460*f4a2713aSLionel Sambuc bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2461*f4a2713aSLionel Sambuc bool AttrsLastTime = false; 2462*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 2463*f4a2713aSLionel Sambuc while (1) { 2464*f4a2713aSLionel Sambuc bool isInvalid = false; 2465*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 2466*f4a2713aSLionel Sambuc unsigned DiagID = 0; 2467*f4a2713aSLionel Sambuc 2468*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 2469*f4a2713aSLionel Sambuc 2470*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 2471*f4a2713aSLionel Sambuc default: 2472*f4a2713aSLionel Sambuc DoneWithDeclSpec: 2473*f4a2713aSLionel Sambuc if (!AttrsLastTime) 2474*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 2475*f4a2713aSLionel Sambuc else { 2476*f4a2713aSLionel Sambuc // Reject C++11 attributes that appertain to decl specifiers as 2477*f4a2713aSLionel Sambuc // we don't support any C++11 attributes that appertain to decl 2478*f4a2713aSLionel Sambuc // specifiers. This also conforms to what g++ 4.8 is doing. 2479*f4a2713aSLionel Sambuc ProhibitCXX11Attributes(attrs); 2480*f4a2713aSLionel Sambuc 2481*f4a2713aSLionel Sambuc DS.takeAttributesFrom(attrs); 2482*f4a2713aSLionel Sambuc } 2483*f4a2713aSLionel Sambuc 2484*f4a2713aSLionel Sambuc // If this is not a declaration specifier token, we're done reading decl 2485*f4a2713aSLionel Sambuc // specifiers. First verify that DeclSpec's are consistent. 2486*f4a2713aSLionel Sambuc DS.Finish(Diags, PP); 2487*f4a2713aSLionel Sambuc return; 2488*f4a2713aSLionel Sambuc 2489*f4a2713aSLionel Sambuc case tok::l_square: 2490*f4a2713aSLionel Sambuc case tok::kw_alignas: 2491*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier()) 2492*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2493*f4a2713aSLionel Sambuc 2494*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 2495*f4a2713aSLionel Sambuc // FIXME: It would be good to recover by accepting the attributes, 2496*f4a2713aSLionel Sambuc // but attempting to do that now would cause serious 2497*f4a2713aSLionel Sambuc // madness in terms of diagnostics. 2498*f4a2713aSLionel Sambuc attrs.clear(); 2499*f4a2713aSLionel Sambuc attrs.Range = SourceRange(); 2500*f4a2713aSLionel Sambuc 2501*f4a2713aSLionel Sambuc ParseCXX11Attributes(attrs); 2502*f4a2713aSLionel Sambuc AttrsLastTime = true; 2503*f4a2713aSLionel Sambuc continue; 2504*f4a2713aSLionel Sambuc 2505*f4a2713aSLionel Sambuc case tok::code_completion: { 2506*f4a2713aSLionel Sambuc Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; 2507*f4a2713aSLionel Sambuc if (DS.hasTypeSpecifier()) { 2508*f4a2713aSLionel Sambuc bool AllowNonIdentifiers 2509*f4a2713aSLionel Sambuc = (getCurScope()->getFlags() & (Scope::ControlScope | 2510*f4a2713aSLionel Sambuc Scope::BlockScope | 2511*f4a2713aSLionel Sambuc Scope::TemplateParamScope | 2512*f4a2713aSLionel Sambuc Scope::FunctionPrototypeScope | 2513*f4a2713aSLionel Sambuc Scope::AtCatchScope)) == 0; 2514*f4a2713aSLionel Sambuc bool AllowNestedNameSpecifiers 2515*f4a2713aSLionel Sambuc = DSContext == DSC_top_level || 2516*f4a2713aSLionel Sambuc (DSContext == DSC_class && DS.isFriendSpecified()); 2517*f4a2713aSLionel Sambuc 2518*f4a2713aSLionel Sambuc Actions.CodeCompleteDeclSpec(getCurScope(), DS, 2519*f4a2713aSLionel Sambuc AllowNonIdentifiers, 2520*f4a2713aSLionel Sambuc AllowNestedNameSpecifiers); 2521*f4a2713aSLionel Sambuc return cutOffParsing(); 2522*f4a2713aSLionel Sambuc } 2523*f4a2713aSLionel Sambuc 2524*f4a2713aSLionel Sambuc if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) 2525*f4a2713aSLionel Sambuc CCC = Sema::PCC_LocalDeclarationSpecifiers; 2526*f4a2713aSLionel Sambuc else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) 2527*f4a2713aSLionel Sambuc CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 2528*f4a2713aSLionel Sambuc : Sema::PCC_Template; 2529*f4a2713aSLionel Sambuc else if (DSContext == DSC_class) 2530*f4a2713aSLionel Sambuc CCC = Sema::PCC_Class; 2531*f4a2713aSLionel Sambuc else if (CurParsedObjCImpl) 2532*f4a2713aSLionel Sambuc CCC = Sema::PCC_ObjCImplementation; 2533*f4a2713aSLionel Sambuc 2534*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); 2535*f4a2713aSLionel Sambuc return cutOffParsing(); 2536*f4a2713aSLionel Sambuc } 2537*f4a2713aSLionel Sambuc 2538*f4a2713aSLionel Sambuc case tok::coloncolon: // ::foo::bar 2539*f4a2713aSLionel Sambuc // C++ scope specifier. Annotate and loop, or bail out on error. 2540*f4a2713aSLionel Sambuc if (TryAnnotateCXXScopeToken(EnteringContext)) { 2541*f4a2713aSLionel Sambuc if (!DS.hasTypeSpecifier()) 2542*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 2543*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2544*f4a2713aSLionel Sambuc } 2545*f4a2713aSLionel Sambuc if (Tok.is(tok::coloncolon)) // ::new or ::delete 2546*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2547*f4a2713aSLionel Sambuc continue; 2548*f4a2713aSLionel Sambuc 2549*f4a2713aSLionel Sambuc case tok::annot_cxxscope: { 2550*f4a2713aSLionel Sambuc if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector()) 2551*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2552*f4a2713aSLionel Sambuc 2553*f4a2713aSLionel Sambuc CXXScopeSpec SS; 2554*f4a2713aSLionel Sambuc Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2555*f4a2713aSLionel Sambuc Tok.getAnnotationRange(), 2556*f4a2713aSLionel Sambuc SS); 2557*f4a2713aSLionel Sambuc 2558*f4a2713aSLionel Sambuc // We are looking for a qualified typename. 2559*f4a2713aSLionel Sambuc Token Next = NextToken(); 2560*f4a2713aSLionel Sambuc if (Next.is(tok::annot_template_id) && 2561*f4a2713aSLionel Sambuc static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) 2562*f4a2713aSLionel Sambuc ->Kind == TNK_Type_template) { 2563*f4a2713aSLionel Sambuc // We have a qualified template-id, e.g., N::A<int> 2564*f4a2713aSLionel Sambuc 2565*f4a2713aSLionel Sambuc // C++ [class.qual]p2: 2566*f4a2713aSLionel Sambuc // In a lookup in which the constructor is an acceptable lookup 2567*f4a2713aSLionel Sambuc // result and the nested-name-specifier nominates a class C: 2568*f4a2713aSLionel Sambuc // 2569*f4a2713aSLionel Sambuc // - if the name specified after the 2570*f4a2713aSLionel Sambuc // nested-name-specifier, when looked up in C, is the 2571*f4a2713aSLionel Sambuc // injected-class-name of C (Clause 9), or 2572*f4a2713aSLionel Sambuc // 2573*f4a2713aSLionel Sambuc // - if the name specified after the nested-name-specifier 2574*f4a2713aSLionel Sambuc // is the same as the identifier or the 2575*f4a2713aSLionel Sambuc // simple-template-id's template-name in the last 2576*f4a2713aSLionel Sambuc // component of the nested-name-specifier, 2577*f4a2713aSLionel Sambuc // 2578*f4a2713aSLionel Sambuc // the name is instead considered to name the constructor of 2579*f4a2713aSLionel Sambuc // class C. 2580*f4a2713aSLionel Sambuc // 2581*f4a2713aSLionel Sambuc // Thus, if the template-name is actually the constructor 2582*f4a2713aSLionel Sambuc // name, then the code is ill-formed; this interpretation is 2583*f4a2713aSLionel Sambuc // reinforced by the NAD status of core issue 635. 2584*f4a2713aSLionel Sambuc TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 2585*f4a2713aSLionel Sambuc if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2586*f4a2713aSLionel Sambuc TemplateId->Name && 2587*f4a2713aSLionel Sambuc Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 2588*f4a2713aSLionel Sambuc if (isConstructorDeclarator()) { 2589*f4a2713aSLionel Sambuc // The user meant this to be an out-of-line constructor 2590*f4a2713aSLionel Sambuc // definition, but template arguments are not allowed 2591*f4a2713aSLionel Sambuc // there. Just allow this as a constructor; we'll 2592*f4a2713aSLionel Sambuc // complain about it later. 2593*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2594*f4a2713aSLionel Sambuc } 2595*f4a2713aSLionel Sambuc 2596*f4a2713aSLionel Sambuc // The user meant this to name a type, but it actually names 2597*f4a2713aSLionel Sambuc // a constructor with some extraneous template 2598*f4a2713aSLionel Sambuc // arguments. Complain, then parse it as a type as the user 2599*f4a2713aSLionel Sambuc // intended. 2600*f4a2713aSLionel Sambuc Diag(TemplateId->TemplateNameLoc, 2601*f4a2713aSLionel Sambuc diag::err_out_of_line_template_id_names_constructor) 2602*f4a2713aSLionel Sambuc << TemplateId->Name; 2603*f4a2713aSLionel Sambuc } 2604*f4a2713aSLionel Sambuc 2605*f4a2713aSLionel Sambuc DS.getTypeSpecScope() = SS; 2606*f4a2713aSLionel Sambuc ConsumeToken(); // The C++ scope. 2607*f4a2713aSLionel Sambuc assert(Tok.is(tok::annot_template_id) && 2608*f4a2713aSLionel Sambuc "ParseOptionalCXXScopeSpecifier not working"); 2609*f4a2713aSLionel Sambuc AnnotateTemplateIdTokenAsType(); 2610*f4a2713aSLionel Sambuc continue; 2611*f4a2713aSLionel Sambuc } 2612*f4a2713aSLionel Sambuc 2613*f4a2713aSLionel Sambuc if (Next.is(tok::annot_typename)) { 2614*f4a2713aSLionel Sambuc DS.getTypeSpecScope() = SS; 2615*f4a2713aSLionel Sambuc ConsumeToken(); // The C++ scope. 2616*f4a2713aSLionel Sambuc if (Tok.getAnnotationValue()) { 2617*f4a2713aSLionel Sambuc ParsedType T = getTypeAnnotation(Tok); 2618*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, 2619*f4a2713aSLionel Sambuc Tok.getAnnotationEndLoc(), 2620*f4a2713aSLionel Sambuc PrevSpec, DiagID, T); 2621*f4a2713aSLionel Sambuc if (isInvalid) 2622*f4a2713aSLionel Sambuc break; 2623*f4a2713aSLionel Sambuc } 2624*f4a2713aSLionel Sambuc else 2625*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 2626*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2627*f4a2713aSLionel Sambuc ConsumeToken(); // The typename 2628*f4a2713aSLionel Sambuc } 2629*f4a2713aSLionel Sambuc 2630*f4a2713aSLionel Sambuc if (Next.isNot(tok::identifier)) 2631*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2632*f4a2713aSLionel Sambuc 2633*f4a2713aSLionel Sambuc // If we're in a context where the identifier could be a class name, 2634*f4a2713aSLionel Sambuc // check whether this is a constructor declaration. 2635*f4a2713aSLionel Sambuc if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2636*f4a2713aSLionel Sambuc Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 2637*f4a2713aSLionel Sambuc &SS)) { 2638*f4a2713aSLionel Sambuc if (isConstructorDeclarator()) 2639*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2640*f4a2713aSLionel Sambuc 2641*f4a2713aSLionel Sambuc // As noted in C++ [class.qual]p2 (cited above), when the name 2642*f4a2713aSLionel Sambuc // of the class is qualified in a context where it could name 2643*f4a2713aSLionel Sambuc // a constructor, its a constructor name. However, we've 2644*f4a2713aSLionel Sambuc // looked at the declarator, and the user probably meant this 2645*f4a2713aSLionel Sambuc // to be a type. Complain that it isn't supposed to be treated 2646*f4a2713aSLionel Sambuc // as a type, then proceed to parse it as a type. 2647*f4a2713aSLionel Sambuc Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) 2648*f4a2713aSLionel Sambuc << Next.getIdentifierInfo(); 2649*f4a2713aSLionel Sambuc } 2650*f4a2713aSLionel Sambuc 2651*f4a2713aSLionel Sambuc ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), 2652*f4a2713aSLionel Sambuc Next.getLocation(), 2653*f4a2713aSLionel Sambuc getCurScope(), &SS, 2654*f4a2713aSLionel Sambuc false, false, ParsedType(), 2655*f4a2713aSLionel Sambuc /*IsCtorOrDtorName=*/false, 2656*f4a2713aSLionel Sambuc /*NonTrivialSourceInfo=*/true); 2657*f4a2713aSLionel Sambuc 2658*f4a2713aSLionel Sambuc // If the referenced identifier is not a type, then this declspec is 2659*f4a2713aSLionel Sambuc // erroneous: We already checked about that it has no type specifier, and 2660*f4a2713aSLionel Sambuc // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the 2661*f4a2713aSLionel Sambuc // typename. 2662*f4a2713aSLionel Sambuc if (!TypeRep) { 2663*f4a2713aSLionel Sambuc ConsumeToken(); // Eat the scope spec so the identifier is current. 2664*f4a2713aSLionel Sambuc ParsedAttributesWithRange Attrs(AttrFactory); 2665*f4a2713aSLionel Sambuc if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) { 2666*f4a2713aSLionel Sambuc if (!Attrs.empty()) { 2667*f4a2713aSLionel Sambuc AttrsLastTime = true; 2668*f4a2713aSLionel Sambuc attrs.takeAllFrom(Attrs); 2669*f4a2713aSLionel Sambuc } 2670*f4a2713aSLionel Sambuc continue; 2671*f4a2713aSLionel Sambuc } 2672*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2673*f4a2713aSLionel Sambuc } 2674*f4a2713aSLionel Sambuc 2675*f4a2713aSLionel Sambuc DS.getTypeSpecScope() = SS; 2676*f4a2713aSLionel Sambuc ConsumeToken(); // The C++ scope. 2677*f4a2713aSLionel Sambuc 2678*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2679*f4a2713aSLionel Sambuc DiagID, TypeRep); 2680*f4a2713aSLionel Sambuc if (isInvalid) 2681*f4a2713aSLionel Sambuc break; 2682*f4a2713aSLionel Sambuc 2683*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 2684*f4a2713aSLionel Sambuc ConsumeToken(); // The typename. 2685*f4a2713aSLionel Sambuc 2686*f4a2713aSLionel Sambuc continue; 2687*f4a2713aSLionel Sambuc } 2688*f4a2713aSLionel Sambuc 2689*f4a2713aSLionel Sambuc case tok::annot_typename: { 2690*f4a2713aSLionel Sambuc // If we've previously seen a tag definition, we were almost surely 2691*f4a2713aSLionel Sambuc // missing a semicolon after it. 2692*f4a2713aSLionel Sambuc if (DS.hasTypeSpecifier() && DS.hasTagDefinition()) 2693*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2694*f4a2713aSLionel Sambuc 2695*f4a2713aSLionel Sambuc if (Tok.getAnnotationValue()) { 2696*f4a2713aSLionel Sambuc ParsedType T = getTypeAnnotation(Tok); 2697*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2698*f4a2713aSLionel Sambuc DiagID, T); 2699*f4a2713aSLionel Sambuc } else 2700*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 2701*f4a2713aSLionel Sambuc 2702*f4a2713aSLionel Sambuc if (isInvalid) 2703*f4a2713aSLionel Sambuc break; 2704*f4a2713aSLionel Sambuc 2705*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2706*f4a2713aSLionel Sambuc ConsumeToken(); // The typename 2707*f4a2713aSLionel Sambuc 2708*f4a2713aSLionel Sambuc // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2709*f4a2713aSLionel Sambuc // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2710*f4a2713aSLionel Sambuc // Objective-C interface. 2711*f4a2713aSLionel Sambuc if (Tok.is(tok::less) && getLangOpts().ObjC1) 2712*f4a2713aSLionel Sambuc ParseObjCProtocolQualifiers(DS); 2713*f4a2713aSLionel Sambuc 2714*f4a2713aSLionel Sambuc continue; 2715*f4a2713aSLionel Sambuc } 2716*f4a2713aSLionel Sambuc 2717*f4a2713aSLionel Sambuc case tok::kw___is_signed: 2718*f4a2713aSLionel Sambuc // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang 2719*f4a2713aSLionel Sambuc // typically treats it as a trait. If we see __is_signed as it appears 2720*f4a2713aSLionel Sambuc // in libstdc++, e.g., 2721*f4a2713aSLionel Sambuc // 2722*f4a2713aSLionel Sambuc // static const bool __is_signed; 2723*f4a2713aSLionel Sambuc // 2724*f4a2713aSLionel Sambuc // then treat __is_signed as an identifier rather than as a keyword. 2725*f4a2713aSLionel Sambuc if (DS.getTypeSpecType() == TST_bool && 2726*f4a2713aSLionel Sambuc DS.getTypeQualifiers() == DeclSpec::TQ_const && 2727*f4a2713aSLionel Sambuc DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2728*f4a2713aSLionel Sambuc Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 2729*f4a2713aSLionel Sambuc Tok.setKind(tok::identifier); 2730*f4a2713aSLionel Sambuc } 2731*f4a2713aSLionel Sambuc 2732*f4a2713aSLionel Sambuc // We're done with the declaration-specifiers. 2733*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2734*f4a2713aSLionel Sambuc 2735*f4a2713aSLionel Sambuc // typedef-name 2736*f4a2713aSLionel Sambuc case tok::kw_decltype: 2737*f4a2713aSLionel Sambuc case tok::identifier: { 2738*f4a2713aSLionel Sambuc // In C++, check to see if this is a scope specifier like foo::bar::, if 2739*f4a2713aSLionel Sambuc // so handle it as such. This is important for ctor parsing. 2740*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 2741*f4a2713aSLionel Sambuc if (TryAnnotateCXXScopeToken(EnteringContext)) { 2742*f4a2713aSLionel Sambuc if (!DS.hasTypeSpecifier()) 2743*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 2744*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2745*f4a2713aSLionel Sambuc } 2746*f4a2713aSLionel Sambuc if (!Tok.is(tok::identifier)) 2747*f4a2713aSLionel Sambuc continue; 2748*f4a2713aSLionel Sambuc } 2749*f4a2713aSLionel Sambuc 2750*f4a2713aSLionel Sambuc // This identifier can only be a typedef name if we haven't already seen 2751*f4a2713aSLionel Sambuc // a type-specifier. Without this check we misparse: 2752*f4a2713aSLionel Sambuc // typedef int X; struct Y { short X; }; as 'short int'. 2753*f4a2713aSLionel Sambuc if (DS.hasTypeSpecifier()) 2754*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2755*f4a2713aSLionel Sambuc 2756*f4a2713aSLionel Sambuc // Check for need to substitute AltiVec keyword tokens. 2757*f4a2713aSLionel Sambuc if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) 2758*f4a2713aSLionel Sambuc break; 2759*f4a2713aSLionel Sambuc 2760*f4a2713aSLionel Sambuc // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not 2761*f4a2713aSLionel Sambuc // allow the use of a typedef name as a type specifier. 2762*f4a2713aSLionel Sambuc if (DS.isTypeAltiVecVector()) 2763*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2764*f4a2713aSLionel Sambuc 2765*f4a2713aSLionel Sambuc ParsedType TypeRep = 2766*f4a2713aSLionel Sambuc Actions.getTypeName(*Tok.getIdentifierInfo(), 2767*f4a2713aSLionel Sambuc Tok.getLocation(), getCurScope()); 2768*f4a2713aSLionel Sambuc 2769*f4a2713aSLionel Sambuc // If this is not a typedef name, don't parse it as part of the declspec, 2770*f4a2713aSLionel Sambuc // it must be an implicit int or an error. 2771*f4a2713aSLionel Sambuc if (!TypeRep) { 2772*f4a2713aSLionel Sambuc ParsedAttributesWithRange Attrs(AttrFactory); 2773*f4a2713aSLionel Sambuc if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) { 2774*f4a2713aSLionel Sambuc if (!Attrs.empty()) { 2775*f4a2713aSLionel Sambuc AttrsLastTime = true; 2776*f4a2713aSLionel Sambuc attrs.takeAllFrom(Attrs); 2777*f4a2713aSLionel Sambuc } 2778*f4a2713aSLionel Sambuc continue; 2779*f4a2713aSLionel Sambuc } 2780*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2781*f4a2713aSLionel Sambuc } 2782*f4a2713aSLionel Sambuc 2783*f4a2713aSLionel Sambuc // If we're in a context where the identifier could be a class name, 2784*f4a2713aSLionel Sambuc // check whether this is a constructor declaration. 2785*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2786*f4a2713aSLionel Sambuc Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) && 2787*f4a2713aSLionel Sambuc isConstructorDeclarator()) 2788*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2789*f4a2713aSLionel Sambuc 2790*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2791*f4a2713aSLionel Sambuc DiagID, TypeRep); 2792*f4a2713aSLionel Sambuc if (isInvalid) 2793*f4a2713aSLionel Sambuc break; 2794*f4a2713aSLionel Sambuc 2795*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 2796*f4a2713aSLionel Sambuc ConsumeToken(); // The identifier 2797*f4a2713aSLionel Sambuc 2798*f4a2713aSLionel Sambuc // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2799*f4a2713aSLionel Sambuc // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2800*f4a2713aSLionel Sambuc // Objective-C interface. 2801*f4a2713aSLionel Sambuc if (Tok.is(tok::less) && getLangOpts().ObjC1) 2802*f4a2713aSLionel Sambuc ParseObjCProtocolQualifiers(DS); 2803*f4a2713aSLionel Sambuc 2804*f4a2713aSLionel Sambuc // Need to support trailing type qualifiers (e.g. "id<p> const"). 2805*f4a2713aSLionel Sambuc // If a type specifier follows, it will be diagnosed elsewhere. 2806*f4a2713aSLionel Sambuc continue; 2807*f4a2713aSLionel Sambuc } 2808*f4a2713aSLionel Sambuc 2809*f4a2713aSLionel Sambuc // type-name 2810*f4a2713aSLionel Sambuc case tok::annot_template_id: { 2811*f4a2713aSLionel Sambuc TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2812*f4a2713aSLionel Sambuc if (TemplateId->Kind != TNK_Type_template) { 2813*f4a2713aSLionel Sambuc // This template-id does not refer to a type name, so we're 2814*f4a2713aSLionel Sambuc // done with the type-specifiers. 2815*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2816*f4a2713aSLionel Sambuc } 2817*f4a2713aSLionel Sambuc 2818*f4a2713aSLionel Sambuc // If we're in a context where the template-id could be a 2819*f4a2713aSLionel Sambuc // constructor name or specialization, check whether this is a 2820*f4a2713aSLionel Sambuc // constructor declaration. 2821*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2822*f4a2713aSLionel Sambuc Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) && 2823*f4a2713aSLionel Sambuc isConstructorDeclarator()) 2824*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 2825*f4a2713aSLionel Sambuc 2826*f4a2713aSLionel Sambuc // Turn the template-id annotation token into a type annotation 2827*f4a2713aSLionel Sambuc // token, then try again to parse it as a type-specifier. 2828*f4a2713aSLionel Sambuc AnnotateTemplateIdTokenAsType(); 2829*f4a2713aSLionel Sambuc continue; 2830*f4a2713aSLionel Sambuc } 2831*f4a2713aSLionel Sambuc 2832*f4a2713aSLionel Sambuc // GNU attributes support. 2833*f4a2713aSLionel Sambuc case tok::kw___attribute: 2834*f4a2713aSLionel Sambuc ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs); 2835*f4a2713aSLionel Sambuc continue; 2836*f4a2713aSLionel Sambuc 2837*f4a2713aSLionel Sambuc // Microsoft declspec support. 2838*f4a2713aSLionel Sambuc case tok::kw___declspec: 2839*f4a2713aSLionel Sambuc ParseMicrosoftDeclSpec(DS.getAttributes()); 2840*f4a2713aSLionel Sambuc continue; 2841*f4a2713aSLionel Sambuc 2842*f4a2713aSLionel Sambuc // Microsoft single token adornments. 2843*f4a2713aSLionel Sambuc case tok::kw___forceinline: { 2844*f4a2713aSLionel Sambuc isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID); 2845*f4a2713aSLionel Sambuc IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 2846*f4a2713aSLionel Sambuc SourceLocation AttrNameLoc = Tok.getLocation(); 2847*f4a2713aSLionel Sambuc // FIXME: This does not work correctly if it is set to be a declspec 2848*f4a2713aSLionel Sambuc // attribute, and a GNU attribute is simply incorrect. 2849*f4a2713aSLionel Sambuc DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0, 2850*f4a2713aSLionel Sambuc AttributeList::AS_GNU); 2851*f4a2713aSLionel Sambuc break; 2852*f4a2713aSLionel Sambuc } 2853*f4a2713aSLionel Sambuc 2854*f4a2713aSLionel Sambuc case tok::kw___sptr: 2855*f4a2713aSLionel Sambuc case tok::kw___uptr: 2856*f4a2713aSLionel Sambuc case tok::kw___ptr64: 2857*f4a2713aSLionel Sambuc case tok::kw___ptr32: 2858*f4a2713aSLionel Sambuc case tok::kw___w64: 2859*f4a2713aSLionel Sambuc case tok::kw___cdecl: 2860*f4a2713aSLionel Sambuc case tok::kw___stdcall: 2861*f4a2713aSLionel Sambuc case tok::kw___fastcall: 2862*f4a2713aSLionel Sambuc case tok::kw___thiscall: 2863*f4a2713aSLionel Sambuc case tok::kw___unaligned: 2864*f4a2713aSLionel Sambuc ParseMicrosoftTypeAttributes(DS.getAttributes()); 2865*f4a2713aSLionel Sambuc continue; 2866*f4a2713aSLionel Sambuc 2867*f4a2713aSLionel Sambuc // Borland single token adornments. 2868*f4a2713aSLionel Sambuc case tok::kw___pascal: 2869*f4a2713aSLionel Sambuc ParseBorlandTypeAttributes(DS.getAttributes()); 2870*f4a2713aSLionel Sambuc continue; 2871*f4a2713aSLionel Sambuc 2872*f4a2713aSLionel Sambuc // OpenCL single token adornments. 2873*f4a2713aSLionel Sambuc case tok::kw___kernel: 2874*f4a2713aSLionel Sambuc ParseOpenCLAttributes(DS.getAttributes()); 2875*f4a2713aSLionel Sambuc continue; 2876*f4a2713aSLionel Sambuc 2877*f4a2713aSLionel Sambuc // storage-class-specifier 2878*f4a2713aSLionel Sambuc case tok::kw_typedef: 2879*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, 2880*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2881*f4a2713aSLionel Sambuc break; 2882*f4a2713aSLionel Sambuc case tok::kw_extern: 2883*f4a2713aSLionel Sambuc if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2884*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_thread_before) << "extern"; 2885*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc, 2886*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2887*f4a2713aSLionel Sambuc break; 2888*f4a2713aSLionel Sambuc case tok::kw___private_extern__: 2889*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern, 2890*f4a2713aSLionel Sambuc Loc, PrevSpec, DiagID); 2891*f4a2713aSLionel Sambuc break; 2892*f4a2713aSLionel Sambuc case tok::kw_static: 2893*f4a2713aSLionel Sambuc if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2894*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_thread_before) << "static"; 2895*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc, 2896*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2897*f4a2713aSLionel Sambuc break; 2898*f4a2713aSLionel Sambuc case tok::kw_auto: 2899*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11) { 2900*f4a2713aSLionel Sambuc if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { 2901*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2902*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2903*f4a2713aSLionel Sambuc if (!isInvalid) 2904*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_auto_storage_class) 2905*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); 2906*f4a2713aSLionel Sambuc } else 2907*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, 2908*f4a2713aSLionel Sambuc DiagID); 2909*f4a2713aSLionel Sambuc } else 2910*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2911*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2912*f4a2713aSLionel Sambuc break; 2913*f4a2713aSLionel Sambuc case tok::kw_register: 2914*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, 2915*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2916*f4a2713aSLionel Sambuc break; 2917*f4a2713aSLionel Sambuc case tok::kw_mutable: 2918*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc, 2919*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2920*f4a2713aSLionel Sambuc break; 2921*f4a2713aSLionel Sambuc case tok::kw___thread: 2922*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc, 2923*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2924*f4a2713aSLionel Sambuc break; 2925*f4a2713aSLionel Sambuc case tok::kw_thread_local: 2926*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc, 2927*f4a2713aSLionel Sambuc PrevSpec, DiagID); 2928*f4a2713aSLionel Sambuc break; 2929*f4a2713aSLionel Sambuc case tok::kw__Thread_local: 2930*f4a2713aSLionel Sambuc isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local, 2931*f4a2713aSLionel Sambuc Loc, PrevSpec, DiagID); 2932*f4a2713aSLionel Sambuc break; 2933*f4a2713aSLionel Sambuc 2934*f4a2713aSLionel Sambuc // function-specifier 2935*f4a2713aSLionel Sambuc case tok::kw_inline: 2936*f4a2713aSLionel Sambuc isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID); 2937*f4a2713aSLionel Sambuc break; 2938*f4a2713aSLionel Sambuc case tok::kw_virtual: 2939*f4a2713aSLionel Sambuc isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID); 2940*f4a2713aSLionel Sambuc break; 2941*f4a2713aSLionel Sambuc case tok::kw_explicit: 2942*f4a2713aSLionel Sambuc isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID); 2943*f4a2713aSLionel Sambuc break; 2944*f4a2713aSLionel Sambuc case tok::kw__Noreturn: 2945*f4a2713aSLionel Sambuc if (!getLangOpts().C11) 2946*f4a2713aSLionel Sambuc Diag(Loc, diag::ext_c11_noreturn); 2947*f4a2713aSLionel Sambuc isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID); 2948*f4a2713aSLionel Sambuc break; 2949*f4a2713aSLionel Sambuc 2950*f4a2713aSLionel Sambuc // alignment-specifier 2951*f4a2713aSLionel Sambuc case tok::kw__Alignas: 2952*f4a2713aSLionel Sambuc if (!getLangOpts().C11) 2953*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_c11_alignment) << Tok.getName(); 2954*f4a2713aSLionel Sambuc ParseAlignmentSpecifier(DS.getAttributes()); 2955*f4a2713aSLionel Sambuc continue; 2956*f4a2713aSLionel Sambuc 2957*f4a2713aSLionel Sambuc // friend 2958*f4a2713aSLionel Sambuc case tok::kw_friend: 2959*f4a2713aSLionel Sambuc if (DSContext == DSC_class) 2960*f4a2713aSLionel Sambuc isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); 2961*f4a2713aSLionel Sambuc else { 2962*f4a2713aSLionel Sambuc PrevSpec = ""; // not actually used by the diagnostic 2963*f4a2713aSLionel Sambuc DiagID = diag::err_friend_invalid_in_context; 2964*f4a2713aSLionel Sambuc isInvalid = true; 2965*f4a2713aSLionel Sambuc } 2966*f4a2713aSLionel Sambuc break; 2967*f4a2713aSLionel Sambuc 2968*f4a2713aSLionel Sambuc // Modules 2969*f4a2713aSLionel Sambuc case tok::kw___module_private__: 2970*f4a2713aSLionel Sambuc isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); 2971*f4a2713aSLionel Sambuc break; 2972*f4a2713aSLionel Sambuc 2973*f4a2713aSLionel Sambuc // constexpr 2974*f4a2713aSLionel Sambuc case tok::kw_constexpr: 2975*f4a2713aSLionel Sambuc isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); 2976*f4a2713aSLionel Sambuc break; 2977*f4a2713aSLionel Sambuc 2978*f4a2713aSLionel Sambuc // type-specifier 2979*f4a2713aSLionel Sambuc case tok::kw_short: 2980*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, 2981*f4a2713aSLionel Sambuc DiagID); 2982*f4a2713aSLionel Sambuc break; 2983*f4a2713aSLionel Sambuc case tok::kw_long: 2984*f4a2713aSLionel Sambuc if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) 2985*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, 2986*f4a2713aSLionel Sambuc DiagID); 2987*f4a2713aSLionel Sambuc else 2988*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2989*f4a2713aSLionel Sambuc DiagID); 2990*f4a2713aSLionel Sambuc break; 2991*f4a2713aSLionel Sambuc case tok::kw___int64: 2992*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2993*f4a2713aSLionel Sambuc DiagID); 2994*f4a2713aSLionel Sambuc break; 2995*f4a2713aSLionel Sambuc case tok::kw_signed: 2996*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, 2997*f4a2713aSLionel Sambuc DiagID); 2998*f4a2713aSLionel Sambuc break; 2999*f4a2713aSLionel Sambuc case tok::kw_unsigned: 3000*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, 3001*f4a2713aSLionel Sambuc DiagID); 3002*f4a2713aSLionel Sambuc break; 3003*f4a2713aSLionel Sambuc case tok::kw__Complex: 3004*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec, 3005*f4a2713aSLionel Sambuc DiagID); 3006*f4a2713aSLionel Sambuc break; 3007*f4a2713aSLionel Sambuc case tok::kw__Imaginary: 3008*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec, 3009*f4a2713aSLionel Sambuc DiagID); 3010*f4a2713aSLionel Sambuc break; 3011*f4a2713aSLionel Sambuc case tok::kw_void: 3012*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, 3013*f4a2713aSLionel Sambuc DiagID); 3014*f4a2713aSLionel Sambuc break; 3015*f4a2713aSLionel Sambuc case tok::kw_char: 3016*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, 3017*f4a2713aSLionel Sambuc DiagID); 3018*f4a2713aSLionel Sambuc break; 3019*f4a2713aSLionel Sambuc case tok::kw_int: 3020*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, 3021*f4a2713aSLionel Sambuc DiagID); 3022*f4a2713aSLionel Sambuc break; 3023*f4a2713aSLionel Sambuc case tok::kw___int128: 3024*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, 3025*f4a2713aSLionel Sambuc DiagID); 3026*f4a2713aSLionel Sambuc break; 3027*f4a2713aSLionel Sambuc case tok::kw_half: 3028*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, 3029*f4a2713aSLionel Sambuc DiagID); 3030*f4a2713aSLionel Sambuc break; 3031*f4a2713aSLionel Sambuc case tok::kw_float: 3032*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, 3033*f4a2713aSLionel Sambuc DiagID); 3034*f4a2713aSLionel Sambuc break; 3035*f4a2713aSLionel Sambuc case tok::kw_double: 3036*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, 3037*f4a2713aSLionel Sambuc DiagID); 3038*f4a2713aSLionel Sambuc break; 3039*f4a2713aSLionel Sambuc case tok::kw_wchar_t: 3040*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, 3041*f4a2713aSLionel Sambuc DiagID); 3042*f4a2713aSLionel Sambuc break; 3043*f4a2713aSLionel Sambuc case tok::kw_char16_t: 3044*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, 3045*f4a2713aSLionel Sambuc DiagID); 3046*f4a2713aSLionel Sambuc break; 3047*f4a2713aSLionel Sambuc case tok::kw_char32_t: 3048*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, 3049*f4a2713aSLionel Sambuc DiagID); 3050*f4a2713aSLionel Sambuc break; 3051*f4a2713aSLionel Sambuc case tok::kw_bool: 3052*f4a2713aSLionel Sambuc case tok::kw__Bool: 3053*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_bool) && 3054*f4a2713aSLionel Sambuc DS.getTypeSpecType() != DeclSpec::TST_unspecified && 3055*f4a2713aSLionel Sambuc DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 3056*f4a2713aSLionel Sambuc PrevSpec = ""; // Not used by the diagnostic. 3057*f4a2713aSLionel Sambuc DiagID = diag::err_bool_redeclaration; 3058*f4a2713aSLionel Sambuc // For better error recovery. 3059*f4a2713aSLionel Sambuc Tok.setKind(tok::identifier); 3060*f4a2713aSLionel Sambuc isInvalid = true; 3061*f4a2713aSLionel Sambuc } else { 3062*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, 3063*f4a2713aSLionel Sambuc DiagID); 3064*f4a2713aSLionel Sambuc } 3065*f4a2713aSLionel Sambuc break; 3066*f4a2713aSLionel Sambuc case tok::kw__Decimal32: 3067*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec, 3068*f4a2713aSLionel Sambuc DiagID); 3069*f4a2713aSLionel Sambuc break; 3070*f4a2713aSLionel Sambuc case tok::kw__Decimal64: 3071*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec, 3072*f4a2713aSLionel Sambuc DiagID); 3073*f4a2713aSLionel Sambuc break; 3074*f4a2713aSLionel Sambuc case tok::kw__Decimal128: 3075*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, 3076*f4a2713aSLionel Sambuc DiagID); 3077*f4a2713aSLionel Sambuc break; 3078*f4a2713aSLionel Sambuc case tok::kw___vector: 3079*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 3080*f4a2713aSLionel Sambuc break; 3081*f4a2713aSLionel Sambuc case tok::kw___pixel: 3082*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 3083*f4a2713aSLionel Sambuc break; 3084*f4a2713aSLionel Sambuc case tok::kw_image1d_t: 3085*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc, 3086*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3087*f4a2713aSLionel Sambuc break; 3088*f4a2713aSLionel Sambuc case tok::kw_image1d_array_t: 3089*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc, 3090*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3091*f4a2713aSLionel Sambuc break; 3092*f4a2713aSLionel Sambuc case tok::kw_image1d_buffer_t: 3093*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc, 3094*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3095*f4a2713aSLionel Sambuc break; 3096*f4a2713aSLionel Sambuc case tok::kw_image2d_t: 3097*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc, 3098*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3099*f4a2713aSLionel Sambuc break; 3100*f4a2713aSLionel Sambuc case tok::kw_image2d_array_t: 3101*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc, 3102*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3103*f4a2713aSLionel Sambuc break; 3104*f4a2713aSLionel Sambuc case tok::kw_image3d_t: 3105*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc, 3106*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3107*f4a2713aSLionel Sambuc break; 3108*f4a2713aSLionel Sambuc case tok::kw_sampler_t: 3109*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc, 3110*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3111*f4a2713aSLionel Sambuc break; 3112*f4a2713aSLionel Sambuc case tok::kw_event_t: 3113*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc, 3114*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3115*f4a2713aSLionel Sambuc break; 3116*f4a2713aSLionel Sambuc case tok::kw___unknown_anytype: 3117*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, 3118*f4a2713aSLionel Sambuc PrevSpec, DiagID); 3119*f4a2713aSLionel Sambuc break; 3120*f4a2713aSLionel Sambuc 3121*f4a2713aSLionel Sambuc // class-specifier: 3122*f4a2713aSLionel Sambuc case tok::kw_class: 3123*f4a2713aSLionel Sambuc case tok::kw_struct: 3124*f4a2713aSLionel Sambuc case tok::kw___interface: 3125*f4a2713aSLionel Sambuc case tok::kw_union: { 3126*f4a2713aSLionel Sambuc tok::TokenKind Kind = Tok.getKind(); 3127*f4a2713aSLionel Sambuc ConsumeToken(); 3128*f4a2713aSLionel Sambuc 3129*f4a2713aSLionel Sambuc // These are attributes following class specifiers. 3130*f4a2713aSLionel Sambuc // To produce better diagnostic, we parse them when 3131*f4a2713aSLionel Sambuc // parsing class specifier. 3132*f4a2713aSLionel Sambuc ParsedAttributesWithRange Attributes(AttrFactory); 3133*f4a2713aSLionel Sambuc ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, 3134*f4a2713aSLionel Sambuc EnteringContext, DSContext, Attributes); 3135*f4a2713aSLionel Sambuc 3136*f4a2713aSLionel Sambuc // If there are attributes following class specifier, 3137*f4a2713aSLionel Sambuc // take them over and handle them here. 3138*f4a2713aSLionel Sambuc if (!Attributes.empty()) { 3139*f4a2713aSLionel Sambuc AttrsLastTime = true; 3140*f4a2713aSLionel Sambuc attrs.takeAllFrom(Attributes); 3141*f4a2713aSLionel Sambuc } 3142*f4a2713aSLionel Sambuc continue; 3143*f4a2713aSLionel Sambuc } 3144*f4a2713aSLionel Sambuc 3145*f4a2713aSLionel Sambuc // enum-specifier: 3146*f4a2713aSLionel Sambuc case tok::kw_enum: 3147*f4a2713aSLionel Sambuc ConsumeToken(); 3148*f4a2713aSLionel Sambuc ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext); 3149*f4a2713aSLionel Sambuc continue; 3150*f4a2713aSLionel Sambuc 3151*f4a2713aSLionel Sambuc // cv-qualifier: 3152*f4a2713aSLionel Sambuc case tok::kw_const: 3153*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, 3154*f4a2713aSLionel Sambuc getLangOpts()); 3155*f4a2713aSLionel Sambuc break; 3156*f4a2713aSLionel Sambuc case tok::kw_volatile: 3157*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 3158*f4a2713aSLionel Sambuc getLangOpts()); 3159*f4a2713aSLionel Sambuc break; 3160*f4a2713aSLionel Sambuc case tok::kw_restrict: 3161*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 3162*f4a2713aSLionel Sambuc getLangOpts()); 3163*f4a2713aSLionel Sambuc break; 3164*f4a2713aSLionel Sambuc 3165*f4a2713aSLionel Sambuc // C++ typename-specifier: 3166*f4a2713aSLionel Sambuc case tok::kw_typename: 3167*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) { 3168*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 3169*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 3170*f4a2713aSLionel Sambuc } 3171*f4a2713aSLionel Sambuc if (!Tok.is(tok::kw_typename)) 3172*f4a2713aSLionel Sambuc continue; 3173*f4a2713aSLionel Sambuc break; 3174*f4a2713aSLionel Sambuc 3175*f4a2713aSLionel Sambuc // GNU typeof support. 3176*f4a2713aSLionel Sambuc case tok::kw_typeof: 3177*f4a2713aSLionel Sambuc ParseTypeofSpecifier(DS); 3178*f4a2713aSLionel Sambuc continue; 3179*f4a2713aSLionel Sambuc 3180*f4a2713aSLionel Sambuc case tok::annot_decltype: 3181*f4a2713aSLionel Sambuc ParseDecltypeSpecifier(DS); 3182*f4a2713aSLionel Sambuc continue; 3183*f4a2713aSLionel Sambuc 3184*f4a2713aSLionel Sambuc case tok::kw___underlying_type: 3185*f4a2713aSLionel Sambuc ParseUnderlyingTypeSpecifier(DS); 3186*f4a2713aSLionel Sambuc continue; 3187*f4a2713aSLionel Sambuc 3188*f4a2713aSLionel Sambuc case tok::kw__Atomic: 3189*f4a2713aSLionel Sambuc // C11 6.7.2.4/4: 3190*f4a2713aSLionel Sambuc // If the _Atomic keyword is immediately followed by a left parenthesis, 3191*f4a2713aSLionel Sambuc // it is interpreted as a type specifier (with a type name), not as a 3192*f4a2713aSLionel Sambuc // type qualifier. 3193*f4a2713aSLionel Sambuc if (NextToken().is(tok::l_paren)) { 3194*f4a2713aSLionel Sambuc ParseAtomicSpecifier(DS); 3195*f4a2713aSLionel Sambuc continue; 3196*f4a2713aSLionel Sambuc } 3197*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 3198*f4a2713aSLionel Sambuc getLangOpts()); 3199*f4a2713aSLionel Sambuc break; 3200*f4a2713aSLionel Sambuc 3201*f4a2713aSLionel Sambuc // OpenCL qualifiers: 3202*f4a2713aSLionel Sambuc case tok::kw_private: 3203*f4a2713aSLionel Sambuc if (!getLangOpts().OpenCL) 3204*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 3205*f4a2713aSLionel Sambuc case tok::kw___private: 3206*f4a2713aSLionel Sambuc case tok::kw___global: 3207*f4a2713aSLionel Sambuc case tok::kw___local: 3208*f4a2713aSLionel Sambuc case tok::kw___constant: 3209*f4a2713aSLionel Sambuc case tok::kw___read_only: 3210*f4a2713aSLionel Sambuc case tok::kw___write_only: 3211*f4a2713aSLionel Sambuc case tok::kw___read_write: 3212*f4a2713aSLionel Sambuc ParseOpenCLQualifiers(DS); 3213*f4a2713aSLionel Sambuc break; 3214*f4a2713aSLionel Sambuc 3215*f4a2713aSLionel Sambuc case tok::less: 3216*f4a2713aSLionel Sambuc // GCC ObjC supports types like "<SomeProtocol>" as a synonym for 3217*f4a2713aSLionel Sambuc // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous, 3218*f4a2713aSLionel Sambuc // but we support it. 3219*f4a2713aSLionel Sambuc if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1) 3220*f4a2713aSLionel Sambuc goto DoneWithDeclSpec; 3221*f4a2713aSLionel Sambuc 3222*f4a2713aSLionel Sambuc if (!ParseObjCProtocolQualifiers(DS)) 3223*f4a2713aSLionel Sambuc Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) 3224*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(Loc, "id") 3225*f4a2713aSLionel Sambuc << SourceRange(Loc, DS.getSourceRange().getEnd()); 3226*f4a2713aSLionel Sambuc 3227*f4a2713aSLionel Sambuc // Need to support trailing type qualifiers (e.g. "id<p> const"). 3228*f4a2713aSLionel Sambuc // If a type specifier follows, it will be diagnosed elsewhere. 3229*f4a2713aSLionel Sambuc continue; 3230*f4a2713aSLionel Sambuc } 3231*f4a2713aSLionel Sambuc // If the specifier wasn't legal, issue a diagnostic. 3232*f4a2713aSLionel Sambuc if (isInvalid) { 3233*f4a2713aSLionel Sambuc assert(PrevSpec && "Method did not return previous specifier!"); 3234*f4a2713aSLionel Sambuc assert(DiagID); 3235*f4a2713aSLionel Sambuc 3236*f4a2713aSLionel Sambuc if (DiagID == diag::ext_duplicate_declspec) 3237*f4a2713aSLionel Sambuc Diag(Tok, DiagID) 3238*f4a2713aSLionel Sambuc << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); 3239*f4a2713aSLionel Sambuc else 3240*f4a2713aSLionel Sambuc Diag(Tok, DiagID) << PrevSpec; 3241*f4a2713aSLionel Sambuc } 3242*f4a2713aSLionel Sambuc 3243*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 3244*f4a2713aSLionel Sambuc if (DiagID != diag::err_bool_redeclaration) 3245*f4a2713aSLionel Sambuc ConsumeToken(); 3246*f4a2713aSLionel Sambuc 3247*f4a2713aSLionel Sambuc AttrsLastTime = false; 3248*f4a2713aSLionel Sambuc } 3249*f4a2713aSLionel Sambuc } 3250*f4a2713aSLionel Sambuc 3251*f4a2713aSLionel Sambuc /// ParseStructDeclaration - Parse a struct declaration without the terminating 3252*f4a2713aSLionel Sambuc /// semicolon. 3253*f4a2713aSLionel Sambuc /// 3254*f4a2713aSLionel Sambuc /// struct-declaration: 3255*f4a2713aSLionel Sambuc /// specifier-qualifier-list struct-declarator-list 3256*f4a2713aSLionel Sambuc /// [GNU] __extension__ struct-declaration 3257*f4a2713aSLionel Sambuc /// [GNU] specifier-qualifier-list 3258*f4a2713aSLionel Sambuc /// struct-declarator-list: 3259*f4a2713aSLionel Sambuc /// struct-declarator 3260*f4a2713aSLionel Sambuc /// struct-declarator-list ',' struct-declarator 3261*f4a2713aSLionel Sambuc /// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator 3262*f4a2713aSLionel Sambuc /// struct-declarator: 3263*f4a2713aSLionel Sambuc /// declarator 3264*f4a2713aSLionel Sambuc /// [GNU] declarator attributes[opt] 3265*f4a2713aSLionel Sambuc /// declarator[opt] ':' constant-expression 3266*f4a2713aSLionel Sambuc /// [GNU] declarator[opt] ':' constant-expression attributes[opt] 3267*f4a2713aSLionel Sambuc /// 3268*f4a2713aSLionel Sambuc void Parser:: 3269*f4a2713aSLionel Sambuc ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) { 3270*f4a2713aSLionel Sambuc 3271*f4a2713aSLionel Sambuc if (Tok.is(tok::kw___extension__)) { 3272*f4a2713aSLionel Sambuc // __extension__ silences extension warnings in the subexpression. 3273*f4a2713aSLionel Sambuc ExtensionRAIIObject O(Diags); // Use RAII to do this. 3274*f4a2713aSLionel Sambuc ConsumeToken(); 3275*f4a2713aSLionel Sambuc return ParseStructDeclaration(DS, Fields); 3276*f4a2713aSLionel Sambuc } 3277*f4a2713aSLionel Sambuc 3278*f4a2713aSLionel Sambuc // Parse the common specifier-qualifiers-list piece. 3279*f4a2713aSLionel Sambuc ParseSpecifierQualifierList(DS); 3280*f4a2713aSLionel Sambuc 3281*f4a2713aSLionel Sambuc // If there are no declarators, this is a free-standing declaration 3282*f4a2713aSLionel Sambuc // specifier. Let the actions module cope with it. 3283*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 3284*f4a2713aSLionel Sambuc Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 3285*f4a2713aSLionel Sambuc DS); 3286*f4a2713aSLionel Sambuc DS.complete(TheDecl); 3287*f4a2713aSLionel Sambuc return; 3288*f4a2713aSLionel Sambuc } 3289*f4a2713aSLionel Sambuc 3290*f4a2713aSLionel Sambuc // Read struct-declarators until we find the semicolon. 3291*f4a2713aSLionel Sambuc bool FirstDeclarator = true; 3292*f4a2713aSLionel Sambuc SourceLocation CommaLoc; 3293*f4a2713aSLionel Sambuc while (1) { 3294*f4a2713aSLionel Sambuc ParsingFieldDeclarator DeclaratorInfo(*this, DS); 3295*f4a2713aSLionel Sambuc DeclaratorInfo.D.setCommaLoc(CommaLoc); 3296*f4a2713aSLionel Sambuc 3297*f4a2713aSLionel Sambuc // Attributes are only allowed here on successive declarators. 3298*f4a2713aSLionel Sambuc if (!FirstDeclarator) 3299*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(DeclaratorInfo.D); 3300*f4a2713aSLionel Sambuc 3301*f4a2713aSLionel Sambuc /// struct-declarator: declarator 3302*f4a2713aSLionel Sambuc /// struct-declarator: declarator[opt] ':' constant-expression 3303*f4a2713aSLionel Sambuc if (Tok.isNot(tok::colon)) { 3304*f4a2713aSLionel Sambuc // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 3305*f4a2713aSLionel Sambuc ColonProtectionRAIIObject X(*this); 3306*f4a2713aSLionel Sambuc ParseDeclarator(DeclaratorInfo.D); 3307*f4a2713aSLionel Sambuc } 3308*f4a2713aSLionel Sambuc 3309*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) { 3310*f4a2713aSLionel Sambuc ConsumeToken(); 3311*f4a2713aSLionel Sambuc ExprResult Res(ParseConstantExpression()); 3312*f4a2713aSLionel Sambuc if (Res.isInvalid()) 3313*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 3314*f4a2713aSLionel Sambuc else 3315*f4a2713aSLionel Sambuc DeclaratorInfo.BitfieldSize = Res.release(); 3316*f4a2713aSLionel Sambuc } 3317*f4a2713aSLionel Sambuc 3318*f4a2713aSLionel Sambuc // If attributes exist after the declarator, parse them. 3319*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(DeclaratorInfo.D); 3320*f4a2713aSLionel Sambuc 3321*f4a2713aSLionel Sambuc // We're done with this declarator; invoke the callback. 3322*f4a2713aSLionel Sambuc Fields.invoke(DeclaratorInfo); 3323*f4a2713aSLionel Sambuc 3324*f4a2713aSLionel Sambuc // If we don't have a comma, it is either the end of the list (a ';') 3325*f4a2713aSLionel Sambuc // or an error, bail out. 3326*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 3327*f4a2713aSLionel Sambuc return; 3328*f4a2713aSLionel Sambuc 3329*f4a2713aSLionel Sambuc // Consume the comma. 3330*f4a2713aSLionel Sambuc CommaLoc = ConsumeToken(); 3331*f4a2713aSLionel Sambuc 3332*f4a2713aSLionel Sambuc FirstDeclarator = false; 3333*f4a2713aSLionel Sambuc } 3334*f4a2713aSLionel Sambuc } 3335*f4a2713aSLionel Sambuc 3336*f4a2713aSLionel Sambuc /// ParseStructUnionBody 3337*f4a2713aSLionel Sambuc /// struct-contents: 3338*f4a2713aSLionel Sambuc /// struct-declaration-list 3339*f4a2713aSLionel Sambuc /// [EXT] empty 3340*f4a2713aSLionel Sambuc /// [GNU] "struct-declaration-list" without terminatoring ';' 3341*f4a2713aSLionel Sambuc /// struct-declaration-list: 3342*f4a2713aSLionel Sambuc /// struct-declaration 3343*f4a2713aSLionel Sambuc /// struct-declaration-list struct-declaration 3344*f4a2713aSLionel Sambuc /// [OBC] '@' 'defs' '(' class-name ')' 3345*f4a2713aSLionel Sambuc /// 3346*f4a2713aSLionel Sambuc void Parser::ParseStructUnionBody(SourceLocation RecordLoc, 3347*f4a2713aSLionel Sambuc unsigned TagType, Decl *TagDecl) { 3348*f4a2713aSLionel Sambuc PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 3349*f4a2713aSLionel Sambuc "parsing struct/union body"); 3350*f4a2713aSLionel Sambuc assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); 3351*f4a2713aSLionel Sambuc 3352*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_brace); 3353*f4a2713aSLionel Sambuc if (T.consumeOpen()) 3354*f4a2713aSLionel Sambuc return; 3355*f4a2713aSLionel Sambuc 3356*f4a2713aSLionel Sambuc ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); 3357*f4a2713aSLionel Sambuc Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 3358*f4a2713aSLionel Sambuc 3359*f4a2713aSLionel Sambuc SmallVector<Decl *, 32> FieldDecls; 3360*f4a2713aSLionel Sambuc 3361*f4a2713aSLionel Sambuc // While we still have something to read, read the declarations in the struct. 3362*f4a2713aSLionel Sambuc while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3363*f4a2713aSLionel Sambuc // Each iteration of this loop reads one struct-declaration. 3364*f4a2713aSLionel Sambuc 3365*f4a2713aSLionel Sambuc // Check for extraneous top-level semicolon. 3366*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 3367*f4a2713aSLionel Sambuc ConsumeExtraSemi(InsideStruct, TagType); 3368*f4a2713aSLionel Sambuc continue; 3369*f4a2713aSLionel Sambuc } 3370*f4a2713aSLionel Sambuc 3371*f4a2713aSLionel Sambuc // Parse _Static_assert declaration. 3372*f4a2713aSLionel Sambuc if (Tok.is(tok::kw__Static_assert)) { 3373*f4a2713aSLionel Sambuc SourceLocation DeclEnd; 3374*f4a2713aSLionel Sambuc ParseStaticAssertDeclaration(DeclEnd); 3375*f4a2713aSLionel Sambuc continue; 3376*f4a2713aSLionel Sambuc } 3377*f4a2713aSLionel Sambuc 3378*f4a2713aSLionel Sambuc if (Tok.is(tok::annot_pragma_pack)) { 3379*f4a2713aSLionel Sambuc HandlePragmaPack(); 3380*f4a2713aSLionel Sambuc continue; 3381*f4a2713aSLionel Sambuc } 3382*f4a2713aSLionel Sambuc 3383*f4a2713aSLionel Sambuc if (Tok.is(tok::annot_pragma_align)) { 3384*f4a2713aSLionel Sambuc HandlePragmaAlign(); 3385*f4a2713aSLionel Sambuc continue; 3386*f4a2713aSLionel Sambuc } 3387*f4a2713aSLionel Sambuc 3388*f4a2713aSLionel Sambuc if (!Tok.is(tok::at)) { 3389*f4a2713aSLionel Sambuc struct CFieldCallback : FieldCallback { 3390*f4a2713aSLionel Sambuc Parser &P; 3391*f4a2713aSLionel Sambuc Decl *TagDecl; 3392*f4a2713aSLionel Sambuc SmallVectorImpl<Decl *> &FieldDecls; 3393*f4a2713aSLionel Sambuc 3394*f4a2713aSLionel Sambuc CFieldCallback(Parser &P, Decl *TagDecl, 3395*f4a2713aSLionel Sambuc SmallVectorImpl<Decl *> &FieldDecls) : 3396*f4a2713aSLionel Sambuc P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} 3397*f4a2713aSLionel Sambuc 3398*f4a2713aSLionel Sambuc void invoke(ParsingFieldDeclarator &FD) { 3399*f4a2713aSLionel Sambuc // Install the declarator into the current TagDecl. 3400*f4a2713aSLionel Sambuc Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, 3401*f4a2713aSLionel Sambuc FD.D.getDeclSpec().getSourceRange().getBegin(), 3402*f4a2713aSLionel Sambuc FD.D, FD.BitfieldSize); 3403*f4a2713aSLionel Sambuc FieldDecls.push_back(Field); 3404*f4a2713aSLionel Sambuc FD.complete(Field); 3405*f4a2713aSLionel Sambuc } 3406*f4a2713aSLionel Sambuc } Callback(*this, TagDecl, FieldDecls); 3407*f4a2713aSLionel Sambuc 3408*f4a2713aSLionel Sambuc // Parse all the comma separated declarators. 3409*f4a2713aSLionel Sambuc ParsingDeclSpec DS(*this); 3410*f4a2713aSLionel Sambuc ParseStructDeclaration(DS, Callback); 3411*f4a2713aSLionel Sambuc } else { // Handle @defs 3412*f4a2713aSLionel Sambuc ConsumeToken(); 3413*f4a2713aSLionel Sambuc if (!Tok.isObjCAtKeyword(tok::objc_defs)) { 3414*f4a2713aSLionel Sambuc Diag(Tok, diag::err_unexpected_at); 3415*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 3416*f4a2713aSLionel Sambuc continue; 3417*f4a2713aSLionel Sambuc } 3418*f4a2713aSLionel Sambuc ConsumeToken(); 3419*f4a2713aSLionel Sambuc ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); 3420*f4a2713aSLionel Sambuc if (!Tok.is(tok::identifier)) { 3421*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 3422*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 3423*f4a2713aSLionel Sambuc continue; 3424*f4a2713aSLionel Sambuc } 3425*f4a2713aSLionel Sambuc SmallVector<Decl *, 16> Fields; 3426*f4a2713aSLionel Sambuc Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), 3427*f4a2713aSLionel Sambuc Tok.getIdentifierInfo(), Fields); 3428*f4a2713aSLionel Sambuc FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); 3429*f4a2713aSLionel Sambuc ConsumeToken(); 3430*f4a2713aSLionel Sambuc ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); 3431*f4a2713aSLionel Sambuc } 3432*f4a2713aSLionel Sambuc 3433*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 3434*f4a2713aSLionel Sambuc ConsumeToken(); 3435*f4a2713aSLionel Sambuc } else if (Tok.is(tok::r_brace)) { 3436*f4a2713aSLionel Sambuc ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); 3437*f4a2713aSLionel Sambuc break; 3438*f4a2713aSLionel Sambuc } else { 3439*f4a2713aSLionel Sambuc ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 3440*f4a2713aSLionel Sambuc // Skip to end of block or statement to avoid ext-warning on extra ';'. 3441*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 3442*f4a2713aSLionel Sambuc // If we stopped at a ';', eat it. 3443*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) ConsumeToken(); 3444*f4a2713aSLionel Sambuc } 3445*f4a2713aSLionel Sambuc } 3446*f4a2713aSLionel Sambuc 3447*f4a2713aSLionel Sambuc T.consumeClose(); 3448*f4a2713aSLionel Sambuc 3449*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 3450*f4a2713aSLionel Sambuc // If attributes exist after struct contents, parse them. 3451*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(attrs); 3452*f4a2713aSLionel Sambuc 3453*f4a2713aSLionel Sambuc Actions.ActOnFields(getCurScope(), 3454*f4a2713aSLionel Sambuc RecordLoc, TagDecl, FieldDecls, 3455*f4a2713aSLionel Sambuc T.getOpenLocation(), T.getCloseLocation(), 3456*f4a2713aSLionel Sambuc attrs.getList()); 3457*f4a2713aSLionel Sambuc StructScope.Exit(); 3458*f4a2713aSLionel Sambuc Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 3459*f4a2713aSLionel Sambuc T.getCloseLocation()); 3460*f4a2713aSLionel Sambuc } 3461*f4a2713aSLionel Sambuc 3462*f4a2713aSLionel Sambuc /// ParseEnumSpecifier 3463*f4a2713aSLionel Sambuc /// enum-specifier: [C99 6.7.2.2] 3464*f4a2713aSLionel Sambuc /// 'enum' identifier[opt] '{' enumerator-list '}' 3465*f4a2713aSLionel Sambuc ///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}' 3466*f4a2713aSLionel Sambuc /// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt] 3467*f4a2713aSLionel Sambuc /// '}' attributes[opt] 3468*f4a2713aSLionel Sambuc /// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt] 3469*f4a2713aSLionel Sambuc /// '}' 3470*f4a2713aSLionel Sambuc /// 'enum' identifier 3471*f4a2713aSLionel Sambuc /// [GNU] 'enum' attributes[opt] identifier 3472*f4a2713aSLionel Sambuc /// 3473*f4a2713aSLionel Sambuc /// [C++11] enum-head '{' enumerator-list[opt] '}' 3474*f4a2713aSLionel Sambuc /// [C++11] enum-head '{' enumerator-list ',' '}' 3475*f4a2713aSLionel Sambuc /// 3476*f4a2713aSLionel Sambuc /// enum-head: [C++11] 3477*f4a2713aSLionel Sambuc /// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt] 3478*f4a2713aSLionel Sambuc /// enum-key attribute-specifier-seq[opt] nested-name-specifier 3479*f4a2713aSLionel Sambuc /// identifier enum-base[opt] 3480*f4a2713aSLionel Sambuc /// 3481*f4a2713aSLionel Sambuc /// enum-key: [C++11] 3482*f4a2713aSLionel Sambuc /// 'enum' 3483*f4a2713aSLionel Sambuc /// 'enum' 'class' 3484*f4a2713aSLionel Sambuc /// 'enum' 'struct' 3485*f4a2713aSLionel Sambuc /// 3486*f4a2713aSLionel Sambuc /// enum-base: [C++11] 3487*f4a2713aSLionel Sambuc /// ':' type-specifier-seq 3488*f4a2713aSLionel Sambuc /// 3489*f4a2713aSLionel Sambuc /// [C++] elaborated-type-specifier: 3490*f4a2713aSLionel Sambuc /// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier 3491*f4a2713aSLionel Sambuc /// 3492*f4a2713aSLionel Sambuc void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, 3493*f4a2713aSLionel Sambuc const ParsedTemplateInfo &TemplateInfo, 3494*f4a2713aSLionel Sambuc AccessSpecifier AS, DeclSpecContext DSC) { 3495*f4a2713aSLionel Sambuc // Parse the tag portion of this. 3496*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 3497*f4a2713aSLionel Sambuc // Code completion for an enum name. 3498*f4a2713aSLionel Sambuc Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); 3499*f4a2713aSLionel Sambuc return cutOffParsing(); 3500*f4a2713aSLionel Sambuc } 3501*f4a2713aSLionel Sambuc 3502*f4a2713aSLionel Sambuc // If attributes exist after tag, parse them. 3503*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 3504*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(attrs); 3505*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 3506*f4a2713aSLionel Sambuc 3507*f4a2713aSLionel Sambuc // If declspecs exist after tag, parse them. 3508*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___declspec)) 3509*f4a2713aSLionel Sambuc ParseMicrosoftDeclSpec(attrs); 3510*f4a2713aSLionel Sambuc 3511*f4a2713aSLionel Sambuc SourceLocation ScopedEnumKWLoc; 3512*f4a2713aSLionel Sambuc bool IsScopedUsingClassTag = false; 3513*f4a2713aSLionel Sambuc 3514*f4a2713aSLionel Sambuc // In C++11, recognize 'enum class' and 'enum struct'. 3515*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) { 3516*f4a2713aSLionel Sambuc Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum 3517*f4a2713aSLionel Sambuc : diag::ext_scoped_enum); 3518*f4a2713aSLionel Sambuc IsScopedUsingClassTag = Tok.is(tok::kw_class); 3519*f4a2713aSLionel Sambuc ScopedEnumKWLoc = ConsumeToken(); 3520*f4a2713aSLionel Sambuc 3521*f4a2713aSLionel Sambuc // Attributes are not allowed between these keywords. Diagnose, 3522*f4a2713aSLionel Sambuc // but then just treat them like they appeared in the right place. 3523*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 3524*f4a2713aSLionel Sambuc 3525*f4a2713aSLionel Sambuc // They are allowed afterwards, though. 3526*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(attrs); 3527*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 3528*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___declspec)) 3529*f4a2713aSLionel Sambuc ParseMicrosoftDeclSpec(attrs); 3530*f4a2713aSLionel Sambuc } 3531*f4a2713aSLionel Sambuc 3532*f4a2713aSLionel Sambuc // C++11 [temp.explicit]p12: 3533*f4a2713aSLionel Sambuc // The usual access controls do not apply to names used to specify 3534*f4a2713aSLionel Sambuc // explicit instantiations. 3535*f4a2713aSLionel Sambuc // We extend this to also cover explicit specializations. Note that 3536*f4a2713aSLionel Sambuc // we don't suppress if this turns out to be an elaborated type 3537*f4a2713aSLionel Sambuc // specifier. 3538*f4a2713aSLionel Sambuc bool shouldDelayDiagsInTag = 3539*f4a2713aSLionel Sambuc (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 3540*f4a2713aSLionel Sambuc TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 3541*f4a2713aSLionel Sambuc SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 3542*f4a2713aSLionel Sambuc 3543*f4a2713aSLionel Sambuc // Enum definitions should not be parsed in a trailing-return-type. 3544*f4a2713aSLionel Sambuc bool AllowDeclaration = DSC != DSC_trailing; 3545*f4a2713aSLionel Sambuc 3546*f4a2713aSLionel Sambuc bool AllowFixedUnderlyingType = AllowDeclaration && 3547*f4a2713aSLionel Sambuc (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt || 3548*f4a2713aSLionel Sambuc getLangOpts().ObjC2); 3549*f4a2713aSLionel Sambuc 3550*f4a2713aSLionel Sambuc CXXScopeSpec &SS = DS.getTypeSpecScope(); 3551*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 3552*f4a2713aSLionel Sambuc // "enum foo : bar;" is not a potential typo for "enum foo::bar;" 3553*f4a2713aSLionel Sambuc // if a fixed underlying type is allowed. 3554*f4a2713aSLionel Sambuc ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); 3555*f4a2713aSLionel Sambuc 3556*f4a2713aSLionel Sambuc if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3557*f4a2713aSLionel Sambuc /*EnteringContext=*/true)) 3558*f4a2713aSLionel Sambuc return; 3559*f4a2713aSLionel Sambuc 3560*f4a2713aSLionel Sambuc if (SS.isSet() && Tok.isNot(tok::identifier)) { 3561*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 3562*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_brace)) { 3563*f4a2713aSLionel Sambuc // Has no name and is not a definition. 3564*f4a2713aSLionel Sambuc // Skip the rest of this declarator, up until the comma or semicolon. 3565*f4a2713aSLionel Sambuc SkipUntil(tok::comma, StopAtSemi); 3566*f4a2713aSLionel Sambuc return; 3567*f4a2713aSLionel Sambuc } 3568*f4a2713aSLionel Sambuc } 3569*f4a2713aSLionel Sambuc } 3570*f4a2713aSLionel Sambuc 3571*f4a2713aSLionel Sambuc // Must have either 'enum name' or 'enum {...}'. 3572*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && 3573*f4a2713aSLionel Sambuc !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { 3574*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident_lbrace); 3575*f4a2713aSLionel Sambuc 3576*f4a2713aSLionel Sambuc // Skip the rest of this declarator, up until the comma or semicolon. 3577*f4a2713aSLionel Sambuc SkipUntil(tok::comma, StopAtSemi); 3578*f4a2713aSLionel Sambuc return; 3579*f4a2713aSLionel Sambuc } 3580*f4a2713aSLionel Sambuc 3581*f4a2713aSLionel Sambuc // If an identifier is present, consume and remember it. 3582*f4a2713aSLionel Sambuc IdentifierInfo *Name = 0; 3583*f4a2713aSLionel Sambuc SourceLocation NameLoc; 3584*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 3585*f4a2713aSLionel Sambuc Name = Tok.getIdentifierInfo(); 3586*f4a2713aSLionel Sambuc NameLoc = ConsumeToken(); 3587*f4a2713aSLionel Sambuc } 3588*f4a2713aSLionel Sambuc 3589*f4a2713aSLionel Sambuc if (!Name && ScopedEnumKWLoc.isValid()) { 3590*f4a2713aSLionel Sambuc // C++0x 7.2p2: The optional identifier shall not be omitted in the 3591*f4a2713aSLionel Sambuc // declaration of a scoped enumeration. 3592*f4a2713aSLionel Sambuc Diag(Tok, diag::err_scoped_enum_missing_identifier); 3593*f4a2713aSLionel Sambuc ScopedEnumKWLoc = SourceLocation(); 3594*f4a2713aSLionel Sambuc IsScopedUsingClassTag = false; 3595*f4a2713aSLionel Sambuc } 3596*f4a2713aSLionel Sambuc 3597*f4a2713aSLionel Sambuc // Okay, end the suppression area. We'll decide whether to emit the 3598*f4a2713aSLionel Sambuc // diagnostics in a second. 3599*f4a2713aSLionel Sambuc if (shouldDelayDiagsInTag) 3600*f4a2713aSLionel Sambuc diagsFromTag.done(); 3601*f4a2713aSLionel Sambuc 3602*f4a2713aSLionel Sambuc TypeResult BaseType; 3603*f4a2713aSLionel Sambuc 3604*f4a2713aSLionel Sambuc // Parse the fixed underlying type. 3605*f4a2713aSLionel Sambuc bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3606*f4a2713aSLionel Sambuc if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { 3607*f4a2713aSLionel Sambuc bool PossibleBitfield = false; 3608*f4a2713aSLionel Sambuc if (CanBeBitfield) { 3609*f4a2713aSLionel Sambuc // If we're in class scope, this can either be an enum declaration with 3610*f4a2713aSLionel Sambuc // an underlying type, or a declaration of a bitfield member. We try to 3611*f4a2713aSLionel Sambuc // use a simple disambiguation scheme first to catch the common cases 3612*f4a2713aSLionel Sambuc // (integer literal, sizeof); if it's still ambiguous, we then consider 3613*f4a2713aSLionel Sambuc // anything that's a simple-type-specifier followed by '(' as an 3614*f4a2713aSLionel Sambuc // expression. This suffices because function types are not valid 3615*f4a2713aSLionel Sambuc // underlying types anyway. 3616*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, 3617*f4a2713aSLionel Sambuc Sema::ConstantEvaluated); 3618*f4a2713aSLionel Sambuc TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind()); 3619*f4a2713aSLionel Sambuc // If the next token starts an expression, we know we're parsing a 3620*f4a2713aSLionel Sambuc // bit-field. This is the common case. 3621*f4a2713aSLionel Sambuc if (TPR == TPResult::True()) 3622*f4a2713aSLionel Sambuc PossibleBitfield = true; 3623*f4a2713aSLionel Sambuc // If the next token starts a type-specifier-seq, it may be either a 3624*f4a2713aSLionel Sambuc // a fixed underlying type or the start of a function-style cast in C++; 3625*f4a2713aSLionel Sambuc // lookahead one more token to see if it's obvious that we have a 3626*f4a2713aSLionel Sambuc // fixed underlying type. 3627*f4a2713aSLionel Sambuc else if (TPR == TPResult::False() && 3628*f4a2713aSLionel Sambuc GetLookAheadToken(2).getKind() == tok::semi) { 3629*f4a2713aSLionel Sambuc // Consume the ':'. 3630*f4a2713aSLionel Sambuc ConsumeToken(); 3631*f4a2713aSLionel Sambuc } else { 3632*f4a2713aSLionel Sambuc // We have the start of a type-specifier-seq, so we have to perform 3633*f4a2713aSLionel Sambuc // tentative parsing to determine whether we have an expression or a 3634*f4a2713aSLionel Sambuc // type. 3635*f4a2713aSLionel Sambuc TentativeParsingAction TPA(*this); 3636*f4a2713aSLionel Sambuc 3637*f4a2713aSLionel Sambuc // Consume the ':'. 3638*f4a2713aSLionel Sambuc ConsumeToken(); 3639*f4a2713aSLionel Sambuc 3640*f4a2713aSLionel Sambuc // If we see a type specifier followed by an open-brace, we have an 3641*f4a2713aSLionel Sambuc // ambiguity between an underlying type and a C++11 braced 3642*f4a2713aSLionel Sambuc // function-style cast. Resolve this by always treating it as an 3643*f4a2713aSLionel Sambuc // underlying type. 3644*f4a2713aSLionel Sambuc // FIXME: The standard is not entirely clear on how to disambiguate in 3645*f4a2713aSLionel Sambuc // this case. 3646*f4a2713aSLionel Sambuc if ((getLangOpts().CPlusPlus && 3647*f4a2713aSLionel Sambuc isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) || 3648*f4a2713aSLionel Sambuc (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) { 3649*f4a2713aSLionel Sambuc // We'll parse this as a bitfield later. 3650*f4a2713aSLionel Sambuc PossibleBitfield = true; 3651*f4a2713aSLionel Sambuc TPA.Revert(); 3652*f4a2713aSLionel Sambuc } else { 3653*f4a2713aSLionel Sambuc // We have a type-specifier-seq. 3654*f4a2713aSLionel Sambuc TPA.Commit(); 3655*f4a2713aSLionel Sambuc } 3656*f4a2713aSLionel Sambuc } 3657*f4a2713aSLionel Sambuc } else { 3658*f4a2713aSLionel Sambuc // Consume the ':'. 3659*f4a2713aSLionel Sambuc ConsumeToken(); 3660*f4a2713aSLionel Sambuc } 3661*f4a2713aSLionel Sambuc 3662*f4a2713aSLionel Sambuc if (!PossibleBitfield) { 3663*f4a2713aSLionel Sambuc SourceRange Range; 3664*f4a2713aSLionel Sambuc BaseType = ParseTypeName(&Range); 3665*f4a2713aSLionel Sambuc 3666*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11) { 3667*f4a2713aSLionel Sambuc Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type); 3668*f4a2713aSLionel Sambuc } else if (!getLangOpts().ObjC2) { 3669*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) 3670*f4a2713aSLionel Sambuc Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range; 3671*f4a2713aSLionel Sambuc else 3672*f4a2713aSLionel Sambuc Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range; 3673*f4a2713aSLionel Sambuc } 3674*f4a2713aSLionel Sambuc } 3675*f4a2713aSLionel Sambuc } 3676*f4a2713aSLionel Sambuc 3677*f4a2713aSLionel Sambuc // There are four options here. If we have 'friend enum foo;' then this is a 3678*f4a2713aSLionel Sambuc // friend declaration, and cannot have an accompanying definition. If we have 3679*f4a2713aSLionel Sambuc // 'enum foo;', then this is a forward declaration. If we have 3680*f4a2713aSLionel Sambuc // 'enum foo {...' then this is a definition. Otherwise we have something 3681*f4a2713aSLionel Sambuc // like 'enum foo xyz', a reference. 3682*f4a2713aSLionel Sambuc // 3683*f4a2713aSLionel Sambuc // This is needed to handle stuff like this right (C99 6.7.2.3p11): 3684*f4a2713aSLionel Sambuc // enum foo {..}; void bar() { enum foo; } <- new foo in bar. 3685*f4a2713aSLionel Sambuc // enum foo {..}; void bar() { enum foo x; } <- use of old foo. 3686*f4a2713aSLionel Sambuc // 3687*f4a2713aSLionel Sambuc Sema::TagUseKind TUK; 3688*f4a2713aSLionel Sambuc if (!AllowDeclaration) { 3689*f4a2713aSLionel Sambuc TUK = Sema::TUK_Reference; 3690*f4a2713aSLionel Sambuc } else if (Tok.is(tok::l_brace)) { 3691*f4a2713aSLionel Sambuc if (DS.isFriendSpecified()) { 3692*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 3693*f4a2713aSLionel Sambuc << SourceRange(DS.getFriendSpecLoc()); 3694*f4a2713aSLionel Sambuc ConsumeBrace(); 3695*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi); 3696*f4a2713aSLionel Sambuc TUK = Sema::TUK_Friend; 3697*f4a2713aSLionel Sambuc } else { 3698*f4a2713aSLionel Sambuc TUK = Sema::TUK_Definition; 3699*f4a2713aSLionel Sambuc } 3700*f4a2713aSLionel Sambuc } else if (DSC != DSC_type_specifier && 3701*f4a2713aSLionel Sambuc (Tok.is(tok::semi) || 3702*f4a2713aSLionel Sambuc (Tok.isAtStartOfLine() && 3703*f4a2713aSLionel Sambuc !isValidAfterTypeSpecifier(CanBeBitfield)))) { 3704*f4a2713aSLionel Sambuc TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 3705*f4a2713aSLionel Sambuc if (Tok.isNot(tok::semi)) { 3706*f4a2713aSLionel Sambuc // A semicolon was missing after this declaration. Diagnose and recover. 3707*f4a2713aSLionel Sambuc ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 3708*f4a2713aSLionel Sambuc "enum"); 3709*f4a2713aSLionel Sambuc PP.EnterToken(Tok); 3710*f4a2713aSLionel Sambuc Tok.setKind(tok::semi); 3711*f4a2713aSLionel Sambuc } 3712*f4a2713aSLionel Sambuc } else { 3713*f4a2713aSLionel Sambuc TUK = Sema::TUK_Reference; 3714*f4a2713aSLionel Sambuc } 3715*f4a2713aSLionel Sambuc 3716*f4a2713aSLionel Sambuc // If this is an elaborated type specifier, and we delayed 3717*f4a2713aSLionel Sambuc // diagnostics before, just merge them into the current pool. 3718*f4a2713aSLionel Sambuc if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) { 3719*f4a2713aSLionel Sambuc diagsFromTag.redelay(); 3720*f4a2713aSLionel Sambuc } 3721*f4a2713aSLionel Sambuc 3722*f4a2713aSLionel Sambuc MultiTemplateParamsArg TParams; 3723*f4a2713aSLionel Sambuc if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 3724*f4a2713aSLionel Sambuc TUK != Sema::TUK_Reference) { 3725*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus11 || !SS.isSet()) { 3726*f4a2713aSLionel Sambuc // Skip the rest of this declarator, up until the comma or semicolon. 3727*f4a2713aSLionel Sambuc Diag(Tok, diag::err_enum_template); 3728*f4a2713aSLionel Sambuc SkipUntil(tok::comma, StopAtSemi); 3729*f4a2713aSLionel Sambuc return; 3730*f4a2713aSLionel Sambuc } 3731*f4a2713aSLionel Sambuc 3732*f4a2713aSLionel Sambuc if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 3733*f4a2713aSLionel Sambuc // Enumerations can't be explicitly instantiated. 3734*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 3735*f4a2713aSLionel Sambuc Diag(StartLoc, diag::err_explicit_instantiation_enum); 3736*f4a2713aSLionel Sambuc return; 3737*f4a2713aSLionel Sambuc } 3738*f4a2713aSLionel Sambuc 3739*f4a2713aSLionel Sambuc assert(TemplateInfo.TemplateParams && "no template parameters"); 3740*f4a2713aSLionel Sambuc TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(), 3741*f4a2713aSLionel Sambuc TemplateInfo.TemplateParams->size()); 3742*f4a2713aSLionel Sambuc } 3743*f4a2713aSLionel Sambuc 3744*f4a2713aSLionel Sambuc if (TUK == Sema::TUK_Reference) 3745*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 3746*f4a2713aSLionel Sambuc 3747*f4a2713aSLionel Sambuc if (!Name && TUK != Sema::TUK_Definition) { 3748*f4a2713aSLionel Sambuc Diag(Tok, diag::err_enumerator_unnamed_no_def); 3749*f4a2713aSLionel Sambuc 3750*f4a2713aSLionel Sambuc // Skip the rest of this declarator, up until the comma or semicolon. 3751*f4a2713aSLionel Sambuc SkipUntil(tok::comma, StopAtSemi); 3752*f4a2713aSLionel Sambuc return; 3753*f4a2713aSLionel Sambuc } 3754*f4a2713aSLionel Sambuc 3755*f4a2713aSLionel Sambuc bool Owned = false; 3756*f4a2713aSLionel Sambuc bool IsDependent = false; 3757*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 3758*f4a2713aSLionel Sambuc unsigned DiagID; 3759*f4a2713aSLionel Sambuc Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, 3760*f4a2713aSLionel Sambuc StartLoc, SS, Name, NameLoc, attrs.getList(), 3761*f4a2713aSLionel Sambuc AS, DS.getModulePrivateSpecLoc(), TParams, 3762*f4a2713aSLionel Sambuc Owned, IsDependent, ScopedEnumKWLoc, 3763*f4a2713aSLionel Sambuc IsScopedUsingClassTag, BaseType); 3764*f4a2713aSLionel Sambuc 3765*f4a2713aSLionel Sambuc if (IsDependent) { 3766*f4a2713aSLionel Sambuc // This enum has a dependent nested-name-specifier. Handle it as a 3767*f4a2713aSLionel Sambuc // dependent tag. 3768*f4a2713aSLionel Sambuc if (!Name) { 3769*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 3770*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_type_name_after_typename); 3771*f4a2713aSLionel Sambuc return; 3772*f4a2713aSLionel Sambuc } 3773*f4a2713aSLionel Sambuc 3774*f4a2713aSLionel Sambuc TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum, 3775*f4a2713aSLionel Sambuc TUK, SS, Name, StartLoc, 3776*f4a2713aSLionel Sambuc NameLoc); 3777*f4a2713aSLionel Sambuc if (Type.isInvalid()) { 3778*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 3779*f4a2713aSLionel Sambuc return; 3780*f4a2713aSLionel Sambuc } 3781*f4a2713aSLionel Sambuc 3782*f4a2713aSLionel Sambuc if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 3783*f4a2713aSLionel Sambuc NameLoc.isValid() ? NameLoc : StartLoc, 3784*f4a2713aSLionel Sambuc PrevSpec, DiagID, Type.get())) 3785*f4a2713aSLionel Sambuc Diag(StartLoc, DiagID) << PrevSpec; 3786*f4a2713aSLionel Sambuc 3787*f4a2713aSLionel Sambuc return; 3788*f4a2713aSLionel Sambuc } 3789*f4a2713aSLionel Sambuc 3790*f4a2713aSLionel Sambuc if (!TagDecl) { 3791*f4a2713aSLionel Sambuc // The action failed to produce an enumeration tag. If this is a 3792*f4a2713aSLionel Sambuc // definition, consume the entire definition. 3793*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 3794*f4a2713aSLionel Sambuc ConsumeBrace(); 3795*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi); 3796*f4a2713aSLionel Sambuc } 3797*f4a2713aSLionel Sambuc 3798*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 3799*f4a2713aSLionel Sambuc return; 3800*f4a2713aSLionel Sambuc } 3801*f4a2713aSLionel Sambuc 3802*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) 3803*f4a2713aSLionel Sambuc ParseEnumBody(StartLoc, TagDecl); 3804*f4a2713aSLionel Sambuc 3805*f4a2713aSLionel Sambuc if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, 3806*f4a2713aSLionel Sambuc NameLoc.isValid() ? NameLoc : StartLoc, 3807*f4a2713aSLionel Sambuc PrevSpec, DiagID, TagDecl, Owned)) 3808*f4a2713aSLionel Sambuc Diag(StartLoc, DiagID) << PrevSpec; 3809*f4a2713aSLionel Sambuc } 3810*f4a2713aSLionel Sambuc 3811*f4a2713aSLionel Sambuc /// ParseEnumBody - Parse a {} enclosed enumerator-list. 3812*f4a2713aSLionel Sambuc /// enumerator-list: 3813*f4a2713aSLionel Sambuc /// enumerator 3814*f4a2713aSLionel Sambuc /// enumerator-list ',' enumerator 3815*f4a2713aSLionel Sambuc /// enumerator: 3816*f4a2713aSLionel Sambuc /// enumeration-constant 3817*f4a2713aSLionel Sambuc /// enumeration-constant '=' constant-expression 3818*f4a2713aSLionel Sambuc /// enumeration-constant: 3819*f4a2713aSLionel Sambuc /// identifier 3820*f4a2713aSLionel Sambuc /// 3821*f4a2713aSLionel Sambuc void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { 3822*f4a2713aSLionel Sambuc // Enter the scope of the enum body and start the definition. 3823*f4a2713aSLionel Sambuc ParseScope EnumScope(this, Scope::DeclScope); 3824*f4a2713aSLionel Sambuc Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); 3825*f4a2713aSLionel Sambuc 3826*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_brace); 3827*f4a2713aSLionel Sambuc T.consumeOpen(); 3828*f4a2713aSLionel Sambuc 3829*f4a2713aSLionel Sambuc // C does not allow an empty enumerator-list, C++ does [dcl.enum]. 3830*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) 3831*f4a2713aSLionel Sambuc Diag(Tok, diag::error_empty_enum); 3832*f4a2713aSLionel Sambuc 3833*f4a2713aSLionel Sambuc SmallVector<Decl *, 32> EnumConstantDecls; 3834*f4a2713aSLionel Sambuc 3835*f4a2713aSLionel Sambuc Decl *LastEnumConstDecl = 0; 3836*f4a2713aSLionel Sambuc 3837*f4a2713aSLionel Sambuc // Parse the enumerator-list. 3838*f4a2713aSLionel Sambuc while (Tok.is(tok::identifier)) { 3839*f4a2713aSLionel Sambuc IdentifierInfo *Ident = Tok.getIdentifierInfo(); 3840*f4a2713aSLionel Sambuc SourceLocation IdentLoc = ConsumeToken(); 3841*f4a2713aSLionel Sambuc 3842*f4a2713aSLionel Sambuc // If attributes exist after the enumerator, parse them. 3843*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 3844*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(attrs); 3845*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 3846*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 3847*f4a2713aSLionel Sambuc 3848*f4a2713aSLionel Sambuc SourceLocation EqualLoc; 3849*f4a2713aSLionel Sambuc ExprResult AssignedVal; 3850*f4a2713aSLionel Sambuc ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); 3851*f4a2713aSLionel Sambuc 3852*f4a2713aSLionel Sambuc if (Tok.is(tok::equal)) { 3853*f4a2713aSLionel Sambuc EqualLoc = ConsumeToken(); 3854*f4a2713aSLionel Sambuc AssignedVal = ParseConstantExpression(); 3855*f4a2713aSLionel Sambuc if (AssignedVal.isInvalid()) 3856*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch); 3857*f4a2713aSLionel Sambuc } 3858*f4a2713aSLionel Sambuc 3859*f4a2713aSLionel Sambuc // Install the enumerator constant into EnumDecl. 3860*f4a2713aSLionel Sambuc Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, 3861*f4a2713aSLionel Sambuc LastEnumConstDecl, 3862*f4a2713aSLionel Sambuc IdentLoc, Ident, 3863*f4a2713aSLionel Sambuc attrs.getList(), EqualLoc, 3864*f4a2713aSLionel Sambuc AssignedVal.release()); 3865*f4a2713aSLionel Sambuc PD.complete(EnumConstDecl); 3866*f4a2713aSLionel Sambuc 3867*f4a2713aSLionel Sambuc EnumConstantDecls.push_back(EnumConstDecl); 3868*f4a2713aSLionel Sambuc LastEnumConstDecl = EnumConstDecl; 3869*f4a2713aSLionel Sambuc 3870*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 3871*f4a2713aSLionel Sambuc // We're missing a comma between enumerators. 3872*f4a2713aSLionel Sambuc SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 3873*f4a2713aSLionel Sambuc Diag(Loc, diag::err_enumerator_list_missing_comma) 3874*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(Loc, ", "); 3875*f4a2713aSLionel Sambuc continue; 3876*f4a2713aSLionel Sambuc } 3877*f4a2713aSLionel Sambuc 3878*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 3879*f4a2713aSLionel Sambuc break; 3880*f4a2713aSLionel Sambuc SourceLocation CommaLoc = ConsumeToken(); 3881*f4a2713aSLionel Sambuc 3882*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 3883*f4a2713aSLionel Sambuc if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) 3884*f4a2713aSLionel Sambuc Diag(CommaLoc, getLangOpts().CPlusPlus ? 3885*f4a2713aSLionel Sambuc diag::ext_enumerator_list_comma_cxx : 3886*f4a2713aSLionel Sambuc diag::ext_enumerator_list_comma_c) 3887*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(CommaLoc); 3888*f4a2713aSLionel Sambuc else if (getLangOpts().CPlusPlus11) 3889*f4a2713aSLionel Sambuc Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma) 3890*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(CommaLoc); 3891*f4a2713aSLionel Sambuc } 3892*f4a2713aSLionel Sambuc } 3893*f4a2713aSLionel Sambuc 3894*f4a2713aSLionel Sambuc // Eat the }. 3895*f4a2713aSLionel Sambuc T.consumeClose(); 3896*f4a2713aSLionel Sambuc 3897*f4a2713aSLionel Sambuc // If attributes exist after the identifier list, parse them. 3898*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 3899*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(attrs); 3900*f4a2713aSLionel Sambuc 3901*f4a2713aSLionel Sambuc Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), 3902*f4a2713aSLionel Sambuc EnumDecl, EnumConstantDecls, 3903*f4a2713aSLionel Sambuc getCurScope(), 3904*f4a2713aSLionel Sambuc attrs.getList()); 3905*f4a2713aSLionel Sambuc 3906*f4a2713aSLionel Sambuc EnumScope.Exit(); 3907*f4a2713aSLionel Sambuc Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, 3908*f4a2713aSLionel Sambuc T.getCloseLocation()); 3909*f4a2713aSLionel Sambuc 3910*f4a2713aSLionel Sambuc // The next token must be valid after an enum definition. If not, a ';' 3911*f4a2713aSLionel Sambuc // was probably forgotten. 3912*f4a2713aSLionel Sambuc bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3913*f4a2713aSLionel Sambuc if (!isValidAfterTypeSpecifier(CanBeBitfield)) { 3914*f4a2713aSLionel Sambuc ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum"); 3915*f4a2713aSLionel Sambuc // Push this token back into the preprocessor and change our current token 3916*f4a2713aSLionel Sambuc // to ';' so that the rest of the code recovers as though there were an 3917*f4a2713aSLionel Sambuc // ';' after the definition. 3918*f4a2713aSLionel Sambuc PP.EnterToken(Tok); 3919*f4a2713aSLionel Sambuc Tok.setKind(tok::semi); 3920*f4a2713aSLionel Sambuc } 3921*f4a2713aSLionel Sambuc } 3922*f4a2713aSLionel Sambuc 3923*f4a2713aSLionel Sambuc /// isTypeSpecifierQualifier - Return true if the current token could be the 3924*f4a2713aSLionel Sambuc /// start of a type-qualifier-list. 3925*f4a2713aSLionel Sambuc bool Parser::isTypeQualifier() const { 3926*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 3927*f4a2713aSLionel Sambuc default: return false; 3928*f4a2713aSLionel Sambuc 3929*f4a2713aSLionel Sambuc // type-qualifier only in OpenCL 3930*f4a2713aSLionel Sambuc case tok::kw_private: 3931*f4a2713aSLionel Sambuc return getLangOpts().OpenCL; 3932*f4a2713aSLionel Sambuc 3933*f4a2713aSLionel Sambuc // type-qualifier 3934*f4a2713aSLionel Sambuc case tok::kw_const: 3935*f4a2713aSLionel Sambuc case tok::kw_volatile: 3936*f4a2713aSLionel Sambuc case tok::kw_restrict: 3937*f4a2713aSLionel Sambuc case tok::kw___private: 3938*f4a2713aSLionel Sambuc case tok::kw___local: 3939*f4a2713aSLionel Sambuc case tok::kw___global: 3940*f4a2713aSLionel Sambuc case tok::kw___constant: 3941*f4a2713aSLionel Sambuc case tok::kw___read_only: 3942*f4a2713aSLionel Sambuc case tok::kw___read_write: 3943*f4a2713aSLionel Sambuc case tok::kw___write_only: 3944*f4a2713aSLionel Sambuc return true; 3945*f4a2713aSLionel Sambuc } 3946*f4a2713aSLionel Sambuc } 3947*f4a2713aSLionel Sambuc 3948*f4a2713aSLionel Sambuc /// isKnownToBeTypeSpecifier - Return true if we know that the specified token 3949*f4a2713aSLionel Sambuc /// is definitely a type-specifier. Return false if it isn't part of a type 3950*f4a2713aSLionel Sambuc /// specifier or if we're not sure. 3951*f4a2713aSLionel Sambuc bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { 3952*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 3953*f4a2713aSLionel Sambuc default: return false; 3954*f4a2713aSLionel Sambuc // type-specifiers 3955*f4a2713aSLionel Sambuc case tok::kw_short: 3956*f4a2713aSLionel Sambuc case tok::kw_long: 3957*f4a2713aSLionel Sambuc case tok::kw___int64: 3958*f4a2713aSLionel Sambuc case tok::kw___int128: 3959*f4a2713aSLionel Sambuc case tok::kw_signed: 3960*f4a2713aSLionel Sambuc case tok::kw_unsigned: 3961*f4a2713aSLionel Sambuc case tok::kw__Complex: 3962*f4a2713aSLionel Sambuc case tok::kw__Imaginary: 3963*f4a2713aSLionel Sambuc case tok::kw_void: 3964*f4a2713aSLionel Sambuc case tok::kw_char: 3965*f4a2713aSLionel Sambuc case tok::kw_wchar_t: 3966*f4a2713aSLionel Sambuc case tok::kw_char16_t: 3967*f4a2713aSLionel Sambuc case tok::kw_char32_t: 3968*f4a2713aSLionel Sambuc case tok::kw_int: 3969*f4a2713aSLionel Sambuc case tok::kw_half: 3970*f4a2713aSLionel Sambuc case tok::kw_float: 3971*f4a2713aSLionel Sambuc case tok::kw_double: 3972*f4a2713aSLionel Sambuc case tok::kw_bool: 3973*f4a2713aSLionel Sambuc case tok::kw__Bool: 3974*f4a2713aSLionel Sambuc case tok::kw__Decimal32: 3975*f4a2713aSLionel Sambuc case tok::kw__Decimal64: 3976*f4a2713aSLionel Sambuc case tok::kw__Decimal128: 3977*f4a2713aSLionel Sambuc case tok::kw___vector: 3978*f4a2713aSLionel Sambuc 3979*f4a2713aSLionel Sambuc // OpenCL specific types: 3980*f4a2713aSLionel Sambuc case tok::kw_image1d_t: 3981*f4a2713aSLionel Sambuc case tok::kw_image1d_array_t: 3982*f4a2713aSLionel Sambuc case tok::kw_image1d_buffer_t: 3983*f4a2713aSLionel Sambuc case tok::kw_image2d_t: 3984*f4a2713aSLionel Sambuc case tok::kw_image2d_array_t: 3985*f4a2713aSLionel Sambuc case tok::kw_image3d_t: 3986*f4a2713aSLionel Sambuc case tok::kw_sampler_t: 3987*f4a2713aSLionel Sambuc case tok::kw_event_t: 3988*f4a2713aSLionel Sambuc 3989*f4a2713aSLionel Sambuc // struct-or-union-specifier (C99) or class-specifier (C++) 3990*f4a2713aSLionel Sambuc case tok::kw_class: 3991*f4a2713aSLionel Sambuc case tok::kw_struct: 3992*f4a2713aSLionel Sambuc case tok::kw___interface: 3993*f4a2713aSLionel Sambuc case tok::kw_union: 3994*f4a2713aSLionel Sambuc // enum-specifier 3995*f4a2713aSLionel Sambuc case tok::kw_enum: 3996*f4a2713aSLionel Sambuc 3997*f4a2713aSLionel Sambuc // typedef-name 3998*f4a2713aSLionel Sambuc case tok::annot_typename: 3999*f4a2713aSLionel Sambuc return true; 4000*f4a2713aSLionel Sambuc } 4001*f4a2713aSLionel Sambuc } 4002*f4a2713aSLionel Sambuc 4003*f4a2713aSLionel Sambuc /// isTypeSpecifierQualifier - Return true if the current token could be the 4004*f4a2713aSLionel Sambuc /// start of a specifier-qualifier-list. 4005*f4a2713aSLionel Sambuc bool Parser::isTypeSpecifierQualifier() { 4006*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 4007*f4a2713aSLionel Sambuc default: return false; 4008*f4a2713aSLionel Sambuc 4009*f4a2713aSLionel Sambuc case tok::identifier: // foo::bar 4010*f4a2713aSLionel Sambuc if (TryAltiVecVectorToken()) 4011*f4a2713aSLionel Sambuc return true; 4012*f4a2713aSLionel Sambuc // Fall through. 4013*f4a2713aSLionel Sambuc case tok::kw_typename: // typename T::type 4014*f4a2713aSLionel Sambuc // Annotate typenames and C++ scope specifiers. If we get one, just 4015*f4a2713aSLionel Sambuc // recurse to handle whatever we get. 4016*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 4017*f4a2713aSLionel Sambuc return true; 4018*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) 4019*f4a2713aSLionel Sambuc return false; 4020*f4a2713aSLionel Sambuc return isTypeSpecifierQualifier(); 4021*f4a2713aSLionel Sambuc 4022*f4a2713aSLionel Sambuc case tok::coloncolon: // ::foo::bar 4023*f4a2713aSLionel Sambuc if (NextToken().is(tok::kw_new) || // ::new 4024*f4a2713aSLionel Sambuc NextToken().is(tok::kw_delete)) // ::delete 4025*f4a2713aSLionel Sambuc return false; 4026*f4a2713aSLionel Sambuc 4027*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 4028*f4a2713aSLionel Sambuc return true; 4029*f4a2713aSLionel Sambuc return isTypeSpecifierQualifier(); 4030*f4a2713aSLionel Sambuc 4031*f4a2713aSLionel Sambuc // GNU attributes support. 4032*f4a2713aSLionel Sambuc case tok::kw___attribute: 4033*f4a2713aSLionel Sambuc // GNU typeof support. 4034*f4a2713aSLionel Sambuc case tok::kw_typeof: 4035*f4a2713aSLionel Sambuc 4036*f4a2713aSLionel Sambuc // type-specifiers 4037*f4a2713aSLionel Sambuc case tok::kw_short: 4038*f4a2713aSLionel Sambuc case tok::kw_long: 4039*f4a2713aSLionel Sambuc case tok::kw___int64: 4040*f4a2713aSLionel Sambuc case tok::kw___int128: 4041*f4a2713aSLionel Sambuc case tok::kw_signed: 4042*f4a2713aSLionel Sambuc case tok::kw_unsigned: 4043*f4a2713aSLionel Sambuc case tok::kw__Complex: 4044*f4a2713aSLionel Sambuc case tok::kw__Imaginary: 4045*f4a2713aSLionel Sambuc case tok::kw_void: 4046*f4a2713aSLionel Sambuc case tok::kw_char: 4047*f4a2713aSLionel Sambuc case tok::kw_wchar_t: 4048*f4a2713aSLionel Sambuc case tok::kw_char16_t: 4049*f4a2713aSLionel Sambuc case tok::kw_char32_t: 4050*f4a2713aSLionel Sambuc case tok::kw_int: 4051*f4a2713aSLionel Sambuc case tok::kw_half: 4052*f4a2713aSLionel Sambuc case tok::kw_float: 4053*f4a2713aSLionel Sambuc case tok::kw_double: 4054*f4a2713aSLionel Sambuc case tok::kw_bool: 4055*f4a2713aSLionel Sambuc case tok::kw__Bool: 4056*f4a2713aSLionel Sambuc case tok::kw__Decimal32: 4057*f4a2713aSLionel Sambuc case tok::kw__Decimal64: 4058*f4a2713aSLionel Sambuc case tok::kw__Decimal128: 4059*f4a2713aSLionel Sambuc case tok::kw___vector: 4060*f4a2713aSLionel Sambuc 4061*f4a2713aSLionel Sambuc // OpenCL specific types: 4062*f4a2713aSLionel Sambuc case tok::kw_image1d_t: 4063*f4a2713aSLionel Sambuc case tok::kw_image1d_array_t: 4064*f4a2713aSLionel Sambuc case tok::kw_image1d_buffer_t: 4065*f4a2713aSLionel Sambuc case tok::kw_image2d_t: 4066*f4a2713aSLionel Sambuc case tok::kw_image2d_array_t: 4067*f4a2713aSLionel Sambuc case tok::kw_image3d_t: 4068*f4a2713aSLionel Sambuc case tok::kw_sampler_t: 4069*f4a2713aSLionel Sambuc case tok::kw_event_t: 4070*f4a2713aSLionel Sambuc 4071*f4a2713aSLionel Sambuc // struct-or-union-specifier (C99) or class-specifier (C++) 4072*f4a2713aSLionel Sambuc case tok::kw_class: 4073*f4a2713aSLionel Sambuc case tok::kw_struct: 4074*f4a2713aSLionel Sambuc case tok::kw___interface: 4075*f4a2713aSLionel Sambuc case tok::kw_union: 4076*f4a2713aSLionel Sambuc // enum-specifier 4077*f4a2713aSLionel Sambuc case tok::kw_enum: 4078*f4a2713aSLionel Sambuc 4079*f4a2713aSLionel Sambuc // type-qualifier 4080*f4a2713aSLionel Sambuc case tok::kw_const: 4081*f4a2713aSLionel Sambuc case tok::kw_volatile: 4082*f4a2713aSLionel Sambuc case tok::kw_restrict: 4083*f4a2713aSLionel Sambuc 4084*f4a2713aSLionel Sambuc // Debugger support. 4085*f4a2713aSLionel Sambuc case tok::kw___unknown_anytype: 4086*f4a2713aSLionel Sambuc 4087*f4a2713aSLionel Sambuc // typedef-name 4088*f4a2713aSLionel Sambuc case tok::annot_typename: 4089*f4a2713aSLionel Sambuc return true; 4090*f4a2713aSLionel Sambuc 4091*f4a2713aSLionel Sambuc // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 4092*f4a2713aSLionel Sambuc case tok::less: 4093*f4a2713aSLionel Sambuc return getLangOpts().ObjC1; 4094*f4a2713aSLionel Sambuc 4095*f4a2713aSLionel Sambuc case tok::kw___cdecl: 4096*f4a2713aSLionel Sambuc case tok::kw___stdcall: 4097*f4a2713aSLionel Sambuc case tok::kw___fastcall: 4098*f4a2713aSLionel Sambuc case tok::kw___thiscall: 4099*f4a2713aSLionel Sambuc case tok::kw___w64: 4100*f4a2713aSLionel Sambuc case tok::kw___ptr64: 4101*f4a2713aSLionel Sambuc case tok::kw___ptr32: 4102*f4a2713aSLionel Sambuc case tok::kw___pascal: 4103*f4a2713aSLionel Sambuc case tok::kw___unaligned: 4104*f4a2713aSLionel Sambuc 4105*f4a2713aSLionel Sambuc case tok::kw___private: 4106*f4a2713aSLionel Sambuc case tok::kw___local: 4107*f4a2713aSLionel Sambuc case tok::kw___global: 4108*f4a2713aSLionel Sambuc case tok::kw___constant: 4109*f4a2713aSLionel Sambuc case tok::kw___read_only: 4110*f4a2713aSLionel Sambuc case tok::kw___read_write: 4111*f4a2713aSLionel Sambuc case tok::kw___write_only: 4112*f4a2713aSLionel Sambuc 4113*f4a2713aSLionel Sambuc return true; 4114*f4a2713aSLionel Sambuc 4115*f4a2713aSLionel Sambuc case tok::kw_private: 4116*f4a2713aSLionel Sambuc return getLangOpts().OpenCL; 4117*f4a2713aSLionel Sambuc 4118*f4a2713aSLionel Sambuc // C11 _Atomic 4119*f4a2713aSLionel Sambuc case tok::kw__Atomic: 4120*f4a2713aSLionel Sambuc return true; 4121*f4a2713aSLionel Sambuc } 4122*f4a2713aSLionel Sambuc } 4123*f4a2713aSLionel Sambuc 4124*f4a2713aSLionel Sambuc /// isDeclarationSpecifier() - Return true if the current token is part of a 4125*f4a2713aSLionel Sambuc /// declaration specifier. 4126*f4a2713aSLionel Sambuc /// 4127*f4a2713aSLionel Sambuc /// \param DisambiguatingWithExpression True to indicate that the purpose of 4128*f4a2713aSLionel Sambuc /// this check is to disambiguate between an expression and a declaration. 4129*f4a2713aSLionel Sambuc bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { 4130*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 4131*f4a2713aSLionel Sambuc default: return false; 4132*f4a2713aSLionel Sambuc 4133*f4a2713aSLionel Sambuc case tok::kw_private: 4134*f4a2713aSLionel Sambuc return getLangOpts().OpenCL; 4135*f4a2713aSLionel Sambuc 4136*f4a2713aSLionel Sambuc case tok::identifier: // foo::bar 4137*f4a2713aSLionel Sambuc // Unfortunate hack to support "Class.factoryMethod" notation. 4138*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && NextToken().is(tok::period)) 4139*f4a2713aSLionel Sambuc return false; 4140*f4a2713aSLionel Sambuc if (TryAltiVecVectorToken()) 4141*f4a2713aSLionel Sambuc return true; 4142*f4a2713aSLionel Sambuc // Fall through. 4143*f4a2713aSLionel Sambuc case tok::kw_decltype: // decltype(T())::type 4144*f4a2713aSLionel Sambuc case tok::kw_typename: // typename T::type 4145*f4a2713aSLionel Sambuc // Annotate typenames and C++ scope specifiers. If we get one, just 4146*f4a2713aSLionel Sambuc // recurse to handle whatever we get. 4147*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 4148*f4a2713aSLionel Sambuc return true; 4149*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) 4150*f4a2713aSLionel Sambuc return false; 4151*f4a2713aSLionel Sambuc 4152*f4a2713aSLionel Sambuc // If we're in Objective-C and we have an Objective-C class type followed 4153*f4a2713aSLionel Sambuc // by an identifier and then either ':' or ']', in a place where an 4154*f4a2713aSLionel Sambuc // expression is permitted, then this is probably a class message send 4155*f4a2713aSLionel Sambuc // missing the initial '['. In this case, we won't consider this to be 4156*f4a2713aSLionel Sambuc // the start of a declaration. 4157*f4a2713aSLionel Sambuc if (DisambiguatingWithExpression && 4158*f4a2713aSLionel Sambuc isStartOfObjCClassMessageMissingOpenBracket()) 4159*f4a2713aSLionel Sambuc return false; 4160*f4a2713aSLionel Sambuc 4161*f4a2713aSLionel Sambuc return isDeclarationSpecifier(); 4162*f4a2713aSLionel Sambuc 4163*f4a2713aSLionel Sambuc case tok::coloncolon: // ::foo::bar 4164*f4a2713aSLionel Sambuc if (NextToken().is(tok::kw_new) || // ::new 4165*f4a2713aSLionel Sambuc NextToken().is(tok::kw_delete)) // ::delete 4166*f4a2713aSLionel Sambuc return false; 4167*f4a2713aSLionel Sambuc 4168*f4a2713aSLionel Sambuc // Annotate typenames and C++ scope specifiers. If we get one, just 4169*f4a2713aSLionel Sambuc // recurse to handle whatever we get. 4170*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 4171*f4a2713aSLionel Sambuc return true; 4172*f4a2713aSLionel Sambuc return isDeclarationSpecifier(); 4173*f4a2713aSLionel Sambuc 4174*f4a2713aSLionel Sambuc // storage-class-specifier 4175*f4a2713aSLionel Sambuc case tok::kw_typedef: 4176*f4a2713aSLionel Sambuc case tok::kw_extern: 4177*f4a2713aSLionel Sambuc case tok::kw___private_extern__: 4178*f4a2713aSLionel Sambuc case tok::kw_static: 4179*f4a2713aSLionel Sambuc case tok::kw_auto: 4180*f4a2713aSLionel Sambuc case tok::kw_register: 4181*f4a2713aSLionel Sambuc case tok::kw___thread: 4182*f4a2713aSLionel Sambuc case tok::kw_thread_local: 4183*f4a2713aSLionel Sambuc case tok::kw__Thread_local: 4184*f4a2713aSLionel Sambuc 4185*f4a2713aSLionel Sambuc // Modules 4186*f4a2713aSLionel Sambuc case tok::kw___module_private__: 4187*f4a2713aSLionel Sambuc 4188*f4a2713aSLionel Sambuc // Debugger support 4189*f4a2713aSLionel Sambuc case tok::kw___unknown_anytype: 4190*f4a2713aSLionel Sambuc 4191*f4a2713aSLionel Sambuc // type-specifiers 4192*f4a2713aSLionel Sambuc case tok::kw_short: 4193*f4a2713aSLionel Sambuc case tok::kw_long: 4194*f4a2713aSLionel Sambuc case tok::kw___int64: 4195*f4a2713aSLionel Sambuc case tok::kw___int128: 4196*f4a2713aSLionel Sambuc case tok::kw_signed: 4197*f4a2713aSLionel Sambuc case tok::kw_unsigned: 4198*f4a2713aSLionel Sambuc case tok::kw__Complex: 4199*f4a2713aSLionel Sambuc case tok::kw__Imaginary: 4200*f4a2713aSLionel Sambuc case tok::kw_void: 4201*f4a2713aSLionel Sambuc case tok::kw_char: 4202*f4a2713aSLionel Sambuc case tok::kw_wchar_t: 4203*f4a2713aSLionel Sambuc case tok::kw_char16_t: 4204*f4a2713aSLionel Sambuc case tok::kw_char32_t: 4205*f4a2713aSLionel Sambuc 4206*f4a2713aSLionel Sambuc case tok::kw_int: 4207*f4a2713aSLionel Sambuc case tok::kw_half: 4208*f4a2713aSLionel Sambuc case tok::kw_float: 4209*f4a2713aSLionel Sambuc case tok::kw_double: 4210*f4a2713aSLionel Sambuc case tok::kw_bool: 4211*f4a2713aSLionel Sambuc case tok::kw__Bool: 4212*f4a2713aSLionel Sambuc case tok::kw__Decimal32: 4213*f4a2713aSLionel Sambuc case tok::kw__Decimal64: 4214*f4a2713aSLionel Sambuc case tok::kw__Decimal128: 4215*f4a2713aSLionel Sambuc case tok::kw___vector: 4216*f4a2713aSLionel Sambuc 4217*f4a2713aSLionel Sambuc // OpenCL specific types: 4218*f4a2713aSLionel Sambuc case tok::kw_image1d_t: 4219*f4a2713aSLionel Sambuc case tok::kw_image1d_array_t: 4220*f4a2713aSLionel Sambuc case tok::kw_image1d_buffer_t: 4221*f4a2713aSLionel Sambuc case tok::kw_image2d_t: 4222*f4a2713aSLionel Sambuc case tok::kw_image2d_array_t: 4223*f4a2713aSLionel Sambuc case tok::kw_image3d_t: 4224*f4a2713aSLionel Sambuc case tok::kw_sampler_t: 4225*f4a2713aSLionel Sambuc case tok::kw_event_t: 4226*f4a2713aSLionel Sambuc 4227*f4a2713aSLionel Sambuc // struct-or-union-specifier (C99) or class-specifier (C++) 4228*f4a2713aSLionel Sambuc case tok::kw_class: 4229*f4a2713aSLionel Sambuc case tok::kw_struct: 4230*f4a2713aSLionel Sambuc case tok::kw_union: 4231*f4a2713aSLionel Sambuc case tok::kw___interface: 4232*f4a2713aSLionel Sambuc // enum-specifier 4233*f4a2713aSLionel Sambuc case tok::kw_enum: 4234*f4a2713aSLionel Sambuc 4235*f4a2713aSLionel Sambuc // type-qualifier 4236*f4a2713aSLionel Sambuc case tok::kw_const: 4237*f4a2713aSLionel Sambuc case tok::kw_volatile: 4238*f4a2713aSLionel Sambuc case tok::kw_restrict: 4239*f4a2713aSLionel Sambuc 4240*f4a2713aSLionel Sambuc // function-specifier 4241*f4a2713aSLionel Sambuc case tok::kw_inline: 4242*f4a2713aSLionel Sambuc case tok::kw_virtual: 4243*f4a2713aSLionel Sambuc case tok::kw_explicit: 4244*f4a2713aSLionel Sambuc case tok::kw__Noreturn: 4245*f4a2713aSLionel Sambuc 4246*f4a2713aSLionel Sambuc // alignment-specifier 4247*f4a2713aSLionel Sambuc case tok::kw__Alignas: 4248*f4a2713aSLionel Sambuc 4249*f4a2713aSLionel Sambuc // friend keyword. 4250*f4a2713aSLionel Sambuc case tok::kw_friend: 4251*f4a2713aSLionel Sambuc 4252*f4a2713aSLionel Sambuc // static_assert-declaration 4253*f4a2713aSLionel Sambuc case tok::kw__Static_assert: 4254*f4a2713aSLionel Sambuc 4255*f4a2713aSLionel Sambuc // GNU typeof support. 4256*f4a2713aSLionel Sambuc case tok::kw_typeof: 4257*f4a2713aSLionel Sambuc 4258*f4a2713aSLionel Sambuc // GNU attributes. 4259*f4a2713aSLionel Sambuc case tok::kw___attribute: 4260*f4a2713aSLionel Sambuc 4261*f4a2713aSLionel Sambuc // C++11 decltype and constexpr. 4262*f4a2713aSLionel Sambuc case tok::annot_decltype: 4263*f4a2713aSLionel Sambuc case tok::kw_constexpr: 4264*f4a2713aSLionel Sambuc 4265*f4a2713aSLionel Sambuc // C11 _Atomic 4266*f4a2713aSLionel Sambuc case tok::kw__Atomic: 4267*f4a2713aSLionel Sambuc return true; 4268*f4a2713aSLionel Sambuc 4269*f4a2713aSLionel Sambuc // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 4270*f4a2713aSLionel Sambuc case tok::less: 4271*f4a2713aSLionel Sambuc return getLangOpts().ObjC1; 4272*f4a2713aSLionel Sambuc 4273*f4a2713aSLionel Sambuc // typedef-name 4274*f4a2713aSLionel Sambuc case tok::annot_typename: 4275*f4a2713aSLionel Sambuc return !DisambiguatingWithExpression || 4276*f4a2713aSLionel Sambuc !isStartOfObjCClassMessageMissingOpenBracket(); 4277*f4a2713aSLionel Sambuc 4278*f4a2713aSLionel Sambuc case tok::kw___declspec: 4279*f4a2713aSLionel Sambuc case tok::kw___cdecl: 4280*f4a2713aSLionel Sambuc case tok::kw___stdcall: 4281*f4a2713aSLionel Sambuc case tok::kw___fastcall: 4282*f4a2713aSLionel Sambuc case tok::kw___thiscall: 4283*f4a2713aSLionel Sambuc case tok::kw___w64: 4284*f4a2713aSLionel Sambuc case tok::kw___sptr: 4285*f4a2713aSLionel Sambuc case tok::kw___uptr: 4286*f4a2713aSLionel Sambuc case tok::kw___ptr64: 4287*f4a2713aSLionel Sambuc case tok::kw___ptr32: 4288*f4a2713aSLionel Sambuc case tok::kw___forceinline: 4289*f4a2713aSLionel Sambuc case tok::kw___pascal: 4290*f4a2713aSLionel Sambuc case tok::kw___unaligned: 4291*f4a2713aSLionel Sambuc 4292*f4a2713aSLionel Sambuc case tok::kw___private: 4293*f4a2713aSLionel Sambuc case tok::kw___local: 4294*f4a2713aSLionel Sambuc case tok::kw___global: 4295*f4a2713aSLionel Sambuc case tok::kw___constant: 4296*f4a2713aSLionel Sambuc case tok::kw___read_only: 4297*f4a2713aSLionel Sambuc case tok::kw___read_write: 4298*f4a2713aSLionel Sambuc case tok::kw___write_only: 4299*f4a2713aSLionel Sambuc 4300*f4a2713aSLionel Sambuc return true; 4301*f4a2713aSLionel Sambuc } 4302*f4a2713aSLionel Sambuc } 4303*f4a2713aSLionel Sambuc 4304*f4a2713aSLionel Sambuc bool Parser::isConstructorDeclarator() { 4305*f4a2713aSLionel Sambuc TentativeParsingAction TPA(*this); 4306*f4a2713aSLionel Sambuc 4307*f4a2713aSLionel Sambuc // Parse the C++ scope specifier. 4308*f4a2713aSLionel Sambuc CXXScopeSpec SS; 4309*f4a2713aSLionel Sambuc if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 4310*f4a2713aSLionel Sambuc /*EnteringContext=*/true)) { 4311*f4a2713aSLionel Sambuc TPA.Revert(); 4312*f4a2713aSLionel Sambuc return false; 4313*f4a2713aSLionel Sambuc } 4314*f4a2713aSLionel Sambuc 4315*f4a2713aSLionel Sambuc // Parse the constructor name. 4316*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 4317*f4a2713aSLionel Sambuc // We already know that we have a constructor name; just consume 4318*f4a2713aSLionel Sambuc // the token. 4319*f4a2713aSLionel Sambuc ConsumeToken(); 4320*f4a2713aSLionel Sambuc } else { 4321*f4a2713aSLionel Sambuc TPA.Revert(); 4322*f4a2713aSLionel Sambuc return false; 4323*f4a2713aSLionel Sambuc } 4324*f4a2713aSLionel Sambuc 4325*f4a2713aSLionel Sambuc // Current class name must be followed by a left parenthesis. 4326*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 4327*f4a2713aSLionel Sambuc TPA.Revert(); 4328*f4a2713aSLionel Sambuc return false; 4329*f4a2713aSLionel Sambuc } 4330*f4a2713aSLionel Sambuc ConsumeParen(); 4331*f4a2713aSLionel Sambuc 4332*f4a2713aSLionel Sambuc // A right parenthesis, or ellipsis followed by a right parenthesis signals 4333*f4a2713aSLionel Sambuc // that we have a constructor. 4334*f4a2713aSLionel Sambuc if (Tok.is(tok::r_paren) || 4335*f4a2713aSLionel Sambuc (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) { 4336*f4a2713aSLionel Sambuc TPA.Revert(); 4337*f4a2713aSLionel Sambuc return true; 4338*f4a2713aSLionel Sambuc } 4339*f4a2713aSLionel Sambuc 4340*f4a2713aSLionel Sambuc // A C++11 attribute here signals that we have a constructor, and is an 4341*f4a2713aSLionel Sambuc // attribute on the first constructor parameter. 4342*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && 4343*f4a2713aSLionel Sambuc isCXX11AttributeSpecifier(/*Disambiguate*/ false, 4344*f4a2713aSLionel Sambuc /*OuterMightBeMessageSend*/ true)) { 4345*f4a2713aSLionel Sambuc TPA.Revert(); 4346*f4a2713aSLionel Sambuc return true; 4347*f4a2713aSLionel Sambuc } 4348*f4a2713aSLionel Sambuc 4349*f4a2713aSLionel Sambuc // If we need to, enter the specified scope. 4350*f4a2713aSLionel Sambuc DeclaratorScopeObj DeclScopeObj(*this, SS); 4351*f4a2713aSLionel Sambuc if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 4352*f4a2713aSLionel Sambuc DeclScopeObj.EnterDeclaratorScope(); 4353*f4a2713aSLionel Sambuc 4354*f4a2713aSLionel Sambuc // Optionally skip Microsoft attributes. 4355*f4a2713aSLionel Sambuc ParsedAttributes Attrs(AttrFactory); 4356*f4a2713aSLionel Sambuc MaybeParseMicrosoftAttributes(Attrs); 4357*f4a2713aSLionel Sambuc 4358*f4a2713aSLionel Sambuc // Check whether the next token(s) are part of a declaration 4359*f4a2713aSLionel Sambuc // specifier, in which case we have the start of a parameter and, 4360*f4a2713aSLionel Sambuc // therefore, we know that this is a constructor. 4361*f4a2713aSLionel Sambuc bool IsConstructor = false; 4362*f4a2713aSLionel Sambuc if (isDeclarationSpecifier()) 4363*f4a2713aSLionel Sambuc IsConstructor = true; 4364*f4a2713aSLionel Sambuc else if (Tok.is(tok::identifier) || 4365*f4a2713aSLionel Sambuc (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) { 4366*f4a2713aSLionel Sambuc // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type. 4367*f4a2713aSLionel Sambuc // This might be a parenthesized member name, but is more likely to 4368*f4a2713aSLionel Sambuc // be a constructor declaration with an invalid argument type. Keep 4369*f4a2713aSLionel Sambuc // looking. 4370*f4a2713aSLionel Sambuc if (Tok.is(tok::annot_cxxscope)) 4371*f4a2713aSLionel Sambuc ConsumeToken(); 4372*f4a2713aSLionel Sambuc ConsumeToken(); 4373*f4a2713aSLionel Sambuc 4374*f4a2713aSLionel Sambuc // If this is not a constructor, we must be parsing a declarator, 4375*f4a2713aSLionel Sambuc // which must have one of the following syntactic forms (see the 4376*f4a2713aSLionel Sambuc // grammar extract at the start of ParseDirectDeclarator): 4377*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 4378*f4a2713aSLionel Sambuc case tok::l_paren: 4379*f4a2713aSLionel Sambuc // C(X ( int)); 4380*f4a2713aSLionel Sambuc case tok::l_square: 4381*f4a2713aSLionel Sambuc // C(X [ 5]); 4382*f4a2713aSLionel Sambuc // C(X [ [attribute]]); 4383*f4a2713aSLionel Sambuc case tok::coloncolon: 4384*f4a2713aSLionel Sambuc // C(X :: Y); 4385*f4a2713aSLionel Sambuc // C(X :: *p); 4386*f4a2713aSLionel Sambuc case tok::r_paren: 4387*f4a2713aSLionel Sambuc // C(X ) 4388*f4a2713aSLionel Sambuc // Assume this isn't a constructor, rather than assuming it's a 4389*f4a2713aSLionel Sambuc // constructor with an unnamed parameter of an ill-formed type. 4390*f4a2713aSLionel Sambuc break; 4391*f4a2713aSLionel Sambuc 4392*f4a2713aSLionel Sambuc default: 4393*f4a2713aSLionel Sambuc IsConstructor = true; 4394*f4a2713aSLionel Sambuc break; 4395*f4a2713aSLionel Sambuc } 4396*f4a2713aSLionel Sambuc } 4397*f4a2713aSLionel Sambuc 4398*f4a2713aSLionel Sambuc TPA.Revert(); 4399*f4a2713aSLionel Sambuc return IsConstructor; 4400*f4a2713aSLionel Sambuc } 4401*f4a2713aSLionel Sambuc 4402*f4a2713aSLionel Sambuc /// ParseTypeQualifierListOpt 4403*f4a2713aSLionel Sambuc /// type-qualifier-list: [C99 6.7.5] 4404*f4a2713aSLionel Sambuc /// type-qualifier 4405*f4a2713aSLionel Sambuc /// [vendor] attributes 4406*f4a2713aSLionel Sambuc /// [ only if VendorAttributesAllowed=true ] 4407*f4a2713aSLionel Sambuc /// type-qualifier-list type-qualifier 4408*f4a2713aSLionel Sambuc /// [vendor] type-qualifier-list attributes 4409*f4a2713aSLionel Sambuc /// [ only if VendorAttributesAllowed=true ] 4410*f4a2713aSLionel Sambuc /// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq 4411*f4a2713aSLionel Sambuc /// [ only if CXX11AttributesAllowed=true ] 4412*f4a2713aSLionel Sambuc /// Note: vendor can be GNU, MS, etc. 4413*f4a2713aSLionel Sambuc /// 4414*f4a2713aSLionel Sambuc void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, 4415*f4a2713aSLionel Sambuc bool VendorAttributesAllowed, 4416*f4a2713aSLionel Sambuc bool CXX11AttributesAllowed, 4417*f4a2713aSLionel Sambuc bool AtomicAllowed, 4418*f4a2713aSLionel Sambuc bool IdentifierRequired) { 4419*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && 4420*f4a2713aSLionel Sambuc isCXX11AttributeSpecifier()) { 4421*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 4422*f4a2713aSLionel Sambuc ParseCXX11Attributes(attrs); 4423*f4a2713aSLionel Sambuc DS.takeAttributesFrom(attrs); 4424*f4a2713aSLionel Sambuc } 4425*f4a2713aSLionel Sambuc 4426*f4a2713aSLionel Sambuc SourceLocation EndLoc; 4427*f4a2713aSLionel Sambuc 4428*f4a2713aSLionel Sambuc while (1) { 4429*f4a2713aSLionel Sambuc bool isInvalid = false; 4430*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 4431*f4a2713aSLionel Sambuc unsigned DiagID = 0; 4432*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 4433*f4a2713aSLionel Sambuc 4434*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 4435*f4a2713aSLionel Sambuc case tok::code_completion: 4436*f4a2713aSLionel Sambuc Actions.CodeCompleteTypeQualifiers(DS); 4437*f4a2713aSLionel Sambuc return cutOffParsing(); 4438*f4a2713aSLionel Sambuc 4439*f4a2713aSLionel Sambuc case tok::kw_const: 4440*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, 4441*f4a2713aSLionel Sambuc getLangOpts()); 4442*f4a2713aSLionel Sambuc break; 4443*f4a2713aSLionel Sambuc case tok::kw_volatile: 4444*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 4445*f4a2713aSLionel Sambuc getLangOpts()); 4446*f4a2713aSLionel Sambuc break; 4447*f4a2713aSLionel Sambuc case tok::kw_restrict: 4448*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 4449*f4a2713aSLionel Sambuc getLangOpts()); 4450*f4a2713aSLionel Sambuc break; 4451*f4a2713aSLionel Sambuc case tok::kw__Atomic: 4452*f4a2713aSLionel Sambuc if (!AtomicAllowed) 4453*f4a2713aSLionel Sambuc goto DoneWithTypeQuals; 4454*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 4455*f4a2713aSLionel Sambuc getLangOpts()); 4456*f4a2713aSLionel Sambuc break; 4457*f4a2713aSLionel Sambuc 4458*f4a2713aSLionel Sambuc // OpenCL qualifiers: 4459*f4a2713aSLionel Sambuc case tok::kw_private: 4460*f4a2713aSLionel Sambuc if (!getLangOpts().OpenCL) 4461*f4a2713aSLionel Sambuc goto DoneWithTypeQuals; 4462*f4a2713aSLionel Sambuc case tok::kw___private: 4463*f4a2713aSLionel Sambuc case tok::kw___global: 4464*f4a2713aSLionel Sambuc case tok::kw___local: 4465*f4a2713aSLionel Sambuc case tok::kw___constant: 4466*f4a2713aSLionel Sambuc case tok::kw___read_only: 4467*f4a2713aSLionel Sambuc case tok::kw___write_only: 4468*f4a2713aSLionel Sambuc case tok::kw___read_write: 4469*f4a2713aSLionel Sambuc ParseOpenCLQualifiers(DS); 4470*f4a2713aSLionel Sambuc break; 4471*f4a2713aSLionel Sambuc 4472*f4a2713aSLionel Sambuc case tok::kw___uptr: 4473*f4a2713aSLionel Sambuc // GNU libc headers in C mode use '__uptr' as an identifer which conflicts 4474*f4a2713aSLionel Sambuc // with the MS modifier keyword. 4475*f4a2713aSLionel Sambuc if (VendorAttributesAllowed && !getLangOpts().CPlusPlus && 4476*f4a2713aSLionel Sambuc IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi) && 4477*f4a2713aSLionel Sambuc PP.getSourceManager().isInSystemHeader(Loc)) { 4478*f4a2713aSLionel Sambuc Tok.setKind(tok::identifier); 4479*f4a2713aSLionel Sambuc continue; 4480*f4a2713aSLionel Sambuc } 4481*f4a2713aSLionel Sambuc case tok::kw___sptr: 4482*f4a2713aSLionel Sambuc case tok::kw___w64: 4483*f4a2713aSLionel Sambuc case tok::kw___ptr64: 4484*f4a2713aSLionel Sambuc case tok::kw___ptr32: 4485*f4a2713aSLionel Sambuc case tok::kw___cdecl: 4486*f4a2713aSLionel Sambuc case tok::kw___stdcall: 4487*f4a2713aSLionel Sambuc case tok::kw___fastcall: 4488*f4a2713aSLionel Sambuc case tok::kw___thiscall: 4489*f4a2713aSLionel Sambuc case tok::kw___unaligned: 4490*f4a2713aSLionel Sambuc if (VendorAttributesAllowed) { 4491*f4a2713aSLionel Sambuc ParseMicrosoftTypeAttributes(DS.getAttributes()); 4492*f4a2713aSLionel Sambuc continue; 4493*f4a2713aSLionel Sambuc } 4494*f4a2713aSLionel Sambuc goto DoneWithTypeQuals; 4495*f4a2713aSLionel Sambuc case tok::kw___pascal: 4496*f4a2713aSLionel Sambuc if (VendorAttributesAllowed) { 4497*f4a2713aSLionel Sambuc ParseBorlandTypeAttributes(DS.getAttributes()); 4498*f4a2713aSLionel Sambuc continue; 4499*f4a2713aSLionel Sambuc } 4500*f4a2713aSLionel Sambuc goto DoneWithTypeQuals; 4501*f4a2713aSLionel Sambuc case tok::kw___attribute: 4502*f4a2713aSLionel Sambuc if (VendorAttributesAllowed) { 4503*f4a2713aSLionel Sambuc ParseGNUAttributes(DS.getAttributes()); 4504*f4a2713aSLionel Sambuc continue; // do *not* consume the next token! 4505*f4a2713aSLionel Sambuc } 4506*f4a2713aSLionel Sambuc // otherwise, FALL THROUGH! 4507*f4a2713aSLionel Sambuc default: 4508*f4a2713aSLionel Sambuc DoneWithTypeQuals: 4509*f4a2713aSLionel Sambuc // If this is not a type-qualifier token, we're done reading type 4510*f4a2713aSLionel Sambuc // qualifiers. First verify that DeclSpec's are consistent. 4511*f4a2713aSLionel Sambuc DS.Finish(Diags, PP); 4512*f4a2713aSLionel Sambuc if (EndLoc.isValid()) 4513*f4a2713aSLionel Sambuc DS.SetRangeEnd(EndLoc); 4514*f4a2713aSLionel Sambuc return; 4515*f4a2713aSLionel Sambuc } 4516*f4a2713aSLionel Sambuc 4517*f4a2713aSLionel Sambuc // If the specifier combination wasn't legal, issue a diagnostic. 4518*f4a2713aSLionel Sambuc if (isInvalid) { 4519*f4a2713aSLionel Sambuc assert(PrevSpec && "Method did not return previous specifier!"); 4520*f4a2713aSLionel Sambuc Diag(Tok, DiagID) << PrevSpec; 4521*f4a2713aSLionel Sambuc } 4522*f4a2713aSLionel Sambuc EndLoc = ConsumeToken(); 4523*f4a2713aSLionel Sambuc } 4524*f4a2713aSLionel Sambuc } 4525*f4a2713aSLionel Sambuc 4526*f4a2713aSLionel Sambuc 4527*f4a2713aSLionel Sambuc /// ParseDeclarator - Parse and verify a newly-initialized declarator. 4528*f4a2713aSLionel Sambuc /// 4529*f4a2713aSLionel Sambuc void Parser::ParseDeclarator(Declarator &D) { 4530*f4a2713aSLionel Sambuc /// This implements the 'declarator' production in the C grammar, then checks 4531*f4a2713aSLionel Sambuc /// for well-formedness and issues diagnostics. 4532*f4a2713aSLionel Sambuc ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4533*f4a2713aSLionel Sambuc } 4534*f4a2713aSLionel Sambuc 4535*f4a2713aSLionel Sambuc static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { 4536*f4a2713aSLionel Sambuc if (Kind == tok::star || Kind == tok::caret) 4537*f4a2713aSLionel Sambuc return true; 4538*f4a2713aSLionel Sambuc 4539*f4a2713aSLionel Sambuc // We parse rvalue refs in C++03, because otherwise the errors are scary. 4540*f4a2713aSLionel Sambuc if (!Lang.CPlusPlus) 4541*f4a2713aSLionel Sambuc return false; 4542*f4a2713aSLionel Sambuc 4543*f4a2713aSLionel Sambuc return Kind == tok::amp || Kind == tok::ampamp; 4544*f4a2713aSLionel Sambuc } 4545*f4a2713aSLionel Sambuc 4546*f4a2713aSLionel Sambuc /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator 4547*f4a2713aSLionel Sambuc /// is parsed by the function passed to it. Pass null, and the direct-declarator 4548*f4a2713aSLionel Sambuc /// isn't parsed at all, making this function effectively parse the C++ 4549*f4a2713aSLionel Sambuc /// ptr-operator production. 4550*f4a2713aSLionel Sambuc /// 4551*f4a2713aSLionel Sambuc /// If the grammar of this construct is extended, matching changes must also be 4552*f4a2713aSLionel Sambuc /// made to TryParseDeclarator and MightBeDeclarator, and possibly to 4553*f4a2713aSLionel Sambuc /// isConstructorDeclarator. 4554*f4a2713aSLionel Sambuc /// 4555*f4a2713aSLionel Sambuc /// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] 4556*f4a2713aSLionel Sambuc /// [C] pointer[opt] direct-declarator 4557*f4a2713aSLionel Sambuc /// [C++] direct-declarator 4558*f4a2713aSLionel Sambuc /// [C++] ptr-operator declarator 4559*f4a2713aSLionel Sambuc /// 4560*f4a2713aSLionel Sambuc /// pointer: [C99 6.7.5] 4561*f4a2713aSLionel Sambuc /// '*' type-qualifier-list[opt] 4562*f4a2713aSLionel Sambuc /// '*' type-qualifier-list[opt] pointer 4563*f4a2713aSLionel Sambuc /// 4564*f4a2713aSLionel Sambuc /// ptr-operator: 4565*f4a2713aSLionel Sambuc /// '*' cv-qualifier-seq[opt] 4566*f4a2713aSLionel Sambuc /// '&' 4567*f4a2713aSLionel Sambuc /// [C++0x] '&&' 4568*f4a2713aSLionel Sambuc /// [GNU] '&' restrict[opt] attributes[opt] 4569*f4a2713aSLionel Sambuc /// [GNU?] '&&' restrict[opt] attributes[opt] 4570*f4a2713aSLionel Sambuc /// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4571*f4a2713aSLionel Sambuc void Parser::ParseDeclaratorInternal(Declarator &D, 4572*f4a2713aSLionel Sambuc DirectDeclParseFunction DirectDeclParser) { 4573*f4a2713aSLionel Sambuc if (Diags.hasAllExtensionsSilenced()) 4574*f4a2713aSLionel Sambuc D.setExtension(); 4575*f4a2713aSLionel Sambuc 4576*f4a2713aSLionel Sambuc // C++ member pointers start with a '::' or a nested-name. 4577*f4a2713aSLionel Sambuc // Member pointers get special handling, since there's no place for the 4578*f4a2713aSLionel Sambuc // scope spec in the generic path below. 4579*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && 4580*f4a2713aSLionel Sambuc (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || 4581*f4a2713aSLionel Sambuc Tok.is(tok::annot_cxxscope))) { 4582*f4a2713aSLionel Sambuc bool EnteringContext = D.getContext() == Declarator::FileContext || 4583*f4a2713aSLionel Sambuc D.getContext() == Declarator::MemberContext; 4584*f4a2713aSLionel Sambuc CXXScopeSpec SS; 4585*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); 4586*f4a2713aSLionel Sambuc 4587*f4a2713aSLionel Sambuc if (SS.isNotEmpty()) { 4588*f4a2713aSLionel Sambuc if (Tok.isNot(tok::star)) { 4589*f4a2713aSLionel Sambuc // The scope spec really belongs to the direct-declarator. 4590*f4a2713aSLionel Sambuc if (D.mayHaveIdentifier()) 4591*f4a2713aSLionel Sambuc D.getCXXScopeSpec() = SS; 4592*f4a2713aSLionel Sambuc else 4593*f4a2713aSLionel Sambuc AnnotateScopeToken(SS, true); 4594*f4a2713aSLionel Sambuc 4595*f4a2713aSLionel Sambuc if (DirectDeclParser) 4596*f4a2713aSLionel Sambuc (this->*DirectDeclParser)(D); 4597*f4a2713aSLionel Sambuc return; 4598*f4a2713aSLionel Sambuc } 4599*f4a2713aSLionel Sambuc 4600*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 4601*f4a2713aSLionel Sambuc D.SetRangeEnd(Loc); 4602*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 4603*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS); 4604*f4a2713aSLionel Sambuc D.ExtendWithDeclSpec(DS); 4605*f4a2713aSLionel Sambuc 4606*f4a2713aSLionel Sambuc // Recurse to parse whatever is left. 4607*f4a2713aSLionel Sambuc ParseDeclaratorInternal(D, DirectDeclParser); 4608*f4a2713aSLionel Sambuc 4609*f4a2713aSLionel Sambuc // Sema will have to catch (syntactically invalid) pointers into global 4610*f4a2713aSLionel Sambuc // scope. It has to catch pointers into namespace scope anyway. 4611*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), 4612*f4a2713aSLionel Sambuc Loc), 4613*f4a2713aSLionel Sambuc DS.getAttributes(), 4614*f4a2713aSLionel Sambuc /* Don't replace range end. */SourceLocation()); 4615*f4a2713aSLionel Sambuc return; 4616*f4a2713aSLionel Sambuc } 4617*f4a2713aSLionel Sambuc } 4618*f4a2713aSLionel Sambuc 4619*f4a2713aSLionel Sambuc tok::TokenKind Kind = Tok.getKind(); 4620*f4a2713aSLionel Sambuc // Not a pointer, C++ reference, or block. 4621*f4a2713aSLionel Sambuc if (!isPtrOperatorToken(Kind, getLangOpts())) { 4622*f4a2713aSLionel Sambuc if (DirectDeclParser) 4623*f4a2713aSLionel Sambuc (this->*DirectDeclParser)(D); 4624*f4a2713aSLionel Sambuc return; 4625*f4a2713aSLionel Sambuc } 4626*f4a2713aSLionel Sambuc 4627*f4a2713aSLionel Sambuc // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference, 4628*f4a2713aSLionel Sambuc // '&&' -> rvalue reference 4629*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. 4630*f4a2713aSLionel Sambuc D.SetRangeEnd(Loc); 4631*f4a2713aSLionel Sambuc 4632*f4a2713aSLionel Sambuc if (Kind == tok::star || Kind == tok::caret) { 4633*f4a2713aSLionel Sambuc // Is a pointer. 4634*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 4635*f4a2713aSLionel Sambuc 4636*f4a2713aSLionel Sambuc // FIXME: GNU attributes are not allowed here in a new-type-id. 4637*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier()); 4638*f4a2713aSLionel Sambuc D.ExtendWithDeclSpec(DS); 4639*f4a2713aSLionel Sambuc 4640*f4a2713aSLionel Sambuc // Recursively parse the declarator. 4641*f4a2713aSLionel Sambuc ParseDeclaratorInternal(D, DirectDeclParser); 4642*f4a2713aSLionel Sambuc if (Kind == tok::star) 4643*f4a2713aSLionel Sambuc // Remember that we parsed a pointer type, and remember the type-quals. 4644*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, 4645*f4a2713aSLionel Sambuc DS.getConstSpecLoc(), 4646*f4a2713aSLionel Sambuc DS.getVolatileSpecLoc(), 4647*f4a2713aSLionel Sambuc DS.getRestrictSpecLoc()), 4648*f4a2713aSLionel Sambuc DS.getAttributes(), 4649*f4a2713aSLionel Sambuc SourceLocation()); 4650*f4a2713aSLionel Sambuc else 4651*f4a2713aSLionel Sambuc // Remember that we parsed a Block type, and remember the type-quals. 4652*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), 4653*f4a2713aSLionel Sambuc Loc), 4654*f4a2713aSLionel Sambuc DS.getAttributes(), 4655*f4a2713aSLionel Sambuc SourceLocation()); 4656*f4a2713aSLionel Sambuc } else { 4657*f4a2713aSLionel Sambuc // Is a reference 4658*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 4659*f4a2713aSLionel Sambuc 4660*f4a2713aSLionel Sambuc // Complain about rvalue references in C++03, but then go on and build 4661*f4a2713aSLionel Sambuc // the declarator. 4662*f4a2713aSLionel Sambuc if (Kind == tok::ampamp) 4663*f4a2713aSLionel Sambuc Diag(Loc, getLangOpts().CPlusPlus11 ? 4664*f4a2713aSLionel Sambuc diag::warn_cxx98_compat_rvalue_reference : 4665*f4a2713aSLionel Sambuc diag::ext_rvalue_reference); 4666*f4a2713aSLionel Sambuc 4667*f4a2713aSLionel Sambuc // GNU-style and C++11 attributes are allowed here, as is restrict. 4668*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS); 4669*f4a2713aSLionel Sambuc D.ExtendWithDeclSpec(DS); 4670*f4a2713aSLionel Sambuc 4671*f4a2713aSLionel Sambuc // C++ 8.3.2p1: cv-qualified references are ill-formed except when the 4672*f4a2713aSLionel Sambuc // cv-qualifiers are introduced through the use of a typedef or of a 4673*f4a2713aSLionel Sambuc // template type argument, in which case the cv-qualifiers are ignored. 4674*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { 4675*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 4676*f4a2713aSLionel Sambuc Diag(DS.getConstSpecLoc(), 4677*f4a2713aSLionel Sambuc diag::err_invalid_reference_qualifier_application) << "const"; 4678*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) 4679*f4a2713aSLionel Sambuc Diag(DS.getVolatileSpecLoc(), 4680*f4a2713aSLionel Sambuc diag::err_invalid_reference_qualifier_application) << "volatile"; 4681*f4a2713aSLionel Sambuc // 'restrict' is permitted as an extension. 4682*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) 4683*f4a2713aSLionel Sambuc Diag(DS.getAtomicSpecLoc(), 4684*f4a2713aSLionel Sambuc diag::err_invalid_reference_qualifier_application) << "_Atomic"; 4685*f4a2713aSLionel Sambuc } 4686*f4a2713aSLionel Sambuc 4687*f4a2713aSLionel Sambuc // Recursively parse the declarator. 4688*f4a2713aSLionel Sambuc ParseDeclaratorInternal(D, DirectDeclParser); 4689*f4a2713aSLionel Sambuc 4690*f4a2713aSLionel Sambuc if (D.getNumTypeObjects() > 0) { 4691*f4a2713aSLionel Sambuc // C++ [dcl.ref]p4: There shall be no references to references. 4692*f4a2713aSLionel Sambuc DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1); 4693*f4a2713aSLionel Sambuc if (InnerChunk.Kind == DeclaratorChunk::Reference) { 4694*f4a2713aSLionel Sambuc if (const IdentifierInfo *II = D.getIdentifier()) 4695*f4a2713aSLionel Sambuc Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4696*f4a2713aSLionel Sambuc << II; 4697*f4a2713aSLionel Sambuc else 4698*f4a2713aSLionel Sambuc Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4699*f4a2713aSLionel Sambuc << "type name"; 4700*f4a2713aSLionel Sambuc 4701*f4a2713aSLionel Sambuc // Once we've complained about the reference-to-reference, we 4702*f4a2713aSLionel Sambuc // can go ahead and build the (technically ill-formed) 4703*f4a2713aSLionel Sambuc // declarator: reference collapsing will take care of it. 4704*f4a2713aSLionel Sambuc } 4705*f4a2713aSLionel Sambuc } 4706*f4a2713aSLionel Sambuc 4707*f4a2713aSLionel Sambuc // Remember that we parsed a reference type. 4708*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, 4709*f4a2713aSLionel Sambuc Kind == tok::amp), 4710*f4a2713aSLionel Sambuc DS.getAttributes(), 4711*f4a2713aSLionel Sambuc SourceLocation()); 4712*f4a2713aSLionel Sambuc } 4713*f4a2713aSLionel Sambuc } 4714*f4a2713aSLionel Sambuc 4715*f4a2713aSLionel Sambuc static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D, 4716*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc) { 4717*f4a2713aSLionel Sambuc if (EllipsisLoc.isValid()) { 4718*f4a2713aSLionel Sambuc FixItHint Insertion; 4719*f4a2713aSLionel Sambuc if (!D.getEllipsisLoc().isValid()) { 4720*f4a2713aSLionel Sambuc Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "..."); 4721*f4a2713aSLionel Sambuc D.setEllipsisLoc(EllipsisLoc); 4722*f4a2713aSLionel Sambuc } 4723*f4a2713aSLionel Sambuc P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration) 4724*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName(); 4725*f4a2713aSLionel Sambuc } 4726*f4a2713aSLionel Sambuc } 4727*f4a2713aSLionel Sambuc 4728*f4a2713aSLionel Sambuc /// ParseDirectDeclarator 4729*f4a2713aSLionel Sambuc /// direct-declarator: [C99 6.7.5] 4730*f4a2713aSLionel Sambuc /// [C99] identifier 4731*f4a2713aSLionel Sambuc /// '(' declarator ')' 4732*f4a2713aSLionel Sambuc /// [GNU] '(' attributes declarator ')' 4733*f4a2713aSLionel Sambuc /// [C90] direct-declarator '[' constant-expression[opt] ']' 4734*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4735*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4736*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4737*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4738*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '[' constant-expression[opt] ']' 4739*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] 4740*f4a2713aSLionel Sambuc /// direct-declarator '(' parameter-type-list ')' 4741*f4a2713aSLionel Sambuc /// direct-declarator '(' identifier-list[opt] ')' 4742*f4a2713aSLionel Sambuc /// [GNU] direct-declarator '(' parameter-forward-declarations 4743*f4a2713aSLionel Sambuc /// parameter-type-list[opt] ')' 4744*f4a2713aSLionel Sambuc /// [C++] direct-declarator '(' parameter-declaration-clause ')' 4745*f4a2713aSLionel Sambuc /// cv-qualifier-seq[opt] exception-specification[opt] 4746*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '(' parameter-declaration-clause ')' 4747*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] cv-qualifier-seq[opt] 4748*f4a2713aSLionel Sambuc /// ref-qualifier[opt] exception-specification[opt] 4749*f4a2713aSLionel Sambuc /// [C++] declarator-id 4750*f4a2713aSLionel Sambuc /// [C++11] declarator-id attribute-specifier-seq[opt] 4751*f4a2713aSLionel Sambuc /// 4752*f4a2713aSLionel Sambuc /// declarator-id: [C++ 8] 4753*f4a2713aSLionel Sambuc /// '...'[opt] id-expression 4754*f4a2713aSLionel Sambuc /// '::'[opt] nested-name-specifier[opt] type-name 4755*f4a2713aSLionel Sambuc /// 4756*f4a2713aSLionel Sambuc /// id-expression: [C++ 5.1] 4757*f4a2713aSLionel Sambuc /// unqualified-id 4758*f4a2713aSLionel Sambuc /// qualified-id 4759*f4a2713aSLionel Sambuc /// 4760*f4a2713aSLionel Sambuc /// unqualified-id: [C++ 5.1] 4761*f4a2713aSLionel Sambuc /// identifier 4762*f4a2713aSLionel Sambuc /// operator-function-id 4763*f4a2713aSLionel Sambuc /// conversion-function-id 4764*f4a2713aSLionel Sambuc /// '~' class-name 4765*f4a2713aSLionel Sambuc /// template-id 4766*f4a2713aSLionel Sambuc /// 4767*f4a2713aSLionel Sambuc /// Note, any additional constructs added here may need corresponding changes 4768*f4a2713aSLionel Sambuc /// in isConstructorDeclarator. 4769*f4a2713aSLionel Sambuc void Parser::ParseDirectDeclarator(Declarator &D) { 4770*f4a2713aSLionel Sambuc DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); 4771*f4a2713aSLionel Sambuc 4772*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) { 4773*f4a2713aSLionel Sambuc // ParseDeclaratorInternal might already have parsed the scope. 4774*f4a2713aSLionel Sambuc if (D.getCXXScopeSpec().isEmpty()) { 4775*f4a2713aSLionel Sambuc bool EnteringContext = D.getContext() == Declarator::FileContext || 4776*f4a2713aSLionel Sambuc D.getContext() == Declarator::MemberContext; 4777*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), 4778*f4a2713aSLionel Sambuc EnteringContext); 4779*f4a2713aSLionel Sambuc } 4780*f4a2713aSLionel Sambuc 4781*f4a2713aSLionel Sambuc if (D.getCXXScopeSpec().isValid()) { 4782*f4a2713aSLionel Sambuc if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4783*f4a2713aSLionel Sambuc // Change the declaration context for name lookup, until this function 4784*f4a2713aSLionel Sambuc // is exited (and the declarator has been parsed). 4785*f4a2713aSLionel Sambuc DeclScopeObj.EnterDeclaratorScope(); 4786*f4a2713aSLionel Sambuc } 4787*f4a2713aSLionel Sambuc 4788*f4a2713aSLionel Sambuc // C++0x [dcl.fct]p14: 4789*f4a2713aSLionel Sambuc // There is a syntactic ambiguity when an ellipsis occurs at the end 4790*f4a2713aSLionel Sambuc // of a parameter-declaration-clause without a preceding comma. In 4791*f4a2713aSLionel Sambuc // this case, the ellipsis is parsed as part of the 4792*f4a2713aSLionel Sambuc // abstract-declarator if the type of the parameter names a template 4793*f4a2713aSLionel Sambuc // parameter pack that has not been expanded; otherwise, it is parsed 4794*f4a2713aSLionel Sambuc // as part of the parameter-declaration-clause. 4795*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && 4796*f4a2713aSLionel Sambuc !((D.getContext() == Declarator::PrototypeContext || 4797*f4a2713aSLionel Sambuc D.getContext() == Declarator::LambdaExprParameterContext || 4798*f4a2713aSLionel Sambuc D.getContext() == Declarator::BlockLiteralContext) && 4799*f4a2713aSLionel Sambuc NextToken().is(tok::r_paren) && 4800*f4a2713aSLionel Sambuc !D.hasGroupingParens() && 4801*f4a2713aSLionel Sambuc !Actions.containsUnexpandedParameterPacks(D))) { 4802*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ConsumeToken(); 4803*f4a2713aSLionel Sambuc if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { 4804*f4a2713aSLionel Sambuc // The ellipsis was put in the wrong place. Recover, and explain to 4805*f4a2713aSLionel Sambuc // the user what they should have done. 4806*f4a2713aSLionel Sambuc ParseDeclarator(D); 4807*f4a2713aSLionel Sambuc diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4808*f4a2713aSLionel Sambuc return; 4809*f4a2713aSLionel Sambuc } else 4810*f4a2713aSLionel Sambuc D.setEllipsisLoc(EllipsisLoc); 4811*f4a2713aSLionel Sambuc 4812*f4a2713aSLionel Sambuc // The ellipsis can't be followed by a parenthesized declarator. We 4813*f4a2713aSLionel Sambuc // check for that in ParseParenDeclarator, after we have disambiguated 4814*f4a2713aSLionel Sambuc // the l_paren token. 4815*f4a2713aSLionel Sambuc } 4816*f4a2713aSLionel Sambuc 4817*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 4818*f4a2713aSLionel Sambuc Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { 4819*f4a2713aSLionel Sambuc // We found something that indicates the start of an unqualified-id. 4820*f4a2713aSLionel Sambuc // Parse that unqualified-id. 4821*f4a2713aSLionel Sambuc bool AllowConstructorName; 4822*f4a2713aSLionel Sambuc if (D.getDeclSpec().hasTypeSpecifier()) 4823*f4a2713aSLionel Sambuc AllowConstructorName = false; 4824*f4a2713aSLionel Sambuc else if (D.getCXXScopeSpec().isSet()) 4825*f4a2713aSLionel Sambuc AllowConstructorName = 4826*f4a2713aSLionel Sambuc (D.getContext() == Declarator::FileContext || 4827*f4a2713aSLionel Sambuc D.getContext() == Declarator::MemberContext); 4828*f4a2713aSLionel Sambuc else 4829*f4a2713aSLionel Sambuc AllowConstructorName = (D.getContext() == Declarator::MemberContext); 4830*f4a2713aSLionel Sambuc 4831*f4a2713aSLionel Sambuc SourceLocation TemplateKWLoc; 4832*f4a2713aSLionel Sambuc if (ParseUnqualifiedId(D.getCXXScopeSpec(), 4833*f4a2713aSLionel Sambuc /*EnteringContext=*/true, 4834*f4a2713aSLionel Sambuc /*AllowDestructorName=*/true, 4835*f4a2713aSLionel Sambuc AllowConstructorName, 4836*f4a2713aSLionel Sambuc ParsedType(), 4837*f4a2713aSLionel Sambuc TemplateKWLoc, 4838*f4a2713aSLionel Sambuc D.getName()) || 4839*f4a2713aSLionel Sambuc // Once we're past the identifier, if the scope was bad, mark the 4840*f4a2713aSLionel Sambuc // whole declarator bad. 4841*f4a2713aSLionel Sambuc D.getCXXScopeSpec().isInvalid()) { 4842*f4a2713aSLionel Sambuc D.SetIdentifier(0, Tok.getLocation()); 4843*f4a2713aSLionel Sambuc D.setInvalidType(true); 4844*f4a2713aSLionel Sambuc } else { 4845*f4a2713aSLionel Sambuc // Parsed the unqualified-id; update range information and move along. 4846*f4a2713aSLionel Sambuc if (D.getSourceRange().getBegin().isInvalid()) 4847*f4a2713aSLionel Sambuc D.SetRangeBegin(D.getName().getSourceRange().getBegin()); 4848*f4a2713aSLionel Sambuc D.SetRangeEnd(D.getName().getSourceRange().getEnd()); 4849*f4a2713aSLionel Sambuc } 4850*f4a2713aSLionel Sambuc goto PastIdentifier; 4851*f4a2713aSLionel Sambuc } 4852*f4a2713aSLionel Sambuc } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { 4853*f4a2713aSLionel Sambuc assert(!getLangOpts().CPlusPlus && 4854*f4a2713aSLionel Sambuc "There's a C++-specific check for tok::identifier above"); 4855*f4a2713aSLionel Sambuc assert(Tok.getIdentifierInfo() && "Not an identifier?"); 4856*f4a2713aSLionel Sambuc D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 4857*f4a2713aSLionel Sambuc ConsumeToken(); 4858*f4a2713aSLionel Sambuc goto PastIdentifier; 4859*f4a2713aSLionel Sambuc } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) { 4860*f4a2713aSLionel Sambuc // A virt-specifier isn't treated as an identifier if it appears after a 4861*f4a2713aSLionel Sambuc // trailing-return-type. 4862*f4a2713aSLionel Sambuc if (D.getContext() != Declarator::TrailingReturnContext || 4863*f4a2713aSLionel Sambuc !isCXX11VirtSpecifier(Tok)) { 4864*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id) 4865*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(Tok.getLocation()); 4866*f4a2713aSLionel Sambuc D.SetIdentifier(0, Tok.getLocation()); 4867*f4a2713aSLionel Sambuc ConsumeToken(); 4868*f4a2713aSLionel Sambuc goto PastIdentifier; 4869*f4a2713aSLionel Sambuc } 4870*f4a2713aSLionel Sambuc } 4871*f4a2713aSLionel Sambuc 4872*f4a2713aSLionel Sambuc if (Tok.is(tok::l_paren)) { 4873*f4a2713aSLionel Sambuc // direct-declarator: '(' declarator ')' 4874*f4a2713aSLionel Sambuc // direct-declarator: '(' attributes declarator ')' 4875*f4a2713aSLionel Sambuc // Example: 'char (*X)' or 'int (*XX)(void)' 4876*f4a2713aSLionel Sambuc ParseParenDeclarator(D); 4877*f4a2713aSLionel Sambuc 4878*f4a2713aSLionel Sambuc // If the declarator was parenthesized, we entered the declarator 4879*f4a2713aSLionel Sambuc // scope when parsing the parenthesized declarator, then exited 4880*f4a2713aSLionel Sambuc // the scope already. Re-enter the scope, if we need to. 4881*f4a2713aSLionel Sambuc if (D.getCXXScopeSpec().isSet()) { 4882*f4a2713aSLionel Sambuc // If there was an error parsing parenthesized declarator, declarator 4883*f4a2713aSLionel Sambuc // scope may have been entered before. Don't do it again. 4884*f4a2713aSLionel Sambuc if (!D.isInvalidType() && 4885*f4a2713aSLionel Sambuc Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4886*f4a2713aSLionel Sambuc // Change the declaration context for name lookup, until this function 4887*f4a2713aSLionel Sambuc // is exited (and the declarator has been parsed). 4888*f4a2713aSLionel Sambuc DeclScopeObj.EnterDeclaratorScope(); 4889*f4a2713aSLionel Sambuc } 4890*f4a2713aSLionel Sambuc } else if (D.mayOmitIdentifier()) { 4891*f4a2713aSLionel Sambuc // This could be something simple like "int" (in which case the declarator 4892*f4a2713aSLionel Sambuc // portion is empty), if an abstract-declarator is allowed. 4893*f4a2713aSLionel Sambuc D.SetIdentifier(0, Tok.getLocation()); 4894*f4a2713aSLionel Sambuc 4895*f4a2713aSLionel Sambuc // The grammar for abstract-pack-declarator does not allow grouping parens. 4896*f4a2713aSLionel Sambuc // FIXME: Revisit this once core issue 1488 is resolved. 4897*f4a2713aSLionel Sambuc if (D.hasEllipsis() && D.hasGroupingParens()) 4898*f4a2713aSLionel Sambuc Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()), 4899*f4a2713aSLionel Sambuc diag::ext_abstract_pack_declarator_parens); 4900*f4a2713aSLionel Sambuc } else { 4901*f4a2713aSLionel Sambuc if (Tok.getKind() == tok::annot_pragma_parser_crash) 4902*f4a2713aSLionel Sambuc LLVM_BUILTIN_TRAP; 4903*f4a2713aSLionel Sambuc if (D.getContext() == Declarator::MemberContext) 4904*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_member_name_or_semi) 4905*f4a2713aSLionel Sambuc << D.getDeclSpec().getSourceRange(); 4906*f4a2713aSLionel Sambuc else if (getLangOpts().CPlusPlus) { 4907*f4a2713aSLionel Sambuc if (Tok.is(tok::period) || Tok.is(tok::arrow)) 4908*f4a2713aSLionel Sambuc Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow); 4909*f4a2713aSLionel Sambuc else { 4910*f4a2713aSLionel Sambuc SourceLocation Loc = D.getCXXScopeSpec().getEndLoc(); 4911*f4a2713aSLionel Sambuc if (Tok.isAtStartOfLine() && Loc.isValid()) 4912*f4a2713aSLionel Sambuc Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id) 4913*f4a2713aSLionel Sambuc << getLangOpts().CPlusPlus; 4914*f4a2713aSLionel Sambuc else 4915*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_unqualified_id) 4916*f4a2713aSLionel Sambuc << getLangOpts().CPlusPlus; 4917*f4a2713aSLionel Sambuc } 4918*f4a2713aSLionel Sambuc } else 4919*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident_lparen); 4920*f4a2713aSLionel Sambuc D.SetIdentifier(0, Tok.getLocation()); 4921*f4a2713aSLionel Sambuc D.setInvalidType(true); 4922*f4a2713aSLionel Sambuc } 4923*f4a2713aSLionel Sambuc 4924*f4a2713aSLionel Sambuc PastIdentifier: 4925*f4a2713aSLionel Sambuc assert(D.isPastIdentifier() && 4926*f4a2713aSLionel Sambuc "Haven't past the location of the identifier yet?"); 4927*f4a2713aSLionel Sambuc 4928*f4a2713aSLionel Sambuc // Don't parse attributes unless we have parsed an unparenthesized name. 4929*f4a2713aSLionel Sambuc if (D.hasName() && !D.getNumTypeObjects()) 4930*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(D); 4931*f4a2713aSLionel Sambuc 4932*f4a2713aSLionel Sambuc while (1) { 4933*f4a2713aSLionel Sambuc if (Tok.is(tok::l_paren)) { 4934*f4a2713aSLionel Sambuc // Enter function-declaration scope, limiting any declarators to the 4935*f4a2713aSLionel Sambuc // function prototype scope, including parameter declarators. 4936*f4a2713aSLionel Sambuc ParseScope PrototypeScope(this, 4937*f4a2713aSLionel Sambuc Scope::FunctionPrototypeScope|Scope::DeclScope| 4938*f4a2713aSLionel Sambuc (D.isFunctionDeclaratorAFunctionDeclaration() 4939*f4a2713aSLionel Sambuc ? Scope::FunctionDeclarationScope : 0)); 4940*f4a2713aSLionel Sambuc 4941*f4a2713aSLionel Sambuc // The paren may be part of a C++ direct initializer, eg. "int x(1);". 4942*f4a2713aSLionel Sambuc // In such a case, check if we actually have a function declarator; if it 4943*f4a2713aSLionel Sambuc // is not, the declarator has been fully parsed. 4944*f4a2713aSLionel Sambuc bool IsAmbiguous = false; 4945*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) { 4946*f4a2713aSLionel Sambuc // The name of the declarator, if any, is tentatively declared within 4947*f4a2713aSLionel Sambuc // a possible direct initializer. 4948*f4a2713aSLionel Sambuc TentativelyDeclaredIdentifiers.push_back(D.getIdentifier()); 4949*f4a2713aSLionel Sambuc bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous); 4950*f4a2713aSLionel Sambuc TentativelyDeclaredIdentifiers.pop_back(); 4951*f4a2713aSLionel Sambuc if (!IsFunctionDecl) 4952*f4a2713aSLionel Sambuc break; 4953*f4a2713aSLionel Sambuc } 4954*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 4955*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 4956*f4a2713aSLionel Sambuc T.consumeOpen(); 4957*f4a2713aSLionel Sambuc ParseFunctionDeclarator(D, attrs, T, IsAmbiguous); 4958*f4a2713aSLionel Sambuc PrototypeScope.Exit(); 4959*f4a2713aSLionel Sambuc } else if (Tok.is(tok::l_square)) { 4960*f4a2713aSLionel Sambuc ParseBracketDeclarator(D); 4961*f4a2713aSLionel Sambuc } else { 4962*f4a2713aSLionel Sambuc break; 4963*f4a2713aSLionel Sambuc } 4964*f4a2713aSLionel Sambuc } 4965*f4a2713aSLionel Sambuc } 4966*f4a2713aSLionel Sambuc 4967*f4a2713aSLionel Sambuc /// ParseParenDeclarator - We parsed the declarator D up to a paren. This is 4968*f4a2713aSLionel Sambuc /// only called before the identifier, so these are most likely just grouping 4969*f4a2713aSLionel Sambuc /// parens for precedence. If we find that these are actually function 4970*f4a2713aSLionel Sambuc /// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator. 4971*f4a2713aSLionel Sambuc /// 4972*f4a2713aSLionel Sambuc /// direct-declarator: 4973*f4a2713aSLionel Sambuc /// '(' declarator ')' 4974*f4a2713aSLionel Sambuc /// [GNU] '(' attributes declarator ')' 4975*f4a2713aSLionel Sambuc /// direct-declarator '(' parameter-type-list ')' 4976*f4a2713aSLionel Sambuc /// direct-declarator '(' identifier-list[opt] ')' 4977*f4a2713aSLionel Sambuc /// [GNU] direct-declarator '(' parameter-forward-declarations 4978*f4a2713aSLionel Sambuc /// parameter-type-list[opt] ')' 4979*f4a2713aSLionel Sambuc /// 4980*f4a2713aSLionel Sambuc void Parser::ParseParenDeclarator(Declarator &D) { 4981*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 4982*f4a2713aSLionel Sambuc T.consumeOpen(); 4983*f4a2713aSLionel Sambuc 4984*f4a2713aSLionel Sambuc assert(!D.isPastIdentifier() && "Should be called before passing identifier"); 4985*f4a2713aSLionel Sambuc 4986*f4a2713aSLionel Sambuc // Eat any attributes before we look at whether this is a grouping or function 4987*f4a2713aSLionel Sambuc // declarator paren. If this is a grouping paren, the attribute applies to 4988*f4a2713aSLionel Sambuc // the type being built up, for example: 4989*f4a2713aSLionel Sambuc // int (__attribute__(()) *x)(long y) 4990*f4a2713aSLionel Sambuc // If this ends up not being a grouping paren, the attribute applies to the 4991*f4a2713aSLionel Sambuc // first argument, for example: 4992*f4a2713aSLionel Sambuc // int (__attribute__(()) int x) 4993*f4a2713aSLionel Sambuc // In either case, we need to eat any attributes to be able to determine what 4994*f4a2713aSLionel Sambuc // sort of paren this is. 4995*f4a2713aSLionel Sambuc // 4996*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 4997*f4a2713aSLionel Sambuc bool RequiresArg = false; 4998*f4a2713aSLionel Sambuc if (Tok.is(tok::kw___attribute)) { 4999*f4a2713aSLionel Sambuc ParseGNUAttributes(attrs); 5000*f4a2713aSLionel Sambuc 5001*f4a2713aSLionel Sambuc // We require that the argument list (if this is a non-grouping paren) be 5002*f4a2713aSLionel Sambuc // present even if the attribute list was empty. 5003*f4a2713aSLionel Sambuc RequiresArg = true; 5004*f4a2713aSLionel Sambuc } 5005*f4a2713aSLionel Sambuc 5006*f4a2713aSLionel Sambuc // Eat any Microsoft extensions. 5007*f4a2713aSLionel Sambuc ParseMicrosoftTypeAttributes(attrs); 5008*f4a2713aSLionel Sambuc 5009*f4a2713aSLionel Sambuc // Eat any Borland extensions. 5010*f4a2713aSLionel Sambuc if (Tok.is(tok::kw___pascal)) 5011*f4a2713aSLionel Sambuc ParseBorlandTypeAttributes(attrs); 5012*f4a2713aSLionel Sambuc 5013*f4a2713aSLionel Sambuc // If we haven't past the identifier yet (or where the identifier would be 5014*f4a2713aSLionel Sambuc // stored, if this is an abstract declarator), then this is probably just 5015*f4a2713aSLionel Sambuc // grouping parens. However, if this could be an abstract-declarator, then 5016*f4a2713aSLionel Sambuc // this could also be the start of function arguments (consider 'void()'). 5017*f4a2713aSLionel Sambuc bool isGrouping; 5018*f4a2713aSLionel Sambuc 5019*f4a2713aSLionel Sambuc if (!D.mayOmitIdentifier()) { 5020*f4a2713aSLionel Sambuc // If this can't be an abstract-declarator, this *must* be a grouping 5021*f4a2713aSLionel Sambuc // paren, because we haven't seen the identifier yet. 5022*f4a2713aSLionel Sambuc isGrouping = true; 5023*f4a2713aSLionel Sambuc } else if (Tok.is(tok::r_paren) || // 'int()' is a function. 5024*f4a2713aSLionel Sambuc (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && 5025*f4a2713aSLionel Sambuc NextToken().is(tok::r_paren)) || // C++ int(...) 5026*f4a2713aSLionel Sambuc isDeclarationSpecifier() || // 'int(int)' is a function. 5027*f4a2713aSLionel Sambuc isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function. 5028*f4a2713aSLionel Sambuc // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is 5029*f4a2713aSLionel Sambuc // considered to be a type, not a K&R identifier-list. 5030*f4a2713aSLionel Sambuc isGrouping = false; 5031*f4a2713aSLionel Sambuc } else { 5032*f4a2713aSLionel Sambuc // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'. 5033*f4a2713aSLionel Sambuc isGrouping = true; 5034*f4a2713aSLionel Sambuc } 5035*f4a2713aSLionel Sambuc 5036*f4a2713aSLionel Sambuc // If this is a grouping paren, handle: 5037*f4a2713aSLionel Sambuc // direct-declarator: '(' declarator ')' 5038*f4a2713aSLionel Sambuc // direct-declarator: '(' attributes declarator ')' 5039*f4a2713aSLionel Sambuc if (isGrouping) { 5040*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = D.getEllipsisLoc(); 5041*f4a2713aSLionel Sambuc D.setEllipsisLoc(SourceLocation()); 5042*f4a2713aSLionel Sambuc 5043*f4a2713aSLionel Sambuc bool hadGroupingParens = D.hasGroupingParens(); 5044*f4a2713aSLionel Sambuc D.setGroupingParens(true); 5045*f4a2713aSLionel Sambuc ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 5046*f4a2713aSLionel Sambuc // Match the ')'. 5047*f4a2713aSLionel Sambuc T.consumeClose(); 5048*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), 5049*f4a2713aSLionel Sambuc T.getCloseLocation()), 5050*f4a2713aSLionel Sambuc attrs, T.getCloseLocation()); 5051*f4a2713aSLionel Sambuc 5052*f4a2713aSLionel Sambuc D.setGroupingParens(hadGroupingParens); 5053*f4a2713aSLionel Sambuc 5054*f4a2713aSLionel Sambuc // An ellipsis cannot be placed outside parentheses. 5055*f4a2713aSLionel Sambuc if (EllipsisLoc.isValid()) 5056*f4a2713aSLionel Sambuc diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 5057*f4a2713aSLionel Sambuc 5058*f4a2713aSLionel Sambuc return; 5059*f4a2713aSLionel Sambuc } 5060*f4a2713aSLionel Sambuc 5061*f4a2713aSLionel Sambuc // Okay, if this wasn't a grouping paren, it must be the start of a function 5062*f4a2713aSLionel Sambuc // argument list. Recognize that this declarator will never have an 5063*f4a2713aSLionel Sambuc // identifier (and remember where it would have been), then call into 5064*f4a2713aSLionel Sambuc // ParseFunctionDeclarator to handle of argument list. 5065*f4a2713aSLionel Sambuc D.SetIdentifier(0, Tok.getLocation()); 5066*f4a2713aSLionel Sambuc 5067*f4a2713aSLionel Sambuc // Enter function-declaration scope, limiting any declarators to the 5068*f4a2713aSLionel Sambuc // function prototype scope, including parameter declarators. 5069*f4a2713aSLionel Sambuc ParseScope PrototypeScope(this, 5070*f4a2713aSLionel Sambuc Scope::FunctionPrototypeScope | Scope::DeclScope | 5071*f4a2713aSLionel Sambuc (D.isFunctionDeclaratorAFunctionDeclaration() 5072*f4a2713aSLionel Sambuc ? Scope::FunctionDeclarationScope : 0)); 5073*f4a2713aSLionel Sambuc ParseFunctionDeclarator(D, attrs, T, false, RequiresArg); 5074*f4a2713aSLionel Sambuc PrototypeScope.Exit(); 5075*f4a2713aSLionel Sambuc } 5076*f4a2713aSLionel Sambuc 5077*f4a2713aSLionel Sambuc /// ParseFunctionDeclarator - We are after the identifier and have parsed the 5078*f4a2713aSLionel Sambuc /// declarator D up to a paren, which indicates that we are parsing function 5079*f4a2713aSLionel Sambuc /// arguments. 5080*f4a2713aSLionel Sambuc /// 5081*f4a2713aSLionel Sambuc /// If FirstArgAttrs is non-null, then the caller parsed those arguments 5082*f4a2713aSLionel Sambuc /// immediately after the open paren - they should be considered to be the 5083*f4a2713aSLionel Sambuc /// first argument of a parameter. 5084*f4a2713aSLionel Sambuc /// 5085*f4a2713aSLionel Sambuc /// If RequiresArg is true, then the first argument of the function is required 5086*f4a2713aSLionel Sambuc /// to be present and required to not be an identifier list. 5087*f4a2713aSLionel Sambuc /// 5088*f4a2713aSLionel Sambuc /// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt], 5089*f4a2713aSLionel Sambuc /// (C++11) ref-qualifier[opt], exception-specification[opt], 5090*f4a2713aSLionel Sambuc /// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt]. 5091*f4a2713aSLionel Sambuc /// 5092*f4a2713aSLionel Sambuc /// [C++11] exception-specification: 5093*f4a2713aSLionel Sambuc /// dynamic-exception-specification 5094*f4a2713aSLionel Sambuc /// noexcept-specification 5095*f4a2713aSLionel Sambuc /// 5096*f4a2713aSLionel Sambuc void Parser::ParseFunctionDeclarator(Declarator &D, 5097*f4a2713aSLionel Sambuc ParsedAttributes &FirstArgAttrs, 5098*f4a2713aSLionel Sambuc BalancedDelimiterTracker &Tracker, 5099*f4a2713aSLionel Sambuc bool IsAmbiguous, 5100*f4a2713aSLionel Sambuc bool RequiresArg) { 5101*f4a2713aSLionel Sambuc assert(getCurScope()->isFunctionPrototypeScope() && 5102*f4a2713aSLionel Sambuc "Should call from a Function scope"); 5103*f4a2713aSLionel Sambuc // lparen is already consumed! 5104*f4a2713aSLionel Sambuc assert(D.isPastIdentifier() && "Should not call before identifier!"); 5105*f4a2713aSLionel Sambuc 5106*f4a2713aSLionel Sambuc // This should be true when the function has typed arguments. 5107*f4a2713aSLionel Sambuc // Otherwise, it is treated as a K&R-style function. 5108*f4a2713aSLionel Sambuc bool HasProto = false; 5109*f4a2713aSLionel Sambuc // Build up an array of information about the parsed arguments. 5110*f4a2713aSLionel Sambuc SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 5111*f4a2713aSLionel Sambuc // Remember where we see an ellipsis, if any. 5112*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc; 5113*f4a2713aSLionel Sambuc 5114*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 5115*f4a2713aSLionel Sambuc bool RefQualifierIsLValueRef = true; 5116*f4a2713aSLionel Sambuc SourceLocation RefQualifierLoc; 5117*f4a2713aSLionel Sambuc SourceLocation ConstQualifierLoc; 5118*f4a2713aSLionel Sambuc SourceLocation VolatileQualifierLoc; 5119*f4a2713aSLionel Sambuc ExceptionSpecificationType ESpecType = EST_None; 5120*f4a2713aSLionel Sambuc SourceRange ESpecRange; 5121*f4a2713aSLionel Sambuc SmallVector<ParsedType, 2> DynamicExceptions; 5122*f4a2713aSLionel Sambuc SmallVector<SourceRange, 2> DynamicExceptionRanges; 5123*f4a2713aSLionel Sambuc ExprResult NoexceptExpr; 5124*f4a2713aSLionel Sambuc ParsedAttributes FnAttrs(AttrFactory); 5125*f4a2713aSLionel Sambuc TypeResult TrailingReturnType; 5126*f4a2713aSLionel Sambuc 5127*f4a2713aSLionel Sambuc Actions.ActOnStartFunctionDeclarator(); 5128*f4a2713aSLionel Sambuc /* LocalEndLoc is the end location for the local FunctionTypeLoc. 5129*f4a2713aSLionel Sambuc EndLoc is the end location for the function declarator. 5130*f4a2713aSLionel Sambuc They differ for trailing return types. */ 5131*f4a2713aSLionel Sambuc SourceLocation StartLoc, LocalEndLoc, EndLoc; 5132*f4a2713aSLionel Sambuc SourceLocation LParenLoc, RParenLoc; 5133*f4a2713aSLionel Sambuc LParenLoc = Tracker.getOpenLocation(); 5134*f4a2713aSLionel Sambuc StartLoc = LParenLoc; 5135*f4a2713aSLionel Sambuc 5136*f4a2713aSLionel Sambuc if (isFunctionDeclaratorIdentifierList()) { 5137*f4a2713aSLionel Sambuc if (RequiresArg) 5138*f4a2713aSLionel Sambuc Diag(Tok, diag::err_argument_required_after_attribute); 5139*f4a2713aSLionel Sambuc 5140*f4a2713aSLionel Sambuc ParseFunctionDeclaratorIdentifierList(D, ParamInfo); 5141*f4a2713aSLionel Sambuc 5142*f4a2713aSLionel Sambuc Tracker.consumeClose(); 5143*f4a2713aSLionel Sambuc RParenLoc = Tracker.getCloseLocation(); 5144*f4a2713aSLionel Sambuc LocalEndLoc = RParenLoc; 5145*f4a2713aSLionel Sambuc EndLoc = RParenLoc; 5146*f4a2713aSLionel Sambuc } else { 5147*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) 5148*f4a2713aSLionel Sambuc ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, 5149*f4a2713aSLionel Sambuc EllipsisLoc); 5150*f4a2713aSLionel Sambuc else if (RequiresArg) 5151*f4a2713aSLionel Sambuc Diag(Tok, diag::err_argument_required_after_attribute); 5152*f4a2713aSLionel Sambuc 5153*f4a2713aSLionel Sambuc HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; 5154*f4a2713aSLionel Sambuc 5155*f4a2713aSLionel Sambuc // If we have the closing ')', eat it. 5156*f4a2713aSLionel Sambuc Tracker.consumeClose(); 5157*f4a2713aSLionel Sambuc RParenLoc = Tracker.getCloseLocation(); 5158*f4a2713aSLionel Sambuc LocalEndLoc = RParenLoc; 5159*f4a2713aSLionel Sambuc EndLoc = RParenLoc; 5160*f4a2713aSLionel Sambuc 5161*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 5162*f4a2713aSLionel Sambuc // FIXME: Accept these components in any order, and produce fixits to 5163*f4a2713aSLionel Sambuc // correct the order if the user gets it wrong. Ideally we should deal 5164*f4a2713aSLionel Sambuc // with the virt-specifier-seq and pure-specifier in the same way. 5165*f4a2713aSLionel Sambuc 5166*f4a2713aSLionel Sambuc // Parse cv-qualifier-seq[opt]. 5167*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false, 5168*f4a2713aSLionel Sambuc /*CXX11AttributesAllowed*/ false, 5169*f4a2713aSLionel Sambuc /*AtomicAllowed*/ false); 5170*f4a2713aSLionel Sambuc if (!DS.getSourceRange().getEnd().isInvalid()) { 5171*f4a2713aSLionel Sambuc EndLoc = DS.getSourceRange().getEnd(); 5172*f4a2713aSLionel Sambuc ConstQualifierLoc = DS.getConstSpecLoc(); 5173*f4a2713aSLionel Sambuc VolatileQualifierLoc = DS.getVolatileSpecLoc(); 5174*f4a2713aSLionel Sambuc } 5175*f4a2713aSLionel Sambuc 5176*f4a2713aSLionel Sambuc // Parse ref-qualifier[opt]. 5177*f4a2713aSLionel Sambuc if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) { 5178*f4a2713aSLionel Sambuc Diag(Tok, getLangOpts().CPlusPlus11 ? 5179*f4a2713aSLionel Sambuc diag::warn_cxx98_compat_ref_qualifier : 5180*f4a2713aSLionel Sambuc diag::ext_ref_qualifier); 5181*f4a2713aSLionel Sambuc 5182*f4a2713aSLionel Sambuc RefQualifierIsLValueRef = Tok.is(tok::amp); 5183*f4a2713aSLionel Sambuc RefQualifierLoc = ConsumeToken(); 5184*f4a2713aSLionel Sambuc EndLoc = RefQualifierLoc; 5185*f4a2713aSLionel Sambuc } 5186*f4a2713aSLionel Sambuc 5187*f4a2713aSLionel Sambuc // C++11 [expr.prim.general]p3: 5188*f4a2713aSLionel Sambuc // If a declaration declares a member function or member function 5189*f4a2713aSLionel Sambuc // template of a class X, the expression this is a prvalue of type 5190*f4a2713aSLionel Sambuc // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 5191*f4a2713aSLionel Sambuc // and the end of the function-definition, member-declarator, or 5192*f4a2713aSLionel Sambuc // declarator. 5193*f4a2713aSLionel Sambuc // FIXME: currently, "static" case isn't handled correctly. 5194*f4a2713aSLionel Sambuc bool IsCXX11MemberFunction = 5195*f4a2713aSLionel Sambuc getLangOpts().CPlusPlus11 && 5196*f4a2713aSLionel Sambuc (D.getContext() == Declarator::MemberContext 5197*f4a2713aSLionel Sambuc ? !D.getDeclSpec().isFriendSpecified() 5198*f4a2713aSLionel Sambuc : D.getContext() == Declarator::FileContext && 5199*f4a2713aSLionel Sambuc D.getCXXScopeSpec().isValid() && 5200*f4a2713aSLionel Sambuc Actions.CurContext->isRecord()); 5201*f4a2713aSLionel Sambuc Sema::CXXThisScopeRAII ThisScope(Actions, 5202*f4a2713aSLionel Sambuc dyn_cast<CXXRecordDecl>(Actions.CurContext), 5203*f4a2713aSLionel Sambuc DS.getTypeQualifiers() | 5204*f4a2713aSLionel Sambuc (D.getDeclSpec().isConstexprSpecified() && 5205*f4a2713aSLionel Sambuc !getLangOpts().CPlusPlus1y 5206*f4a2713aSLionel Sambuc ? Qualifiers::Const : 0), 5207*f4a2713aSLionel Sambuc IsCXX11MemberFunction); 5208*f4a2713aSLionel Sambuc 5209*f4a2713aSLionel Sambuc // Parse exception-specification[opt]. 5210*f4a2713aSLionel Sambuc ESpecType = tryParseExceptionSpecification(ESpecRange, 5211*f4a2713aSLionel Sambuc DynamicExceptions, 5212*f4a2713aSLionel Sambuc DynamicExceptionRanges, 5213*f4a2713aSLionel Sambuc NoexceptExpr); 5214*f4a2713aSLionel Sambuc if (ESpecType != EST_None) 5215*f4a2713aSLionel Sambuc EndLoc = ESpecRange.getEnd(); 5216*f4a2713aSLionel Sambuc 5217*f4a2713aSLionel Sambuc // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes 5218*f4a2713aSLionel Sambuc // after the exception-specification. 5219*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(FnAttrs); 5220*f4a2713aSLionel Sambuc 5221*f4a2713aSLionel Sambuc // Parse trailing-return-type[opt]. 5222*f4a2713aSLionel Sambuc LocalEndLoc = EndLoc; 5223*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) { 5224*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_trailing_return_type); 5225*f4a2713aSLionel Sambuc if (D.getDeclSpec().getTypeSpecType() == TST_auto) 5226*f4a2713aSLionel Sambuc StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); 5227*f4a2713aSLionel Sambuc LocalEndLoc = Tok.getLocation(); 5228*f4a2713aSLionel Sambuc SourceRange Range; 5229*f4a2713aSLionel Sambuc TrailingReturnType = ParseTrailingReturnType(Range); 5230*f4a2713aSLionel Sambuc EndLoc = Range.getEnd(); 5231*f4a2713aSLionel Sambuc } 5232*f4a2713aSLionel Sambuc } 5233*f4a2713aSLionel Sambuc } 5234*f4a2713aSLionel Sambuc 5235*f4a2713aSLionel Sambuc // Remember that we parsed a function type, and remember the attributes. 5236*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, 5237*f4a2713aSLionel Sambuc IsAmbiguous, 5238*f4a2713aSLionel Sambuc LParenLoc, 5239*f4a2713aSLionel Sambuc ParamInfo.data(), ParamInfo.size(), 5240*f4a2713aSLionel Sambuc EllipsisLoc, RParenLoc, 5241*f4a2713aSLionel Sambuc DS.getTypeQualifiers(), 5242*f4a2713aSLionel Sambuc RefQualifierIsLValueRef, 5243*f4a2713aSLionel Sambuc RefQualifierLoc, ConstQualifierLoc, 5244*f4a2713aSLionel Sambuc VolatileQualifierLoc, 5245*f4a2713aSLionel Sambuc /*MutableLoc=*/SourceLocation(), 5246*f4a2713aSLionel Sambuc ESpecType, ESpecRange.getBegin(), 5247*f4a2713aSLionel Sambuc DynamicExceptions.data(), 5248*f4a2713aSLionel Sambuc DynamicExceptionRanges.data(), 5249*f4a2713aSLionel Sambuc DynamicExceptions.size(), 5250*f4a2713aSLionel Sambuc NoexceptExpr.isUsable() ? 5251*f4a2713aSLionel Sambuc NoexceptExpr.get() : 0, 5252*f4a2713aSLionel Sambuc StartLoc, LocalEndLoc, D, 5253*f4a2713aSLionel Sambuc TrailingReturnType), 5254*f4a2713aSLionel Sambuc FnAttrs, EndLoc); 5255*f4a2713aSLionel Sambuc 5256*f4a2713aSLionel Sambuc Actions.ActOnEndFunctionDeclarator(); 5257*f4a2713aSLionel Sambuc } 5258*f4a2713aSLionel Sambuc 5259*f4a2713aSLionel Sambuc /// isFunctionDeclaratorIdentifierList - This parameter list may have an 5260*f4a2713aSLionel Sambuc /// identifier list form for a K&R-style function: void foo(a,b,c) 5261*f4a2713aSLionel Sambuc /// 5262*f4a2713aSLionel Sambuc /// Note that identifier-lists are only allowed for normal declarators, not for 5263*f4a2713aSLionel Sambuc /// abstract-declarators. 5264*f4a2713aSLionel Sambuc bool Parser::isFunctionDeclaratorIdentifierList() { 5265*f4a2713aSLionel Sambuc return !getLangOpts().CPlusPlus 5266*f4a2713aSLionel Sambuc && Tok.is(tok::identifier) 5267*f4a2713aSLionel Sambuc && !TryAltiVecVectorToken() 5268*f4a2713aSLionel Sambuc // K&R identifier lists can't have typedefs as identifiers, per C99 5269*f4a2713aSLionel Sambuc // 6.7.5.3p11. 5270*f4a2713aSLionel Sambuc && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) 5271*f4a2713aSLionel Sambuc // Identifier lists follow a really simple grammar: the identifiers can 5272*f4a2713aSLionel Sambuc // be followed *only* by a ", identifier" or ")". However, K&R 5273*f4a2713aSLionel Sambuc // identifier lists are really rare in the brave new modern world, and 5274*f4a2713aSLionel Sambuc // it is very common for someone to typo a type in a non-K&R style 5275*f4a2713aSLionel Sambuc // list. If we are presented with something like: "void foo(intptr x, 5276*f4a2713aSLionel Sambuc // float y)", we don't want to start parsing the function declarator as 5277*f4a2713aSLionel Sambuc // though it is a K&R style declarator just because intptr is an 5278*f4a2713aSLionel Sambuc // invalid type. 5279*f4a2713aSLionel Sambuc // 5280*f4a2713aSLionel Sambuc // To handle this, we check to see if the token after the first 5281*f4a2713aSLionel Sambuc // identifier is a "," or ")". Only then do we parse it as an 5282*f4a2713aSLionel Sambuc // identifier list. 5283*f4a2713aSLionel Sambuc && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); 5284*f4a2713aSLionel Sambuc } 5285*f4a2713aSLionel Sambuc 5286*f4a2713aSLionel Sambuc /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator 5287*f4a2713aSLionel Sambuc /// we found a K&R-style identifier list instead of a typed parameter list. 5288*f4a2713aSLionel Sambuc /// 5289*f4a2713aSLionel Sambuc /// After returning, ParamInfo will hold the parsed parameters. 5290*f4a2713aSLionel Sambuc /// 5291*f4a2713aSLionel Sambuc /// identifier-list: [C99 6.7.5] 5292*f4a2713aSLionel Sambuc /// identifier 5293*f4a2713aSLionel Sambuc /// identifier-list ',' identifier 5294*f4a2713aSLionel Sambuc /// 5295*f4a2713aSLionel Sambuc void Parser::ParseFunctionDeclaratorIdentifierList( 5296*f4a2713aSLionel Sambuc Declarator &D, 5297*f4a2713aSLionel Sambuc SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) { 5298*f4a2713aSLionel Sambuc // If there was no identifier specified for the declarator, either we are in 5299*f4a2713aSLionel Sambuc // an abstract-declarator, or we are in a parameter declarator which was found 5300*f4a2713aSLionel Sambuc // to be abstract. In abstract-declarators, identifier lists are not valid: 5301*f4a2713aSLionel Sambuc // diagnose this. 5302*f4a2713aSLionel Sambuc if (!D.getIdentifier()) 5303*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_ident_list_in_param); 5304*f4a2713aSLionel Sambuc 5305*f4a2713aSLionel Sambuc // Maintain an efficient lookup of params we have seen so far. 5306*f4a2713aSLionel Sambuc llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar; 5307*f4a2713aSLionel Sambuc 5308*f4a2713aSLionel Sambuc while (1) { 5309*f4a2713aSLionel Sambuc // If this isn't an identifier, report the error and skip until ')'. 5310*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 5311*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 5312*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 5313*f4a2713aSLionel Sambuc // Forget we parsed anything. 5314*f4a2713aSLionel Sambuc ParamInfo.clear(); 5315*f4a2713aSLionel Sambuc return; 5316*f4a2713aSLionel Sambuc } 5317*f4a2713aSLionel Sambuc 5318*f4a2713aSLionel Sambuc IdentifierInfo *ParmII = Tok.getIdentifierInfo(); 5319*f4a2713aSLionel Sambuc 5320*f4a2713aSLionel Sambuc // Reject 'typedef int y; int test(x, y)', but continue parsing. 5321*f4a2713aSLionel Sambuc if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope())) 5322*f4a2713aSLionel Sambuc Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; 5323*f4a2713aSLionel Sambuc 5324*f4a2713aSLionel Sambuc // Verify that the argument identifier has not already been mentioned. 5325*f4a2713aSLionel Sambuc if (!ParamsSoFar.insert(ParmII)) { 5326*f4a2713aSLionel Sambuc Diag(Tok, diag::err_param_redefinition) << ParmII; 5327*f4a2713aSLionel Sambuc } else { 5328*f4a2713aSLionel Sambuc // Remember this identifier in ParamInfo. 5329*f4a2713aSLionel Sambuc ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5330*f4a2713aSLionel Sambuc Tok.getLocation(), 5331*f4a2713aSLionel Sambuc 0)); 5332*f4a2713aSLionel Sambuc } 5333*f4a2713aSLionel Sambuc 5334*f4a2713aSLionel Sambuc // Eat the identifier. 5335*f4a2713aSLionel Sambuc ConsumeToken(); 5336*f4a2713aSLionel Sambuc 5337*f4a2713aSLionel Sambuc // The list continues if we see a comma. 5338*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 5339*f4a2713aSLionel Sambuc break; 5340*f4a2713aSLionel Sambuc ConsumeToken(); 5341*f4a2713aSLionel Sambuc } 5342*f4a2713aSLionel Sambuc } 5343*f4a2713aSLionel Sambuc 5344*f4a2713aSLionel Sambuc /// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list 5345*f4a2713aSLionel Sambuc /// after the opening parenthesis. This function will not parse a K&R-style 5346*f4a2713aSLionel Sambuc /// identifier list. 5347*f4a2713aSLionel Sambuc /// 5348*f4a2713aSLionel Sambuc /// D is the declarator being parsed. If FirstArgAttrs is non-null, then the 5349*f4a2713aSLionel Sambuc /// caller parsed those arguments immediately after the open paren - they should 5350*f4a2713aSLionel Sambuc /// be considered to be part of the first parameter. 5351*f4a2713aSLionel Sambuc /// 5352*f4a2713aSLionel Sambuc /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will 5353*f4a2713aSLionel Sambuc /// be the location of the ellipsis, if any was parsed. 5354*f4a2713aSLionel Sambuc /// 5355*f4a2713aSLionel Sambuc /// parameter-type-list: [C99 6.7.5] 5356*f4a2713aSLionel Sambuc /// parameter-list 5357*f4a2713aSLionel Sambuc /// parameter-list ',' '...' 5358*f4a2713aSLionel Sambuc /// [C++] parameter-list '...' 5359*f4a2713aSLionel Sambuc /// 5360*f4a2713aSLionel Sambuc /// parameter-list: [C99 6.7.5] 5361*f4a2713aSLionel Sambuc /// parameter-declaration 5362*f4a2713aSLionel Sambuc /// parameter-list ',' parameter-declaration 5363*f4a2713aSLionel Sambuc /// 5364*f4a2713aSLionel Sambuc /// parameter-declaration: [C99 6.7.5] 5365*f4a2713aSLionel Sambuc /// declaration-specifiers declarator 5366*f4a2713aSLionel Sambuc /// [C++] declaration-specifiers declarator '=' assignment-expression 5367*f4a2713aSLionel Sambuc /// [C++11] initializer-clause 5368*f4a2713aSLionel Sambuc /// [GNU] declaration-specifiers declarator attributes 5369*f4a2713aSLionel Sambuc /// declaration-specifiers abstract-declarator[opt] 5370*f4a2713aSLionel Sambuc /// [C++] declaration-specifiers abstract-declarator[opt] 5371*f4a2713aSLionel Sambuc /// '=' assignment-expression 5372*f4a2713aSLionel Sambuc /// [GNU] declaration-specifiers abstract-declarator[opt] attributes 5373*f4a2713aSLionel Sambuc /// [C++11] attribute-specifier-seq parameter-declaration 5374*f4a2713aSLionel Sambuc /// 5375*f4a2713aSLionel Sambuc void Parser::ParseParameterDeclarationClause( 5376*f4a2713aSLionel Sambuc Declarator &D, 5377*f4a2713aSLionel Sambuc ParsedAttributes &FirstArgAttrs, 5378*f4a2713aSLionel Sambuc SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, 5379*f4a2713aSLionel Sambuc SourceLocation &EllipsisLoc) { 5380*f4a2713aSLionel Sambuc while (1) { 5381*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) { 5382*f4a2713aSLionel Sambuc // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq 5383*f4a2713aSLionel Sambuc // before deciding this was a parameter-declaration-clause. 5384*f4a2713aSLionel Sambuc EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5385*f4a2713aSLionel Sambuc break; 5386*f4a2713aSLionel Sambuc } 5387*f4a2713aSLionel Sambuc 5388*f4a2713aSLionel Sambuc // Parse the declaration-specifiers. 5389*f4a2713aSLionel Sambuc // Just use the ParsingDeclaration "scope" of the declarator. 5390*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 5391*f4a2713aSLionel Sambuc 5392*f4a2713aSLionel Sambuc // Parse any C++11 attributes. 5393*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(DS.getAttributes()); 5394*f4a2713aSLionel Sambuc 5395*f4a2713aSLionel Sambuc // Skip any Microsoft attributes before a param. 5396*f4a2713aSLionel Sambuc MaybeParseMicrosoftAttributes(DS.getAttributes()); 5397*f4a2713aSLionel Sambuc 5398*f4a2713aSLionel Sambuc SourceLocation DSStart = Tok.getLocation(); 5399*f4a2713aSLionel Sambuc 5400*f4a2713aSLionel Sambuc // If the caller parsed attributes for the first argument, add them now. 5401*f4a2713aSLionel Sambuc // Take them so that we only apply the attributes to the first parameter. 5402*f4a2713aSLionel Sambuc // FIXME: If we can leave the attributes in the token stream somehow, we can 5403*f4a2713aSLionel Sambuc // get rid of a parameter (FirstArgAttrs) and this statement. It might be 5404*f4a2713aSLionel Sambuc // too much hassle. 5405*f4a2713aSLionel Sambuc DS.takeAttributesFrom(FirstArgAttrs); 5406*f4a2713aSLionel Sambuc 5407*f4a2713aSLionel Sambuc ParseDeclarationSpecifiers(DS); 5408*f4a2713aSLionel Sambuc 5409*f4a2713aSLionel Sambuc 5410*f4a2713aSLionel Sambuc // Parse the declarator. This is "PrototypeContext" or 5411*f4a2713aSLionel Sambuc // "LambdaExprParameterContext", because we must accept either 5412*f4a2713aSLionel Sambuc // 'declarator' or 'abstract-declarator' here. 5413*f4a2713aSLionel Sambuc Declarator ParmDeclarator(DS, 5414*f4a2713aSLionel Sambuc D.getContext() == Declarator::LambdaExprContext ? 5415*f4a2713aSLionel Sambuc Declarator::LambdaExprParameterContext : 5416*f4a2713aSLionel Sambuc Declarator::PrototypeContext); 5417*f4a2713aSLionel Sambuc ParseDeclarator(ParmDeclarator); 5418*f4a2713aSLionel Sambuc 5419*f4a2713aSLionel Sambuc // Parse GNU attributes, if present. 5420*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(ParmDeclarator); 5421*f4a2713aSLionel Sambuc 5422*f4a2713aSLionel Sambuc // Remember this parsed parameter in ParamInfo. 5423*f4a2713aSLionel Sambuc IdentifierInfo *ParmII = ParmDeclarator.getIdentifier(); 5424*f4a2713aSLionel Sambuc 5425*f4a2713aSLionel Sambuc // DefArgToks is used when the parsing of default arguments needs 5426*f4a2713aSLionel Sambuc // to be delayed. 5427*f4a2713aSLionel Sambuc CachedTokens *DefArgToks = 0; 5428*f4a2713aSLionel Sambuc 5429*f4a2713aSLionel Sambuc // If no parameter was specified, verify that *something* was specified, 5430*f4a2713aSLionel Sambuc // otherwise we have a missing type and identifier. 5431*f4a2713aSLionel Sambuc if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 && 5432*f4a2713aSLionel Sambuc ParmDeclarator.getNumTypeObjects() == 0) { 5433*f4a2713aSLionel Sambuc // Completely missing, emit error. 5434*f4a2713aSLionel Sambuc Diag(DSStart, diag::err_missing_param); 5435*f4a2713aSLionel Sambuc } else { 5436*f4a2713aSLionel Sambuc // Otherwise, we have something. Add it and let semantic analysis try 5437*f4a2713aSLionel Sambuc // to grok it and add the result to the ParamInfo we are building. 5438*f4a2713aSLionel Sambuc 5439*f4a2713aSLionel Sambuc // Inform the actions module about the parameter declarator, so it gets 5440*f4a2713aSLionel Sambuc // added to the current scope. 5441*f4a2713aSLionel Sambuc Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), 5442*f4a2713aSLionel Sambuc ParmDeclarator); 5443*f4a2713aSLionel Sambuc // Parse the default argument, if any. We parse the default 5444*f4a2713aSLionel Sambuc // arguments in all dialects; the semantic analysis in 5445*f4a2713aSLionel Sambuc // ActOnParamDefaultArgument will reject the default argument in 5446*f4a2713aSLionel Sambuc // C. 5447*f4a2713aSLionel Sambuc if (Tok.is(tok::equal)) { 5448*f4a2713aSLionel Sambuc SourceLocation EqualLoc = Tok.getLocation(); 5449*f4a2713aSLionel Sambuc 5450*f4a2713aSLionel Sambuc // Parse the default argument 5451*f4a2713aSLionel Sambuc if (D.getContext() == Declarator::MemberContext) { 5452*f4a2713aSLionel Sambuc // If we're inside a class definition, cache the tokens 5453*f4a2713aSLionel Sambuc // corresponding to the default argument. We'll actually parse 5454*f4a2713aSLionel Sambuc // them when we see the end of the class definition. 5455*f4a2713aSLionel Sambuc // FIXME: Can we use a smart pointer for Toks? 5456*f4a2713aSLionel Sambuc DefArgToks = new CachedTokens; 5457*f4a2713aSLionel Sambuc 5458*f4a2713aSLionel Sambuc if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) { 5459*f4a2713aSLionel Sambuc delete DefArgToks; 5460*f4a2713aSLionel Sambuc DefArgToks = 0; 5461*f4a2713aSLionel Sambuc Actions.ActOnParamDefaultArgumentError(Param); 5462*f4a2713aSLionel Sambuc } else { 5463*f4a2713aSLionel Sambuc // Mark the end of the default argument so that we know when to 5464*f4a2713aSLionel Sambuc // stop when we parse it later on. 5465*f4a2713aSLionel Sambuc Token DefArgEnd; 5466*f4a2713aSLionel Sambuc DefArgEnd.startToken(); 5467*f4a2713aSLionel Sambuc DefArgEnd.setKind(tok::cxx_defaultarg_end); 5468*f4a2713aSLionel Sambuc DefArgEnd.setLocation(Tok.getLocation()); 5469*f4a2713aSLionel Sambuc DefArgToks->push_back(DefArgEnd); 5470*f4a2713aSLionel Sambuc Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, 5471*f4a2713aSLionel Sambuc (*DefArgToks)[1].getLocation()); 5472*f4a2713aSLionel Sambuc } 5473*f4a2713aSLionel Sambuc } else { 5474*f4a2713aSLionel Sambuc // Consume the '='. 5475*f4a2713aSLionel Sambuc ConsumeToken(); 5476*f4a2713aSLionel Sambuc 5477*f4a2713aSLionel Sambuc // The argument isn't actually potentially evaluated unless it is 5478*f4a2713aSLionel Sambuc // used. 5479*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Eval(Actions, 5480*f4a2713aSLionel Sambuc Sema::PotentiallyEvaluatedIfUsed, 5481*f4a2713aSLionel Sambuc Param); 5482*f4a2713aSLionel Sambuc 5483*f4a2713aSLionel Sambuc ExprResult DefArgResult; 5484*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5485*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 5486*f4a2713aSLionel Sambuc DefArgResult = ParseBraceInitializer(); 5487*f4a2713aSLionel Sambuc } else 5488*f4a2713aSLionel Sambuc DefArgResult = ParseAssignmentExpression(); 5489*f4a2713aSLionel Sambuc if (DefArgResult.isInvalid()) { 5490*f4a2713aSLionel Sambuc Actions.ActOnParamDefaultArgumentError(Param); 5491*f4a2713aSLionel Sambuc SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch); 5492*f4a2713aSLionel Sambuc } else { 5493*f4a2713aSLionel Sambuc // Inform the actions module about the default argument 5494*f4a2713aSLionel Sambuc Actions.ActOnParamDefaultArgument(Param, EqualLoc, 5495*f4a2713aSLionel Sambuc DefArgResult.take()); 5496*f4a2713aSLionel Sambuc } 5497*f4a2713aSLionel Sambuc } 5498*f4a2713aSLionel Sambuc } 5499*f4a2713aSLionel Sambuc 5500*f4a2713aSLionel Sambuc ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5501*f4a2713aSLionel Sambuc ParmDeclarator.getIdentifierLoc(), 5502*f4a2713aSLionel Sambuc Param, DefArgToks)); 5503*f4a2713aSLionel Sambuc } 5504*f4a2713aSLionel Sambuc 5505*f4a2713aSLionel Sambuc // If the next token is a comma, consume it and keep reading arguments. 5506*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) { 5507*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) { 5508*f4a2713aSLionel Sambuc EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5509*f4a2713aSLionel Sambuc 5510*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus) { 5511*f4a2713aSLionel Sambuc // We have ellipsis without a preceding ',', which is ill-formed 5512*f4a2713aSLionel Sambuc // in C. Complain and provide the fix. 5513*f4a2713aSLionel Sambuc Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis) 5514*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(EllipsisLoc, ", "); 5515*f4a2713aSLionel Sambuc } 5516*f4a2713aSLionel Sambuc } 5517*f4a2713aSLionel Sambuc 5518*f4a2713aSLionel Sambuc break; 5519*f4a2713aSLionel Sambuc } 5520*f4a2713aSLionel Sambuc 5521*f4a2713aSLionel Sambuc // Consume the comma. 5522*f4a2713aSLionel Sambuc ConsumeToken(); 5523*f4a2713aSLionel Sambuc } 5524*f4a2713aSLionel Sambuc 5525*f4a2713aSLionel Sambuc } 5526*f4a2713aSLionel Sambuc 5527*f4a2713aSLionel Sambuc /// [C90] direct-declarator '[' constant-expression[opt] ']' 5528*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 5529*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 5530*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 5531*f4a2713aSLionel Sambuc /// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 5532*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '[' constant-expression[opt] ']' 5533*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] 5534*f4a2713aSLionel Sambuc void Parser::ParseBracketDeclarator(Declarator &D) { 5535*f4a2713aSLionel Sambuc if (CheckProhibitedCXX11Attribute()) 5536*f4a2713aSLionel Sambuc return; 5537*f4a2713aSLionel Sambuc 5538*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_square); 5539*f4a2713aSLionel Sambuc T.consumeOpen(); 5540*f4a2713aSLionel Sambuc 5541*f4a2713aSLionel Sambuc // C array syntax has many features, but by-far the most common is [] and [4]. 5542*f4a2713aSLionel Sambuc // This code does a fast path to handle some of the most obvious cases. 5543*f4a2713aSLionel Sambuc if (Tok.getKind() == tok::r_square) { 5544*f4a2713aSLionel Sambuc T.consumeClose(); 5545*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 5546*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 5547*f4a2713aSLionel Sambuc 5548*f4a2713aSLionel Sambuc // Remember that we parsed the empty array type. 5549*f4a2713aSLionel Sambuc ExprResult NumElements; 5550*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, 5551*f4a2713aSLionel Sambuc T.getOpenLocation(), 5552*f4a2713aSLionel Sambuc T.getCloseLocation()), 5553*f4a2713aSLionel Sambuc attrs, T.getCloseLocation()); 5554*f4a2713aSLionel Sambuc return; 5555*f4a2713aSLionel Sambuc } else if (Tok.getKind() == tok::numeric_constant && 5556*f4a2713aSLionel Sambuc GetLookAheadToken(1).is(tok::r_square)) { 5557*f4a2713aSLionel Sambuc // [4] is very common. Parse the numeric constant expression. 5558*f4a2713aSLionel Sambuc ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope())); 5559*f4a2713aSLionel Sambuc ConsumeToken(); 5560*f4a2713aSLionel Sambuc 5561*f4a2713aSLionel Sambuc T.consumeClose(); 5562*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 5563*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 5564*f4a2713aSLionel Sambuc 5565*f4a2713aSLionel Sambuc // Remember that we parsed a array type, and remember its features. 5566*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 5567*f4a2713aSLionel Sambuc ExprRes.release(), 5568*f4a2713aSLionel Sambuc T.getOpenLocation(), 5569*f4a2713aSLionel Sambuc T.getCloseLocation()), 5570*f4a2713aSLionel Sambuc attrs, T.getCloseLocation()); 5571*f4a2713aSLionel Sambuc return; 5572*f4a2713aSLionel Sambuc } 5573*f4a2713aSLionel Sambuc 5574*f4a2713aSLionel Sambuc // If valid, this location is the position where we read the 'static' keyword. 5575*f4a2713aSLionel Sambuc SourceLocation StaticLoc; 5576*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_static)) 5577*f4a2713aSLionel Sambuc StaticLoc = ConsumeToken(); 5578*f4a2713aSLionel Sambuc 5579*f4a2713aSLionel Sambuc // If there is a type-qualifier-list, read it now. 5580*f4a2713aSLionel Sambuc // Type qualifiers in an array subscript are a C99 feature. 5581*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 5582*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS, false /*no attributes*/); 5583*f4a2713aSLionel Sambuc 5584*f4a2713aSLionel Sambuc // If we haven't already read 'static', check to see if there is one after the 5585*f4a2713aSLionel Sambuc // type-qualifier-list. 5586*f4a2713aSLionel Sambuc if (!StaticLoc.isValid() && Tok.is(tok::kw_static)) 5587*f4a2713aSLionel Sambuc StaticLoc = ConsumeToken(); 5588*f4a2713aSLionel Sambuc 5589*f4a2713aSLionel Sambuc // Handle "direct-declarator [ type-qual-list[opt] * ]". 5590*f4a2713aSLionel Sambuc bool isStar = false; 5591*f4a2713aSLionel Sambuc ExprResult NumElements; 5592*f4a2713aSLionel Sambuc 5593*f4a2713aSLionel Sambuc // Handle the case where we have '[*]' as the array size. However, a leading 5594*f4a2713aSLionel Sambuc // star could be the start of an expression, for example 'X[*p + 4]'. Verify 5595*f4a2713aSLionel Sambuc // the token after the star is a ']'. Since stars in arrays are 5596*f4a2713aSLionel Sambuc // infrequent, use of lookahead is not costly here. 5597*f4a2713aSLionel Sambuc if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) { 5598*f4a2713aSLionel Sambuc ConsumeToken(); // Eat the '*'. 5599*f4a2713aSLionel Sambuc 5600*f4a2713aSLionel Sambuc if (StaticLoc.isValid()) { 5601*f4a2713aSLionel Sambuc Diag(StaticLoc, diag::err_unspecified_vla_size_with_static); 5602*f4a2713aSLionel Sambuc StaticLoc = SourceLocation(); // Drop the static. 5603*f4a2713aSLionel Sambuc } 5604*f4a2713aSLionel Sambuc isStar = true; 5605*f4a2713aSLionel Sambuc } else if (Tok.isNot(tok::r_square)) { 5606*f4a2713aSLionel Sambuc // Note, in C89, this production uses the constant-expr production instead 5607*f4a2713aSLionel Sambuc // of assignment-expr. The only difference is that assignment-expr allows 5608*f4a2713aSLionel Sambuc // things like '=' and '*='. Sema rejects these in C89 mode because they 5609*f4a2713aSLionel Sambuc // are not i-c-e's, so we don't need to distinguish between the two here. 5610*f4a2713aSLionel Sambuc 5611*f4a2713aSLionel Sambuc // Parse the constant-expression or assignment-expression now (depending 5612*f4a2713aSLionel Sambuc // on dialect). 5613*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 5614*f4a2713aSLionel Sambuc NumElements = ParseConstantExpression(); 5615*f4a2713aSLionel Sambuc } else { 5616*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, 5617*f4a2713aSLionel Sambuc Sema::ConstantEvaluated); 5618*f4a2713aSLionel Sambuc NumElements = ParseAssignmentExpression(); 5619*f4a2713aSLionel Sambuc } 5620*f4a2713aSLionel Sambuc } 5621*f4a2713aSLionel Sambuc 5622*f4a2713aSLionel Sambuc // If there was an error parsing the assignment-expression, recover. 5623*f4a2713aSLionel Sambuc if (NumElements.isInvalid()) { 5624*f4a2713aSLionel Sambuc D.setInvalidType(true); 5625*f4a2713aSLionel Sambuc // If the expression was invalid, skip it. 5626*f4a2713aSLionel Sambuc SkipUntil(tok::r_square, StopAtSemi); 5627*f4a2713aSLionel Sambuc return; 5628*f4a2713aSLionel Sambuc } 5629*f4a2713aSLionel Sambuc 5630*f4a2713aSLionel Sambuc T.consumeClose(); 5631*f4a2713aSLionel Sambuc 5632*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 5633*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 5634*f4a2713aSLionel Sambuc 5635*f4a2713aSLionel Sambuc // Remember that we parsed a array type, and remember its features. 5636*f4a2713aSLionel Sambuc D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), 5637*f4a2713aSLionel Sambuc StaticLoc.isValid(), isStar, 5638*f4a2713aSLionel Sambuc NumElements.release(), 5639*f4a2713aSLionel Sambuc T.getOpenLocation(), 5640*f4a2713aSLionel Sambuc T.getCloseLocation()), 5641*f4a2713aSLionel Sambuc attrs, T.getCloseLocation()); 5642*f4a2713aSLionel Sambuc } 5643*f4a2713aSLionel Sambuc 5644*f4a2713aSLionel Sambuc /// [GNU] typeof-specifier: 5645*f4a2713aSLionel Sambuc /// typeof ( expressions ) 5646*f4a2713aSLionel Sambuc /// typeof ( type-name ) 5647*f4a2713aSLionel Sambuc /// [GNU/C++] typeof unary-expression 5648*f4a2713aSLionel Sambuc /// 5649*f4a2713aSLionel Sambuc void Parser::ParseTypeofSpecifier(DeclSpec &DS) { 5650*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); 5651*f4a2713aSLionel Sambuc Token OpTok = Tok; 5652*f4a2713aSLionel Sambuc SourceLocation StartLoc = ConsumeToken(); 5653*f4a2713aSLionel Sambuc 5654*f4a2713aSLionel Sambuc const bool hasParens = Tok.is(tok::l_paren); 5655*f4a2713aSLionel Sambuc 5656*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 5657*f4a2713aSLionel Sambuc Sema::ReuseLambdaContextDecl); 5658*f4a2713aSLionel Sambuc 5659*f4a2713aSLionel Sambuc bool isCastExpr; 5660*f4a2713aSLionel Sambuc ParsedType CastTy; 5661*f4a2713aSLionel Sambuc SourceRange CastRange; 5662*f4a2713aSLionel Sambuc ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, 5663*f4a2713aSLionel Sambuc CastTy, CastRange); 5664*f4a2713aSLionel Sambuc if (hasParens) 5665*f4a2713aSLionel Sambuc DS.setTypeofParensRange(CastRange); 5666*f4a2713aSLionel Sambuc 5667*f4a2713aSLionel Sambuc if (CastRange.getEnd().isInvalid()) 5668*f4a2713aSLionel Sambuc // FIXME: Not accurate, the range gets one token more than it should. 5669*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLocation()); 5670*f4a2713aSLionel Sambuc else 5671*f4a2713aSLionel Sambuc DS.SetRangeEnd(CastRange.getEnd()); 5672*f4a2713aSLionel Sambuc 5673*f4a2713aSLionel Sambuc if (isCastExpr) { 5674*f4a2713aSLionel Sambuc if (!CastTy) { 5675*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 5676*f4a2713aSLionel Sambuc return; 5677*f4a2713aSLionel Sambuc } 5678*f4a2713aSLionel Sambuc 5679*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 5680*f4a2713aSLionel Sambuc unsigned DiagID; 5681*f4a2713aSLionel Sambuc // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5682*f4a2713aSLionel Sambuc if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 5683*f4a2713aSLionel Sambuc DiagID, CastTy)) 5684*f4a2713aSLionel Sambuc Diag(StartLoc, DiagID) << PrevSpec; 5685*f4a2713aSLionel Sambuc return; 5686*f4a2713aSLionel Sambuc } 5687*f4a2713aSLionel Sambuc 5688*f4a2713aSLionel Sambuc // If we get here, the operand to the typeof was an expresion. 5689*f4a2713aSLionel Sambuc if (Operand.isInvalid()) { 5690*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 5691*f4a2713aSLionel Sambuc return; 5692*f4a2713aSLionel Sambuc } 5693*f4a2713aSLionel Sambuc 5694*f4a2713aSLionel Sambuc // We might need to transform the operand if it is potentially evaluated. 5695*f4a2713aSLionel Sambuc Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get()); 5696*f4a2713aSLionel Sambuc if (Operand.isInvalid()) { 5697*f4a2713aSLionel Sambuc DS.SetTypeSpecError(); 5698*f4a2713aSLionel Sambuc return; 5699*f4a2713aSLionel Sambuc } 5700*f4a2713aSLionel Sambuc 5701*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 5702*f4a2713aSLionel Sambuc unsigned DiagID; 5703*f4a2713aSLionel Sambuc // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5704*f4a2713aSLionel Sambuc if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 5705*f4a2713aSLionel Sambuc DiagID, Operand.get())) 5706*f4a2713aSLionel Sambuc Diag(StartLoc, DiagID) << PrevSpec; 5707*f4a2713aSLionel Sambuc } 5708*f4a2713aSLionel Sambuc 5709*f4a2713aSLionel Sambuc /// [C11] atomic-specifier: 5710*f4a2713aSLionel Sambuc /// _Atomic ( type-name ) 5711*f4a2713aSLionel Sambuc /// 5712*f4a2713aSLionel Sambuc void Parser::ParseAtomicSpecifier(DeclSpec &DS) { 5713*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) && 5714*f4a2713aSLionel Sambuc "Not an atomic specifier"); 5715*f4a2713aSLionel Sambuc 5716*f4a2713aSLionel Sambuc SourceLocation StartLoc = ConsumeToken(); 5717*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 5718*f4a2713aSLionel Sambuc if (T.consumeOpen()) 5719*f4a2713aSLionel Sambuc return; 5720*f4a2713aSLionel Sambuc 5721*f4a2713aSLionel Sambuc TypeResult Result = ParseTypeName(); 5722*f4a2713aSLionel Sambuc if (Result.isInvalid()) { 5723*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 5724*f4a2713aSLionel Sambuc return; 5725*f4a2713aSLionel Sambuc } 5726*f4a2713aSLionel Sambuc 5727*f4a2713aSLionel Sambuc // Match the ')' 5728*f4a2713aSLionel Sambuc T.consumeClose(); 5729*f4a2713aSLionel Sambuc 5730*f4a2713aSLionel Sambuc if (T.getCloseLocation().isInvalid()) 5731*f4a2713aSLionel Sambuc return; 5732*f4a2713aSLionel Sambuc 5733*f4a2713aSLionel Sambuc DS.setTypeofParensRange(T.getRange()); 5734*f4a2713aSLionel Sambuc DS.SetRangeEnd(T.getCloseLocation()); 5735*f4a2713aSLionel Sambuc 5736*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 5737*f4a2713aSLionel Sambuc unsigned DiagID; 5738*f4a2713aSLionel Sambuc if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec, 5739*f4a2713aSLionel Sambuc DiagID, Result.release())) 5740*f4a2713aSLionel Sambuc Diag(StartLoc, DiagID) << PrevSpec; 5741*f4a2713aSLionel Sambuc } 5742*f4a2713aSLionel Sambuc 5743*f4a2713aSLionel Sambuc 5744*f4a2713aSLionel Sambuc /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called 5745*f4a2713aSLionel Sambuc /// from TryAltiVecVectorToken. 5746*f4a2713aSLionel Sambuc bool Parser::TryAltiVecVectorTokenOutOfLine() { 5747*f4a2713aSLionel Sambuc Token Next = NextToken(); 5748*f4a2713aSLionel Sambuc switch (Next.getKind()) { 5749*f4a2713aSLionel Sambuc default: return false; 5750*f4a2713aSLionel Sambuc case tok::kw_short: 5751*f4a2713aSLionel Sambuc case tok::kw_long: 5752*f4a2713aSLionel Sambuc case tok::kw_signed: 5753*f4a2713aSLionel Sambuc case tok::kw_unsigned: 5754*f4a2713aSLionel Sambuc case tok::kw_void: 5755*f4a2713aSLionel Sambuc case tok::kw_char: 5756*f4a2713aSLionel Sambuc case tok::kw_int: 5757*f4a2713aSLionel Sambuc case tok::kw_float: 5758*f4a2713aSLionel Sambuc case tok::kw_double: 5759*f4a2713aSLionel Sambuc case tok::kw_bool: 5760*f4a2713aSLionel Sambuc case tok::kw___pixel: 5761*f4a2713aSLionel Sambuc Tok.setKind(tok::kw___vector); 5762*f4a2713aSLionel Sambuc return true; 5763*f4a2713aSLionel Sambuc case tok::identifier: 5764*f4a2713aSLionel Sambuc if (Next.getIdentifierInfo() == Ident_pixel) { 5765*f4a2713aSLionel Sambuc Tok.setKind(tok::kw___vector); 5766*f4a2713aSLionel Sambuc return true; 5767*f4a2713aSLionel Sambuc } 5768*f4a2713aSLionel Sambuc if (Next.getIdentifierInfo() == Ident_bool) { 5769*f4a2713aSLionel Sambuc Tok.setKind(tok::kw___vector); 5770*f4a2713aSLionel Sambuc return true; 5771*f4a2713aSLionel Sambuc } 5772*f4a2713aSLionel Sambuc return false; 5773*f4a2713aSLionel Sambuc } 5774*f4a2713aSLionel Sambuc } 5775*f4a2713aSLionel Sambuc 5776*f4a2713aSLionel Sambuc bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, 5777*f4a2713aSLionel Sambuc const char *&PrevSpec, unsigned &DiagID, 5778*f4a2713aSLionel Sambuc bool &isInvalid) { 5779*f4a2713aSLionel Sambuc if (Tok.getIdentifierInfo() == Ident_vector) { 5780*f4a2713aSLionel Sambuc Token Next = NextToken(); 5781*f4a2713aSLionel Sambuc switch (Next.getKind()) { 5782*f4a2713aSLionel Sambuc case tok::kw_short: 5783*f4a2713aSLionel Sambuc case tok::kw_long: 5784*f4a2713aSLionel Sambuc case tok::kw_signed: 5785*f4a2713aSLionel Sambuc case tok::kw_unsigned: 5786*f4a2713aSLionel Sambuc case tok::kw_void: 5787*f4a2713aSLionel Sambuc case tok::kw_char: 5788*f4a2713aSLionel Sambuc case tok::kw_int: 5789*f4a2713aSLionel Sambuc case tok::kw_float: 5790*f4a2713aSLionel Sambuc case tok::kw_double: 5791*f4a2713aSLionel Sambuc case tok::kw_bool: 5792*f4a2713aSLionel Sambuc case tok::kw___pixel: 5793*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5794*f4a2713aSLionel Sambuc return true; 5795*f4a2713aSLionel Sambuc case tok::identifier: 5796*f4a2713aSLionel Sambuc if (Next.getIdentifierInfo() == Ident_pixel) { 5797*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5798*f4a2713aSLionel Sambuc return true; 5799*f4a2713aSLionel Sambuc } 5800*f4a2713aSLionel Sambuc if (Next.getIdentifierInfo() == Ident_bool) { 5801*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5802*f4a2713aSLionel Sambuc return true; 5803*f4a2713aSLionel Sambuc } 5804*f4a2713aSLionel Sambuc break; 5805*f4a2713aSLionel Sambuc default: 5806*f4a2713aSLionel Sambuc break; 5807*f4a2713aSLionel Sambuc } 5808*f4a2713aSLionel Sambuc } else if ((Tok.getIdentifierInfo() == Ident_pixel) && 5809*f4a2713aSLionel Sambuc DS.isTypeAltiVecVector()) { 5810*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 5811*f4a2713aSLionel Sambuc return true; 5812*f4a2713aSLionel Sambuc } else if ((Tok.getIdentifierInfo() == Ident_bool) && 5813*f4a2713aSLionel Sambuc DS.isTypeAltiVecVector()) { 5814*f4a2713aSLionel Sambuc isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID); 5815*f4a2713aSLionel Sambuc return true; 5816*f4a2713aSLionel Sambuc } 5817*f4a2713aSLionel Sambuc return false; 5818*f4a2713aSLionel Sambuc } 5819