1193326Sed//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Declaration portions of the Parser interfaces. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Parse/Parser.h" 15249423Sdim#include "RAIIObjectsForParser.h" 16249423Sdim#include "clang/Basic/AddressSpaces.h" 17249423Sdim#include "clang/Basic/CharInfo.h" 18249423Sdim#include "clang/Basic/OpenCL.h" 19193326Sed#include "clang/Parse/ParseDiagnostic.h" 20239462Sdim#include "clang/Sema/Lookup.h" 21212904Sdim#include "clang/Sema/ParsedTemplate.h" 22212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h" 23249423Sdim#include "clang/Sema/Scope.h" 24193326Sed#include "llvm/ADT/SmallSet.h" 25234353Sdim#include "llvm/ADT/SmallString.h" 26226633Sdim#include "llvm/ADT/StringSwitch.h" 27193326Sedusing namespace clang; 28193326Sed 29193326Sed//===----------------------------------------------------------------------===// 30193326Sed// C99 6.7: Declarations. 31193326Sed//===----------------------------------------------------------------------===// 32193326Sed 33193326Sed/// ParseTypeName 34193326Sed/// type-name: [C99 6.7.6] 35193326Sed/// specifier-qualifier-list abstract-declarator[opt] 36193326Sed/// 37193326Sed/// Called type-id in C++. 38218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range, 39224145Sdim Declarator::TheContext Context, 40224145Sdim AccessSpecifier AS, 41249423Sdim Decl **OwnedType, 42249423Sdim ParsedAttributes *Attrs) { 43234353Sdim DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context); 44239462Sdim if (DSC == DSC_normal) 45239462Sdim DSC = DSC_type_specifier; 46234353Sdim 47193326Sed // Parse the common declaration-specifiers piece. 48221345Sdim DeclSpec DS(AttrFactory); 49249423Sdim if (Attrs) 50249423Sdim DS.addAttributes(Attrs->getList()); 51234353Sdim ParseSpecifierQualifierList(DS, AS, DSC); 52224145Sdim if (OwnedType) 53224145Sdim *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; 54193326Sed 55193326Sed // Parse the abstract-declarator, if present. 56218893Sdim Declarator DeclaratorInfo(DS, Context); 57193326Sed ParseDeclarator(DeclaratorInfo); 58193326Sed if (Range) 59193326Sed *Range = DeclaratorInfo.getSourceRange(); 60193326Sed 61193326Sed if (DeclaratorInfo.isInvalidType()) 62193326Sed return true; 63193326Sed 64210299Sed return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 65193326Sed} 66193326Sed 67226633Sdim 68226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that 69226633Sdim/// require late parsing. 70226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) { 71226633Sdim return llvm::StringSwitch<bool>(II.getName()) 72226633Sdim#include "clang/Parse/AttrLateParsed.inc" 73226633Sdim .Default(false); 74226633Sdim} 75226633Sdim 76199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list. 77193326Sed/// 78193326Sed/// [GNU] attributes: 79193326Sed/// attribute 80193326Sed/// attributes attribute 81193326Sed/// 82193326Sed/// [GNU] attribute: 83193326Sed/// '__attribute__' '(' '(' attribute-list ')' ')' 84193326Sed/// 85193326Sed/// [GNU] attribute-list: 86193326Sed/// attrib 87193326Sed/// attribute_list ',' attrib 88193326Sed/// 89193326Sed/// [GNU] attrib: 90193326Sed/// empty 91193326Sed/// attrib-name 92193326Sed/// attrib-name '(' identifier ')' 93193326Sed/// attrib-name '(' identifier ',' nonempty-expr-list ')' 94193326Sed/// attrib-name '(' argument-expression-list [C99 6.5.2] ')' 95193326Sed/// 96193326Sed/// [GNU] attrib-name: 97193326Sed/// identifier 98193326Sed/// typespec 99193326Sed/// typequal 100193326Sed/// storageclass 101198092Srdivacky/// 102193326Sed/// FIXME: The GCC grammar/code for this construct implies we need two 103198092Srdivacky/// token lookahead. Comment from gcc: "If they start with an identifier 104198092Srdivacky/// which is followed by a comma or close parenthesis, then the arguments 105193326Sed/// start with that identifier; otherwise they are an expression list." 106193326Sed/// 107234353Sdim/// GCC does not require the ',' between attribs in an attribute-list. 108234353Sdim/// 109193326Sed/// At the moment, I am not doing 2 token lookahead. I am also unaware of 110193326Sed/// any attributes that don't work (based on my limited testing). Most 111193326Sed/// attributes are very simple in practice. Until we find a bug, I don't see 112193326Sed/// a pressing need to implement the 2 token lookahead. 113193326Sed 114218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs, 115226633Sdim SourceLocation *endLoc, 116226633Sdim LateParsedAttrList *LateAttrs) { 117199990Srdivacky assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); 118198092Srdivacky 119193326Sed while (Tok.is(tok::kw___attribute)) { 120193326Sed ConsumeToken(); 121193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 122193326Sed "attribute")) { 123193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 124218893Sdim return; 125193326Sed } 126193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { 127193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 128218893Sdim return; 129193326Sed } 130193326Sed // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) 131193326Sed while (Tok.is(tok::identifier) || isDeclarationSpecifier() || 132193326Sed Tok.is(tok::comma)) { 133198092Srdivacky if (Tok.is(tok::comma)) { 134193326Sed // allows for empty/non-empty attributes. ((__vector_size__(16),,,,)) 135193326Sed ConsumeToken(); 136193326Sed continue; 137193326Sed } 138193326Sed // we have an identifier or declaration specifier (const, int, etc.) 139193326Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 140193326Sed SourceLocation AttrNameLoc = ConsumeToken(); 141198092Srdivacky 142226633Sdim if (Tok.is(tok::l_paren)) { 143226633Sdim // handle "parameterized" attributes 144234353Sdim if (LateAttrs && isAttributeLateParsed(*AttrName)) { 145226633Sdim LateParsedAttribute *LA = 146226633Sdim new LateParsedAttribute(this, *AttrName, AttrNameLoc); 147226633Sdim LateAttrs->push_back(LA); 148198092Srdivacky 149234353Sdim // Attributes in a class are parsed at the end of the class, along 150234353Sdim // with other late-parsed declarations. 151243830Sdim if (!ClassStack.empty() && !LateAttrs->parseSoon()) 152234353Sdim getCurrentClass().LateParsedDeclarations.push_back(LA); 153234353Sdim 154226633Sdim // consume everything up to and including the matching right parens 155226633Sdim ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false); 156198092Srdivacky 157226633Sdim Token Eof; 158226633Sdim Eof.startToken(); 159226633Sdim Eof.setLocation(Tok.getLocation()); 160226633Sdim LA->Toks.push_back(Eof); 161226633Sdim } else { 162243830Sdim ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, 163243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 164193326Sed } 165193326Sed } else { 166221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 167239462Sdim 0, SourceLocation(), 0, 0, AttributeList::AS_GNU); 168193326Sed } 169193326Sed } 170193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 171193326Sed SkipUntil(tok::r_paren, false); 172199990Srdivacky SourceLocation Loc = Tok.getLocation(); 173193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 174193326Sed SkipUntil(tok::r_paren, false); 175193326Sed } 176218893Sdim if (endLoc) 177218893Sdim *endLoc = Loc; 178193326Sed } 179193326Sed} 180193326Sed 181251662Sdim/// \brief Determine whether the given attribute has all expression arguments. 182251662Sdimstatic bool attributeHasExprArgs(const IdentifierInfo &II) { 183251662Sdim return llvm::StringSwitch<bool>(II.getName()) 184251662Sdim#include "clang/Parse/AttrExprArgs.inc" 185251662Sdim .Default(false); 186251662Sdim} 187226633Sdim 188243830Sdim/// Parse the arguments to a parameterized GNU attribute or 189243830Sdim/// a C++11 attribute in "gnu" namespace. 190226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, 191226633Sdim SourceLocation AttrNameLoc, 192226633Sdim ParsedAttributes &Attrs, 193243830Sdim SourceLocation *EndLoc, 194243830Sdim IdentifierInfo *ScopeName, 195243830Sdim SourceLocation ScopeLoc, 196243830Sdim AttributeList::Syntax Syntax) { 197226633Sdim 198226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 199226633Sdim 200226633Sdim // Availability attributes have their own grammar. 201226633Sdim if (AttrName->isStr("availability")) { 202226633Sdim ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 203226633Sdim return; 204226633Sdim } 205226633Sdim // Thread safety attributes fit into the FIXME case above, so we 206226633Sdim // just parse the arguments as a list of expressions 207226633Sdim if (IsThreadSafetyAttribute(AttrName->getName())) { 208226633Sdim ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 209226633Sdim return; 210226633Sdim } 211239462Sdim // Type safety attributes have their own grammar. 212239462Sdim if (AttrName->isStr("type_tag_for_datatype")) { 213239462Sdim ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 214239462Sdim return; 215239462Sdim } 216226633Sdim 217226633Sdim ConsumeParen(); // ignore the left paren loc for now 218226633Sdim 219234353Sdim IdentifierInfo *ParmName = 0; 220234353Sdim SourceLocation ParmLoc; 221234353Sdim bool BuiltinType = false; 222226633Sdim 223249423Sdim TypeResult T; 224249423Sdim SourceRange TypeRange; 225249423Sdim bool TypeParsed = false; 226249423Sdim 227234353Sdim switch (Tok.getKind()) { 228234353Sdim case tok::kw_char: 229234353Sdim case tok::kw_wchar_t: 230234353Sdim case tok::kw_char16_t: 231234353Sdim case tok::kw_char32_t: 232234353Sdim case tok::kw_bool: 233234353Sdim case tok::kw_short: 234234353Sdim case tok::kw_int: 235234353Sdim case tok::kw_long: 236234353Sdim case tok::kw___int64: 237234353Sdim case tok::kw___int128: 238234353Sdim case tok::kw_signed: 239234353Sdim case tok::kw_unsigned: 240234353Sdim case tok::kw_float: 241234353Sdim case tok::kw_double: 242234353Sdim case tok::kw_void: 243234353Sdim case tok::kw_typeof: 244234353Sdim // __attribute__(( vec_type_hint(char) )) 245234353Sdim BuiltinType = true; 246249423Sdim T = ParseTypeName(&TypeRange); 247249423Sdim TypeParsed = true; 248234353Sdim break; 249234353Sdim 250234353Sdim case tok::identifier: 251249423Sdim if (AttrName->isStr("vec_type_hint")) { 252249423Sdim T = ParseTypeName(&TypeRange); 253249423Sdim TypeParsed = true; 254249423Sdim break; 255249423Sdim } 256251662Sdim // If the attribute has all expression arguments, and not a "parameter", 257251662Sdim // break out to handle it below. 258251662Sdim if (attributeHasExprArgs(*AttrName)) 259251662Sdim break; 260234353Sdim ParmName = Tok.getIdentifierInfo(); 261234353Sdim ParmLoc = ConsumeToken(); 262234353Sdim break; 263234353Sdim 264234353Sdim default: 265234353Sdim break; 266234353Sdim } 267234353Sdim 268243830Sdim ExprVector ArgExprs; 269249423Sdim bool isInvalid = false; 270249423Sdim bool isParmType = false; 271234353Sdim 272249423Sdim if (!BuiltinType && !AttrName->isStr("vec_type_hint") && 273234353Sdim (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) { 274234353Sdim // Eat the comma. 275234353Sdim if (ParmLoc.isValid()) 276226633Sdim ConsumeToken(); 277226633Sdim 278234353Sdim // Parse the non-empty comma-separated list of expressions. 279234353Sdim while (1) { 280234353Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 281234353Sdim if (ArgExpr.isInvalid()) { 282234353Sdim SkipUntil(tok::r_paren); 283234353Sdim return; 284226633Sdim } 285234353Sdim ArgExprs.push_back(ArgExpr.release()); 286234353Sdim if (Tok.isNot(tok::comma)) 287234353Sdim break; 288234353Sdim ConsumeToken(); // Eat the comma, move to the next argument 289226633Sdim } 290234353Sdim } 291234353Sdim else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) { 292234353Sdim if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<", 293234353Sdim tok::greater)) { 294234353Sdim while (Tok.is(tok::identifier)) { 295234353Sdim ConsumeToken(); 296234353Sdim if (Tok.is(tok::greater)) 297226633Sdim break; 298234353Sdim if (Tok.is(tok::comma)) { 299234353Sdim ConsumeToken(); 300234353Sdim continue; 301226633Sdim } 302226633Sdim } 303234353Sdim if (Tok.isNot(tok::greater)) 304234353Sdim Diag(Tok, diag::err_iboutletcollection_with_protocol); 305234353Sdim SkipUntil(tok::r_paren, false, true); // skip until ')' 306226633Sdim } 307249423Sdim } else if (AttrName->isStr("vec_type_hint")) { 308249423Sdim if (T.get() && !T.isInvalid()) 309249423Sdim isParmType = true; 310249423Sdim else { 311249423Sdim if (Tok.is(tok::identifier)) 312249423Sdim ConsumeToken(); 313249423Sdim if (TypeParsed) 314249423Sdim isInvalid = true; 315249423Sdim } 316226633Sdim } 317234353Sdim 318234353Sdim SourceLocation RParen = Tok.getLocation(); 319249423Sdim if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen) && 320249423Sdim !isInvalid) { 321243830Sdim SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc; 322249423Sdim if (isParmType) { 323249423Sdim Attrs.addNewTypeAttr(AttrName, SourceRange(AttrLoc, RParen), ScopeName, 324249423Sdim ScopeLoc, ParmName, ParmLoc, T.get(), Syntax); 325249423Sdim } else { 326249423Sdim AttributeList *attr = Attrs.addNew( 327249423Sdim AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc, ParmName, 328249423Sdim ParmLoc, ArgExprs.data(), ArgExprs.size(), Syntax); 329249423Sdim if (BuiltinType && 330249423Sdim attr->getKind() == AttributeList::AT_IBOutletCollection) 331249423Sdim Diag(Tok, diag::err_iboutletcollection_builtintype); 332249423Sdim } 333234353Sdim } 334226633Sdim} 335226633Sdim 336239462Sdim/// \brief Parses a single argument for a declspec, including the 337239462Sdim/// surrounding parens. 338239462Sdimvoid Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, 339239462Sdim SourceLocation AttrNameLoc, 340239462Sdim ParsedAttributes &Attrs) 341239462Sdim{ 342239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 343239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 344239462Sdim AttrName->getNameStart(), tok::r_paren)) 345239462Sdim return; 346226633Sdim 347239462Sdim ExprResult ArgExpr(ParseConstantExpression()); 348239462Sdim if (ArgExpr.isInvalid()) { 349239462Sdim T.skipToEnd(); 350239462Sdim return; 351239462Sdim } 352239462Sdim Expr *ExprList = ArgExpr.take(); 353239462Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 354239462Sdim &ExprList, 1, AttributeList::AS_Declspec); 355239462Sdim 356239462Sdim T.consumeClose(); 357239462Sdim} 358239462Sdim 359239462Sdim/// \brief Determines whether a declspec is a "simple" one requiring no 360239462Sdim/// arguments. 361239462Sdimbool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) { 362239462Sdim return llvm::StringSwitch<bool>(Ident->getName()) 363239462Sdim .Case("dllimport", true) 364239462Sdim .Case("dllexport", true) 365239462Sdim .Case("noreturn", true) 366239462Sdim .Case("nothrow", true) 367239462Sdim .Case("noinline", true) 368239462Sdim .Case("naked", true) 369239462Sdim .Case("appdomain", true) 370239462Sdim .Case("process", true) 371239462Sdim .Case("jitintrinsic", true) 372239462Sdim .Case("noalias", true) 373239462Sdim .Case("restrict", true) 374239462Sdim .Case("novtable", true) 375239462Sdim .Case("selectany", true) 376239462Sdim .Case("thread", true) 377251662Sdim .Case("safebuffers", true ) 378239462Sdim .Default(false); 379239462Sdim} 380239462Sdim 381239462Sdim/// \brief Attempts to parse a declspec which is not simple (one that takes 382239462Sdim/// parameters). Will return false if we properly handled the declspec, or 383239462Sdim/// true if it is an unknown declspec. 384239462Sdimvoid Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, 385239462Sdim SourceLocation Loc, 386239462Sdim ParsedAttributes &Attrs) { 387239462Sdim // Try to handle the easy case first -- these declspecs all take a single 388239462Sdim // parameter as their argument. 389239462Sdim if (llvm::StringSwitch<bool>(Ident->getName()) 390239462Sdim .Case("uuid", true) 391239462Sdim .Case("align", true) 392239462Sdim .Case("allocate", true) 393239462Sdim .Default(false)) { 394239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 395239462Sdim } else if (Ident->getName() == "deprecated") { 396239462Sdim // The deprecated declspec has an optional single argument, so we will 397239462Sdim // check for a l-paren to decide whether we should parse an argument or 398239462Sdim // not. 399239462Sdim if (Tok.getKind() == tok::l_paren) 400239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 401239462Sdim else 402239462Sdim Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0, 403239462Sdim AttributeList::AS_Declspec); 404239462Sdim } else if (Ident->getName() == "property") { 405239462Sdim // The property declspec is more complex in that it can take one or two 406239462Sdim // assignment expressions as a parameter, but the lhs of the assignment 407239462Sdim // must be named get or put. 408251662Sdim if (Tok.isNot(tok::l_paren)) { 409251662Sdim Diag(Tok.getLocation(), diag::err_expected_lparen_after) 410251662Sdim << Ident->getNameStart(); 411251662Sdim return; 412251662Sdim } 413239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 414251662Sdim T.expectAndConsume(diag::err_expected_lparen_after, 415251662Sdim Ident->getNameStart(), tok::r_paren); 416251662Sdim 417251662Sdim enum AccessorKind { 418251662Sdim AK_Invalid = -1, 419251662Sdim AK_Put = 0, AK_Get = 1 // indices into AccessorNames 420251662Sdim }; 421251662Sdim IdentifierInfo *AccessorNames[] = { 0, 0 }; 422251662Sdim bool HasInvalidAccessor = false; 423251662Sdim 424251662Sdim // Parse the accessor specifications. 425251662Sdim while (true) { 426251662Sdim // Stop if this doesn't look like an accessor spec. 427251662Sdim if (!Tok.is(tok::identifier)) { 428251662Sdim // If the user wrote a completely empty list, use a special diagnostic. 429251662Sdim if (Tok.is(tok::r_paren) && !HasInvalidAccessor && 430251662Sdim AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) { 431251662Sdim Diag(Loc, diag::err_ms_property_no_getter_or_putter); 432251662Sdim break; 433251662Sdim } 434251662Sdim 435251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor); 436251662Sdim break; 437251662Sdim } 438251662Sdim 439251662Sdim AccessorKind Kind; 440251662Sdim SourceLocation KindLoc = Tok.getLocation(); 441251662Sdim StringRef KindStr = Tok.getIdentifierInfo()->getName(); 442251662Sdim if (KindStr == "get") { 443251662Sdim Kind = AK_Get; 444251662Sdim } else if (KindStr == "put") { 445251662Sdim Kind = AK_Put; 446251662Sdim 447251662Sdim // Recover from the common mistake of using 'set' instead of 'put'. 448251662Sdim } else if (KindStr == "set") { 449251662Sdim Diag(KindLoc, diag::err_ms_property_has_set_accessor) 450251662Sdim << FixItHint::CreateReplacement(KindLoc, "put"); 451251662Sdim Kind = AK_Put; 452251662Sdim 453251662Sdim // Handle the mistake of forgetting the accessor kind by skipping 454251662Sdim // this accessor. 455251662Sdim } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) { 456251662Sdim Diag(KindLoc, diag::err_ms_property_missing_accessor_kind); 457251662Sdim ConsumeToken(); 458251662Sdim HasInvalidAccessor = true; 459251662Sdim goto next_property_accessor; 460251662Sdim 461251662Sdim // Otherwise, complain about the unknown accessor kind. 462251662Sdim } else { 463251662Sdim Diag(KindLoc, diag::err_ms_property_unknown_accessor); 464251662Sdim HasInvalidAccessor = true; 465251662Sdim Kind = AK_Invalid; 466251662Sdim 467251662Sdim // Try to keep parsing unless it doesn't look like an accessor spec. 468251662Sdim if (!NextToken().is(tok::equal)) break; 469251662Sdim } 470251662Sdim 471251662Sdim // Consume the identifier. 472251662Sdim ConsumeToken(); 473251662Sdim 474251662Sdim // Consume the '='. 475251662Sdim if (Tok.is(tok::equal)) { 476251662Sdim ConsumeToken(); 477251662Sdim } else { 478251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_equal) 479251662Sdim << KindStr; 480251662Sdim break; 481251662Sdim } 482251662Sdim 483251662Sdim // Expect the method name. 484251662Sdim if (!Tok.is(tok::identifier)) { 485251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name); 486251662Sdim break; 487251662Sdim } 488251662Sdim 489251662Sdim if (Kind == AK_Invalid) { 490251662Sdim // Just drop invalid accessors. 491251662Sdim } else if (AccessorNames[Kind] != NULL) { 492251662Sdim // Complain about the repeated accessor, ignore it, and keep parsing. 493251662Sdim Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr; 494251662Sdim } else { 495251662Sdim AccessorNames[Kind] = Tok.getIdentifierInfo(); 496251662Sdim } 497251662Sdim ConsumeToken(); 498251662Sdim 499251662Sdim next_property_accessor: 500251662Sdim // Keep processing accessors until we run out. 501251662Sdim if (Tok.is(tok::comma)) { 502251662Sdim ConsumeAnyToken(); 503251662Sdim continue; 504251662Sdim 505251662Sdim // If we run into the ')', stop without consuming it. 506251662Sdim } else if (Tok.is(tok::r_paren)) { 507251662Sdim break; 508251662Sdim } else { 509251662Sdim Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen); 510251662Sdim break; 511251662Sdim } 512251662Sdim } 513251662Sdim 514251662Sdim // Only add the property attribute if it was well-formed. 515251662Sdim if (!HasInvalidAccessor) { 516251662Sdim Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(), 0, 517251662Sdim SourceLocation(), 518251662Sdim AccessorNames[AK_Get], AccessorNames[AK_Put], 519251662Sdim AttributeList::AS_Declspec); 520251662Sdim } 521239462Sdim T.skipToEnd(); 522239462Sdim } else { 523239462Sdim // We don't recognize this as a valid declspec, but instead of creating the 524239462Sdim // attribute and allowing sema to warn about it, we will warn here instead. 525239462Sdim // This is because some attributes have multiple spellings, but we need to 526239462Sdim // disallow that for declspecs (such as align vs aligned). If we made the 527239462Sdim // attribute, we'd have to split the valid declspec spelling logic into 528239462Sdim // both locations. 529239462Sdim Diag(Loc, diag::warn_ms_declspec_unknown) << Ident; 530239462Sdim 531239462Sdim // If there's an open paren, we should eat the open and close parens under 532239462Sdim // the assumption that this unknown declspec has parameters. 533239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 534239462Sdim if (!T.consumeOpen()) 535239462Sdim T.skipToEnd(); 536239462Sdim } 537239462Sdim} 538239462Sdim 539193725Sed/// [MS] decl-specifier: 540193725Sed/// __declspec ( extended-decl-modifier-seq ) 541193725Sed/// 542193725Sed/// [MS] extended-decl-modifier-seq: 543193725Sed/// extended-decl-modifier[opt] 544193725Sed/// extended-decl-modifier extended-decl-modifier-seq 545239462Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) { 546193326Sed assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); 547193725Sed 548193326Sed ConsumeToken(); 549239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 550239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec", 551239462Sdim tok::r_paren)) 552218893Sdim return; 553223017Sdim 554239462Sdim // An empty declspec is perfectly legal and should not warn. Additionally, 555239462Sdim // you can specify multiple attributes per declspec. 556239462Sdim while (Tok.getKind() != tok::r_paren) { 557239462Sdim // We expect either a well-known identifier or a generic string. Anything 558239462Sdim // else is a malformed declspec. 559239462Sdim bool IsString = Tok.getKind() == tok::string_literal ? true : false; 560239462Sdim if (!IsString && Tok.getKind() != tok::identifier && 561239462Sdim Tok.getKind() != tok::kw_restrict) { 562239462Sdim Diag(Tok, diag::err_ms_declspec_type); 563239462Sdim T.skipToEnd(); 564239462Sdim return; 565223017Sdim } 566239462Sdim 567239462Sdim IdentifierInfo *AttrName; 568239462Sdim SourceLocation AttrNameLoc; 569239462Sdim if (IsString) { 570239462Sdim SmallString<8> StrBuffer; 571239462Sdim bool Invalid = false; 572239462Sdim StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid); 573239462Sdim if (Invalid) { 574239462Sdim T.skipToEnd(); 575239462Sdim return; 576193725Sed } 577239462Sdim AttrName = PP.getIdentifierInfo(Str); 578239462Sdim AttrNameLoc = ConsumeStringToken(); 579193725Sed } else { 580239462Sdim AttrName = Tok.getIdentifierInfo(); 581239462Sdim AttrNameLoc = ConsumeToken(); 582193725Sed } 583239462Sdim 584239462Sdim if (IsString || IsSimpleMicrosoftDeclSpec(AttrName)) 585239462Sdim // If we have a generic string, we will allow it because there is no 586239462Sdim // documented list of allowable string declspecs, but we know they exist 587239462Sdim // (for instance, SAL declspecs in older versions of MSVC). 588239462Sdim // 589239462Sdim // Alternatively, if the identifier is a simple one, then it requires no 590239462Sdim // arguments and can be turned into an attribute directly. 591239462Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 592239462Sdim 0, 0, AttributeList::AS_Declspec); 593239462Sdim else 594239462Sdim ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs); 595193725Sed } 596239462Sdim T.consumeClose(); 597193326Sed} 598193326Sed 599218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { 600194179Sed // Treat these like attributes 601194179Sed while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || 602208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || 603226633Sdim Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 604249423Sdim Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) { 605194179Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 606194179Sed SourceLocation AttrNameLoc = ConsumeToken(); 607221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 608249423Sdim SourceLocation(), 0, 0, AttributeList::AS_Keyword); 609194179Sed } 610194179Sed} 611194179Sed 612218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { 613212904Sdim // Treat these like attributes 614212904Sdim while (Tok.is(tok::kw___pascal)) { 615212904Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 616212904Sdim SourceLocation AttrNameLoc = ConsumeToken(); 617221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 618249423Sdim SourceLocation(), 0, 0, AttributeList::AS_Keyword); 619212904Sdim } 620212904Sdim} 621212904Sdim 622218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { 623218893Sdim // Treat these like attributes 624218893Sdim while (Tok.is(tok::kw___kernel)) { 625249423Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 626218893Sdim SourceLocation AttrNameLoc = ConsumeToken(); 627249423Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 628249423Sdim SourceLocation(), 0, 0, AttributeList::AS_Keyword); 629218893Sdim } 630218893Sdim} 631218893Sdim 632221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) { 633249423Sdim // FIXME: The mapping from attribute spelling to semantics should be 634249423Sdim // performed in Sema, not here. 635221345Sdim SourceLocation Loc = Tok.getLocation(); 636221345Sdim switch(Tok.getKind()) { 637221345Sdim // OpenCL qualifiers: 638221345Sdim case tok::kw___private: 639239462Sdim case tok::kw_private: 640221345Sdim DS.getAttributes().addNewInteger( 641239462Sdim Actions.getASTContext(), 642221345Sdim PP.getIdentifierInfo("address_space"), Loc, 0); 643221345Sdim break; 644239462Sdim 645221345Sdim case tok::kw___global: 646221345Sdim DS.getAttributes().addNewInteger( 647221345Sdim Actions.getASTContext(), 648221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global); 649221345Sdim break; 650239462Sdim 651221345Sdim case tok::kw___local: 652221345Sdim DS.getAttributes().addNewInteger( 653221345Sdim Actions.getASTContext(), 654221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local); 655221345Sdim break; 656239462Sdim 657221345Sdim case tok::kw___constant: 658221345Sdim DS.getAttributes().addNewInteger( 659221345Sdim Actions.getASTContext(), 660221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant); 661221345Sdim break; 662239462Sdim 663221345Sdim case tok::kw___read_only: 664221345Sdim DS.getAttributes().addNewInteger( 665239462Sdim Actions.getASTContext(), 666221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only); 667221345Sdim break; 668239462Sdim 669221345Sdim case tok::kw___write_only: 670221345Sdim DS.getAttributes().addNewInteger( 671239462Sdim Actions.getASTContext(), 672221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only); 673221345Sdim break; 674239462Sdim 675221345Sdim case tok::kw___read_write: 676221345Sdim DS.getAttributes().addNewInteger( 677221345Sdim Actions.getASTContext(), 678221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write); 679221345Sdim break; 680221345Sdim default: break; 681221345Sdim } 682221345Sdim} 683221345Sdim 684221345Sdim/// \brief Parse a version number. 685221345Sdim/// 686221345Sdim/// version: 687221345Sdim/// simple-integer 688221345Sdim/// simple-integer ',' simple-integer 689221345Sdim/// simple-integer ',' simple-integer ',' simple-integer 690221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) { 691221345Sdim Range = Tok.getLocation(); 692221345Sdim 693221345Sdim if (!Tok.is(tok::numeric_constant)) { 694221345Sdim Diag(Tok, diag::err_expected_version); 695221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 696221345Sdim return VersionTuple(); 697221345Sdim } 698221345Sdim 699221345Sdim // Parse the major (and possibly minor and subminor) versions, which 700221345Sdim // are stored in the numeric constant. We utilize a quirk of the 701221345Sdim // lexer, which is that it handles something like 1.2.3 as a single 702221345Sdim // numeric constant, rather than two separate tokens. 703234353Sdim SmallString<512> Buffer; 704221345Sdim Buffer.resize(Tok.getLength()+1); 705221345Sdim const char *ThisTokBegin = &Buffer[0]; 706221345Sdim 707221345Sdim // Get the spelling of the token, which eliminates trigraphs, etc. 708221345Sdim bool Invalid = false; 709221345Sdim unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid); 710221345Sdim if (Invalid) 711221345Sdim return VersionTuple(); 712221345Sdim 713221345Sdim // Parse the major version. 714221345Sdim unsigned AfterMajor = 0; 715221345Sdim unsigned Major = 0; 716249423Sdim while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) { 717221345Sdim Major = Major * 10 + ThisTokBegin[AfterMajor] - '0'; 718221345Sdim ++AfterMajor; 719221345Sdim } 720221345Sdim 721221345Sdim if (AfterMajor == 0) { 722221345Sdim Diag(Tok, diag::err_expected_version); 723221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 724221345Sdim return VersionTuple(); 725221345Sdim } 726221345Sdim 727221345Sdim if (AfterMajor == ActualLength) { 728221345Sdim ConsumeToken(); 729221345Sdim 730221345Sdim // We only had a single version component. 731221345Sdim if (Major == 0) { 732221345Sdim Diag(Tok, diag::err_zero_version); 733221345Sdim return VersionTuple(); 734221345Sdim } 735221345Sdim 736221345Sdim return VersionTuple(Major); 737221345Sdim } 738221345Sdim 739221345Sdim if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { 740221345Sdim Diag(Tok, diag::err_expected_version); 741221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 742221345Sdim return VersionTuple(); 743221345Sdim } 744221345Sdim 745221345Sdim // Parse the minor version. 746221345Sdim unsigned AfterMinor = AfterMajor + 1; 747221345Sdim unsigned Minor = 0; 748249423Sdim while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) { 749221345Sdim Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0'; 750221345Sdim ++AfterMinor; 751221345Sdim } 752221345Sdim 753221345Sdim if (AfterMinor == ActualLength) { 754221345Sdim ConsumeToken(); 755239462Sdim 756221345Sdim // We had major.minor. 757221345Sdim if (Major == 0 && Minor == 0) { 758221345Sdim Diag(Tok, diag::err_zero_version); 759221345Sdim return VersionTuple(); 760221345Sdim } 761221345Sdim 762239462Sdim return VersionTuple(Major, Minor); 763221345Sdim } 764221345Sdim 765221345Sdim // If what follows is not a '.', we have a problem. 766221345Sdim if (ThisTokBegin[AfterMinor] != '.') { 767221345Sdim Diag(Tok, diag::err_expected_version); 768221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 769239462Sdim return VersionTuple(); 770221345Sdim } 771221345Sdim 772221345Sdim // Parse the subminor version. 773221345Sdim unsigned AfterSubminor = AfterMinor + 1; 774221345Sdim unsigned Subminor = 0; 775249423Sdim while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) { 776221345Sdim Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0'; 777221345Sdim ++AfterSubminor; 778221345Sdim } 779221345Sdim 780221345Sdim if (AfterSubminor != ActualLength) { 781221345Sdim Diag(Tok, diag::err_expected_version); 782221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 783221345Sdim return VersionTuple(); 784221345Sdim } 785221345Sdim ConsumeToken(); 786221345Sdim return VersionTuple(Major, Minor, Subminor); 787221345Sdim} 788221345Sdim 789221345Sdim/// \brief Parse the contents of the "availability" attribute. 790221345Sdim/// 791221345Sdim/// availability-attribute: 792234353Sdim/// 'availability' '(' platform ',' version-arg-list, opt-message')' 793221345Sdim/// 794221345Sdim/// platform: 795221345Sdim/// identifier 796221345Sdim/// 797221345Sdim/// version-arg-list: 798221345Sdim/// version-arg 799221345Sdim/// version-arg ',' version-arg-list 800221345Sdim/// 801221345Sdim/// version-arg: 802221345Sdim/// 'introduced' '=' version 803221345Sdim/// 'deprecated' '=' version 804234353Sdim/// 'obsoleted' = version 805221345Sdim/// 'unavailable' 806234353Sdim/// opt-message: 807234353Sdim/// 'message' '=' <string> 808221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, 809221345Sdim SourceLocation AvailabilityLoc, 810221345Sdim ParsedAttributes &attrs, 811221345Sdim SourceLocation *endLoc) { 812221345Sdim SourceLocation PlatformLoc; 813221345Sdim IdentifierInfo *Platform = 0; 814221345Sdim 815221345Sdim enum { Introduced, Deprecated, Obsoleted, Unknown }; 816221345Sdim AvailabilityChange Changes[Unknown]; 817234353Sdim ExprResult MessageExpr; 818221345Sdim 819221345Sdim // Opening '('. 820226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 821226633Sdim if (T.consumeOpen()) { 822221345Sdim Diag(Tok, diag::err_expected_lparen); 823221345Sdim return; 824221345Sdim } 825221345Sdim 826221345Sdim // Parse the platform name, 827221345Sdim if (Tok.isNot(tok::identifier)) { 828221345Sdim Diag(Tok, diag::err_availability_expected_platform); 829221345Sdim SkipUntil(tok::r_paren); 830221345Sdim return; 831221345Sdim } 832221345Sdim Platform = Tok.getIdentifierInfo(); 833221345Sdim PlatformLoc = ConsumeToken(); 834221345Sdim 835221345Sdim // Parse the ',' following the platform name. 836221345Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) 837221345Sdim return; 838221345Sdim 839221345Sdim // If we haven't grabbed the pointers for the identifiers 840221345Sdim // "introduced", "deprecated", and "obsoleted", do so now. 841221345Sdim if (!Ident_introduced) { 842221345Sdim Ident_introduced = PP.getIdentifierInfo("introduced"); 843221345Sdim Ident_deprecated = PP.getIdentifierInfo("deprecated"); 844221345Sdim Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); 845221345Sdim Ident_unavailable = PP.getIdentifierInfo("unavailable"); 846234353Sdim Ident_message = PP.getIdentifierInfo("message"); 847221345Sdim } 848221345Sdim 849221345Sdim // Parse the set of introductions/deprecations/removals. 850221345Sdim SourceLocation UnavailableLoc; 851221345Sdim do { 852221345Sdim if (Tok.isNot(tok::identifier)) { 853221345Sdim Diag(Tok, diag::err_availability_expected_change); 854221345Sdim SkipUntil(tok::r_paren); 855221345Sdim return; 856221345Sdim } 857221345Sdim IdentifierInfo *Keyword = Tok.getIdentifierInfo(); 858221345Sdim SourceLocation KeywordLoc = ConsumeToken(); 859221345Sdim 860221345Sdim if (Keyword == Ident_unavailable) { 861221345Sdim if (UnavailableLoc.isValid()) { 862221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 863221345Sdim << Keyword << SourceRange(UnavailableLoc); 864239462Sdim } 865221345Sdim UnavailableLoc = KeywordLoc; 866221345Sdim 867221345Sdim if (Tok.isNot(tok::comma)) 868221345Sdim break; 869221345Sdim 870221345Sdim ConsumeToken(); 871221345Sdim continue; 872239462Sdim } 873239462Sdim 874221345Sdim if (Tok.isNot(tok::equal)) { 875221345Sdim Diag(Tok, diag::err_expected_equal_after) 876221345Sdim << Keyword; 877221345Sdim SkipUntil(tok::r_paren); 878221345Sdim return; 879221345Sdim } 880221345Sdim ConsumeToken(); 881234353Sdim if (Keyword == Ident_message) { 882234353Sdim if (!isTokenStringLiteral()) { 883249423Sdim Diag(Tok, diag::err_expected_string_literal) 884249423Sdim << /*Source='availability attribute'*/2; 885234353Sdim SkipUntil(tok::r_paren); 886234353Sdim return; 887234353Sdim } 888234353Sdim MessageExpr = ParseStringLiteralExpression(); 889234353Sdim break; 890234353Sdim } 891239462Sdim 892221345Sdim SourceRange VersionRange; 893221345Sdim VersionTuple Version = ParseVersionTuple(VersionRange); 894239462Sdim 895221345Sdim if (Version.empty()) { 896221345Sdim SkipUntil(tok::r_paren); 897221345Sdim return; 898221345Sdim } 899221345Sdim 900221345Sdim unsigned Index; 901221345Sdim if (Keyword == Ident_introduced) 902221345Sdim Index = Introduced; 903221345Sdim else if (Keyword == Ident_deprecated) 904221345Sdim Index = Deprecated; 905221345Sdim else if (Keyword == Ident_obsoleted) 906221345Sdim Index = Obsoleted; 907239462Sdim else 908221345Sdim Index = Unknown; 909221345Sdim 910221345Sdim if (Index < Unknown) { 911221345Sdim if (!Changes[Index].KeywordLoc.isInvalid()) { 912221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 913239462Sdim << Keyword 914221345Sdim << SourceRange(Changes[Index].KeywordLoc, 915221345Sdim Changes[Index].VersionRange.getEnd()); 916221345Sdim } 917221345Sdim 918221345Sdim Changes[Index].KeywordLoc = KeywordLoc; 919221345Sdim Changes[Index].Version = Version; 920221345Sdim Changes[Index].VersionRange = VersionRange; 921221345Sdim } else { 922221345Sdim Diag(KeywordLoc, diag::err_availability_unknown_change) 923221345Sdim << Keyword << VersionRange; 924221345Sdim } 925221345Sdim 926221345Sdim if (Tok.isNot(tok::comma)) 927221345Sdim break; 928221345Sdim 929221345Sdim ConsumeToken(); 930221345Sdim } while (true); 931221345Sdim 932221345Sdim // Closing ')'. 933226633Sdim if (T.consumeClose()) 934221345Sdim return; 935221345Sdim 936221345Sdim if (endLoc) 937226633Sdim *endLoc = T.getCloseLocation(); 938221345Sdim 939221345Sdim // The 'unavailable' availability cannot be combined with any other 940221345Sdim // availability changes. Make sure that hasn't happened. 941221345Sdim if (UnavailableLoc.isValid()) { 942221345Sdim bool Complained = false; 943221345Sdim for (unsigned Index = Introduced; Index != Unknown; ++Index) { 944221345Sdim if (Changes[Index].KeywordLoc.isValid()) { 945221345Sdim if (!Complained) { 946221345Sdim Diag(UnavailableLoc, diag::warn_availability_and_unavailable) 947221345Sdim << SourceRange(Changes[Index].KeywordLoc, 948221345Sdim Changes[Index].VersionRange.getEnd()); 949221345Sdim Complained = true; 950221345Sdim } 951221345Sdim 952221345Sdim // Clear out the availability. 953221345Sdim Changes[Index] = AvailabilityChange(); 954221345Sdim } 955221345Sdim } 956221345Sdim } 957221345Sdim 958221345Sdim // Record this attribute 959239462Sdim attrs.addNew(&Availability, 960239462Sdim SourceRange(AvailabilityLoc, T.getCloseLocation()), 961234353Sdim 0, AvailabilityLoc, 962221345Sdim Platform, PlatformLoc, 963221345Sdim Changes[Introduced], 964221345Sdim Changes[Deprecated], 965239462Sdim Changes[Obsoleted], 966234353Sdim UnavailableLoc, MessageExpr.take(), 967239462Sdim AttributeList::AS_GNU); 968221345Sdim} 969221345Sdim 970226633Sdim 971226633Sdim// Late Parsed Attributes: 972226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods 973226633Sdim 974226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {} 975226633Sdim 976226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() { 977226633Sdim Self->ParseLexedAttributes(*Class); 978226633Sdim} 979226633Sdim 980226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() { 981234353Sdim Self->ParseLexedAttribute(*this, true, false); 982226633Sdim} 983226633Sdim 984226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the 985226633Sdim/// scope appropriately. 986226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) { 987226633Sdim // Deal with templates 988226633Sdim // FIXME: Test cases to make sure this does the right thing for templates. 989226633Sdim bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 990226633Sdim ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 991226633Sdim HasTemplateScope); 992226633Sdim if (HasTemplateScope) 993226633Sdim Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 994226633Sdim 995234982Sdim // Set or update the scope flags. 996226633Sdim bool AlreadyHasClassScope = Class.TopLevelClass; 997234982Sdim unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; 998226633Sdim ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 999226633Sdim ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 1000226633Sdim 1001234353Sdim // Enter the scope of nested classes 1002234353Sdim if (!AlreadyHasClassScope) 1003234353Sdim Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 1004234353Sdim Class.TagOrTemplate); 1005239462Sdim if (!Class.LateParsedDeclarations.empty()) { 1006234982Sdim for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ 1007234982Sdim Class.LateParsedDeclarations[i]->ParseLexedAttributes(); 1008234982Sdim } 1009226633Sdim } 1010239462Sdim 1011234353Sdim if (!AlreadyHasClassScope) 1012234353Sdim Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 1013234353Sdim Class.TagOrTemplate); 1014226633Sdim} 1015226633Sdim 1016234353Sdim 1017234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D. 1018234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 1019234353Sdim bool EnterScope, bool OnDefinition) { 1020243830Sdim assert(LAs.parseSoon() && 1021243830Sdim "Attribute list should be marked for immediate parsing."); 1022234353Sdim for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 1023239462Sdim if (D) 1024239462Sdim LAs[i]->addDecl(D); 1025234353Sdim ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 1026234982Sdim delete LAs[i]; 1027234353Sdim } 1028234353Sdim LAs.clear(); 1029234353Sdim} 1030234353Sdim 1031234353Sdim 1032226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed. 1033226633Sdim/// This will be called at the end of parsing a class declaration 1034226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and 1035239462Sdim/// create an attribute with the arguments filled in. We add this 1036226633Sdim/// to the Attribute list for the decl. 1037234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA, 1038234353Sdim bool EnterScope, bool OnDefinition) { 1039226633Sdim // Save the current token position. 1040226633Sdim SourceLocation OrigLoc = Tok.getLocation(); 1041226633Sdim 1042226633Sdim // Append the current token at the end of the new token stream so that it 1043226633Sdim // doesn't get lost. 1044226633Sdim LA.Toks.push_back(Tok); 1045226633Sdim PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); 1046226633Sdim // Consume the previously pushed token. 1047249423Sdim ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 1048226633Sdim 1049234353Sdim if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) { 1050249423Sdim // FIXME: Do not warn on C++11 attributes, once we start supporting 1051249423Sdim // them here. 1052234353Sdim Diag(Tok, diag::warn_attribute_on_function_definition) 1053234353Sdim << LA.AttrName.getName(); 1054234353Sdim } 1055234353Sdim 1056226633Sdim ParsedAttributes Attrs(AttrFactory); 1057226633Sdim SourceLocation endLoc; 1058226633Sdim 1059243830Sdim if (LA.Decls.size() > 0) { 1060234353Sdim Decl *D = LA.Decls[0]; 1061243830Sdim NamedDecl *ND = dyn_cast<NamedDecl>(D); 1062243830Sdim RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 1063226633Sdim 1064243830Sdim // Allow 'this' within late-parsed attributes. 1065243830Sdim Sema::CXXThisScopeRAII ThisScope(Actions, RD, 1066243830Sdim /*TypeQuals=*/0, 1067243830Sdim ND && RD && ND->isCXXInstanceMember()); 1068226633Sdim 1069243830Sdim if (LA.Decls.size() == 1) { 1070243830Sdim // If the Decl is templatized, add template parameters to scope. 1071243830Sdim bool HasTemplateScope = EnterScope && D->isTemplateDecl(); 1072243830Sdim ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); 1073243830Sdim if (HasTemplateScope) 1074243830Sdim Actions.ActOnReenterTemplateScope(Actions.CurScope, D); 1075226633Sdim 1076243830Sdim // If the Decl is on a function, add function parameters to the scope. 1077243830Sdim bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); 1078243830Sdim ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); 1079243830Sdim if (HasFunScope) 1080243830Sdim Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 1081234353Sdim 1082243830Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1083243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 1084243830Sdim 1085243830Sdim if (HasFunScope) { 1086243830Sdim Actions.ActOnExitFunctionContext(); 1087243830Sdim FnScope.Exit(); // Pop scope, and remove Decls from IdResolver 1088243830Sdim } 1089243830Sdim if (HasTemplateScope) { 1090243830Sdim TempScope.Exit(); 1091243830Sdim } 1092243830Sdim } else { 1093243830Sdim // If there are multiple decls, then the decl cannot be within the 1094243830Sdim // function scope. 1095243830Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, 1096243830Sdim 0, SourceLocation(), AttributeList::AS_GNU); 1097234353Sdim } 1098234353Sdim } else { 1099234353Sdim Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 1100226633Sdim } 1101234353Sdim 1102234353Sdim for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) { 1103234353Sdim Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 1104226633Sdim } 1105226633Sdim 1106226633Sdim if (Tok.getLocation() != OrigLoc) { 1107226633Sdim // Due to a parsing error, we either went over the cached tokens or 1108226633Sdim // there are still cached tokens left, so we skip the leftover tokens. 1109226633Sdim // Since this is an uncommon situation that should be avoided, use the 1110226633Sdim // expensive isBeforeInTranslationUnit call. 1111226633Sdim if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 1112226633Sdim OrigLoc)) 1113226633Sdim while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 1114234353Sdim ConsumeAnyToken(); 1115226633Sdim } 1116226633Sdim} 1117226633Sdim 1118226633Sdim/// \brief Wrapper around a case statement checking if AttrName is 1119226633Sdim/// one of the thread safety attributes 1120249423Sdimbool Parser::IsThreadSafetyAttribute(StringRef AttrName) { 1121226633Sdim return llvm::StringSwitch<bool>(AttrName) 1122226633Sdim .Case("guarded_by", true) 1123226633Sdim .Case("guarded_var", true) 1124226633Sdim .Case("pt_guarded_by", true) 1125226633Sdim .Case("pt_guarded_var", true) 1126226633Sdim .Case("lockable", true) 1127226633Sdim .Case("scoped_lockable", true) 1128226633Sdim .Case("no_thread_safety_analysis", true) 1129226633Sdim .Case("acquired_after", true) 1130226633Sdim .Case("acquired_before", true) 1131226633Sdim .Case("exclusive_lock_function", true) 1132226633Sdim .Case("shared_lock_function", true) 1133226633Sdim .Case("exclusive_trylock_function", true) 1134226633Sdim .Case("shared_trylock_function", true) 1135226633Sdim .Case("unlock_function", true) 1136226633Sdim .Case("lock_returned", true) 1137226633Sdim .Case("locks_excluded", true) 1138226633Sdim .Case("exclusive_locks_required", true) 1139226633Sdim .Case("shared_locks_required", true) 1140226633Sdim .Default(false); 1141226633Sdim} 1142226633Sdim 1143226633Sdim/// \brief Parse the contents of thread safety attributes. These 1144226633Sdim/// should always be parsed as an expression list. 1145226633Sdim/// 1146226633Sdim/// We need to special case the parsing due to the fact that if the first token 1147226633Sdim/// of the first argument is an identifier, the main parse loop will store 1148226633Sdim/// that token as a "parameter" and the rest of 1149226633Sdim/// the arguments will be added to a list of "arguments". However, 1150226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each 1151226633Sdim/// argument as an expression and add all arguments to the list of "arguments". 1152226633Sdim/// In future, we will take advantage of this special case to also 1153226633Sdim/// deal with some argument scoping issues here (for example, referring to a 1154226633Sdim/// function parameter in the attribute on that function). 1155226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, 1156226633Sdim SourceLocation AttrNameLoc, 1157226633Sdim ParsedAttributes &Attrs, 1158226633Sdim SourceLocation *EndLoc) { 1159226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1160226633Sdim 1161226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1162226633Sdim T.consumeOpen(); 1163239462Sdim 1164243830Sdim ExprVector ArgExprs; 1165226633Sdim bool ArgExprsOk = true; 1166239462Sdim 1167226633Sdim // now parse the list of expressions 1168234353Sdim while (Tok.isNot(tok::r_paren)) { 1169249423Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 1170226633Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 1171226633Sdim if (ArgExpr.isInvalid()) { 1172226633Sdim ArgExprsOk = false; 1173226633Sdim T.consumeClose(); 1174226633Sdim break; 1175226633Sdim } else { 1176226633Sdim ArgExprs.push_back(ArgExpr.release()); 1177226633Sdim } 1178226633Sdim if (Tok.isNot(tok::comma)) 1179226633Sdim break; 1180226633Sdim ConsumeToken(); // Eat the comma, move to the next argument 1181226633Sdim } 1182226633Sdim // Match the ')'. 1183226633Sdim if (ArgExprsOk && !T.consumeClose()) { 1184226633Sdim Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 1185243830Sdim ArgExprs.data(), ArgExprs.size(), AttributeList::AS_GNU); 1186226633Sdim } 1187226633Sdim if (EndLoc) 1188226633Sdim *EndLoc = T.getCloseLocation(); 1189226633Sdim} 1190226633Sdim 1191239462Sdimvoid Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 1192239462Sdim SourceLocation AttrNameLoc, 1193239462Sdim ParsedAttributes &Attrs, 1194239462Sdim SourceLocation *EndLoc) { 1195239462Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1196239462Sdim 1197239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1198239462Sdim T.consumeOpen(); 1199239462Sdim 1200239462Sdim if (Tok.isNot(tok::identifier)) { 1201239462Sdim Diag(Tok, diag::err_expected_ident); 1202239462Sdim T.skipToEnd(); 1203239462Sdim return; 1204239462Sdim } 1205239462Sdim IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo(); 1206239462Sdim SourceLocation ArgumentKindLoc = ConsumeToken(); 1207239462Sdim 1208239462Sdim if (Tok.isNot(tok::comma)) { 1209239462Sdim Diag(Tok, diag::err_expected_comma); 1210239462Sdim T.skipToEnd(); 1211239462Sdim return; 1212239462Sdim } 1213239462Sdim ConsumeToken(); 1214239462Sdim 1215239462Sdim SourceRange MatchingCTypeRange; 1216239462Sdim TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange); 1217239462Sdim if (MatchingCType.isInvalid()) { 1218239462Sdim T.skipToEnd(); 1219239462Sdim return; 1220239462Sdim } 1221239462Sdim 1222239462Sdim bool LayoutCompatible = false; 1223239462Sdim bool MustBeNull = false; 1224239462Sdim while (Tok.is(tok::comma)) { 1225239462Sdim ConsumeToken(); 1226239462Sdim if (Tok.isNot(tok::identifier)) { 1227239462Sdim Diag(Tok, diag::err_expected_ident); 1228239462Sdim T.skipToEnd(); 1229239462Sdim return; 1230239462Sdim } 1231239462Sdim IdentifierInfo *Flag = Tok.getIdentifierInfo(); 1232239462Sdim if (Flag->isStr("layout_compatible")) 1233239462Sdim LayoutCompatible = true; 1234239462Sdim else if (Flag->isStr("must_be_null")) 1235239462Sdim MustBeNull = true; 1236239462Sdim else { 1237239462Sdim Diag(Tok, diag::err_type_safety_unknown_flag) << Flag; 1238239462Sdim T.skipToEnd(); 1239239462Sdim return; 1240239462Sdim } 1241239462Sdim ConsumeToken(); // consume flag 1242239462Sdim } 1243239462Sdim 1244239462Sdim if (!T.consumeClose()) { 1245239462Sdim Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc, 1246239462Sdim ArgumentKind, ArgumentKindLoc, 1247239462Sdim MatchingCType.release(), LayoutCompatible, 1248239462Sdim MustBeNull, AttributeList::AS_GNU); 1249239462Sdim } 1250239462Sdim 1251239462Sdim if (EndLoc) 1252239462Sdim *EndLoc = T.getCloseLocation(); 1253239462Sdim} 1254239462Sdim 1255234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 1256234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not 1257234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 1258234353Sdim/// situation. 1259234353Sdim/// 1260234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if 1261234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller 1262234353Sdim/// should try to parse it. 1263234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() { 1264234353Sdim assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 1265234353Sdim 1266234353Sdim switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) { 1267234353Sdim case CAK_NotAttributeSpecifier: 1268234353Sdim // No diagnostic: we're in Obj-C++11 and this is not actually an attribute. 1269234353Sdim return false; 1270234353Sdim 1271234353Sdim case CAK_InvalidAttributeSpecifier: 1272234353Sdim Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute); 1273234353Sdim return false; 1274234353Sdim 1275234353Sdim case CAK_AttributeSpecifier: 1276234353Sdim // Parse and discard the attributes. 1277234353Sdim SourceLocation BeginLoc = ConsumeBracket(); 1278234353Sdim ConsumeBracket(); 1279234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/ false); 1280234353Sdim assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); 1281234353Sdim SourceLocation EndLoc = ConsumeBracket(); 1282234353Sdim Diag(BeginLoc, diag::err_attributes_not_allowed) 1283234353Sdim << SourceRange(BeginLoc, EndLoc); 1284234353Sdim return true; 1285234353Sdim } 1286234353Sdim llvm_unreachable("All cases handled above."); 1287234353Sdim} 1288234353Sdim 1289249423Sdim/// \brief We have found the opening square brackets of a C++11 1290249423Sdim/// attribute-specifier in a location where an attribute is not permitted, but 1291249423Sdim/// we know where the attributes ought to be written. Parse them anyway, and 1292249423Sdim/// provide a fixit moving them to the right place. 1293249423Sdimvoid Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, 1294249423Sdim SourceLocation CorrectLocation) { 1295249423Sdim assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) || 1296249423Sdim Tok.is(tok::kw_alignas)); 1297249423Sdim 1298249423Sdim // Consume the attributes. 1299249423Sdim SourceLocation Loc = Tok.getLocation(); 1300249423Sdim ParseCXX11Attributes(Attrs); 1301249423Sdim CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true); 1302249423Sdim 1303249423Sdim Diag(Loc, diag::err_attributes_not_allowed) 1304249423Sdim << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) 1305249423Sdim << FixItHint::CreateRemoval(AttrRange); 1306249423Sdim} 1307249423Sdim 1308218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { 1309218893Sdim Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) 1310218893Sdim << attrs.Range; 1311218893Sdim} 1312218893Sdim 1313243830Sdimvoid Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) { 1314243830Sdim AttributeList *AttrList = attrs.getList(); 1315243830Sdim while (AttrList) { 1316249423Sdim if (AttrList->isCXX11Attribute()) { 1317249423Sdim Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr) 1318243830Sdim << AttrList->getName(); 1319243830Sdim AttrList->setInvalid(); 1320243830Sdim } 1321243830Sdim AttrList = AttrList->getNext(); 1322243830Sdim } 1323243830Sdim} 1324243830Sdim 1325193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of 1326193326Sed/// declaration-specifiers, some number of declarators, and a semicolon. 1327193326Sed/// 'Context' should be a Declarator::TheContext value. This returns the 1328193326Sed/// location of the semicolon in DeclEnd. 1329193326Sed/// 1330193326Sed/// declaration: [C99 6.7] 1331193326Sed/// block-declaration -> 1332193326Sed/// simple-declaration 1333193326Sed/// others [FIXME] 1334193326Sed/// [C++] template-declaration 1335193326Sed/// [C++] namespace-definition 1336193326Sed/// [C++] using-directive 1337194711Sed/// [C++] using-declaration 1338234982Sdim/// [C++11/C11] static_assert-declaration 1339193326Sed/// others... [FIXME] 1340193326Sed/// 1341218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, 1342218893Sdim unsigned Context, 1343199990Srdivacky SourceLocation &DeclEnd, 1344218893Sdim ParsedAttributesWithRange &attrs) { 1345210299Sed ParenBraceBracketBalancer BalancerRAIIObj(*this); 1346226633Sdim // Must temporarily exit the objective-c container scope for 1347226633Sdim // parsing c none objective-c decls. 1348226633Sdim ObjCDeclContextSwitch ObjCDC(*this); 1349239462Sdim 1350212904Sdim Decl *SingleDecl = 0; 1351224145Sdim Decl *OwnedType = 0; 1352193326Sed switch (Tok.getKind()) { 1353193326Sed case tok::kw_template: 1354193326Sed case tok::kw_export: 1355218893Sdim ProhibitAttributes(attrs); 1356193326Sed SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); 1357193326Sed break; 1358212904Sdim case tok::kw_inline: 1359212904Sdim // Could be the start of an inline namespace. Allowed as an ext in C++03. 1360234353Sdim if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { 1361218893Sdim ProhibitAttributes(attrs); 1362212904Sdim SourceLocation InlineLoc = ConsumeToken(); 1363212904Sdim SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); 1364212904Sdim break; 1365212904Sdim } 1366239462Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, 1367218893Sdim true); 1368193326Sed case tok::kw_namespace: 1369218893Sdim ProhibitAttributes(attrs); 1370193326Sed SingleDecl = ParseNamespace(Context, DeclEnd); 1371193326Sed break; 1372193326Sed case tok::kw_using: 1373218893Sdim SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), 1374224145Sdim DeclEnd, attrs, &OwnedType); 1375193326Sed break; 1376193326Sed case tok::kw_static_assert: 1377221345Sdim case tok::kw__Static_assert: 1378218893Sdim ProhibitAttributes(attrs); 1379193326Sed SingleDecl = ParseStaticAssertDeclaration(DeclEnd); 1380193326Sed break; 1381193326Sed default: 1382218893Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true); 1383193326Sed } 1384239462Sdim 1385193326Sed // This routine returns a DeclGroup, if the thing we parsed only contains a 1386224145Sdim // single decl, convert it now. Alias declarations can also declare a type; 1387224145Sdim // include that too if it is present. 1388224145Sdim return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType); 1389193326Sed} 1390193326Sed 1391193326Sed/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl] 1392193326Sed/// declaration-specifiers init-declarator-list[opt] ';' 1393239462Sdim/// [C++11] attribute-specifier-seq decl-specifier-seq[opt] 1394239462Sdim/// init-declarator-list ';' 1395193326Sed///[C90/C++]init-declarator-list ';' [TODO] 1396193326Sed/// [OMP] threadprivate-directive [TODO] 1397193326Sed/// 1398239462Sdim/// for-range-declaration: [C++11 6.5p1: stmt.ranged] 1399221345Sdim/// attribute-specifier-seq[opt] type-specifier-seq declarator 1400221345Sdim/// 1401193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the 1402206275Srdivacky/// declaration. If it is true, it checks for and eats it. 1403221345Sdim/// 1404221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead 1405221345Sdim/// of a simple-declaration. If we find that we are, we also parse the 1406221345Sdim/// for-range-initializer, and place it here. 1407239462SdimParser::DeclGroupPtrTy 1408239462SdimParser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context, 1409239462Sdim SourceLocation &DeclEnd, 1410249423Sdim ParsedAttributesWithRange &Attrs, 1411239462Sdim bool RequireSemi, ForRangeInit *FRI) { 1412193326Sed // Parse the common declaration-specifiers piece. 1413198893Srdivacky ParsingDeclSpec DS(*this); 1414221345Sdim 1415202379Srdivacky ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, 1416218893Sdim getDeclSpecContextFromDeclaratorContext(Context)); 1417234353Sdim 1418193326Sed // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 1419193326Sed // declaration-specifiers init-declarator-list[opt] ';' 1420193326Sed if (Tok.is(tok::semi)) { 1421249423Sdim ProhibitAttributes(Attrs); 1422239462Sdim DeclEnd = Tok.getLocation(); 1423206275Srdivacky if (RequireSemi) ConsumeToken(); 1424212904Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 1425221345Sdim DS); 1426198893Srdivacky DS.complete(TheDecl); 1427193326Sed return Actions.ConvertDeclToDeclGroup(TheDecl); 1428193326Sed } 1429239462Sdim 1430249423Sdim DS.takeAttributesFrom(Attrs); 1431239462Sdim return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI); 1432198893Srdivacky} 1433198092Srdivacky 1434234353Sdim/// Returns true if this might be the start of a declarator, or a common typo 1435234353Sdim/// for a declarator. 1436234353Sdimbool Parser::MightBeDeclarator(unsigned Context) { 1437234353Sdim switch (Tok.getKind()) { 1438234353Sdim case tok::annot_cxxscope: 1439234353Sdim case tok::annot_template_id: 1440234353Sdim case tok::caret: 1441234353Sdim case tok::code_completion: 1442234353Sdim case tok::coloncolon: 1443234353Sdim case tok::ellipsis: 1444234353Sdim case tok::kw___attribute: 1445234353Sdim case tok::kw_operator: 1446234353Sdim case tok::l_paren: 1447234353Sdim case tok::star: 1448234353Sdim return true; 1449234353Sdim 1450234353Sdim case tok::amp: 1451234353Sdim case tok::ampamp: 1452234353Sdim return getLangOpts().CPlusPlus; 1453234353Sdim 1454234353Sdim case tok::l_square: // Might be an attribute on an unnamed bit-field. 1455249423Sdim return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 && 1456234353Sdim NextToken().is(tok::l_square); 1457234353Sdim 1458234353Sdim case tok::colon: // Might be a typo for '::' or an unnamed bit-field. 1459234353Sdim return Context == Declarator::MemberContext || getLangOpts().CPlusPlus; 1460234353Sdim 1461234353Sdim case tok::identifier: 1462234353Sdim switch (NextToken().getKind()) { 1463234353Sdim case tok::code_completion: 1464234353Sdim case tok::coloncolon: 1465234353Sdim case tok::comma: 1466234353Sdim case tok::equal: 1467234353Sdim case tok::equalequal: // Might be a typo for '='. 1468234353Sdim case tok::kw_alignas: 1469234353Sdim case tok::kw_asm: 1470234353Sdim case tok::kw___attribute: 1471234353Sdim case tok::l_brace: 1472234353Sdim case tok::l_paren: 1473234353Sdim case tok::l_square: 1474234353Sdim case tok::less: 1475234353Sdim case tok::r_brace: 1476234353Sdim case tok::r_paren: 1477234353Sdim case tok::r_square: 1478234353Sdim case tok::semi: 1479234353Sdim return true; 1480234353Sdim 1481234353Sdim case tok::colon: 1482234353Sdim // At namespace scope, 'identifier:' is probably a typo for 'identifier::' 1483234353Sdim // and in block scope it's probably a label. Inside a class definition, 1484234353Sdim // this is a bit-field. 1485234353Sdim return Context == Declarator::MemberContext || 1486234353Sdim (getLangOpts().CPlusPlus && Context == Declarator::FileContext); 1487234353Sdim 1488234353Sdim case tok::identifier: // Possible virt-specifier. 1489249423Sdim return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken()); 1490234353Sdim 1491234353Sdim default: 1492234353Sdim return false; 1493234353Sdim } 1494234353Sdim 1495234353Sdim default: 1496234353Sdim return false; 1497234353Sdim } 1498234353Sdim} 1499234353Sdim 1500234353Sdim/// Skip until we reach something which seems like a sensible place to pick 1501234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner 1502234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later. 1503234353Sdimvoid Parser::SkipMalformedDecl() { 1504234353Sdim while (true) { 1505234353Sdim switch (Tok.getKind()) { 1506234353Sdim case tok::l_brace: 1507234353Sdim // Skip until matching }, then stop. We've probably skipped over 1508234353Sdim // a malformed class or function definition or similar. 1509234353Sdim ConsumeBrace(); 1510234353Sdim SkipUntil(tok::r_brace, /*StopAtSemi*/false); 1511234353Sdim if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { 1512234353Sdim // This declaration isn't over yet. Keep skipping. 1513234353Sdim continue; 1514234353Sdim } 1515234353Sdim if (Tok.is(tok::semi)) 1516234353Sdim ConsumeToken(); 1517234353Sdim return; 1518234353Sdim 1519234353Sdim case tok::l_square: 1520234353Sdim ConsumeBracket(); 1521234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/false); 1522234353Sdim continue; 1523234353Sdim 1524234353Sdim case tok::l_paren: 1525234353Sdim ConsumeParen(); 1526234353Sdim SkipUntil(tok::r_paren, /*StopAtSemi*/false); 1527234353Sdim continue; 1528234353Sdim 1529234353Sdim case tok::r_brace: 1530234353Sdim return; 1531234353Sdim 1532234353Sdim case tok::semi: 1533234353Sdim ConsumeToken(); 1534234353Sdim return; 1535234353Sdim 1536234353Sdim case tok::kw_inline: 1537234353Sdim // 'inline namespace' at the start of a line is almost certainly 1538239462Sdim // a good place to pick back up parsing, except in an Objective-C 1539239462Sdim // @interface context. 1540239462Sdim if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) && 1541239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1542234353Sdim return; 1543234353Sdim break; 1544234353Sdim 1545234353Sdim case tok::kw_namespace: 1546234353Sdim // 'namespace' at the start of a line is almost certainly a good 1547239462Sdim // place to pick back up parsing, except in an Objective-C 1548239462Sdim // @interface context. 1549239462Sdim if (Tok.isAtStartOfLine() && 1550239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1551234353Sdim return; 1552234353Sdim break; 1553234353Sdim 1554239462Sdim case tok::at: 1555239462Sdim // @end is very much like } in Objective-C contexts. 1556239462Sdim if (NextToken().isObjCAtKeyword(tok::objc_end) && 1557239462Sdim ParsingInObjCContainer) 1558239462Sdim return; 1559239462Sdim break; 1560239462Sdim 1561239462Sdim case tok::minus: 1562239462Sdim case tok::plus: 1563239462Sdim // - and + probably start new method declarations in Objective-C contexts. 1564239462Sdim if (Tok.isAtStartOfLine() && ParsingInObjCContainer) 1565239462Sdim return; 1566239462Sdim break; 1567239462Sdim 1568234353Sdim case tok::eof: 1569234353Sdim return; 1570234353Sdim 1571234353Sdim default: 1572234353Sdim break; 1573234353Sdim } 1574234353Sdim 1575234353Sdim ConsumeAnyToken(); 1576234353Sdim } 1577234353Sdim} 1578234353Sdim 1579198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function 1580198893Srdivacky/// definition or a group of object declarations, actually parse the 1581198893Srdivacky/// result. 1582198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, 1583198893Srdivacky unsigned Context, 1584198893Srdivacky bool AllowFunctionDefinitions, 1585221345Sdim SourceLocation *DeclEnd, 1586221345Sdim ForRangeInit *FRI) { 1587198893Srdivacky // Parse the first declarator. 1588198893Srdivacky ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context)); 1589198893Srdivacky ParseDeclarator(D); 1590193326Sed 1591198893Srdivacky // Bail out if the first declarator didn't seem well-formed. 1592198893Srdivacky if (!D.hasName() && !D.mayOmitIdentifier()) { 1593234353Sdim SkipMalformedDecl(); 1594198893Srdivacky return DeclGroupPtrTy(); 1595198893Srdivacky } 1596198092Srdivacky 1597234353Sdim // Save late-parsed attributes for now; they need to be parsed in the 1598234353Sdim // appropriate function scope after the function Decl has been constructed. 1599243830Sdim // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList. 1600243830Sdim LateParsedAttrList LateParsedAttrs(true); 1601234353Sdim if (D.isFunctionDeclarator()) 1602234353Sdim MaybeParseGNUAttributes(D, &LateParsedAttrs); 1603234353Sdim 1604210299Sed // Check to see if we have a function *definition* which must have a body. 1605251662Sdim if (D.isFunctionDeclarator() && 1606210299Sed // Look at the next token to make sure that this isn't a function 1607210299Sed // declaration. We have to check this because __attribute__ might be the 1608210299Sed // start of a function definition in GCC-extended K&R C. 1609210299Sed !isDeclarationAfterDeclarator()) { 1610239462Sdim 1611251662Sdim if (AllowFunctionDefinitions) { 1612251662Sdim if (isStartOfFunctionDefinition(D)) { 1613251662Sdim if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 1614251662Sdim Diag(Tok, diag::err_function_declared_typedef); 1615198092Srdivacky 1616251662Sdim // Recover by treating the 'typedef' as spurious. 1617251662Sdim DS.ClearStorageClassSpecs(); 1618251662Sdim } 1619251662Sdim 1620251662Sdim Decl *TheDecl = 1621251662Sdim ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); 1622251662Sdim return Actions.ConvertDeclToDeclGroup(TheDecl); 1623198893Srdivacky } 1624198893Srdivacky 1625251662Sdim if (isDeclarationSpecifier()) { 1626251662Sdim // If there is an invalid declaration specifier right after the function 1627251662Sdim // prototype, then we must be in a missing semicolon case where this isn't 1628251662Sdim // actually a body. Just fall through into the code that handles it as a 1629251662Sdim // prototype, and let the top-level code handle the erroneous declspec 1630251662Sdim // where it would otherwise expect a comma or semicolon. 1631251662Sdim } else { 1632251662Sdim Diag(Tok, diag::err_expected_fn_body); 1633251662Sdim SkipUntil(tok::semi); 1634251662Sdim return DeclGroupPtrTy(); 1635251662Sdim } 1636198893Srdivacky } else { 1637251662Sdim if (Tok.is(tok::l_brace)) { 1638251662Sdim Diag(Tok, diag::err_function_definition_not_allowed); 1639251662Sdim SkipUntil(tok::r_brace, true, true); 1640251662Sdim } 1641198893Srdivacky } 1642198893Srdivacky } 1643198893Srdivacky 1644234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1645221345Sdim return DeclGroupPtrTy(); 1646221345Sdim 1647221345Sdim // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we 1648221345Sdim // must parse and analyze the for-range-initializer before the declaration is 1649221345Sdim // analyzed. 1650251662Sdim // 1651251662Sdim // Handle the Objective-C for-in loop variable similarly, although we 1652251662Sdim // don't need to parse the container in advance. 1653251662Sdim if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) { 1654251662Sdim bool IsForRangeLoop = false; 1655251662Sdim if (Tok.is(tok::colon)) { 1656251662Sdim IsForRangeLoop = true; 1657251662Sdim FRI->ColonLoc = ConsumeToken(); 1658251662Sdim if (Tok.is(tok::l_brace)) 1659251662Sdim FRI->RangeExpr = ParseBraceInitializer(); 1660251662Sdim else 1661251662Sdim FRI->RangeExpr = ParseExpression(); 1662251662Sdim } 1663251662Sdim 1664221345Sdim Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1665251662Sdim if (IsForRangeLoop) 1666251662Sdim Actions.ActOnCXXForRangeDecl(ThisDecl); 1667221345Sdim Actions.FinalizeDeclaration(ThisDecl); 1668234353Sdim D.complete(ThisDecl); 1669221345Sdim return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1); 1670221345Sdim } 1671221345Sdim 1672226633Sdim SmallVector<Decl *, 8> DeclsInGroup; 1673221345Sdim Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D); 1674234353Sdim if (LateParsedAttrs.size() > 0) 1675234353Sdim ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); 1676198893Srdivacky D.complete(FirstDecl); 1677212904Sdim if (FirstDecl) 1678198893Srdivacky DeclsInGroup.push_back(FirstDecl); 1679198893Srdivacky 1680234353Sdim bool ExpectSemi = Context != Declarator::ForContext; 1681239462Sdim 1682198893Srdivacky // If we don't have a comma, it is either the end of the list (a ';') or an 1683198893Srdivacky // error, bail out. 1684198893Srdivacky while (Tok.is(tok::comma)) { 1685234353Sdim SourceLocation CommaLoc = ConsumeToken(); 1686198893Srdivacky 1687234353Sdim if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) { 1688234353Sdim // This comma was followed by a line-break and something which can't be 1689234353Sdim // the start of a declarator. The comma was probably a typo for a 1690234353Sdim // semicolon. 1691234353Sdim Diag(CommaLoc, diag::err_expected_semi_declaration) 1692234353Sdim << FixItHint::CreateReplacement(CommaLoc, ";"); 1693234353Sdim ExpectSemi = false; 1694234353Sdim break; 1695234353Sdim } 1696234353Sdim 1697198893Srdivacky // Parse the next declarator. 1698198893Srdivacky D.clear(); 1699234353Sdim D.setCommaLoc(CommaLoc); 1700198893Srdivacky 1701198893Srdivacky // Accept attributes in an init-declarator. In the first declarator in a 1702198893Srdivacky // declaration, these would be part of the declspec. In subsequent 1703198893Srdivacky // declarators, they become part of the declarator itself, so that they 1704198893Srdivacky // don't apply to declarators after *this* one. Examples: 1705198893Srdivacky // short __attribute__((common)) var; -> declspec 1706198893Srdivacky // short var __attribute__((common)); -> declarator 1707198893Srdivacky // short x, __attribute__((common)) var; -> declarator 1708218893Sdim MaybeParseGNUAttributes(D); 1709198893Srdivacky 1710198893Srdivacky ParseDeclarator(D); 1711234353Sdim if (!D.isInvalidType()) { 1712234353Sdim Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); 1713234353Sdim D.complete(ThisDecl); 1714234353Sdim if (ThisDecl) 1715239462Sdim DeclsInGroup.push_back(ThisDecl); 1716234353Sdim } 1717193326Sed } 1718198092Srdivacky 1719198893Srdivacky if (DeclEnd) 1720198893Srdivacky *DeclEnd = Tok.getLocation(); 1721198893Srdivacky 1722234353Sdim if (ExpectSemi && 1723239462Sdim ExpectAndConsumeSemi(Context == Declarator::FileContext 1724239462Sdim ? diag::err_invalid_token_after_toplevel_declarator 1725239462Sdim : diag::err_expected_semi_declaration)) { 1726210299Sed // Okay, there was no semicolon and one was expected. If we see a 1727210299Sed // declaration specifier, just assume it was missing and continue parsing. 1728210299Sed // Otherwise things are very confused and we skip to recover. 1729210299Sed if (!isDeclarationSpecifier()) { 1730210299Sed SkipUntil(tok::r_brace, true, true); 1731210299Sed if (Tok.is(tok::semi)) 1732210299Sed ConsumeToken(); 1733210299Sed } 1734198893Srdivacky } 1735198893Srdivacky 1736210299Sed return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, 1737198893Srdivacky DeclsInGroup.data(), 1738198893Srdivacky DeclsInGroup.size()); 1739193326Sed} 1740193326Sed 1741221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a 1742221345Sdim/// declarator. Returns true on an error. 1743234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) { 1744221345Sdim // If a simple-asm-expr is present, parse it. 1745221345Sdim if (Tok.is(tok::kw_asm)) { 1746221345Sdim SourceLocation Loc; 1747221345Sdim ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1748221345Sdim if (AsmLabel.isInvalid()) { 1749221345Sdim SkipUntil(tok::semi, true, true); 1750221345Sdim return true; 1751221345Sdim } 1752221345Sdim 1753221345Sdim D.setAsmLabel(AsmLabel.release()); 1754221345Sdim D.SetRangeEnd(Loc); 1755221345Sdim } 1756221345Sdim 1757221345Sdim MaybeParseGNUAttributes(D); 1758221345Sdim return false; 1759221345Sdim} 1760221345Sdim 1761193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers 1762193326Sed/// declarator'. This method parses the remainder of the declaration 1763193326Sed/// (including any attributes or initializer, among other things) and 1764193326Sed/// finalizes the declaration. 1765193326Sed/// 1766193326Sed/// init-declarator: [C99 6.7] 1767193326Sed/// declarator 1768193326Sed/// declarator '=' initializer 1769193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] 1770193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer 1771193326Sed/// [C++] declarator initializer[opt] 1772193326Sed/// 1773193326Sed/// [C++] initializer: 1774193326Sed/// [C++] '=' initializer-clause 1775193326Sed/// [C++] '(' expression-list ')' 1776193326Sed/// [C++0x] '=' 'default' [TODO] 1777193326Sed/// [C++0x] '=' 'delete' 1778223017Sdim/// [C++0x] braced-init-list 1779193326Sed/// 1780193326Sed/// According to the standard grammar, =default and =delete are function 1781193326Sed/// definitions, but that definitely doesn't fit with the parser here. 1782193326Sed/// 1783212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, 1784195099Sed const ParsedTemplateInfo &TemplateInfo) { 1785234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1786221345Sdim return 0; 1787198092Srdivacky 1788221345Sdim return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo); 1789221345Sdim} 1790198092Srdivacky 1791221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, 1792221345Sdim const ParsedTemplateInfo &TemplateInfo) { 1793193326Sed // Inform the current actions module that we just parsed this declarator. 1794212904Sdim Decl *ThisDecl = 0; 1795198092Srdivacky switch (TemplateInfo.Kind) { 1796198092Srdivacky case ParsedTemplateInfo::NonTemplate: 1797210299Sed ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1798198092Srdivacky break; 1799239462Sdim 1800198092Srdivacky case ParsedTemplateInfo::Template: 1801198092Srdivacky case ParsedTemplateInfo::ExplicitSpecialization: 1802210299Sed ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), 1803243830Sdim *TemplateInfo.TemplateParams, 1804198092Srdivacky D); 1805198092Srdivacky break; 1806239462Sdim 1807198092Srdivacky case ParsedTemplateInfo::ExplicitInstantiation: { 1808239462Sdim DeclResult ThisRes 1809210299Sed = Actions.ActOnExplicitInstantiation(getCurScope(), 1810198092Srdivacky TemplateInfo.ExternLoc, 1811198092Srdivacky TemplateInfo.TemplateLoc, 1812198092Srdivacky D); 1813198092Srdivacky if (ThisRes.isInvalid()) { 1814198092Srdivacky SkipUntil(tok::semi, true, true); 1815212904Sdim return 0; 1816198092Srdivacky } 1817239462Sdim 1818198092Srdivacky ThisDecl = ThisRes.get(); 1819198092Srdivacky break; 1820198092Srdivacky } 1821198092Srdivacky } 1822198092Srdivacky 1823251662Sdim bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); 1824218893Sdim 1825193326Sed // Parse declarator '=' initializer. 1826234353Sdim // If a '==' or '+=' is found, suggest a fixit to '='. 1827234353Sdim if (isTokenEqualOrEqualTypo()) { 1828193326Sed ConsumeToken(); 1829218893Sdim if (Tok.is(tok::kw_delete)) { 1830223017Sdim if (D.isFunctionDeclarator()) 1831223017Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1832223017Sdim << 1 /* delete */; 1833223017Sdim else 1834223017Sdim Diag(ConsumeToken(), diag::err_deleted_non_function); 1835223017Sdim } else if (Tok.is(tok::kw_default)) { 1836223017Sdim if (D.isFunctionDeclarator()) 1837234353Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1838234353Sdim << 0 /* default */; 1839223017Sdim else 1840223017Sdim Diag(ConsumeToken(), diag::err_default_special_members); 1841193326Sed } else { 1842234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1843201361Srdivacky EnterScope(0); 1844210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1845201361Srdivacky } 1846194613Sed 1847210299Sed if (Tok.is(tok::code_completion)) { 1848210299Sed Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); 1849239462Sdim Actions.FinalizeDeclaration(ThisDecl); 1850226633Sdim cutOffParsing(); 1851226633Sdim return 0; 1852210299Sed } 1853239462Sdim 1854212904Sdim ExprResult Init(ParseInitializer()); 1855194613Sed 1856234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1857210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1858201361Srdivacky ExitScope(); 1859201361Srdivacky } 1860194613Sed 1861193326Sed if (Init.isInvalid()) { 1862204643Srdivacky SkipUntil(tok::comma, true, true); 1863204643Srdivacky Actions.ActOnInitializerError(ThisDecl); 1864204643Srdivacky } else 1865218893Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1866218893Sdim /*DirectInit=*/false, TypeContainsAuto); 1867193326Sed } 1868193326Sed } else if (Tok.is(tok::l_paren)) { 1869193326Sed // Parse C++ direct initializer: '(' expression-list ')' 1870226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1871226633Sdim T.consumeOpen(); 1872226633Sdim 1873243830Sdim ExprVector Exprs; 1874193326Sed CommaLocsTy CommaLocs; 1875193326Sed 1876234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1877201361Srdivacky EnterScope(0); 1878210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1879201361Srdivacky } 1880201361Srdivacky 1881193326Sed if (ParseExpressionList(Exprs, CommaLocs)) { 1882243830Sdim Actions.ActOnInitializerError(ThisDecl); 1883193326Sed SkipUntil(tok::r_paren); 1884201361Srdivacky 1885234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1886210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1887201361Srdivacky ExitScope(); 1888201361Srdivacky } 1889193326Sed } else { 1890193326Sed // Match the ')'. 1891226633Sdim T.consumeClose(); 1892193326Sed 1893193326Sed assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && 1894193326Sed "Unexpected number of commas!"); 1895201361Srdivacky 1896234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1897210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1898201361Srdivacky ExitScope(); 1899201361Srdivacky } 1900201361Srdivacky 1901234353Sdim ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), 1902234353Sdim T.getCloseLocation(), 1903243830Sdim Exprs); 1904234353Sdim Actions.AddInitializerToDecl(ThisDecl, Initializer.take(), 1905234353Sdim /*DirectInit=*/true, TypeContainsAuto); 1906193326Sed } 1907249423Sdim } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) && 1908239462Sdim (!CurParsedObjCImpl || !D.isFunctionDeclarator())) { 1909223017Sdim // Parse C++0x braced-init-list. 1910234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1911234353Sdim 1912223017Sdim if (D.getCXXScopeSpec().isSet()) { 1913223017Sdim EnterScope(0); 1914223017Sdim Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1915223017Sdim } 1916223017Sdim 1917223017Sdim ExprResult Init(ParseBraceInitializer()); 1918223017Sdim 1919223017Sdim if (D.getCXXScopeSpec().isSet()) { 1920223017Sdim Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1921223017Sdim ExitScope(); 1922223017Sdim } 1923223017Sdim 1924223017Sdim if (Init.isInvalid()) { 1925223017Sdim Actions.ActOnInitializerError(ThisDecl); 1926223017Sdim } else 1927223017Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1928223017Sdim /*DirectInit=*/true, TypeContainsAuto); 1929223017Sdim 1930193326Sed } else { 1931218893Sdim Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto); 1932193326Sed } 1933193326Sed 1934219077Sdim Actions.FinalizeDeclaration(ThisDecl); 1935219077Sdim 1936193326Sed return ThisDecl; 1937193326Sed} 1938193326Sed 1939193326Sed/// ParseSpecifierQualifierList 1940193326Sed/// specifier-qualifier-list: 1941193326Sed/// type-specifier specifier-qualifier-list[opt] 1942193326Sed/// type-qualifier specifier-qualifier-list[opt] 1943193326Sed/// [GNU] attributes specifier-qualifier-list[opt] 1944193326Sed/// 1945234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, 1946234353Sdim DeclSpecContext DSC) { 1947193326Sed /// specifier-qualifier-list is a subset of declaration-specifiers. Just 1948193326Sed /// parse declaration-specifiers and complain about extra stuff. 1949226633Sdim /// TODO: diagnose attribute-specifiers and alignment-specifiers. 1950234353Sdim ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC); 1951198092Srdivacky 1952193326Sed // Validate declspec for type-name. 1953193326Sed unsigned Specs = DS.getParsedSpecifiers(); 1954239462Sdim if ((DSC == DSC_type_specifier || DSC == DSC_trailing) && 1955239462Sdim !DS.hasTypeSpecifier()) { 1956234353Sdim Diag(Tok, diag::err_expected_type); 1957234353Sdim DS.SetTypeSpecError(); 1958234353Sdim } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && 1959234353Sdim !DS.hasAttributes()) { 1960193326Sed Diag(Tok, diag::err_typename_requires_specqual); 1961234353Sdim if (!DS.hasTypeSpecifier()) 1962234353Sdim DS.SetTypeSpecError(); 1963234353Sdim } 1964198092Srdivacky 1965193326Sed // Issue diagnostic and remove storage class if present. 1966193326Sed if (Specs & DeclSpec::PQ_StorageClassSpecifier) { 1967193326Sed if (DS.getStorageClassSpecLoc().isValid()) 1968193326Sed Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); 1969193326Sed else 1970251662Sdim Diag(DS.getThreadStorageClassSpecLoc(), 1971251662Sdim diag::err_typename_invalid_storageclass); 1972193326Sed DS.ClearStorageClassSpecs(); 1973193326Sed } 1974198092Srdivacky 1975193326Sed // Issue diagnostic and remove function specfier if present. 1976193326Sed if (Specs & DeclSpec::PQ_FunctionSpecifier) { 1977193326Sed if (DS.isInlineSpecified()) 1978193326Sed Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); 1979193326Sed if (DS.isVirtualSpecified()) 1980193326Sed Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); 1981193326Sed if (DS.isExplicitSpecified()) 1982193326Sed Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); 1983193326Sed DS.ClearFunctionSpecs(); 1984193326Sed } 1985234353Sdim 1986234353Sdim // Issue diagnostic and remove constexpr specfier if present. 1987234353Sdim if (DS.isConstexprSpecified()) { 1988234353Sdim Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); 1989234353Sdim DS.ClearConstexprSpec(); 1990234353Sdim } 1991193326Sed} 1992193326Sed 1993193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the 1994193326Sed/// specified token is valid after the identifier in a declarator which 1995193326Sed/// immediately follows the declspec. For example, these things are valid: 1996193326Sed/// 1997193326Sed/// int x [ 4]; // direct-declarator 1998193326Sed/// int x ( int y); // direct-declarator 1999193326Sed/// int(int x ) // direct-declarator 2000193326Sed/// int x ; // simple-declaration 2001193326Sed/// int x = 17; // init-declarator-list 2002193326Sed/// int x , y; // init-declarator-list 2003193326Sed/// int x __asm__ ("foo"); // init-declarator-list 2004193326Sed/// int x : 4; // struct-declarator 2005193326Sed/// int x { 5}; // C++'0x unified initializers 2006193326Sed/// 2007193326Sed/// This is not, because 'x' does not immediately follow the declspec (though 2008193326Sed/// ')' happens to be valid anyway). 2009193326Sed/// int (x) 2010193326Sed/// 2011193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) { 2012193326Sed return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) || 2013193326Sed T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) || 2014193326Sed T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon); 2015193326Sed} 2016193326Sed 2017193326Sed 2018193326Sed/// ParseImplicitInt - This method is called when we have an non-typename 2019193326Sed/// identifier in a declspec (which normally terminates the decl spec) when 2020193326Sed/// the declspec has no type specifier. In this case, the declspec is either 2021193326Sed/// malformed or is "implicit int" (in K&R and C89). 2022193326Sed/// 2023193326Sed/// This method handles diagnosing this prettily and returns false if the 2024193326Sed/// declspec is done being processed. If it recovers and thinks there may be 2025193326Sed/// other pieces of declspec after it, it returns true. 2026193326Sed/// 2027193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, 2028193326Sed const ParsedTemplateInfo &TemplateInfo, 2029249423Sdim AccessSpecifier AS, DeclSpecContext DSC, 2030249423Sdim ParsedAttributesWithRange &Attrs) { 2031193326Sed assert(Tok.is(tok::identifier) && "should have identifier"); 2032198092Srdivacky 2033193326Sed SourceLocation Loc = Tok.getLocation(); 2034193326Sed // If we see an identifier that is not a type name, we normally would 2035193326Sed // parse it as the identifer being declared. However, when a typename 2036193326Sed // is typo'd or the definition is not included, this will incorrectly 2037193326Sed // parse the typename as the identifier name and fall over misparsing 2038193326Sed // later parts of the diagnostic. 2039193326Sed // 2040193326Sed // As such, we try to do some look-ahead in cases where this would 2041193326Sed // otherwise be an "implicit-int" case to see if this is invalid. For 2042193326Sed // example: "static foo_t x = 4;" In this case, if we parsed foo_t as 2043193326Sed // an identifier with implicit int, we'd get a parse error because the 2044193326Sed // next token is obviously invalid for a type. Parse these as a case 2045193326Sed // with an invalid type specifier. 2046193326Sed assert(!DS.hasTypeSpecifier() && "Type specifier checked above"); 2047198092Srdivacky 2048193326Sed // Since we know that this either implicit int (which is rare) or an 2049239462Sdim // error, do lookahead to try to do better recovery. This never applies 2050239462Sdim // within a type specifier. Outside of C++, we allow this even if the 2051239462Sdim // language doesn't "officially" support implicit int -- we support 2052251662Sdim // implicit int as an extension in C99 and C11. 2053239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2054251662Sdim !getLangOpts().CPlusPlus && 2055234353Sdim isValidAfterIdentifierInDeclarator(NextToken())) { 2056193326Sed // If this token is valid for implicit int, e.g. "static x = 4", then 2057193326Sed // we just avoid eating the identifier, so it will be parsed as the 2058193326Sed // identifier in the declarator. 2059193326Sed return false; 2060193326Sed } 2061198092Srdivacky 2062239462Sdim if (getLangOpts().CPlusPlus && 2063239462Sdim DS.getStorageClassSpec() == DeclSpec::SCS_auto) { 2064239462Sdim // Don't require a type specifier if we have the 'auto' storage class 2065239462Sdim // specifier in C++98 -- we'll promote it to a type specifier. 2066239462Sdim return false; 2067239462Sdim } 2068239462Sdim 2069193326Sed // Otherwise, if we don't consume this token, we are going to emit an 2070193326Sed // error anyway. Try to recover from various common problems. Check 2071193326Sed // to see if this was a reference to a tag name without a tag specified. 2072193326Sed // This is a common problem in C (saying 'foo' instead of 'struct foo'). 2073193326Sed // 2074193326Sed // C++ doesn't need this, and isTagName doesn't take SS. 2075193326Sed if (SS == 0) { 2076221345Sdim const char *TagName = 0, *FixitTagName = 0; 2077193326Sed tok::TokenKind TagKind = tok::unknown; 2078198092Srdivacky 2079210299Sed switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) { 2080193326Sed default: break; 2081221345Sdim case DeclSpec::TST_enum: 2082221345Sdim TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break; 2083221345Sdim case DeclSpec::TST_union: 2084221345Sdim TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break; 2085221345Sdim case DeclSpec::TST_struct: 2086221345Sdim TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break; 2087243830Sdim case DeclSpec::TST_interface: 2088243830Sdim TagName="__interface"; FixitTagName = "__interface "; 2089243830Sdim TagKind=tok::kw___interface;break; 2090221345Sdim case DeclSpec::TST_class: 2091221345Sdim TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; 2092193326Sed } 2093198092Srdivacky 2094193326Sed if (TagName) { 2095239462Sdim IdentifierInfo *TokenName = Tok.getIdentifierInfo(); 2096239462Sdim LookupResult R(Actions, TokenName, SourceLocation(), 2097239462Sdim Sema::LookupOrdinaryName); 2098239462Sdim 2099193326Sed Diag(Loc, diag::err_use_of_tag_name_without_tag) 2100239462Sdim << TokenName << TagName << getLangOpts().CPlusPlus 2101239462Sdim << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName); 2102198092Srdivacky 2103239462Sdim if (Actions.LookupParsedName(R, getCurScope(), SS)) { 2104239462Sdim for (LookupResult::iterator I = R.begin(), IEnd = R.end(); 2105239462Sdim I != IEnd; ++I) 2106239462Sdim Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type) 2107239462Sdim << TokenName << TagName; 2108239462Sdim } 2109239462Sdim 2110193326Sed // Parse this as a tag as if the missing tag were present. 2111193326Sed if (TagKind == tok::kw_enum) 2112234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); 2113193326Sed else 2114234353Sdim ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, 2115249423Sdim /*EnteringContext*/ false, DSC_normal, Attrs); 2116193326Sed return true; 2117193326Sed } 2118193326Sed } 2119198092Srdivacky 2120239462Sdim // Determine whether this identifier could plausibly be the name of something 2121239462Sdim // being declared (with a missing type). 2122239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 2123239462Sdim (!SS || DSC == DSC_top_level || DSC == DSC_class)) { 2124239462Sdim // Look ahead to the next token to try to figure out what this declaration 2125239462Sdim // was supposed to be. 2126239462Sdim switch (NextToken().getKind()) { 2127239462Sdim case tok::comma: 2128239462Sdim case tok::equal: 2129239462Sdim case tok::kw_asm: 2130239462Sdim case tok::l_brace: 2131239462Sdim case tok::l_square: 2132239462Sdim case tok::semi: 2133239462Sdim // This looks like a variable declaration. The type is probably missing. 2134239462Sdim // We're done parsing decl-specifiers. 2135239462Sdim return false; 2136239462Sdim 2137239462Sdim case tok::l_paren: { 2138239462Sdim // static x(4); // 'x' is not a type 2139239462Sdim // x(int n); // 'x' is not a type 2140239462Sdim // x (*p)[]; // 'x' is a type 2141239462Sdim // 2142239462Sdim // Since we're in an error case (or the rare 'implicit int in C++' MS 2143239462Sdim // extension), we can afford to perform a tentative parse to determine 2144239462Sdim // which case we're in. 2145239462Sdim TentativeParsingAction PA(*this); 2146239462Sdim ConsumeToken(); 2147239462Sdim TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false); 2148239462Sdim PA.Revert(); 2149239462Sdim if (TPR == TPResult::False()) 2150239462Sdim return false; 2151239462Sdim // The identifier is followed by a parenthesized declarator. 2152239462Sdim // It's supposed to be a type. 2153239462Sdim break; 2154239462Sdim } 2155239462Sdim 2156239462Sdim default: 2157239462Sdim // This is probably supposed to be a type. This includes cases like: 2158239462Sdim // int f(itn); 2159239462Sdim // struct S { unsinged : 4; }; 2160239462Sdim break; 2161239462Sdim } 2162239462Sdim } 2163239462Sdim 2164239462Sdim // This is almost certainly an invalid type name. Let the action emit a 2165198092Srdivacky // diagnostic and attempt to recover. 2166212904Sdim ParsedType T; 2167239462Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 2168239462Sdim if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) { 2169198092Srdivacky // The action emitted a diagnostic, so we don't have to. 2170198092Srdivacky if (T) { 2171198092Srdivacky // The action has suggested that the type T could be used. Set that as 2172198092Srdivacky // the type in the declaration specifiers, consume the would-be type 2173198092Srdivacky // name token, and we're done. 2174198092Srdivacky const char *PrevSpec; 2175198092Srdivacky unsigned DiagID; 2176212904Sdim DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); 2177198092Srdivacky DS.SetRangeEnd(Tok.getLocation()); 2178198092Srdivacky ConsumeToken(); 2179198092Srdivacky // There may be other declaration specifiers after this. 2180198092Srdivacky return true; 2181239462Sdim } else if (II != Tok.getIdentifierInfo()) { 2182239462Sdim // If no type was suggested, the correction is to a keyword 2183239462Sdim Tok.setKind(II->getTokenID()); 2184239462Sdim // There may be other declaration specifiers after this. 2185239462Sdim return true; 2186198092Srdivacky } 2187239462Sdim 2188198092Srdivacky // Fall through; the action had no suggestion for us. 2189198092Srdivacky } else { 2190198092Srdivacky // The action did not emit a diagnostic, so emit one now. 2191198092Srdivacky SourceRange R; 2192198092Srdivacky if (SS) R = SS->getRange(); 2193198092Srdivacky Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R; 2194198092Srdivacky } 2195198092Srdivacky 2196198092Srdivacky // Mark this as an error. 2197234353Sdim DS.SetTypeSpecError(); 2198193326Sed DS.SetRangeEnd(Tok.getLocation()); 2199193326Sed ConsumeToken(); 2200198092Srdivacky 2201193326Sed // TODO: Could inject an invalid typedef decl in an enclosing scope to 2202193326Sed // avoid rippling error messages on subsequent uses of the same type, 2203193326Sed // could be useful if #include was forgotten. 2204193326Sed return false; 2205193326Sed} 2206193326Sed 2207202379Srdivacky/// \brief Determine the declaration specifier context from the declarator 2208202379Srdivacky/// context. 2209202379Srdivacky/// 2210202379Srdivacky/// \param Context the declarator context, which is one of the 2211202379Srdivacky/// Declarator::TheContext enumerator values. 2212239462SdimParser::DeclSpecContext 2213202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { 2214202379Srdivacky if (Context == Declarator::MemberContext) 2215202379Srdivacky return DSC_class; 2216202379Srdivacky if (Context == Declarator::FileContext) 2217202379Srdivacky return DSC_top_level; 2218234353Sdim if (Context == Declarator::TrailingReturnContext) 2219234353Sdim return DSC_trailing; 2220202379Srdivacky return DSC_normal; 2221202379Srdivacky} 2222202379Srdivacky 2223226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier. 2224226633Sdim/// 2225226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a 2226226633Sdim/// type. Ideally, the type should be propagated directly into Sema. 2227226633Sdim/// 2228234353Sdim/// [C11] type-id 2229234353Sdim/// [C11] constant-expression 2230234353Sdim/// [C++0x] type-id ...[opt] 2231234353Sdim/// [C++0x] assignment-expression ...[opt] 2232234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start, 2233234353Sdim SourceLocation &EllipsisLoc) { 2234234353Sdim ExprResult ER; 2235226633Sdim if (isTypeIdInParens()) { 2236226633Sdim SourceLocation TypeLoc = Tok.getLocation(); 2237226633Sdim ParsedType Ty = ParseTypeName().get(); 2238226633Sdim SourceRange TypeRange(Start, Tok.getLocation()); 2239234353Sdim ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true, 2240234353Sdim Ty.getAsOpaquePtr(), TypeRange); 2241226633Sdim } else 2242234353Sdim ER = ParseConstantExpression(); 2243234353Sdim 2244249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis)) 2245234353Sdim EllipsisLoc = ConsumeToken(); 2246234353Sdim 2247234353Sdim return ER; 2248226633Sdim} 2249226633Sdim 2250226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the 2251226633Sdim/// attribute to Attrs. 2252226633Sdim/// 2253226633Sdim/// alignment-specifier: 2254234353Sdim/// [C11] '_Alignas' '(' type-id ')' 2255234353Sdim/// [C11] '_Alignas' '(' constant-expression ')' 2256249423Sdim/// [C++11] 'alignas' '(' type-id ...[opt] ')' 2257249423Sdim/// [C++11] 'alignas' '(' assignment-expression ...[opt] ')' 2258226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, 2259249423Sdim SourceLocation *EndLoc) { 2260226633Sdim assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) && 2261226633Sdim "Not an alignment-specifier!"); 2262226633Sdim 2263249423Sdim IdentifierInfo *KWName = Tok.getIdentifierInfo(); 2264249423Sdim SourceLocation KWLoc = ConsumeToken(); 2265226633Sdim 2266226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2267226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2268226633Sdim return; 2269226633Sdim 2270234353Sdim SourceLocation EllipsisLoc; 2271234353Sdim ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); 2272226633Sdim if (ArgExpr.isInvalid()) { 2273226633Sdim SkipUntil(tok::r_paren); 2274226633Sdim return; 2275226633Sdim } 2276226633Sdim 2277226633Sdim T.consumeClose(); 2278249423Sdim if (EndLoc) 2279249423Sdim *EndLoc = T.getCloseLocation(); 2280226633Sdim 2281243830Sdim ExprVector ArgExprs; 2282226633Sdim ArgExprs.push_back(ArgExpr.release()); 2283249423Sdim Attrs.addNew(KWName, KWLoc, 0, KWLoc, 0, T.getOpenLocation(), 2284249423Sdim ArgExprs.data(), 1, AttributeList::AS_Keyword, EllipsisLoc); 2285226633Sdim} 2286226633Sdim 2287193326Sed/// ParseDeclarationSpecifiers 2288193326Sed/// declaration-specifiers: [C99 6.7] 2289193326Sed/// storage-class-specifier declaration-specifiers[opt] 2290193326Sed/// type-specifier declaration-specifiers[opt] 2291193326Sed/// [C99] function-specifier declaration-specifiers[opt] 2292234353Sdim/// [C11] alignment-specifier declaration-specifiers[opt] 2293193326Sed/// [GNU] attributes declaration-specifiers[opt] 2294226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt] 2295193326Sed/// 2296193326Sed/// storage-class-specifier: [C99 6.7.1] 2297193326Sed/// 'typedef' 2298193326Sed/// 'extern' 2299193326Sed/// 'static' 2300193326Sed/// 'auto' 2301193326Sed/// 'register' 2302193326Sed/// [C++] 'mutable' 2303251662Sdim/// [C++11] 'thread_local' 2304251662Sdim/// [C11] '_Thread_local' 2305193326Sed/// [GNU] '__thread' 2306193326Sed/// function-specifier: [C99 6.7.4] 2307193326Sed/// [C99] 'inline' 2308193326Sed/// [C++] 'virtual' 2309193326Sed/// [C++] 'explicit' 2310218893Sdim/// [OpenCL] '__kernel' 2311193326Sed/// 'friend': [C++ dcl.friend] 2312198954Srdivacky/// 'constexpr': [C++0x dcl.constexpr] 2313193326Sed 2314193326Sed/// 2315193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS, 2316193326Sed const ParsedTemplateInfo &TemplateInfo, 2317198092Srdivacky AccessSpecifier AS, 2318234353Sdim DeclSpecContext DSContext, 2319234353Sdim LateParsedAttrList *LateAttrs) { 2320221345Sdim if (DS.getSourceRange().isInvalid()) { 2321221345Sdim DS.SetRangeStart(Tok.getLocation()); 2322221345Sdim DS.SetRangeEnd(Tok.getLocation()); 2323221345Sdim } 2324239462Sdim 2325234353Sdim bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2326239462Sdim bool AttrsLastTime = false; 2327239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 2328193326Sed while (1) { 2329198092Srdivacky bool isInvalid = false; 2330193326Sed const char *PrevSpec = 0; 2331198092Srdivacky unsigned DiagID = 0; 2332198092Srdivacky 2333193326Sed SourceLocation Loc = Tok.getLocation(); 2334193326Sed 2335193326Sed switch (Tok.getKind()) { 2336198092Srdivacky default: 2337193326Sed DoneWithDeclSpec: 2338239462Sdim if (!AttrsLastTime) 2339239462Sdim ProhibitAttributes(attrs); 2340243830Sdim else { 2341243830Sdim // Reject C++11 attributes that appertain to decl specifiers as 2342243830Sdim // we don't support any C++11 attributes that appertain to decl 2343243830Sdim // specifiers. This also conforms to what g++ 4.8 is doing. 2344243830Sdim ProhibitCXX11Attributes(attrs); 2345243830Sdim 2346239462Sdim DS.takeAttributesFrom(attrs); 2347243830Sdim } 2348226633Sdim 2349193326Sed // If this is not a declaration specifier token, we're done reading decl 2350193326Sed // specifiers. First verify that DeclSpec's are consistent. 2351193326Sed DS.Finish(Diags, PP); 2352193326Sed return; 2353198092Srdivacky 2354239462Sdim case tok::l_square: 2355239462Sdim case tok::kw_alignas: 2356249423Sdim if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier()) 2357239462Sdim goto DoneWithDeclSpec; 2358239462Sdim 2359239462Sdim ProhibitAttributes(attrs); 2360239462Sdim // FIXME: It would be good to recover by accepting the attributes, 2361239462Sdim // but attempting to do that now would cause serious 2362239462Sdim // madness in terms of diagnostics. 2363239462Sdim attrs.clear(); 2364239462Sdim attrs.Range = SourceRange(); 2365239462Sdim 2366239462Sdim ParseCXX11Attributes(attrs); 2367239462Sdim AttrsLastTime = true; 2368239462Sdim continue; 2369239462Sdim 2370212904Sdim case tok::code_completion: { 2371212904Sdim Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; 2372212904Sdim if (DS.hasTypeSpecifier()) { 2373212904Sdim bool AllowNonIdentifiers 2374212904Sdim = (getCurScope()->getFlags() & (Scope::ControlScope | 2375212904Sdim Scope::BlockScope | 2376212904Sdim Scope::TemplateParamScope | 2377212904Sdim Scope::FunctionPrototypeScope | 2378212904Sdim Scope::AtCatchScope)) == 0; 2379212904Sdim bool AllowNestedNameSpecifiers 2380239462Sdim = DSContext == DSC_top_level || 2381212904Sdim (DSContext == DSC_class && DS.isFriendSpecified()); 2382212904Sdim 2383218893Sdim Actions.CodeCompleteDeclSpec(getCurScope(), DS, 2384239462Sdim AllowNonIdentifiers, 2385218893Sdim AllowNestedNameSpecifiers); 2386226633Sdim return cutOffParsing(); 2387239462Sdim } 2388239462Sdim 2389218893Sdim if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) 2390218893Sdim CCC = Sema::PCC_LocalDeclarationSpecifiers; 2391218893Sdim else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) 2392239462Sdim CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 2393212904Sdim : Sema::PCC_Template; 2394212904Sdim else if (DSContext == DSC_class) 2395212904Sdim CCC = Sema::PCC_Class; 2396234353Sdim else if (CurParsedObjCImpl) 2397212904Sdim CCC = Sema::PCC_ObjCImplementation; 2398239462Sdim 2399212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); 2400226633Sdim return cutOffParsing(); 2401212904Sdim } 2402212904Sdim 2403193326Sed case tok::coloncolon: // ::foo::bar 2404204643Srdivacky // C++ scope specifier. Annotate and loop, or bail out on error. 2405204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 2406204643Srdivacky if (!DS.hasTypeSpecifier()) 2407204643Srdivacky DS.SetTypeSpecError(); 2408204643Srdivacky goto DoneWithDeclSpec; 2409204643Srdivacky } 2410204643Srdivacky if (Tok.is(tok::coloncolon)) // ::new or ::delete 2411204643Srdivacky goto DoneWithDeclSpec; 2412204643Srdivacky continue; 2413193326Sed 2414193326Sed case tok::annot_cxxscope: { 2415239462Sdim if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector()) 2416193326Sed goto DoneWithDeclSpec; 2417193326Sed 2418200583Srdivacky CXXScopeSpec SS; 2419219077Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2420219077Sdim Tok.getAnnotationRange(), 2421219077Sdim SS); 2422200583Srdivacky 2423193326Sed // We are looking for a qualified typename. 2424193326Sed Token Next = NextToken(); 2425198092Srdivacky if (Next.is(tok::annot_template_id) && 2426193326Sed static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) 2427193326Sed ->Kind == TNK_Type_template) { 2428193326Sed // We have a qualified template-id, e.g., N::A<int> 2429202379Srdivacky 2430202379Srdivacky // C++ [class.qual]p2: 2431202379Srdivacky // In a lookup in which the constructor is an acceptable lookup 2432202379Srdivacky // result and the nested-name-specifier nominates a class C: 2433202379Srdivacky // 2434202379Srdivacky // - if the name specified after the 2435202379Srdivacky // nested-name-specifier, when looked up in C, is the 2436202379Srdivacky // injected-class-name of C (Clause 9), or 2437202379Srdivacky // 2438202379Srdivacky // - if the name specified after the nested-name-specifier 2439202379Srdivacky // is the same as the identifier or the 2440202379Srdivacky // simple-template-id's template-name in the last 2441202379Srdivacky // component of the nested-name-specifier, 2442202379Srdivacky // 2443202379Srdivacky // the name is instead considered to name the constructor of 2444202379Srdivacky // class C. 2445239462Sdim // 2446202379Srdivacky // Thus, if the template-name is actually the constructor 2447202379Srdivacky // name, then the code is ill-formed; this interpretation is 2448239462Sdim // reinforced by the NAD status of core issue 635. 2449224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 2450249423Sdim if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2451207619Srdivacky TemplateId->Name && 2452210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 2453202379Srdivacky if (isConstructorDeclarator()) { 2454202379Srdivacky // The user meant this to be an out-of-line constructor 2455202379Srdivacky // definition, but template arguments are not allowed 2456202379Srdivacky // there. Just allow this as a constructor; we'll 2457202379Srdivacky // complain about it later. 2458202379Srdivacky goto DoneWithDeclSpec; 2459202379Srdivacky } 2460202379Srdivacky 2461202379Srdivacky // The user meant this to name a type, but it actually names 2462202379Srdivacky // a constructor with some extraneous template 2463202379Srdivacky // arguments. Complain, then parse it as a type as the user 2464202379Srdivacky // intended. 2465202379Srdivacky Diag(TemplateId->TemplateNameLoc, 2466202379Srdivacky diag::err_out_of_line_template_id_names_constructor) 2467202379Srdivacky << TemplateId->Name; 2468202379Srdivacky } 2469202379Srdivacky 2470200583Srdivacky DS.getTypeSpecScope() = SS; 2471200583Srdivacky ConsumeToken(); // The C++ scope. 2472198092Srdivacky assert(Tok.is(tok::annot_template_id) && 2473193326Sed "ParseOptionalCXXScopeSpecifier not working"); 2474221345Sdim AnnotateTemplateIdTokenAsType(); 2475193326Sed continue; 2476193326Sed } 2477193326Sed 2478198092Srdivacky if (Next.is(tok::annot_typename)) { 2479200583Srdivacky DS.getTypeSpecScope() = SS; 2480200583Srdivacky ConsumeToken(); // The C++ scope. 2481212904Sdim if (Tok.getAnnotationValue()) { 2482212904Sdim ParsedType T = getTypeAnnotation(Tok); 2483218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, 2484239462Sdim Tok.getAnnotationEndLoc(), 2485212904Sdim PrevSpec, DiagID, T); 2486243830Sdim if (isInvalid) 2487243830Sdim break; 2488212904Sdim } 2489198092Srdivacky else 2490198092Srdivacky DS.SetTypeSpecError(); 2491198092Srdivacky DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2492198092Srdivacky ConsumeToken(); // The typename 2493198092Srdivacky } 2494198092Srdivacky 2495193326Sed if (Next.isNot(tok::identifier)) 2496193326Sed goto DoneWithDeclSpec; 2497193326Sed 2498202379Srdivacky // If we're in a context where the identifier could be a class name, 2499202379Srdivacky // check whether this is a constructor declaration. 2500249423Sdim if ((DSContext == DSC_top_level || DSContext == DSC_class) && 2501239462Sdim Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 2502202379Srdivacky &SS)) { 2503202379Srdivacky if (isConstructorDeclarator()) 2504202379Srdivacky goto DoneWithDeclSpec; 2505193326Sed 2506202379Srdivacky // As noted in C++ [class.qual]p2 (cited above), when the name 2507202379Srdivacky // of the class is qualified in a context where it could name 2508202379Srdivacky // a constructor, its a constructor name. However, we've 2509202379Srdivacky // looked at the declarator, and the user probably meant this 2510202379Srdivacky // to be a type. Complain that it isn't supposed to be treated 2511202379Srdivacky // as a type, then proceed to parse it as a type. 2512202379Srdivacky Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) 2513202379Srdivacky << Next.getIdentifierInfo(); 2514202379Srdivacky } 2515202379Srdivacky 2516212904Sdim ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), 2517212904Sdim Next.getLocation(), 2518221345Sdim getCurScope(), &SS, 2519221345Sdim false, false, ParsedType(), 2520234353Sdim /*IsCtorOrDtorName=*/false, 2521221345Sdim /*NonTrivialSourceInfo=*/true); 2522193326Sed 2523193326Sed // If the referenced identifier is not a type, then this declspec is 2524193326Sed // erroneous: We already checked about that it has no type specifier, and 2525193326Sed // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the 2526198092Srdivacky // typename. 2527193326Sed if (TypeRep == 0) { 2528193326Sed ConsumeToken(); // Eat the scope spec so the identifier is current. 2529249423Sdim ParsedAttributesWithRange Attrs(AttrFactory); 2530249423Sdim if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) { 2531249423Sdim if (!Attrs.empty()) { 2532249423Sdim AttrsLastTime = true; 2533249423Sdim attrs.takeAllFrom(Attrs); 2534249423Sdim } 2535249423Sdim continue; 2536249423Sdim } 2537193326Sed goto DoneWithDeclSpec; 2538193326Sed } 2539198092Srdivacky 2540200583Srdivacky DS.getTypeSpecScope() = SS; 2541193326Sed ConsumeToken(); // The C++ scope. 2542193326Sed 2543193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2544198092Srdivacky DiagID, TypeRep); 2545193326Sed if (isInvalid) 2546193326Sed break; 2547198092Srdivacky 2548193326Sed DS.SetRangeEnd(Tok.getLocation()); 2549193326Sed ConsumeToken(); // The typename. 2550193326Sed 2551193326Sed continue; 2552193326Sed } 2553198092Srdivacky 2554193326Sed case tok::annot_typename: { 2555212904Sdim if (Tok.getAnnotationValue()) { 2556212904Sdim ParsedType T = getTypeAnnotation(Tok); 2557193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2558212904Sdim DiagID, T); 2559212904Sdim } else 2560193326Sed DS.SetTypeSpecError(); 2561239462Sdim 2562206275Srdivacky if (isInvalid) 2563206275Srdivacky break; 2564206275Srdivacky 2565193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2566193326Sed ConsumeToken(); // The typename 2567198092Srdivacky 2568193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2569193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2570239462Sdim // Objective-C interface. 2571234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2572218893Sdim ParseObjCProtocolQualifiers(DS); 2573239462Sdim 2574193326Sed continue; 2575193326Sed } 2576198092Srdivacky 2577221345Sdim case tok::kw___is_signed: 2578221345Sdim // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang 2579221345Sdim // typically treats it as a trait. If we see __is_signed as it appears 2580221345Sdim // in libstdc++, e.g., 2581221345Sdim // 2582221345Sdim // static const bool __is_signed; 2583221345Sdim // 2584221345Sdim // then treat __is_signed as an identifier rather than as a keyword. 2585221345Sdim if (DS.getTypeSpecType() == TST_bool && 2586221345Sdim DS.getTypeQualifiers() == DeclSpec::TQ_const && 2587221345Sdim DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2588221345Sdim Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 2589221345Sdim Tok.setKind(tok::identifier); 2590221345Sdim } 2591221345Sdim 2592221345Sdim // We're done with the declaration-specifiers. 2593221345Sdim goto DoneWithDeclSpec; 2594239462Sdim 2595193326Sed // typedef-name 2596234353Sdim case tok::kw_decltype: 2597193326Sed case tok::identifier: { 2598193326Sed // In C++, check to see if this is a scope specifier like foo::bar::, if 2599193326Sed // so handle it as such. This is important for ctor parsing. 2600234353Sdim if (getLangOpts().CPlusPlus) { 2601204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 2602204643Srdivacky if (!DS.hasTypeSpecifier()) 2603204643Srdivacky DS.SetTypeSpecError(); 2604204643Srdivacky goto DoneWithDeclSpec; 2605204643Srdivacky } 2606204643Srdivacky if (!Tok.is(tok::identifier)) 2607204643Srdivacky continue; 2608204643Srdivacky } 2609198092Srdivacky 2610193326Sed // This identifier can only be a typedef name if we haven't already seen 2611193326Sed // a type-specifier. Without this check we misparse: 2612193326Sed // typedef int X; struct Y { short X; }; as 'short int'. 2613193326Sed if (DS.hasTypeSpecifier()) 2614193326Sed goto DoneWithDeclSpec; 2615198092Srdivacky 2616203955Srdivacky // Check for need to substitute AltiVec keyword tokens. 2617203955Srdivacky if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) 2618203955Srdivacky break; 2619203955Srdivacky 2620239462Sdim // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not 2621239462Sdim // allow the use of a typedef name as a type specifier. 2622239462Sdim if (DS.isTypeAltiVecVector()) 2623239462Sdim goto DoneWithDeclSpec; 2624239462Sdim 2625212904Sdim ParsedType TypeRep = 2626212904Sdim Actions.getTypeName(*Tok.getIdentifierInfo(), 2627212904Sdim Tok.getLocation(), getCurScope()); 2628193326Sed 2629193326Sed // If this is not a typedef name, don't parse it as part of the declspec, 2630193326Sed // it must be an implicit int or an error. 2631212904Sdim if (!TypeRep) { 2632249423Sdim ParsedAttributesWithRange Attrs(AttrFactory); 2633249423Sdim if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) { 2634249423Sdim if (!Attrs.empty()) { 2635249423Sdim AttrsLastTime = true; 2636249423Sdim attrs.takeAllFrom(Attrs); 2637249423Sdim } 2638249423Sdim continue; 2639249423Sdim } 2640193326Sed goto DoneWithDeclSpec; 2641193326Sed } 2642193326Sed 2643202379Srdivacky // If we're in a context where the identifier could be a class name, 2644202379Srdivacky // check whether this is a constructor declaration. 2645234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2646210299Sed Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) && 2647202379Srdivacky isConstructorDeclarator()) 2648193326Sed goto DoneWithDeclSpec; 2649193326Sed 2650193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2651198092Srdivacky DiagID, TypeRep); 2652193326Sed if (isInvalid) 2653193326Sed break; 2654198092Srdivacky 2655193326Sed DS.SetRangeEnd(Tok.getLocation()); 2656193326Sed ConsumeToken(); // The identifier 2657193326Sed 2658193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2659193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2660239462Sdim // Objective-C interface. 2661234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2662218893Sdim ParseObjCProtocolQualifiers(DS); 2663239462Sdim 2664193326Sed // Need to support trailing type qualifiers (e.g. "id<p> const"). 2665193326Sed // If a type specifier follows, it will be diagnosed elsewhere. 2666193326Sed continue; 2667193326Sed } 2668193326Sed 2669193326Sed // type-name 2670193326Sed case tok::annot_template_id: { 2671224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2672193326Sed if (TemplateId->Kind != TNK_Type_template) { 2673193326Sed // This template-id does not refer to a type name, so we're 2674193326Sed // done with the type-specifiers. 2675193326Sed goto DoneWithDeclSpec; 2676193326Sed } 2677193326Sed 2678202379Srdivacky // If we're in a context where the template-id could be a 2679202379Srdivacky // constructor name or specialization, check whether this is a 2680202379Srdivacky // constructor declaration. 2681234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2682210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) && 2683202379Srdivacky isConstructorDeclarator()) 2684202379Srdivacky goto DoneWithDeclSpec; 2685202379Srdivacky 2686193326Sed // Turn the template-id annotation token into a type annotation 2687193326Sed // token, then try again to parse it as a type-specifier. 2688193326Sed AnnotateTemplateIdTokenAsType(); 2689193326Sed continue; 2690193326Sed } 2691193326Sed 2692193326Sed // GNU attributes support. 2693193326Sed case tok::kw___attribute: 2694234353Sdim ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs); 2695193326Sed continue; 2696193326Sed 2697193326Sed // Microsoft declspec support. 2698193326Sed case tok::kw___declspec: 2699218893Sdim ParseMicrosoftDeclSpec(DS.getAttributes()); 2700193326Sed continue; 2701198092Srdivacky 2702193326Sed // Microsoft single token adornments. 2703239462Sdim case tok::kw___forceinline: { 2704249423Sdim isInvalid = DS.setFunctionSpecInline(Loc); 2705239462Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 2706243830Sdim SourceLocation AttrNameLoc = Tok.getLocation(); 2707239462Sdim // FIXME: This does not work correctly if it is set to be a declspec 2708239462Sdim // attribute, and a GNU attribute is simply incorrect. 2709239462Sdim DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 2710239462Sdim SourceLocation(), 0, 0, AttributeList::AS_GNU); 2711243830Sdim break; 2712239462Sdim } 2713194179Sed 2714194179Sed case tok::kw___ptr64: 2715226633Sdim case tok::kw___ptr32: 2716193326Sed case tok::kw___w64: 2717193326Sed case tok::kw___cdecl: 2718193326Sed case tok::kw___stdcall: 2719193326Sed case tok::kw___fastcall: 2720208600Srdivacky case tok::kw___thiscall: 2721226633Sdim case tok::kw___unaligned: 2722218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 2723194179Sed continue; 2724194179Sed 2725212904Sdim // Borland single token adornments. 2726212904Sdim case tok::kw___pascal: 2727218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 2728212904Sdim continue; 2729212904Sdim 2730218893Sdim // OpenCL single token adornments. 2731218893Sdim case tok::kw___kernel: 2732218893Sdim ParseOpenCLAttributes(DS.getAttributes()); 2733218893Sdim continue; 2734218893Sdim 2735193326Sed // storage-class-specifier 2736193326Sed case tok::kw_typedef: 2737226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, 2738226633Sdim PrevSpec, DiagID); 2739193326Sed break; 2740193326Sed case tok::kw_extern: 2741251662Sdim if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2742193326Sed Diag(Tok, diag::ext_thread_before) << "extern"; 2743226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc, 2744226633Sdim PrevSpec, DiagID); 2745193326Sed break; 2746193326Sed case tok::kw___private_extern__: 2747226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern, 2748226633Sdim Loc, PrevSpec, DiagID); 2749193326Sed break; 2750193326Sed case tok::kw_static: 2751251662Sdim if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread) 2752193326Sed Diag(Tok, diag::ext_thread_before) << "static"; 2753226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc, 2754226633Sdim PrevSpec, DiagID); 2755193326Sed break; 2756193326Sed case tok::kw_auto: 2757249423Sdim if (getLangOpts().CPlusPlus11) { 2758219077Sdim if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { 2759226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2760226633Sdim PrevSpec, DiagID); 2761219077Sdim if (!isInvalid) 2762226633Sdim Diag(Tok, diag::ext_auto_storage_class) 2763219077Sdim << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); 2764226633Sdim } else 2765219077Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, 2766219077Sdim DiagID); 2767226633Sdim } else 2768226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2769226633Sdim PrevSpec, DiagID); 2770193326Sed break; 2771193326Sed case tok::kw_register: 2772226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, 2773226633Sdim PrevSpec, DiagID); 2774193326Sed break; 2775193326Sed case tok::kw_mutable: 2776226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc, 2777226633Sdim PrevSpec, DiagID); 2778193326Sed break; 2779193326Sed case tok::kw___thread: 2780251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc, 2781251662Sdim PrevSpec, DiagID); 2782193326Sed break; 2783251662Sdim case tok::kw_thread_local: 2784251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc, 2785251662Sdim PrevSpec, DiagID); 2786251662Sdim break; 2787251662Sdim case tok::kw__Thread_local: 2788251662Sdim isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local, 2789251662Sdim Loc, PrevSpec, DiagID); 2790251662Sdim break; 2791198092Srdivacky 2792193326Sed // function-specifier 2793193326Sed case tok::kw_inline: 2794249423Sdim isInvalid = DS.setFunctionSpecInline(Loc); 2795193326Sed break; 2796193326Sed case tok::kw_virtual: 2797249423Sdim isInvalid = DS.setFunctionSpecVirtual(Loc); 2798193326Sed break; 2799193326Sed case tok::kw_explicit: 2800249423Sdim isInvalid = DS.setFunctionSpecExplicit(Loc); 2801193326Sed break; 2802249423Sdim case tok::kw__Noreturn: 2803249423Sdim if (!getLangOpts().C11) 2804249423Sdim Diag(Loc, diag::ext_c11_noreturn); 2805249423Sdim isInvalid = DS.setFunctionSpecNoreturn(Loc); 2806249423Sdim break; 2807193326Sed 2808226633Sdim // alignment-specifier 2809226633Sdim case tok::kw__Alignas: 2810234353Sdim if (!getLangOpts().C11) 2811239462Sdim Diag(Tok, diag::ext_c11_alignment) << Tok.getName(); 2812226633Sdim ParseAlignmentSpecifier(DS.getAttributes()); 2813226633Sdim continue; 2814226633Sdim 2815193326Sed // friend 2816193326Sed case tok::kw_friend: 2817198092Srdivacky if (DSContext == DSC_class) 2818198092Srdivacky isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); 2819198092Srdivacky else { 2820198092Srdivacky PrevSpec = ""; // not actually used by the diagnostic 2821198092Srdivacky DiagID = diag::err_friend_invalid_in_context; 2822198092Srdivacky isInvalid = true; 2823198092Srdivacky } 2824193326Sed break; 2825198092Srdivacky 2826226633Sdim // Modules 2827226633Sdim case tok::kw___module_private__: 2828226633Sdim isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); 2829226633Sdim break; 2830239462Sdim 2831198954Srdivacky // constexpr 2832198954Srdivacky case tok::kw_constexpr: 2833198954Srdivacky isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); 2834198954Srdivacky break; 2835198954Srdivacky 2836193326Sed // type-specifier 2837193326Sed case tok::kw_short: 2838198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, 2839198092Srdivacky DiagID); 2840193326Sed break; 2841193326Sed case tok::kw_long: 2842193326Sed if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) 2843198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, 2844198092Srdivacky DiagID); 2845193326Sed else 2846198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2847198092Srdivacky DiagID); 2848193326Sed break; 2849221345Sdim case tok::kw___int64: 2850221345Sdim isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2851221345Sdim DiagID); 2852221345Sdim break; 2853193326Sed case tok::kw_signed: 2854198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, 2855198092Srdivacky DiagID); 2856193326Sed break; 2857193326Sed case tok::kw_unsigned: 2858198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, 2859198092Srdivacky DiagID); 2860193326Sed break; 2861193326Sed case tok::kw__Complex: 2862198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec, 2863198092Srdivacky DiagID); 2864193326Sed break; 2865193326Sed case tok::kw__Imaginary: 2866198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec, 2867198092Srdivacky DiagID); 2868193326Sed break; 2869193326Sed case tok::kw_void: 2870198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, 2871198092Srdivacky DiagID); 2872193326Sed break; 2873193326Sed case tok::kw_char: 2874198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, 2875198092Srdivacky DiagID); 2876193326Sed break; 2877193326Sed case tok::kw_int: 2878198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, 2879198092Srdivacky DiagID); 2880193326Sed break; 2881234353Sdim case tok::kw___int128: 2882234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, 2883234353Sdim DiagID); 2884234353Sdim break; 2885234353Sdim case tok::kw_half: 2886234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, 2887234353Sdim DiagID); 2888234353Sdim break; 2889193326Sed case tok::kw_float: 2890198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, 2891198092Srdivacky DiagID); 2892193326Sed break; 2893193326Sed case tok::kw_double: 2894198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, 2895198092Srdivacky DiagID); 2896193326Sed break; 2897193326Sed case tok::kw_wchar_t: 2898198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, 2899198092Srdivacky DiagID); 2900193326Sed break; 2901198092Srdivacky case tok::kw_char16_t: 2902198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, 2903198092Srdivacky DiagID); 2904198092Srdivacky break; 2905198092Srdivacky case tok::kw_char32_t: 2906198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, 2907198092Srdivacky DiagID); 2908198092Srdivacky break; 2909193326Sed case tok::kw_bool: 2910193326Sed case tok::kw__Bool: 2911218893Sdim if (Tok.is(tok::kw_bool) && 2912218893Sdim DS.getTypeSpecType() != DeclSpec::TST_unspecified && 2913218893Sdim DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 2914218893Sdim PrevSpec = ""; // Not used by the diagnostic. 2915218893Sdim DiagID = diag::err_bool_redeclaration; 2916221345Sdim // For better error recovery. 2917221345Sdim Tok.setKind(tok::identifier); 2918218893Sdim isInvalid = true; 2919218893Sdim } else { 2920218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, 2921218893Sdim DiagID); 2922218893Sdim } 2923193326Sed break; 2924193326Sed case tok::kw__Decimal32: 2925198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec, 2926198092Srdivacky DiagID); 2927193326Sed break; 2928193326Sed case tok::kw__Decimal64: 2929198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec, 2930198092Srdivacky DiagID); 2931193326Sed break; 2932193326Sed case tok::kw__Decimal128: 2933198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, 2934198092Srdivacky DiagID); 2935193326Sed break; 2936203955Srdivacky case tok::kw___vector: 2937203955Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 2938203955Srdivacky break; 2939203955Srdivacky case tok::kw___pixel: 2940203955Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 2941203955Srdivacky break; 2942249423Sdim case tok::kw_image1d_t: 2943249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc, 2944249423Sdim PrevSpec, DiagID); 2945249423Sdim break; 2946249423Sdim case tok::kw_image1d_array_t: 2947249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc, 2948249423Sdim PrevSpec, DiagID); 2949249423Sdim break; 2950249423Sdim case tok::kw_image1d_buffer_t: 2951249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc, 2952249423Sdim PrevSpec, DiagID); 2953249423Sdim break; 2954249423Sdim case tok::kw_image2d_t: 2955249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc, 2956249423Sdim PrevSpec, DiagID); 2957249423Sdim break; 2958249423Sdim case tok::kw_image2d_array_t: 2959249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc, 2960249423Sdim PrevSpec, DiagID); 2961249423Sdim break; 2962249423Sdim case tok::kw_image3d_t: 2963249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc, 2964249423Sdim PrevSpec, DiagID); 2965249423Sdim break; 2966249423Sdim case tok::kw_sampler_t: 2967249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc, 2968249423Sdim PrevSpec, DiagID); 2969249423Sdim break; 2970249423Sdim case tok::kw_event_t: 2971249423Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc, 2972249423Sdim PrevSpec, DiagID); 2973249423Sdim break; 2974221345Sdim case tok::kw___unknown_anytype: 2975221345Sdim isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, 2976221345Sdim PrevSpec, DiagID); 2977221345Sdim break; 2978193326Sed 2979193326Sed // class-specifier: 2980193326Sed case tok::kw_class: 2981193326Sed case tok::kw_struct: 2982243830Sdim case tok::kw___interface: 2983193326Sed case tok::kw_union: { 2984193326Sed tok::TokenKind Kind = Tok.getKind(); 2985193326Sed ConsumeToken(); 2986249423Sdim 2987249423Sdim // These are attributes following class specifiers. 2988249423Sdim // To produce better diagnostic, we parse them when 2989249423Sdim // parsing class specifier. 2990249423Sdim ParsedAttributesWithRange Attributes(AttrFactory); 2991234353Sdim ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, 2992249423Sdim EnteringContext, DSContext, Attributes); 2993249423Sdim 2994249423Sdim // If there are attributes following class specifier, 2995249423Sdim // take them over and handle them here. 2996249423Sdim if (!Attributes.empty()) { 2997249423Sdim AttrsLastTime = true; 2998249423Sdim attrs.takeAllFrom(Attributes); 2999249423Sdim } 3000193326Sed continue; 3001193326Sed } 3002193326Sed 3003193326Sed // enum-specifier: 3004193326Sed case tok::kw_enum: 3005193326Sed ConsumeToken(); 3006234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext); 3007193326Sed continue; 3008193326Sed 3009193326Sed // cv-qualifier: 3010193326Sed case tok::kw_const: 3011198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, 3012243830Sdim getLangOpts()); 3013193326Sed break; 3014193326Sed case tok::kw_volatile: 3015198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 3016243830Sdim getLangOpts()); 3017193326Sed break; 3018193326Sed case tok::kw_restrict: 3019198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 3020243830Sdim getLangOpts()); 3021193326Sed break; 3022193326Sed 3023193326Sed // C++ typename-specifier: 3024193326Sed case tok::kw_typename: 3025204643Srdivacky if (TryAnnotateTypeOrScopeToken()) { 3026204643Srdivacky DS.SetTypeSpecError(); 3027204643Srdivacky goto DoneWithDeclSpec; 3028204643Srdivacky } 3029204643Srdivacky if (!Tok.is(tok::kw_typename)) 3030193326Sed continue; 3031193326Sed break; 3032193326Sed 3033193326Sed // GNU typeof support. 3034193326Sed case tok::kw_typeof: 3035193326Sed ParseTypeofSpecifier(DS); 3036193326Sed continue; 3037193326Sed 3038234353Sdim case tok::annot_decltype: 3039195099Sed ParseDecltypeSpecifier(DS); 3040195099Sed continue; 3041195099Sed 3042223017Sdim case tok::kw___underlying_type: 3043223017Sdim ParseUnderlyingTypeSpecifier(DS); 3044226633Sdim continue; 3045223017Sdim 3046226633Sdim case tok::kw__Atomic: 3047249423Sdim // C11 6.7.2.4/4: 3048249423Sdim // If the _Atomic keyword is immediately followed by a left parenthesis, 3049249423Sdim // it is interpreted as a type specifier (with a type name), not as a 3050249423Sdim // type qualifier. 3051249423Sdim if (NextToken().is(tok::l_paren)) { 3052249423Sdim ParseAtomicSpecifier(DS); 3053249423Sdim continue; 3054249423Sdim } 3055249423Sdim isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 3056249423Sdim getLangOpts()); 3057249423Sdim break; 3058226633Sdim 3059221345Sdim // OpenCL qualifiers: 3060239462Sdim case tok::kw_private: 3061234353Sdim if (!getLangOpts().OpenCL) 3062221345Sdim goto DoneWithDeclSpec; 3063221345Sdim case tok::kw___private: 3064221345Sdim case tok::kw___global: 3065221345Sdim case tok::kw___local: 3066221345Sdim case tok::kw___constant: 3067221345Sdim case tok::kw___read_only: 3068221345Sdim case tok::kw___write_only: 3069221345Sdim case tok::kw___read_write: 3070221345Sdim ParseOpenCLQualifiers(DS); 3071221345Sdim break; 3072239462Sdim 3073193326Sed case tok::less: 3074193326Sed // GCC ObjC supports types like "<SomeProtocol>" as a synonym for 3075193326Sed // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous, 3076193326Sed // but we support it. 3077234353Sdim if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1) 3078193326Sed goto DoneWithDeclSpec; 3079198092Srdivacky 3080218893Sdim if (!ParseObjCProtocolQualifiers(DS)) 3081193326Sed Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) 3082206084Srdivacky << FixItHint::CreateInsertion(Loc, "id") 3083218893Sdim << SourceRange(Loc, DS.getSourceRange().getEnd()); 3084239462Sdim 3085218893Sdim // Need to support trailing type qualifiers (e.g. "id<p> const"). 3086218893Sdim // If a type specifier follows, it will be diagnosed elsewhere. 3087218893Sdim continue; 3088193326Sed } 3089198092Srdivacky // If the specifier wasn't legal, issue a diagnostic. 3090193326Sed if (isInvalid) { 3091193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 3092198092Srdivacky assert(DiagID); 3093239462Sdim 3094212904Sdim if (DiagID == diag::ext_duplicate_declspec) 3095212904Sdim Diag(Tok, DiagID) 3096212904Sdim << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); 3097212904Sdim else 3098212904Sdim Diag(Tok, DiagID) << PrevSpec; 3099193326Sed } 3100219077Sdim 3101193326Sed DS.SetRangeEnd(Tok.getLocation()); 3102221345Sdim if (DiagID != diag::err_bool_redeclaration) 3103221345Sdim ConsumeToken(); 3104239462Sdim 3105239462Sdim AttrsLastTime = false; 3106193326Sed } 3107193326Sed} 3108193326Sed 3109193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating 3110193326Sed/// semicolon. 3111193326Sed/// 3112193326Sed/// struct-declaration: 3113193326Sed/// specifier-qualifier-list struct-declarator-list 3114193326Sed/// [GNU] __extension__ struct-declaration 3115193326Sed/// [GNU] specifier-qualifier-list 3116193326Sed/// struct-declarator-list: 3117193326Sed/// struct-declarator 3118193326Sed/// struct-declarator-list ',' struct-declarator 3119193326Sed/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator 3120193326Sed/// struct-declarator: 3121193326Sed/// declarator 3122193326Sed/// [GNU] declarator attributes[opt] 3123193326Sed/// declarator[opt] ':' constant-expression 3124193326Sed/// [GNU] declarator[opt] ':' constant-expression attributes[opt] 3125193326Sed/// 3126193326Sedvoid Parser:: 3127239462SdimParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) { 3128239462Sdim 3129193326Sed if (Tok.is(tok::kw___extension__)) { 3130193326Sed // __extension__ silences extension warnings in the subexpression. 3131193326Sed ExtensionRAIIObject O(Diags); // Use RAII to do this. 3132193326Sed ConsumeToken(); 3133193326Sed return ParseStructDeclaration(DS, Fields); 3134193326Sed } 3135198092Srdivacky 3136193326Sed // Parse the common specifier-qualifiers-list piece. 3137193326Sed ParseSpecifierQualifierList(DS); 3138198092Srdivacky 3139193326Sed // If there are no declarators, this is a free-standing declaration 3140193326Sed // specifier. Let the actions module cope with it. 3141193326Sed if (Tok.is(tok::semi)) { 3142239462Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 3143239462Sdim DS); 3144239462Sdim DS.complete(TheDecl); 3145193326Sed return; 3146193326Sed } 3147193326Sed 3148193326Sed // Read struct-declarators until we find the semicolon. 3149198893Srdivacky bool FirstDeclarator = true; 3150234353Sdim SourceLocation CommaLoc; 3151193326Sed while (1) { 3152239462Sdim ParsingFieldDeclarator DeclaratorInfo(*this, DS); 3153234353Sdim DeclaratorInfo.D.setCommaLoc(CommaLoc); 3154198092Srdivacky 3155198893Srdivacky // Attributes are only allowed here on successive declarators. 3156218893Sdim if (!FirstDeclarator) 3157218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 3158198893Srdivacky 3159193326Sed /// struct-declarator: declarator 3160193326Sed /// struct-declarator: declarator[opt] ':' constant-expression 3161200583Srdivacky if (Tok.isNot(tok::colon)) { 3162200583Srdivacky // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 3163200583Srdivacky ColonProtectionRAIIObject X(*this); 3164193326Sed ParseDeclarator(DeclaratorInfo.D); 3165200583Srdivacky } 3166198092Srdivacky 3167193326Sed if (Tok.is(tok::colon)) { 3168193326Sed ConsumeToken(); 3169212904Sdim ExprResult Res(ParseConstantExpression()); 3170193326Sed if (Res.isInvalid()) 3171193326Sed SkipUntil(tok::semi, true, true); 3172193326Sed else 3173193326Sed DeclaratorInfo.BitfieldSize = Res.release(); 3174193326Sed } 3175193326Sed 3176193326Sed // If attributes exist after the declarator, parse them. 3177218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 3178193326Sed 3179198893Srdivacky // We're done with this declarator; invoke the callback. 3180239462Sdim Fields.invoke(DeclaratorInfo); 3181198893Srdivacky 3182193326Sed // If we don't have a comma, it is either the end of the list (a ';') 3183193326Sed // or an error, bail out. 3184193326Sed if (Tok.isNot(tok::comma)) 3185193326Sed return; 3186193326Sed 3187193326Sed // Consume the comma. 3188234353Sdim CommaLoc = ConsumeToken(); 3189193326Sed 3190198893Srdivacky FirstDeclarator = false; 3191193326Sed } 3192193326Sed} 3193193326Sed 3194193326Sed/// ParseStructUnionBody 3195193326Sed/// struct-contents: 3196193326Sed/// struct-declaration-list 3197193326Sed/// [EXT] empty 3198193326Sed/// [GNU] "struct-declaration-list" without terminatoring ';' 3199193326Sed/// struct-declaration-list: 3200193326Sed/// struct-declaration 3201193326Sed/// struct-declaration-list struct-declaration 3202193326Sed/// [OBC] '@' 'defs' '(' class-name ')' 3203193326Sed/// 3204193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc, 3205212904Sdim unsigned TagType, Decl *TagDecl) { 3206212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 3207212904Sdim "parsing struct/union body"); 3208249423Sdim assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); 3209198092Srdivacky 3210226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3211226633Sdim if (T.consumeOpen()) 3212226633Sdim return; 3213198092Srdivacky 3214193326Sed ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); 3215210299Sed Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 3216193326Sed 3217249423Sdim // Empty structs are an extension in C (C99 6.7.2.1p7). 3218249423Sdim if (Tok.is(tok::r_brace)) { 3219234353Sdim Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union); 3220234353Sdim Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union); 3221234353Sdim } 3222193326Sed 3223226633Sdim SmallVector<Decl *, 32> FieldDecls; 3224193326Sed 3225193326Sed // While we still have something to read, read the declarations in the struct. 3226193326Sed while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3227193326Sed // Each iteration of this loop reads one struct-declaration. 3228198092Srdivacky 3229193326Sed // Check for extraneous top-level semicolon. 3230193326Sed if (Tok.is(tok::semi)) { 3231239462Sdim ConsumeExtraSemi(InsideStruct, TagType); 3232193326Sed continue; 3233193326Sed } 3234193326Sed 3235249423Sdim // Parse _Static_assert declaration. 3236249423Sdim if (Tok.is(tok::kw__Static_assert)) { 3237249423Sdim SourceLocation DeclEnd; 3238249423Sdim ParseStaticAssertDeclaration(DeclEnd); 3239249423Sdim continue; 3240249423Sdim } 3241249423Sdim 3242251662Sdim if (Tok.is(tok::annot_pragma_pack)) { 3243251662Sdim HandlePragmaPack(); 3244251662Sdim continue; 3245251662Sdim } 3246251662Sdim 3247251662Sdim if (Tok.is(tok::annot_pragma_align)) { 3248251662Sdim HandlePragmaAlign(); 3249251662Sdim continue; 3250251662Sdim } 3251251662Sdim 3252193326Sed if (!Tok.is(tok::at)) { 3253198893Srdivacky struct CFieldCallback : FieldCallback { 3254198893Srdivacky Parser &P; 3255212904Sdim Decl *TagDecl; 3256226633Sdim SmallVectorImpl<Decl *> &FieldDecls; 3257198092Srdivacky 3258212904Sdim CFieldCallback(Parser &P, Decl *TagDecl, 3259226633Sdim SmallVectorImpl<Decl *> &FieldDecls) : 3260198893Srdivacky P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} 3261198893Srdivacky 3262239462Sdim void invoke(ParsingFieldDeclarator &FD) { 3263198893Srdivacky // Install the declarator into the current TagDecl. 3264212904Sdim Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, 3265198893Srdivacky FD.D.getDeclSpec().getSourceRange().getBegin(), 3266198893Srdivacky FD.D, FD.BitfieldSize); 3267198893Srdivacky FieldDecls.push_back(Field); 3268239462Sdim FD.complete(Field); 3269198092Srdivacky } 3270198893Srdivacky } Callback(*this, TagDecl, FieldDecls); 3271198893Srdivacky 3272239462Sdim // Parse all the comma separated declarators. 3273239462Sdim ParsingDeclSpec DS(*this); 3274198893Srdivacky ParseStructDeclaration(DS, Callback); 3275193326Sed } else { // Handle @defs 3276193326Sed ConsumeToken(); 3277193326Sed if (!Tok.isObjCAtKeyword(tok::objc_defs)) { 3278193326Sed Diag(Tok, diag::err_unexpected_at); 3279203955Srdivacky SkipUntil(tok::semi, true); 3280193326Sed continue; 3281193326Sed } 3282193326Sed ConsumeToken(); 3283193326Sed ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); 3284193326Sed if (!Tok.is(tok::identifier)) { 3285193326Sed Diag(Tok, diag::err_expected_ident); 3286203955Srdivacky SkipUntil(tok::semi, true); 3287193326Sed continue; 3288193326Sed } 3289226633Sdim SmallVector<Decl *, 16> Fields; 3290210299Sed Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), 3291193326Sed Tok.getIdentifierInfo(), Fields); 3292193326Sed FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); 3293193326Sed ConsumeToken(); 3294193326Sed ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); 3295198092Srdivacky } 3296193326Sed 3297193326Sed if (Tok.is(tok::semi)) { 3298193326Sed ConsumeToken(); 3299193326Sed } else if (Tok.is(tok::r_brace)) { 3300203955Srdivacky ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); 3301193326Sed break; 3302193326Sed } else { 3303203955Srdivacky ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 3304203955Srdivacky // Skip to end of block or statement to avoid ext-warning on extra ';'. 3305193326Sed SkipUntil(tok::r_brace, true, true); 3306203955Srdivacky // If we stopped at a ';', eat it. 3307203955Srdivacky if (Tok.is(tok::semi)) ConsumeToken(); 3308193326Sed } 3309193326Sed } 3310198092Srdivacky 3311226633Sdim T.consumeClose(); 3312198092Srdivacky 3313221345Sdim ParsedAttributes attrs(AttrFactory); 3314193326Sed // If attributes exist after struct contents, parse them. 3315218893Sdim MaybeParseGNUAttributes(attrs); 3316193326Sed 3317210299Sed Actions.ActOnFields(getCurScope(), 3318226633Sdim RecordLoc, TagDecl, FieldDecls, 3319226633Sdim T.getOpenLocation(), T.getCloseLocation(), 3320218893Sdim attrs.getList()); 3321193326Sed StructScope.Exit(); 3322226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 3323226633Sdim T.getCloseLocation()); 3324193326Sed} 3325193326Sed 3326193326Sed/// ParseEnumSpecifier 3327193326Sed/// enum-specifier: [C99 6.7.2.2] 3328193326Sed/// 'enum' identifier[opt] '{' enumerator-list '}' 3329193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}' 3330193326Sed/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt] 3331193326Sed/// '}' attributes[opt] 3332234353Sdim/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt] 3333234353Sdim/// '}' 3334193326Sed/// 'enum' identifier 3335193326Sed/// [GNU] 'enum' attributes[opt] identifier 3336193326Sed/// 3337234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}' 3338234353Sdim/// [C++11] enum-head '{' enumerator-list ',' '}' 3339218893Sdim/// 3340234353Sdim/// enum-head: [C++11] 3341234353Sdim/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt] 3342234353Sdim/// enum-key attribute-specifier-seq[opt] nested-name-specifier 3343234353Sdim/// identifier enum-base[opt] 3344218893Sdim/// 3345234353Sdim/// enum-key: [C++11] 3346218893Sdim/// 'enum' 3347218893Sdim/// 'enum' 'class' 3348218893Sdim/// 'enum' 'struct' 3349218893Sdim/// 3350234353Sdim/// enum-base: [C++11] 3351218893Sdim/// ':' type-specifier-seq 3352218893Sdim/// 3353193326Sed/// [C++] elaborated-type-specifier: 3354193326Sed/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier 3355193326Sed/// 3356193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, 3357204643Srdivacky const ParsedTemplateInfo &TemplateInfo, 3358234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 3359193326Sed // Parse the tag portion of this. 3360198092Srdivacky if (Tok.is(tok::code_completion)) { 3361198092Srdivacky // Code completion for an enum name. 3362210299Sed Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); 3363226633Sdim return cutOffParsing(); 3364198092Srdivacky } 3365224145Sdim 3366239462Sdim // If attributes exist after tag, parse them. 3367239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3368239462Sdim MaybeParseGNUAttributes(attrs); 3369249423Sdim MaybeParseCXX11Attributes(attrs); 3370239462Sdim 3371239462Sdim // If declspecs exist after tag, parse them. 3372239462Sdim while (Tok.is(tok::kw___declspec)) 3373239462Sdim ParseMicrosoftDeclSpec(attrs); 3374239462Sdim 3375234353Sdim SourceLocation ScopedEnumKWLoc; 3376224145Sdim bool IsScopedUsingClassTag = false; 3377224145Sdim 3378239462Sdim // In C++11, recognize 'enum class' and 'enum struct'. 3379251662Sdim if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) { 3380251662Sdim Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum 3381251662Sdim : diag::ext_scoped_enum); 3382224145Sdim IsScopedUsingClassTag = Tok.is(tok::kw_class); 3383234353Sdim ScopedEnumKWLoc = ConsumeToken(); 3384234353Sdim 3385239462Sdim // Attributes are not allowed between these keywords. Diagnose, 3386239462Sdim // but then just treat them like they appeared in the right place. 3387239462Sdim ProhibitAttributes(attrs); 3388234353Sdim 3389239462Sdim // They are allowed afterwards, though. 3390239462Sdim MaybeParseGNUAttributes(attrs); 3391249423Sdim MaybeParseCXX11Attributes(attrs); 3392239462Sdim while (Tok.is(tok::kw___declspec)) 3393239462Sdim ParseMicrosoftDeclSpec(attrs); 3394239462Sdim } 3395193326Sed 3396239462Sdim // C++11 [temp.explicit]p12: 3397239462Sdim // The usual access controls do not apply to names used to specify 3398239462Sdim // explicit instantiations. 3399239462Sdim // We extend this to also cover explicit specializations. Note that 3400239462Sdim // we don't suppress if this turns out to be an elaborated type 3401239462Sdim // specifier. 3402239462Sdim bool shouldDelayDiagsInTag = 3403239462Sdim (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 3404239462Sdim TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 3405239462Sdim SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 3406224145Sdim 3407234353Sdim // Enum definitions should not be parsed in a trailing-return-type. 3408234353Sdim bool AllowDeclaration = DSC != DSC_trailing; 3409234353Sdim 3410234353Sdim bool AllowFixedUnderlyingType = AllowDeclaration && 3411249423Sdim (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt || 3412234353Sdim getLangOpts().ObjC2); 3413234353Sdim 3414208600Srdivacky CXXScopeSpec &SS = DS.getTypeSpecScope(); 3415234353Sdim if (getLangOpts().CPlusPlus) { 3416224145Sdim // "enum foo : bar;" is not a potential typo for "enum foo::bar;" 3417224145Sdim // if a fixed underlying type is allowed. 3418224145Sdim ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); 3419239462Sdim 3420239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3421249423Sdim /*EnteringContext=*/true)) 3422204643Srdivacky return; 3423204643Srdivacky 3424204643Srdivacky if (SS.isSet() && Tok.isNot(tok::identifier)) { 3425193326Sed Diag(Tok, diag::err_expected_ident); 3426193326Sed if (Tok.isNot(tok::l_brace)) { 3427193326Sed // Has no name and is not a definition. 3428193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3429193326Sed SkipUntil(tok::comma, true); 3430193326Sed return; 3431193326Sed } 3432193326Sed } 3433193326Sed } 3434198092Srdivacky 3435193326Sed // Must have either 'enum name' or 'enum {...}'. 3436219077Sdim if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && 3437234353Sdim !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { 3438193326Sed Diag(Tok, diag::err_expected_ident_lbrace); 3439198092Srdivacky 3440193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3441193326Sed SkipUntil(tok::comma, true); 3442193326Sed return; 3443193326Sed } 3444198092Srdivacky 3445193326Sed // If an identifier is present, consume and remember it. 3446193326Sed IdentifierInfo *Name = 0; 3447193326Sed SourceLocation NameLoc; 3448193326Sed if (Tok.is(tok::identifier)) { 3449193326Sed Name = Tok.getIdentifierInfo(); 3450193326Sed NameLoc = ConsumeToken(); 3451193326Sed } 3452198092Srdivacky 3453234353Sdim if (!Name && ScopedEnumKWLoc.isValid()) { 3454218893Sdim // C++0x 7.2p2: The optional identifier shall not be omitted in the 3455218893Sdim // declaration of a scoped enumeration. 3456218893Sdim Diag(Tok, diag::err_scoped_enum_missing_identifier); 3457234353Sdim ScopedEnumKWLoc = SourceLocation(); 3458218893Sdim IsScopedUsingClassTag = false; 3459218893Sdim } 3460218893Sdim 3461239462Sdim // Okay, end the suppression area. We'll decide whether to emit the 3462239462Sdim // diagnostics in a second. 3463239462Sdim if (shouldDelayDiagsInTag) 3464239462Sdim diagsFromTag.done(); 3465234353Sdim 3466218893Sdim TypeResult BaseType; 3467218893Sdim 3468218893Sdim // Parse the fixed underlying type. 3469239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3470219077Sdim if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { 3471218893Sdim bool PossibleBitfield = false; 3472239462Sdim if (CanBeBitfield) { 3473218893Sdim // If we're in class scope, this can either be an enum declaration with 3474218893Sdim // an underlying type, or a declaration of a bitfield member. We try to 3475218893Sdim // use a simple disambiguation scheme first to catch the common cases 3476239462Sdim // (integer literal, sizeof); if it's still ambiguous, we then consider 3477239462Sdim // anything that's a simple-type-specifier followed by '(' as an 3478239462Sdim // expression. This suffices because function types are not valid 3479218893Sdim // underlying types anyway. 3480243830Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 3481243830Sdim Sema::ConstantEvaluated); 3482218893Sdim TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind()); 3483239462Sdim // If the next token starts an expression, we know we're parsing a 3484218893Sdim // bit-field. This is the common case. 3485218893Sdim if (TPR == TPResult::True()) 3486218893Sdim PossibleBitfield = true; 3487218893Sdim // If the next token starts a type-specifier-seq, it may be either a 3488218893Sdim // a fixed underlying type or the start of a function-style cast in C++; 3489239462Sdim // lookahead one more token to see if it's obvious that we have a 3490218893Sdim // fixed underlying type. 3491239462Sdim else if (TPR == TPResult::False() && 3492218893Sdim GetLookAheadToken(2).getKind() == tok::semi) { 3493218893Sdim // Consume the ':'. 3494218893Sdim ConsumeToken(); 3495218893Sdim } else { 3496218893Sdim // We have the start of a type-specifier-seq, so we have to perform 3497218893Sdim // tentative parsing to determine whether we have an expression or a 3498218893Sdim // type. 3499218893Sdim TentativeParsingAction TPA(*this); 3500218893Sdim 3501218893Sdim // Consume the ':'. 3502218893Sdim ConsumeToken(); 3503234353Sdim 3504234353Sdim // If we see a type specifier followed by an open-brace, we have an 3505234353Sdim // ambiguity between an underlying type and a C++11 braced 3506234353Sdim // function-style cast. Resolve this by always treating it as an 3507234353Sdim // underlying type. 3508234353Sdim // FIXME: The standard is not entirely clear on how to disambiguate in 3509234353Sdim // this case. 3510234353Sdim if ((getLangOpts().CPlusPlus && 3511234353Sdim isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) || 3512234353Sdim (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) { 3513218893Sdim // We'll parse this as a bitfield later. 3514218893Sdim PossibleBitfield = true; 3515218893Sdim TPA.Revert(); 3516218893Sdim } else { 3517218893Sdim // We have a type-specifier-seq. 3518218893Sdim TPA.Commit(); 3519218893Sdim } 3520218893Sdim } 3521218893Sdim } else { 3522218893Sdim // Consume the ':'. 3523218893Sdim ConsumeToken(); 3524218893Sdim } 3525218893Sdim 3526218893Sdim if (!PossibleBitfield) { 3527218893Sdim SourceRange Range; 3528218893Sdim BaseType = ParseTypeName(&Range); 3529239462Sdim 3530249423Sdim if (getLangOpts().CPlusPlus11) { 3531234353Sdim Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type); 3532243830Sdim } else if (!getLangOpts().ObjC2) { 3533243830Sdim if (getLangOpts().CPlusPlus) 3534243830Sdim Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range; 3535243830Sdim else 3536243830Sdim Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range; 3537243830Sdim } 3538218893Sdim } 3539218893Sdim } 3540218893Sdim 3541234353Sdim // There are four options here. If we have 'friend enum foo;' then this is a 3542234353Sdim // friend declaration, and cannot have an accompanying definition. If we have 3543234353Sdim // 'enum foo;', then this is a forward declaration. If we have 3544234353Sdim // 'enum foo {...' then this is a definition. Otherwise we have something 3545234353Sdim // like 'enum foo xyz', a reference. 3546193326Sed // 3547193326Sed // This is needed to handle stuff like this right (C99 6.7.2.3p11): 3548193326Sed // enum foo {..}; void bar() { enum foo; } <- new foo in bar. 3549193326Sed // enum foo {..}; void bar() { enum foo x; } <- use of old foo. 3550193326Sed // 3551212904Sdim Sema::TagUseKind TUK; 3552239462Sdim if (!AllowDeclaration) { 3553234353Sdim TUK = Sema::TUK_Reference; 3554239462Sdim } else if (Tok.is(tok::l_brace)) { 3555239462Sdim if (DS.isFriendSpecified()) { 3556239462Sdim Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 3557239462Sdim << SourceRange(DS.getFriendSpecLoc()); 3558239462Sdim ConsumeBrace(); 3559239462Sdim SkipUntil(tok::r_brace); 3560239462Sdim TUK = Sema::TUK_Friend; 3561239462Sdim } else { 3562239462Sdim TUK = Sema::TUK_Definition; 3563239462Sdim } 3564239462Sdim } else if (DSC != DSC_type_specifier && 3565239462Sdim (Tok.is(tok::semi) || 3566239462Sdim (Tok.isAtStartOfLine() && 3567239462Sdim !isValidAfterTypeSpecifier(CanBeBitfield)))) { 3568239462Sdim TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 3569239462Sdim if (Tok.isNot(tok::semi)) { 3570239462Sdim // A semicolon was missing after this declaration. Diagnose and recover. 3571239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 3572239462Sdim "enum"); 3573239462Sdim PP.EnterToken(Tok); 3574239462Sdim Tok.setKind(tok::semi); 3575239462Sdim } 3576239462Sdim } else { 3577212904Sdim TUK = Sema::TUK_Reference; 3578239462Sdim } 3579234353Sdim 3580239462Sdim // If this is an elaborated type specifier, and we delayed 3581239462Sdim // diagnostics before, just merge them into the current pool. 3582239462Sdim if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) { 3583239462Sdim diagsFromTag.redelay(); 3584239462Sdim } 3585239462Sdim 3586234353Sdim MultiTemplateParamsArg TParams; 3587207619Srdivacky if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 3588212904Sdim TUK != Sema::TUK_Reference) { 3589249423Sdim if (!getLangOpts().CPlusPlus11 || !SS.isSet()) { 3590234353Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3591234353Sdim Diag(Tok, diag::err_enum_template); 3592234353Sdim SkipUntil(tok::comma, true); 3593234353Sdim return; 3594234353Sdim } 3595234353Sdim 3596234353Sdim if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 3597234353Sdim // Enumerations can't be explicitly instantiated. 3598234353Sdim DS.SetTypeSpecError(); 3599234353Sdim Diag(StartLoc, diag::err_explicit_instantiation_enum); 3600234353Sdim return; 3601234353Sdim } 3602234353Sdim 3603234353Sdim assert(TemplateInfo.TemplateParams && "no template parameters"); 3604234353Sdim TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(), 3605234353Sdim TemplateInfo.TemplateParams->size()); 3606207619Srdivacky } 3607234353Sdim 3608239462Sdim if (TUK == Sema::TUK_Reference) 3609239462Sdim ProhibitAttributes(attrs); 3610239462Sdim 3611219077Sdim if (!Name && TUK != Sema::TUK_Definition) { 3612219077Sdim Diag(Tok, diag::err_enumerator_unnamed_no_def); 3613234353Sdim 3614219077Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3615219077Sdim SkipUntil(tok::comma, true); 3616219077Sdim return; 3617219077Sdim } 3618234353Sdim 3619193326Sed bool Owned = false; 3620198092Srdivacky bool IsDependent = false; 3621207619Srdivacky const char *PrevSpec = 0; 3622207619Srdivacky unsigned DiagID; 3623212904Sdim Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, 3624218893Sdim StartLoc, SS, Name, NameLoc, attrs.getList(), 3625234353Sdim AS, DS.getModulePrivateSpecLoc(), TParams, 3626234353Sdim Owned, IsDependent, ScopedEnumKWLoc, 3627218893Sdim IsScopedUsingClassTag, BaseType); 3628218893Sdim 3629207619Srdivacky if (IsDependent) { 3630239462Sdim // This enum has a dependent nested-name-specifier. Handle it as a 3631207619Srdivacky // dependent tag. 3632207619Srdivacky if (!Name) { 3633207619Srdivacky DS.SetTypeSpecError(); 3634207619Srdivacky Diag(Tok, diag::err_expected_type_name_after_typename); 3635207619Srdivacky return; 3636207619Srdivacky } 3637239462Sdim 3638210299Sed TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum, 3639239462Sdim TUK, SS, Name, StartLoc, 3640207619Srdivacky NameLoc); 3641207619Srdivacky if (Type.isInvalid()) { 3642207619Srdivacky DS.SetTypeSpecError(); 3643207619Srdivacky return; 3644207619Srdivacky } 3645239462Sdim 3646221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 3647221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3648221345Sdim PrevSpec, DiagID, Type.get())) 3649207619Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3650239462Sdim 3651207619Srdivacky return; 3652207619Srdivacky } 3653198092Srdivacky 3654212904Sdim if (!TagDecl) { 3655239462Sdim // The action failed to produce an enumeration tag. If this is a 3656207619Srdivacky // definition, consume the entire definition. 3657234353Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 3658207619Srdivacky ConsumeBrace(); 3659207619Srdivacky SkipUntil(tok::r_brace); 3660207619Srdivacky } 3661239462Sdim 3662207619Srdivacky DS.SetTypeSpecError(); 3663207619Srdivacky return; 3664207619Srdivacky } 3665198092Srdivacky 3666239462Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) 3667239462Sdim ParseEnumBody(StartLoc, TagDecl); 3668234353Sdim 3669221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, 3670221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3671221345Sdim PrevSpec, DiagID, TagDecl, Owned)) 3672198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3673193326Sed} 3674193326Sed 3675193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list. 3676193326Sed/// enumerator-list: 3677193326Sed/// enumerator 3678193326Sed/// enumerator-list ',' enumerator 3679193326Sed/// enumerator: 3680193326Sed/// enumeration-constant 3681193326Sed/// enumeration-constant '=' constant-expression 3682193326Sed/// enumeration-constant: 3683193326Sed/// identifier 3684193326Sed/// 3685212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { 3686193326Sed // Enter the scope of the enum body and start the definition. 3687193326Sed ParseScope EnumScope(this, Scope::DeclScope); 3688210299Sed Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); 3689193326Sed 3690226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3691226633Sdim T.consumeOpen(); 3692198092Srdivacky 3693193326Sed // C does not allow an empty enumerator-list, C++ does [dcl.enum]. 3694234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) 3695210299Sed Diag(Tok, diag::error_empty_enum); 3696198092Srdivacky 3697226633Sdim SmallVector<Decl *, 32> EnumConstantDecls; 3698193326Sed 3699212904Sdim Decl *LastEnumConstDecl = 0; 3700198092Srdivacky 3701193326Sed // Parse the enumerator-list. 3702193326Sed while (Tok.is(tok::identifier)) { 3703193326Sed IdentifierInfo *Ident = Tok.getIdentifierInfo(); 3704193326Sed SourceLocation IdentLoc = ConsumeToken(); 3705198092Srdivacky 3706218893Sdim // If attributes exist after the enumerator, parse them. 3707239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3708218893Sdim MaybeParseGNUAttributes(attrs); 3709249423Sdim MaybeParseCXX11Attributes(attrs); 3710239462Sdim ProhibitAttributes(attrs); 3711218893Sdim 3712193326Sed SourceLocation EqualLoc; 3713212904Sdim ExprResult AssignedVal; 3714239462Sdim ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); 3715239462Sdim 3716193326Sed if (Tok.is(tok::equal)) { 3717193326Sed EqualLoc = ConsumeToken(); 3718193326Sed AssignedVal = ParseConstantExpression(); 3719193326Sed if (AssignedVal.isInvalid()) 3720193326Sed SkipUntil(tok::comma, tok::r_brace, true, true); 3721193326Sed } 3722198092Srdivacky 3723193326Sed // Install the enumerator constant into EnumDecl. 3724212904Sdim Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, 3725212904Sdim LastEnumConstDecl, 3726212904Sdim IdentLoc, Ident, 3727218893Sdim attrs.getList(), EqualLoc, 3728212904Sdim AssignedVal.release()); 3729234353Sdim PD.complete(EnumConstDecl); 3730239462Sdim 3731193326Sed EnumConstantDecls.push_back(EnumConstDecl); 3732193326Sed LastEnumConstDecl = EnumConstDecl; 3733198092Srdivacky 3734218893Sdim if (Tok.is(tok::identifier)) { 3735218893Sdim // We're missing a comma between enumerators. 3736218893Sdim SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 3737239462Sdim Diag(Loc, diag::err_enumerator_list_missing_comma) 3738218893Sdim << FixItHint::CreateInsertion(Loc, ", "); 3739218893Sdim continue; 3740218893Sdim } 3741239462Sdim 3742193326Sed if (Tok.isNot(tok::comma)) 3743193326Sed break; 3744193326Sed SourceLocation CommaLoc = ConsumeToken(); 3745198092Srdivacky 3746234353Sdim if (Tok.isNot(tok::identifier)) { 3747249423Sdim if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) 3748239462Sdim Diag(CommaLoc, getLangOpts().CPlusPlus ? 3749239462Sdim diag::ext_enumerator_list_comma_cxx : 3750239462Sdim diag::ext_enumerator_list_comma_c) 3751234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3752249423Sdim else if (getLangOpts().CPlusPlus11) 3753234353Sdim Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma) 3754234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3755234353Sdim } 3756193326Sed } 3757198092Srdivacky 3758193326Sed // Eat the }. 3759226633Sdim T.consumeClose(); 3760193326Sed 3761193326Sed // If attributes exist after the identifier list, parse them. 3762221345Sdim ParsedAttributes attrs(AttrFactory); 3763218893Sdim MaybeParseGNUAttributes(attrs); 3764193326Sed 3765226633Sdim Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), 3766251662Sdim EnumDecl, EnumConstantDecls, 3767251662Sdim getCurScope(), 3768226633Sdim attrs.getList()); 3769198092Srdivacky 3770193326Sed EnumScope.Exit(); 3771226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, 3772226633Sdim T.getCloseLocation()); 3773239462Sdim 3774239462Sdim // The next token must be valid after an enum definition. If not, a ';' 3775239462Sdim // was probably forgotten. 3776239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3777239462Sdim if (!isValidAfterTypeSpecifier(CanBeBitfield)) { 3778239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum"); 3779239462Sdim // Push this token back into the preprocessor and change our current token 3780239462Sdim // to ';' so that the rest of the code recovers as though there were an 3781239462Sdim // ';' after the definition. 3782239462Sdim PP.EnterToken(Tok); 3783239462Sdim Tok.setKind(tok::semi); 3784239462Sdim } 3785193326Sed} 3786193326Sed 3787193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3788193326Sed/// start of a type-qualifier-list. 3789193326Sedbool Parser::isTypeQualifier() const { 3790193326Sed switch (Tok.getKind()) { 3791193326Sed default: return false; 3792221345Sdim 3793221345Sdim // type-qualifier only in OpenCL 3794221345Sdim case tok::kw_private: 3795234353Sdim return getLangOpts().OpenCL; 3796221345Sdim 3797193326Sed // type-qualifier 3798193326Sed case tok::kw_const: 3799193326Sed case tok::kw_volatile: 3800193326Sed case tok::kw_restrict: 3801221345Sdim case tok::kw___private: 3802221345Sdim case tok::kw___local: 3803221345Sdim case tok::kw___global: 3804221345Sdim case tok::kw___constant: 3805221345Sdim case tok::kw___read_only: 3806221345Sdim case tok::kw___read_write: 3807221345Sdim case tok::kw___write_only: 3808193326Sed return true; 3809193326Sed } 3810193326Sed} 3811193326Sed 3812204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token 3813204643Srdivacky/// is definitely a type-specifier. Return false if it isn't part of a type 3814204643Srdivacky/// specifier or if we're not sure. 3815204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { 3816204643Srdivacky switch (Tok.getKind()) { 3817204643Srdivacky default: return false; 3818204643Srdivacky // type-specifiers 3819204643Srdivacky case tok::kw_short: 3820204643Srdivacky case tok::kw_long: 3821221345Sdim case tok::kw___int64: 3822234353Sdim case tok::kw___int128: 3823204643Srdivacky case tok::kw_signed: 3824204643Srdivacky case tok::kw_unsigned: 3825204643Srdivacky case tok::kw__Complex: 3826204643Srdivacky case tok::kw__Imaginary: 3827204643Srdivacky case tok::kw_void: 3828204643Srdivacky case tok::kw_char: 3829204643Srdivacky case tok::kw_wchar_t: 3830204643Srdivacky case tok::kw_char16_t: 3831204643Srdivacky case tok::kw_char32_t: 3832204643Srdivacky case tok::kw_int: 3833226633Sdim case tok::kw_half: 3834204643Srdivacky case tok::kw_float: 3835204643Srdivacky case tok::kw_double: 3836204643Srdivacky case tok::kw_bool: 3837204643Srdivacky case tok::kw__Bool: 3838204643Srdivacky case tok::kw__Decimal32: 3839204643Srdivacky case tok::kw__Decimal64: 3840204643Srdivacky case tok::kw__Decimal128: 3841204643Srdivacky case tok::kw___vector: 3842239462Sdim 3843249423Sdim // OpenCL specific types: 3844249423Sdim case tok::kw_image1d_t: 3845249423Sdim case tok::kw_image1d_array_t: 3846249423Sdim case tok::kw_image1d_buffer_t: 3847249423Sdim case tok::kw_image2d_t: 3848249423Sdim case tok::kw_image2d_array_t: 3849249423Sdim case tok::kw_image3d_t: 3850249423Sdim case tok::kw_sampler_t: 3851249423Sdim case tok::kw_event_t: 3852249423Sdim 3853204643Srdivacky // struct-or-union-specifier (C99) or class-specifier (C++) 3854204643Srdivacky case tok::kw_class: 3855204643Srdivacky case tok::kw_struct: 3856243830Sdim case tok::kw___interface: 3857204643Srdivacky case tok::kw_union: 3858204643Srdivacky // enum-specifier 3859204643Srdivacky case tok::kw_enum: 3860239462Sdim 3861204643Srdivacky // typedef-name 3862204643Srdivacky case tok::annot_typename: 3863204643Srdivacky return true; 3864204643Srdivacky } 3865204643Srdivacky} 3866204643Srdivacky 3867193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3868193326Sed/// start of a specifier-qualifier-list. 3869193326Sedbool Parser::isTypeSpecifierQualifier() { 3870193326Sed switch (Tok.getKind()) { 3871193326Sed default: return false; 3872198092Srdivacky 3873193326Sed case tok::identifier: // foo::bar 3874203955Srdivacky if (TryAltiVecVectorToken()) 3875203955Srdivacky return true; 3876203955Srdivacky // Fall through. 3877193326Sed case tok::kw_typename: // typename T::type 3878193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3879193326Sed // recurse to handle whatever we get. 3880193326Sed if (TryAnnotateTypeOrScopeToken()) 3881204643Srdivacky return true; 3882204643Srdivacky if (Tok.is(tok::identifier)) 3883204643Srdivacky return false; 3884204643Srdivacky return isTypeSpecifierQualifier(); 3885193326Sed 3886193326Sed case tok::coloncolon: // ::foo::bar 3887193326Sed if (NextToken().is(tok::kw_new) || // ::new 3888193326Sed NextToken().is(tok::kw_delete)) // ::delete 3889193326Sed return false; 3890193326Sed 3891193326Sed if (TryAnnotateTypeOrScopeToken()) 3892204643Srdivacky return true; 3893204643Srdivacky return isTypeSpecifierQualifier(); 3894198092Srdivacky 3895193326Sed // GNU attributes support. 3896193326Sed case tok::kw___attribute: 3897193326Sed // GNU typeof support. 3898193326Sed case tok::kw_typeof: 3899198092Srdivacky 3900193326Sed // type-specifiers 3901193326Sed case tok::kw_short: 3902193326Sed case tok::kw_long: 3903221345Sdim case tok::kw___int64: 3904234353Sdim case tok::kw___int128: 3905193326Sed case tok::kw_signed: 3906193326Sed case tok::kw_unsigned: 3907193326Sed case tok::kw__Complex: 3908193326Sed case tok::kw__Imaginary: 3909193326Sed case tok::kw_void: 3910193326Sed case tok::kw_char: 3911193326Sed case tok::kw_wchar_t: 3912198092Srdivacky case tok::kw_char16_t: 3913198092Srdivacky case tok::kw_char32_t: 3914193326Sed case tok::kw_int: 3915226633Sdim case tok::kw_half: 3916193326Sed case tok::kw_float: 3917193326Sed case tok::kw_double: 3918193326Sed case tok::kw_bool: 3919193326Sed case tok::kw__Bool: 3920193326Sed case tok::kw__Decimal32: 3921193326Sed case tok::kw__Decimal64: 3922193326Sed case tok::kw__Decimal128: 3923203955Srdivacky case tok::kw___vector: 3924198092Srdivacky 3925249423Sdim // OpenCL specific types: 3926249423Sdim case tok::kw_image1d_t: 3927249423Sdim case tok::kw_image1d_array_t: 3928249423Sdim case tok::kw_image1d_buffer_t: 3929249423Sdim case tok::kw_image2d_t: 3930249423Sdim case tok::kw_image2d_array_t: 3931249423Sdim case tok::kw_image3d_t: 3932249423Sdim case tok::kw_sampler_t: 3933249423Sdim case tok::kw_event_t: 3934249423Sdim 3935193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 3936193326Sed case tok::kw_class: 3937193326Sed case tok::kw_struct: 3938243830Sdim case tok::kw___interface: 3939193326Sed case tok::kw_union: 3940193326Sed // enum-specifier 3941193326Sed case tok::kw_enum: 3942198092Srdivacky 3943193326Sed // type-qualifier 3944193326Sed case tok::kw_const: 3945193326Sed case tok::kw_volatile: 3946193326Sed case tok::kw_restrict: 3947193326Sed 3948249423Sdim // Debugger support. 3949249423Sdim case tok::kw___unknown_anytype: 3950249423Sdim 3951193326Sed // typedef-name 3952193326Sed case tok::annot_typename: 3953193326Sed return true; 3954198092Srdivacky 3955193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 3956193326Sed case tok::less: 3957234353Sdim return getLangOpts().ObjC1; 3958198092Srdivacky 3959193326Sed case tok::kw___cdecl: 3960193326Sed case tok::kw___stdcall: 3961193326Sed case tok::kw___fastcall: 3962208600Srdivacky case tok::kw___thiscall: 3963194179Sed case tok::kw___w64: 3964194179Sed case tok::kw___ptr64: 3965226633Sdim case tok::kw___ptr32: 3966212904Sdim case tok::kw___pascal: 3967226633Sdim case tok::kw___unaligned: 3968221345Sdim 3969221345Sdim case tok::kw___private: 3970221345Sdim case tok::kw___local: 3971221345Sdim case tok::kw___global: 3972221345Sdim case tok::kw___constant: 3973221345Sdim case tok::kw___read_only: 3974221345Sdim case tok::kw___read_write: 3975221345Sdim case tok::kw___write_only: 3976221345Sdim 3977194179Sed return true; 3978221345Sdim 3979221345Sdim case tok::kw_private: 3980234353Sdim return getLangOpts().OpenCL; 3981226633Sdim 3982249423Sdim // C11 _Atomic 3983226633Sdim case tok::kw__Atomic: 3984226633Sdim return true; 3985193326Sed } 3986193326Sed} 3987193326Sed 3988193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a 3989193326Sed/// declaration specifier. 3990218893Sdim/// 3991218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of 3992218893Sdim/// this check is to disambiguate between an expression and a declaration. 3993218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { 3994193326Sed switch (Tok.getKind()) { 3995193326Sed default: return false; 3996198092Srdivacky 3997221345Sdim case tok::kw_private: 3998234353Sdim return getLangOpts().OpenCL; 3999221345Sdim 4000193326Sed case tok::identifier: // foo::bar 4001193326Sed // Unfortunate hack to support "Class.factoryMethod" notation. 4002234353Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::period)) 4003193326Sed return false; 4004203955Srdivacky if (TryAltiVecVectorToken()) 4005203955Srdivacky return true; 4006203955Srdivacky // Fall through. 4007234353Sdim case tok::kw_decltype: // decltype(T())::type 4008193326Sed case tok::kw_typename: // typename T::type 4009193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 4010193326Sed // recurse to handle whatever we get. 4011193326Sed if (TryAnnotateTypeOrScopeToken()) 4012204643Srdivacky return true; 4013204643Srdivacky if (Tok.is(tok::identifier)) 4014204643Srdivacky return false; 4015239462Sdim 4016218893Sdim // If we're in Objective-C and we have an Objective-C class type followed 4017239462Sdim // by an identifier and then either ':' or ']', in a place where an 4018218893Sdim // expression is permitted, then this is probably a class message send 4019218893Sdim // missing the initial '['. In this case, we won't consider this to be 4020218893Sdim // the start of a declaration. 4021239462Sdim if (DisambiguatingWithExpression && 4022218893Sdim isStartOfObjCClassMessageMissingOpenBracket()) 4023218893Sdim return false; 4024239462Sdim 4025204643Srdivacky return isDeclarationSpecifier(); 4026204643Srdivacky 4027193326Sed case tok::coloncolon: // ::foo::bar 4028193326Sed if (NextToken().is(tok::kw_new) || // ::new 4029193326Sed NextToken().is(tok::kw_delete)) // ::delete 4030193326Sed return false; 4031198092Srdivacky 4032193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 4033193326Sed // recurse to handle whatever we get. 4034193326Sed if (TryAnnotateTypeOrScopeToken()) 4035204643Srdivacky return true; 4036204643Srdivacky return isDeclarationSpecifier(); 4037198092Srdivacky 4038193326Sed // storage-class-specifier 4039193326Sed case tok::kw_typedef: 4040193326Sed case tok::kw_extern: 4041193326Sed case tok::kw___private_extern__: 4042193326Sed case tok::kw_static: 4043193326Sed case tok::kw_auto: 4044193326Sed case tok::kw_register: 4045193326Sed case tok::kw___thread: 4046251662Sdim case tok::kw_thread_local: 4047251662Sdim case tok::kw__Thread_local: 4048198092Srdivacky 4049226633Sdim // Modules 4050226633Sdim case tok::kw___module_private__: 4051239462Sdim 4052249423Sdim // Debugger support 4053249423Sdim case tok::kw___unknown_anytype: 4054249423Sdim 4055193326Sed // type-specifiers 4056193326Sed case tok::kw_short: 4057193326Sed case tok::kw_long: 4058221345Sdim case tok::kw___int64: 4059234353Sdim case tok::kw___int128: 4060193326Sed case tok::kw_signed: 4061193326Sed case tok::kw_unsigned: 4062193326Sed case tok::kw__Complex: 4063193326Sed case tok::kw__Imaginary: 4064193326Sed case tok::kw_void: 4065193326Sed case tok::kw_char: 4066193326Sed case tok::kw_wchar_t: 4067198092Srdivacky case tok::kw_char16_t: 4068198092Srdivacky case tok::kw_char32_t: 4069198092Srdivacky 4070193326Sed case tok::kw_int: 4071226633Sdim case tok::kw_half: 4072193326Sed case tok::kw_float: 4073193326Sed case tok::kw_double: 4074193326Sed case tok::kw_bool: 4075193326Sed case tok::kw__Bool: 4076193326Sed case tok::kw__Decimal32: 4077193326Sed case tok::kw__Decimal64: 4078193326Sed case tok::kw__Decimal128: 4079203955Srdivacky case tok::kw___vector: 4080198092Srdivacky 4081249423Sdim // OpenCL specific types: 4082249423Sdim case tok::kw_image1d_t: 4083249423Sdim case tok::kw_image1d_array_t: 4084249423Sdim case tok::kw_image1d_buffer_t: 4085249423Sdim case tok::kw_image2d_t: 4086249423Sdim case tok::kw_image2d_array_t: 4087249423Sdim case tok::kw_image3d_t: 4088249423Sdim case tok::kw_sampler_t: 4089249423Sdim case tok::kw_event_t: 4090249423Sdim 4091193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 4092193326Sed case tok::kw_class: 4093193326Sed case tok::kw_struct: 4094193326Sed case tok::kw_union: 4095243830Sdim case tok::kw___interface: 4096193326Sed // enum-specifier 4097193326Sed case tok::kw_enum: 4098198092Srdivacky 4099193326Sed // type-qualifier 4100193326Sed case tok::kw_const: 4101193326Sed case tok::kw_volatile: 4102193326Sed case tok::kw_restrict: 4103193326Sed 4104193326Sed // function-specifier 4105193326Sed case tok::kw_inline: 4106193326Sed case tok::kw_virtual: 4107193326Sed case tok::kw_explicit: 4108249423Sdim case tok::kw__Noreturn: 4109193326Sed 4110249423Sdim // alignment-specifier 4111249423Sdim case tok::kw__Alignas: 4112249423Sdim 4113243830Sdim // friend keyword. 4114243830Sdim case tok::kw_friend: 4115243830Sdim 4116221345Sdim // static_assert-declaration 4117221345Sdim case tok::kw__Static_assert: 4118193326Sed 4119193326Sed // GNU typeof support. 4120193326Sed case tok::kw_typeof: 4121198092Srdivacky 4122193326Sed // GNU attributes. 4123193326Sed case tok::kw___attribute: 4124198092Srdivacky 4125243830Sdim // C++11 decltype and constexpr. 4126234353Sdim case tok::annot_decltype: 4127243830Sdim case tok::kw_constexpr: 4128224145Sdim 4129249423Sdim // C11 _Atomic 4130226633Sdim case tok::kw__Atomic: 4131226633Sdim return true; 4132226633Sdim 4133193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 4134193326Sed case tok::less: 4135234353Sdim return getLangOpts().ObjC1; 4136198092Srdivacky 4137221345Sdim // typedef-name 4138221345Sdim case tok::annot_typename: 4139221345Sdim return !DisambiguatingWithExpression || 4140221345Sdim !isStartOfObjCClassMessageMissingOpenBracket(); 4141239462Sdim 4142193326Sed case tok::kw___declspec: 4143193326Sed case tok::kw___cdecl: 4144193326Sed case tok::kw___stdcall: 4145193326Sed case tok::kw___fastcall: 4146208600Srdivacky case tok::kw___thiscall: 4147194179Sed case tok::kw___w64: 4148194179Sed case tok::kw___ptr64: 4149226633Sdim case tok::kw___ptr32: 4150194179Sed case tok::kw___forceinline: 4151212904Sdim case tok::kw___pascal: 4152226633Sdim case tok::kw___unaligned: 4153221345Sdim 4154221345Sdim case tok::kw___private: 4155221345Sdim case tok::kw___local: 4156221345Sdim case tok::kw___global: 4157221345Sdim case tok::kw___constant: 4158221345Sdim case tok::kw___read_only: 4159221345Sdim case tok::kw___read_write: 4160221345Sdim case tok::kw___write_only: 4161221345Sdim 4162194179Sed return true; 4163193326Sed } 4164193326Sed} 4165193326Sed 4166202379Srdivackybool Parser::isConstructorDeclarator() { 4167202379Srdivacky TentativeParsingAction TPA(*this); 4168193326Sed 4169202379Srdivacky // Parse the C++ scope specifier. 4170202379Srdivacky CXXScopeSpec SS; 4171239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 4172234353Sdim /*EnteringContext=*/true)) { 4173204643Srdivacky TPA.Revert(); 4174204643Srdivacky return false; 4175204643Srdivacky } 4176202379Srdivacky 4177202379Srdivacky // Parse the constructor name. 4178202379Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 4179202379Srdivacky // We already know that we have a constructor name; just consume 4180202379Srdivacky // the token. 4181202379Srdivacky ConsumeToken(); 4182202379Srdivacky } else { 4183202379Srdivacky TPA.Revert(); 4184202379Srdivacky return false; 4185202379Srdivacky } 4186202379Srdivacky 4187234353Sdim // Current class name must be followed by a left parenthesis. 4188202379Srdivacky if (Tok.isNot(tok::l_paren)) { 4189202379Srdivacky TPA.Revert(); 4190202379Srdivacky return false; 4191202379Srdivacky } 4192202379Srdivacky ConsumeParen(); 4193202379Srdivacky 4194234353Sdim // A right parenthesis, or ellipsis followed by a right parenthesis signals 4195234353Sdim // that we have a constructor. 4196234353Sdim if (Tok.is(tok::r_paren) || 4197234353Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) { 4198202379Srdivacky TPA.Revert(); 4199202379Srdivacky return true; 4200202379Srdivacky } 4201202379Srdivacky 4202202379Srdivacky // If we need to, enter the specified scope. 4203202379Srdivacky DeclaratorScopeObj DeclScopeObj(*this, SS); 4204210299Sed if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 4205202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4206202379Srdivacky 4207218893Sdim // Optionally skip Microsoft attributes. 4208221345Sdim ParsedAttributes Attrs(AttrFactory); 4209218893Sdim MaybeParseMicrosoftAttributes(Attrs); 4210218893Sdim 4211202379Srdivacky // Check whether the next token(s) are part of a declaration 4212202379Srdivacky // specifier, in which case we have the start of a parameter and, 4213202379Srdivacky // therefore, we know that this is a constructor. 4214234353Sdim bool IsConstructor = false; 4215234353Sdim if (isDeclarationSpecifier()) 4216234353Sdim IsConstructor = true; 4217234353Sdim else if (Tok.is(tok::identifier) || 4218234353Sdim (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) { 4219234353Sdim // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type. 4220234353Sdim // This might be a parenthesized member name, but is more likely to 4221234353Sdim // be a constructor declaration with an invalid argument type. Keep 4222234353Sdim // looking. 4223234353Sdim if (Tok.is(tok::annot_cxxscope)) 4224234353Sdim ConsumeToken(); 4225234353Sdim ConsumeToken(); 4226234353Sdim 4227234353Sdim // If this is not a constructor, we must be parsing a declarator, 4228234353Sdim // which must have one of the following syntactic forms (see the 4229234353Sdim // grammar extract at the start of ParseDirectDeclarator): 4230234353Sdim switch (Tok.getKind()) { 4231234353Sdim case tok::l_paren: 4232234353Sdim // C(X ( int)); 4233234353Sdim case tok::l_square: 4234234353Sdim // C(X [ 5]); 4235234353Sdim // C(X [ [attribute]]); 4236234353Sdim case tok::coloncolon: 4237234353Sdim // C(X :: Y); 4238234353Sdim // C(X :: *p); 4239234353Sdim case tok::r_paren: 4240234353Sdim // C(X ) 4241234353Sdim // Assume this isn't a constructor, rather than assuming it's a 4242234353Sdim // constructor with an unnamed parameter of an ill-formed type. 4243234353Sdim break; 4244234353Sdim 4245234353Sdim default: 4246234353Sdim IsConstructor = true; 4247234353Sdim break; 4248234353Sdim } 4249234353Sdim } 4250234353Sdim 4251202379Srdivacky TPA.Revert(); 4252202379Srdivacky return IsConstructor; 4253202379Srdivacky} 4254202379Srdivacky 4255193326Sed/// ParseTypeQualifierListOpt 4256212904Sdim/// type-qualifier-list: [C99 6.7.5] 4257212904Sdim/// type-qualifier 4258239462Sdim/// [vendor] attributes 4259212904Sdim/// [ only if VendorAttributesAllowed=true ] 4260212904Sdim/// type-qualifier-list type-qualifier 4261239462Sdim/// [vendor] type-qualifier-list attributes 4262212904Sdim/// [ only if VendorAttributesAllowed=true ] 4263212904Sdim/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq 4264249423Sdim/// [ only if CXX11AttributesAllowed=true ] 4265212904Sdim/// Note: vendor can be GNU, MS, etc. 4266193326Sed/// 4267212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS, 4268212904Sdim bool VendorAttributesAllowed, 4269249423Sdim bool CXX11AttributesAllowed, 4270249423Sdim bool AtomicAllowed) { 4271249423Sdim if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && 4272234353Sdim isCXX11AttributeSpecifier()) { 4273221345Sdim ParsedAttributesWithRange attrs(AttrFactory); 4274234353Sdim ParseCXX11Attributes(attrs); 4275234353Sdim DS.takeAttributesFrom(attrs); 4276199990Srdivacky } 4277221345Sdim 4278221345Sdim SourceLocation EndLoc; 4279221345Sdim 4280193326Sed while (1) { 4281198092Srdivacky bool isInvalid = false; 4282193326Sed const char *PrevSpec = 0; 4283198092Srdivacky unsigned DiagID = 0; 4284193326Sed SourceLocation Loc = Tok.getLocation(); 4285193326Sed 4286193326Sed switch (Tok.getKind()) { 4287212904Sdim case tok::code_completion: 4288212904Sdim Actions.CodeCompleteTypeQualifiers(DS); 4289226633Sdim return cutOffParsing(); 4290239462Sdim 4291193326Sed case tok::kw_const: 4292198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, 4293243830Sdim getLangOpts()); 4294193326Sed break; 4295193326Sed case tok::kw_volatile: 4296198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 4297243830Sdim getLangOpts()); 4298193326Sed break; 4299193326Sed case tok::kw_restrict: 4300198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 4301243830Sdim getLangOpts()); 4302193326Sed break; 4303249423Sdim case tok::kw__Atomic: 4304249423Sdim if (!AtomicAllowed) 4305249423Sdim goto DoneWithTypeQuals; 4306249423Sdim isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, 4307249423Sdim getLangOpts()); 4308249423Sdim break; 4309221345Sdim 4310221345Sdim // OpenCL qualifiers: 4311239462Sdim case tok::kw_private: 4312234353Sdim if (!getLangOpts().OpenCL) 4313221345Sdim goto DoneWithTypeQuals; 4314221345Sdim case tok::kw___private: 4315221345Sdim case tok::kw___global: 4316221345Sdim case tok::kw___local: 4317221345Sdim case tok::kw___constant: 4318221345Sdim case tok::kw___read_only: 4319221345Sdim case tok::kw___write_only: 4320221345Sdim case tok::kw___read_write: 4321221345Sdim ParseOpenCLQualifiers(DS); 4322221345Sdim break; 4323221345Sdim 4324194179Sed case tok::kw___w64: 4325193326Sed case tok::kw___ptr64: 4326226633Sdim case tok::kw___ptr32: 4327193326Sed case tok::kw___cdecl: 4328193326Sed case tok::kw___stdcall: 4329193326Sed case tok::kw___fastcall: 4330208600Srdivacky case tok::kw___thiscall: 4331226633Sdim case tok::kw___unaligned: 4332212904Sdim if (VendorAttributesAllowed) { 4333218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 4334194179Sed continue; 4335194179Sed } 4336194179Sed goto DoneWithTypeQuals; 4337212904Sdim case tok::kw___pascal: 4338212904Sdim if (VendorAttributesAllowed) { 4339218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 4340212904Sdim continue; 4341212904Sdim } 4342212904Sdim goto DoneWithTypeQuals; 4343193326Sed case tok::kw___attribute: 4344212904Sdim if (VendorAttributesAllowed) { 4345218893Sdim ParseGNUAttributes(DS.getAttributes()); 4346193326Sed continue; // do *not* consume the next token! 4347193326Sed } 4348193326Sed // otherwise, FALL THROUGH! 4349193326Sed default: 4350193326Sed DoneWithTypeQuals: 4351193326Sed // If this is not a type-qualifier token, we're done reading type 4352193326Sed // qualifiers. First verify that DeclSpec's are consistent. 4353193326Sed DS.Finish(Diags, PP); 4354221345Sdim if (EndLoc.isValid()) 4355221345Sdim DS.SetRangeEnd(EndLoc); 4356193326Sed return; 4357193326Sed } 4358193326Sed 4359193326Sed // If the specifier combination wasn't legal, issue a diagnostic. 4360193326Sed if (isInvalid) { 4361193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 4362193326Sed Diag(Tok, DiagID) << PrevSpec; 4363193326Sed } 4364221345Sdim EndLoc = ConsumeToken(); 4365193326Sed } 4366193326Sed} 4367193326Sed 4368193326Sed 4369193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator. 4370193326Sed/// 4371193326Sedvoid Parser::ParseDeclarator(Declarator &D) { 4372193326Sed /// This implements the 'declarator' production in the C grammar, then checks 4373193326Sed /// for well-formedness and issues diagnostics. 4374193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4375193326Sed} 4376193326Sed 4377234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { 4378234353Sdim if (Kind == tok::star || Kind == tok::caret) 4379234353Sdim return true; 4380234353Sdim 4381234353Sdim // We parse rvalue refs in C++03, because otherwise the errors are scary. 4382234353Sdim if (!Lang.CPlusPlus) 4383234353Sdim return false; 4384234353Sdim 4385234353Sdim return Kind == tok::amp || Kind == tok::ampamp; 4386234353Sdim} 4387234353Sdim 4388193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator 4389193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator 4390193326Sed/// isn't parsed at all, making this function effectively parse the C++ 4391193326Sed/// ptr-operator production. 4392193326Sed/// 4393234353Sdim/// If the grammar of this construct is extended, matching changes must also be 4394234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to 4395234353Sdim/// isConstructorDeclarator. 4396234353Sdim/// 4397193326Sed/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] 4398193326Sed/// [C] pointer[opt] direct-declarator 4399193326Sed/// [C++] direct-declarator 4400193326Sed/// [C++] ptr-operator declarator 4401193326Sed/// 4402193326Sed/// pointer: [C99 6.7.5] 4403193326Sed/// '*' type-qualifier-list[opt] 4404193326Sed/// '*' type-qualifier-list[opt] pointer 4405193326Sed/// 4406193326Sed/// ptr-operator: 4407193326Sed/// '*' cv-qualifier-seq[opt] 4408193326Sed/// '&' 4409193326Sed/// [C++0x] '&&' 4410193326Sed/// [GNU] '&' restrict[opt] attributes[opt] 4411193326Sed/// [GNU?] '&&' restrict[opt] attributes[opt] 4412193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4413193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D, 4414193326Sed DirectDeclParseFunction DirectDeclParser) { 4415198092Srdivacky if (Diags.hasAllExtensionsSilenced()) 4416198092Srdivacky D.setExtension(); 4417239462Sdim 4418193326Sed // C++ member pointers start with a '::' or a nested-name. 4419193326Sed // Member pointers get special handling, since there's no place for the 4420193326Sed // scope spec in the generic path below. 4421234353Sdim if (getLangOpts().CPlusPlus && 4422193326Sed (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || 4423193326Sed Tok.is(tok::annot_cxxscope))) { 4424234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4425234353Sdim D.getContext() == Declarator::MemberContext; 4426193326Sed CXXScopeSpec SS; 4427234353Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); 4428204643Srdivacky 4429207619Srdivacky if (SS.isNotEmpty()) { 4430198092Srdivacky if (Tok.isNot(tok::star)) { 4431193326Sed // The scope spec really belongs to the direct-declarator. 4432249423Sdim if (D.mayHaveIdentifier()) 4433249423Sdim D.getCXXScopeSpec() = SS; 4434249423Sdim else 4435249423Sdim AnnotateScopeToken(SS, true); 4436249423Sdim 4437193326Sed if (DirectDeclParser) 4438193326Sed (this->*DirectDeclParser)(D); 4439193326Sed return; 4440193326Sed } 4441193326Sed 4442193326Sed SourceLocation Loc = ConsumeToken(); 4443193326Sed D.SetRangeEnd(Loc); 4444221345Sdim DeclSpec DS(AttrFactory); 4445193326Sed ParseTypeQualifierListOpt(DS); 4446193326Sed D.ExtendWithDeclSpec(DS); 4447193326Sed 4448193326Sed // Recurse to parse whatever is left. 4449193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4450193326Sed 4451193326Sed // Sema will have to catch (syntactically invalid) pointers into global 4452193326Sed // scope. It has to catch pointers into namespace scope anyway. 4453193326Sed D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), 4454221345Sdim Loc), 4455221345Sdim DS.getAttributes(), 4456193326Sed /* Don't replace range end. */SourceLocation()); 4457193326Sed return; 4458193326Sed } 4459193326Sed } 4460193326Sed 4461193326Sed tok::TokenKind Kind = Tok.getKind(); 4462193326Sed // Not a pointer, C++ reference, or block. 4463234353Sdim if (!isPtrOperatorToken(Kind, getLangOpts())) { 4464193326Sed if (DirectDeclParser) 4465193326Sed (this->*DirectDeclParser)(D); 4466193326Sed return; 4467193326Sed } 4468193326Sed 4469193326Sed // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference, 4470193326Sed // '&&' -> rvalue reference 4471193326Sed SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. 4472193326Sed D.SetRangeEnd(Loc); 4473193326Sed 4474193326Sed if (Kind == tok::star || Kind == tok::caret) { 4475193326Sed // Is a pointer. 4476221345Sdim DeclSpec DS(AttrFactory); 4477193326Sed 4478234353Sdim // FIXME: GNU attributes are not allowed here in a new-type-id. 4479193326Sed ParseTypeQualifierListOpt(DS); 4480193326Sed D.ExtendWithDeclSpec(DS); 4481193326Sed 4482193326Sed // Recursively parse the declarator. 4483193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4484193326Sed if (Kind == tok::star) 4485193326Sed // Remember that we parsed a pointer type, and remember the type-quals. 4486193326Sed D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, 4487219077Sdim DS.getConstSpecLoc(), 4488219077Sdim DS.getVolatileSpecLoc(), 4489221345Sdim DS.getRestrictSpecLoc()), 4490221345Sdim DS.getAttributes(), 4491193326Sed SourceLocation()); 4492193326Sed else 4493193326Sed // Remember that we parsed a Block type, and remember the type-quals. 4494198092Srdivacky D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), 4495221345Sdim Loc), 4496221345Sdim DS.getAttributes(), 4497193326Sed SourceLocation()); 4498193326Sed } else { 4499193326Sed // Is a reference 4500221345Sdim DeclSpec DS(AttrFactory); 4501193326Sed 4502193326Sed // Complain about rvalue references in C++03, but then go on and build 4503193326Sed // the declarator. 4504234353Sdim if (Kind == tok::ampamp) 4505249423Sdim Diag(Loc, getLangOpts().CPlusPlus11 ? 4506234353Sdim diag::warn_cxx98_compat_rvalue_reference : 4507234353Sdim diag::ext_rvalue_reference); 4508193326Sed 4509234353Sdim // GNU-style and C++11 attributes are allowed here, as is restrict. 4510234353Sdim ParseTypeQualifierListOpt(DS); 4511234353Sdim D.ExtendWithDeclSpec(DS); 4512234353Sdim 4513193326Sed // C++ 8.3.2p1: cv-qualified references are ill-formed except when the 4514193326Sed // cv-qualifiers are introduced through the use of a typedef or of a 4515193326Sed // template type argument, in which case the cv-qualifiers are ignored. 4516193326Sed if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { 4517193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 4518193326Sed Diag(DS.getConstSpecLoc(), 4519193326Sed diag::err_invalid_reference_qualifier_application) << "const"; 4520193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) 4521193326Sed Diag(DS.getVolatileSpecLoc(), 4522193326Sed diag::err_invalid_reference_qualifier_application) << "volatile"; 4523249423Sdim // 'restrict' is permitted as an extension. 4524249423Sdim if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) 4525249423Sdim Diag(DS.getAtomicSpecLoc(), 4526249423Sdim diag::err_invalid_reference_qualifier_application) << "_Atomic"; 4527193326Sed } 4528193326Sed 4529193326Sed // Recursively parse the declarator. 4530193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4531193326Sed 4532193326Sed if (D.getNumTypeObjects() > 0) { 4533193326Sed // C++ [dcl.ref]p4: There shall be no references to references. 4534193326Sed DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1); 4535193326Sed if (InnerChunk.Kind == DeclaratorChunk::Reference) { 4536193326Sed if (const IdentifierInfo *II = D.getIdentifier()) 4537193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4538193326Sed << II; 4539193326Sed else 4540193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4541193326Sed << "type name"; 4542193326Sed 4543193326Sed // Once we've complained about the reference-to-reference, we 4544193326Sed // can go ahead and build the (technically ill-formed) 4545193326Sed // declarator: reference collapsing will take care of it. 4546193326Sed } 4547193326Sed } 4548193326Sed 4549249423Sdim // Remember that we parsed a reference type. 4550193326Sed D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, 4551193326Sed Kind == tok::amp), 4552221345Sdim DS.getAttributes(), 4553193326Sed SourceLocation()); 4554193326Sed } 4555193326Sed} 4556193326Sed 4557234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D, 4558234353Sdim SourceLocation EllipsisLoc) { 4559234353Sdim if (EllipsisLoc.isValid()) { 4560234353Sdim FixItHint Insertion; 4561234353Sdim if (!D.getEllipsisLoc().isValid()) { 4562234353Sdim Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "..."); 4563234353Sdim D.setEllipsisLoc(EllipsisLoc); 4564234353Sdim } 4565234353Sdim P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration) 4566234353Sdim << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName(); 4567234353Sdim } 4568234353Sdim} 4569234353Sdim 4570193326Sed/// ParseDirectDeclarator 4571193326Sed/// direct-declarator: [C99 6.7.5] 4572193326Sed/// [C99] identifier 4573193326Sed/// '(' declarator ')' 4574193326Sed/// [GNU] '(' attributes declarator ')' 4575193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 4576193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4577193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4578193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4579193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4580234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 4581234353Sdim/// attribute-specifier-seq[opt] 4582193326Sed/// direct-declarator '(' parameter-type-list ')' 4583193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4584193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4585193326Sed/// parameter-type-list[opt] ')' 4586193326Sed/// [C++] direct-declarator '(' parameter-declaration-clause ')' 4587193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 4588234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')' 4589234353Sdim/// attribute-specifier-seq[opt] cv-qualifier-seq[opt] 4590234353Sdim/// ref-qualifier[opt] exception-specification[opt] 4591193326Sed/// [C++] declarator-id 4592234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt] 4593193326Sed/// 4594193326Sed/// declarator-id: [C++ 8] 4595218893Sdim/// '...'[opt] id-expression 4596193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 4597193326Sed/// 4598193326Sed/// id-expression: [C++ 5.1] 4599193326Sed/// unqualified-id 4600198092Srdivacky/// qualified-id 4601193326Sed/// 4602193326Sed/// unqualified-id: [C++ 5.1] 4603198092Srdivacky/// identifier 4604193326Sed/// operator-function-id 4605198092Srdivacky/// conversion-function-id 4606198092Srdivacky/// '~' class-name 4607193326Sed/// template-id 4608193326Sed/// 4609234353Sdim/// Note, any additional constructs added here may need corresponding changes 4610234353Sdim/// in isConstructorDeclarator. 4611193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) { 4612193326Sed DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); 4613193326Sed 4614234353Sdim if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) { 4615198893Srdivacky // ParseDeclaratorInternal might already have parsed the scope. 4616207619Srdivacky if (D.getCXXScopeSpec().isEmpty()) { 4617234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4618234353Sdim D.getContext() == Declarator::MemberContext; 4619239462Sdim ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), 4620234353Sdim EnteringContext); 4621204643Srdivacky } 4622204643Srdivacky 4623207619Srdivacky if (D.getCXXScopeSpec().isValid()) { 4624210299Sed if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4625200583Srdivacky // Change the declaration context for name lookup, until this function 4626200583Srdivacky // is exited (and the declarator has been parsed). 4627200583Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4628207619Srdivacky } 4629207619Srdivacky 4630218893Sdim // C++0x [dcl.fct]p14: 4631218893Sdim // There is a syntactic ambiguity when an ellipsis occurs at the end 4632239462Sdim // of a parameter-declaration-clause without a preceding comma. In 4633239462Sdim // this case, the ellipsis is parsed as part of the 4634239462Sdim // abstract-declarator if the type of the parameter names a template 4635218893Sdim // parameter pack that has not been expanded; otherwise, it is parsed 4636218893Sdim // as part of the parameter-declaration-clause. 4637234353Sdim if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && 4638218893Sdim !((D.getContext() == Declarator::PrototypeContext || 4639218893Sdim D.getContext() == Declarator::BlockLiteralContext) && 4640218893Sdim NextToken().is(tok::r_paren) && 4641249423Sdim !D.hasGroupingParens() && 4642234353Sdim !Actions.containsUnexpandedParameterPacks(D))) { 4643234353Sdim SourceLocation EllipsisLoc = ConsumeToken(); 4644234353Sdim if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { 4645234353Sdim // The ellipsis was put in the wrong place. Recover, and explain to 4646234353Sdim // the user what they should have done. 4647234353Sdim ParseDeclarator(D); 4648234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4649234353Sdim return; 4650234353Sdim } else 4651234353Sdim D.setEllipsisLoc(EllipsisLoc); 4652234353Sdim 4653234353Sdim // The ellipsis can't be followed by a parenthesized declarator. We 4654234353Sdim // check for that in ParseParenDeclarator, after we have disambiguated 4655234353Sdim // the l_paren token. 4656234353Sdim } 4657234353Sdim 4658198893Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 4659198893Srdivacky Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { 4660198893Srdivacky // We found something that indicates the start of an unqualified-id. 4661198893Srdivacky // Parse that unqualified-id. 4662207619Srdivacky bool AllowConstructorName; 4663207619Srdivacky if (D.getDeclSpec().hasTypeSpecifier()) 4664207619Srdivacky AllowConstructorName = false; 4665207619Srdivacky else if (D.getCXXScopeSpec().isSet()) 4666207619Srdivacky AllowConstructorName = 4667207619Srdivacky (D.getContext() == Declarator::FileContext || 4668249423Sdim D.getContext() == Declarator::MemberContext); 4669207619Srdivacky else 4670207619Srdivacky AllowConstructorName = (D.getContext() == Declarator::MemberContext); 4671207619Srdivacky 4672234353Sdim SourceLocation TemplateKWLoc; 4673239462Sdim if (ParseUnqualifiedId(D.getCXXScopeSpec(), 4674239462Sdim /*EnteringContext=*/true, 4675239462Sdim /*AllowDestructorName=*/true, 4676202379Srdivacky AllowConstructorName, 4677212904Sdim ParsedType(), 4678234353Sdim TemplateKWLoc, 4679207619Srdivacky D.getName()) || 4680207619Srdivacky // Once we're past the identifier, if the scope was bad, mark the 4681207619Srdivacky // whole declarator bad. 4682207619Srdivacky D.getCXXScopeSpec().isInvalid()) { 4683193326Sed D.SetIdentifier(0, Tok.getLocation()); 4684193326Sed D.setInvalidType(true); 4685198893Srdivacky } else { 4686198893Srdivacky // Parsed the unqualified-id; update range information and move along. 4687198893Srdivacky if (D.getSourceRange().getBegin().isInvalid()) 4688198893Srdivacky D.SetRangeBegin(D.getName().getSourceRange().getBegin()); 4689198893Srdivacky D.SetRangeEnd(D.getName().getSourceRange().getEnd()); 4690193326Sed } 4691198893Srdivacky goto PastIdentifier; 4692193326Sed } 4693198893Srdivacky } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { 4694234353Sdim assert(!getLangOpts().CPlusPlus && 4695193326Sed "There's a C++-specific check for tok::identifier above"); 4696193326Sed assert(Tok.getIdentifierInfo() && "Not an identifier?"); 4697193326Sed D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 4698193326Sed ConsumeToken(); 4699198893Srdivacky goto PastIdentifier; 4700198893Srdivacky } 4701234353Sdim 4702198893Srdivacky if (Tok.is(tok::l_paren)) { 4703193326Sed // direct-declarator: '(' declarator ')' 4704193326Sed // direct-declarator: '(' attributes declarator ')' 4705193326Sed // Example: 'char (*X)' or 'int (*XX)(void)' 4706193326Sed ParseParenDeclarator(D); 4707202379Srdivacky 4708202379Srdivacky // If the declarator was parenthesized, we entered the declarator 4709202379Srdivacky // scope when parsing the parenthesized declarator, then exited 4710202379Srdivacky // the scope already. Re-enter the scope, if we need to. 4711202379Srdivacky if (D.getCXXScopeSpec().isSet()) { 4712212904Sdim // If there was an error parsing parenthesized declarator, declarator 4713234353Sdim // scope may have been entered before. Don't do it again. 4714212904Sdim if (!D.isInvalidType() && 4715212904Sdim Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4716202379Srdivacky // Change the declaration context for name lookup, until this function 4717202379Srdivacky // is exited (and the declarator has been parsed). 4718202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4719202379Srdivacky } 4720193326Sed } else if (D.mayOmitIdentifier()) { 4721193326Sed // This could be something simple like "int" (in which case the declarator 4722193326Sed // portion is empty), if an abstract-declarator is allowed. 4723193326Sed D.SetIdentifier(0, Tok.getLocation()); 4724249423Sdim 4725249423Sdim // The grammar for abstract-pack-declarator does not allow grouping parens. 4726249423Sdim // FIXME: Revisit this once core issue 1488 is resolved. 4727249423Sdim if (D.hasEllipsis() && D.hasGroupingParens()) 4728249423Sdim Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()), 4729249423Sdim diag::ext_abstract_pack_declarator_parens); 4730193326Sed } else { 4731239462Sdim if (Tok.getKind() == tok::annot_pragma_parser_crash) 4732243830Sdim LLVM_BUILTIN_TRAP; 4733193326Sed if (D.getContext() == Declarator::MemberContext) 4734193326Sed Diag(Tok, diag::err_expected_member_name_or_semi) 4735193326Sed << D.getDeclSpec().getSourceRange(); 4736249423Sdim else if (getLangOpts().CPlusPlus) { 4737249423Sdim if (Tok.is(tok::period) || Tok.is(tok::arrow)) 4738249423Sdim Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow); 4739249423Sdim else 4740249423Sdim Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus; 4741249423Sdim } else 4742193326Sed Diag(Tok, diag::err_expected_ident_lparen); 4743193326Sed D.SetIdentifier(0, Tok.getLocation()); 4744193326Sed D.setInvalidType(true); 4745193326Sed } 4746198092Srdivacky 4747193326Sed PastIdentifier: 4748193326Sed assert(D.isPastIdentifier() && 4749193326Sed "Haven't past the location of the identifier yet?"); 4750198092Srdivacky 4751234353Sdim // Don't parse attributes unless we have parsed an unparenthesized name. 4752234353Sdim if (D.hasName() && !D.getNumTypeObjects()) 4753249423Sdim MaybeParseCXX11Attributes(D); 4754199990Srdivacky 4755193326Sed while (1) { 4756193326Sed if (Tok.is(tok::l_paren)) { 4757234353Sdim // Enter function-declaration scope, limiting any declarators to the 4758234353Sdim // function prototype scope, including parameter declarators. 4759234353Sdim ParseScope PrototypeScope(this, 4760249423Sdim Scope::FunctionPrototypeScope|Scope::DeclScope| 4761249423Sdim (D.isFunctionDeclaratorAFunctionDeclaration() 4762249423Sdim ? Scope::FunctionDeclarationScope : 0)); 4763249423Sdim 4764193326Sed // The paren may be part of a C++ direct initializer, eg. "int x(1);". 4765193326Sed // In such a case, check if we actually have a function declarator; if it 4766193326Sed // is not, the declarator has been fully parsed. 4767239462Sdim bool IsAmbiguous = false; 4768243830Sdim if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) { 4769243830Sdim // The name of the declarator, if any, is tentatively declared within 4770243830Sdim // a possible direct initializer. 4771243830Sdim TentativelyDeclaredIdentifiers.push_back(D.getIdentifier()); 4772243830Sdim bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous); 4773243830Sdim TentativelyDeclaredIdentifiers.pop_back(); 4774243830Sdim if (!IsFunctionDecl) 4775243830Sdim break; 4776243830Sdim } 4777221345Sdim ParsedAttributes attrs(AttrFactory); 4778226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4779226633Sdim T.consumeOpen(); 4780239462Sdim ParseFunctionDeclarator(D, attrs, T, IsAmbiguous); 4781234353Sdim PrototypeScope.Exit(); 4782193326Sed } else if (Tok.is(tok::l_square)) { 4783193326Sed ParseBracketDeclarator(D); 4784193326Sed } else { 4785193326Sed break; 4786193326Sed } 4787193326Sed } 4788239462Sdim} 4789193326Sed 4790193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is 4791193326Sed/// only called before the identifier, so these are most likely just grouping 4792198092Srdivacky/// parens for precedence. If we find that these are actually function 4793193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator. 4794193326Sed/// 4795193326Sed/// direct-declarator: 4796193326Sed/// '(' declarator ')' 4797193326Sed/// [GNU] '(' attributes declarator ')' 4798193326Sed/// direct-declarator '(' parameter-type-list ')' 4799193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4800193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4801193326Sed/// parameter-type-list[opt] ')' 4802193326Sed/// 4803193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) { 4804226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4805226633Sdim T.consumeOpen(); 4806226633Sdim 4807193326Sed assert(!D.isPastIdentifier() && "Should be called before passing identifier"); 4808198092Srdivacky 4809193326Sed // Eat any attributes before we look at whether this is a grouping or function 4810193326Sed // declarator paren. If this is a grouping paren, the attribute applies to 4811193326Sed // the type being built up, for example: 4812193326Sed // int (__attribute__(()) *x)(long y) 4813193326Sed // If this ends up not being a grouping paren, the attribute applies to the 4814193326Sed // first argument, for example: 4815193326Sed // int (__attribute__(()) int x) 4816193326Sed // In either case, we need to eat any attributes to be able to determine what 4817193326Sed // sort of paren this is. 4818193326Sed // 4819221345Sdim ParsedAttributes attrs(AttrFactory); 4820193326Sed bool RequiresArg = false; 4821193326Sed if (Tok.is(tok::kw___attribute)) { 4822218893Sdim ParseGNUAttributes(attrs); 4823198092Srdivacky 4824193326Sed // We require that the argument list (if this is a non-grouping paren) be 4825193326Sed // present even if the attribute list was empty. 4826193326Sed RequiresArg = true; 4827193326Sed } 4828249423Sdim 4829193326Sed // Eat any Microsoft extensions. 4830249423Sdim ParseMicrosoftTypeAttributes(attrs); 4831249423Sdim 4832212904Sdim // Eat any Borland extensions. 4833218893Sdim if (Tok.is(tok::kw___pascal)) 4834218893Sdim ParseBorlandTypeAttributes(attrs); 4835198092Srdivacky 4836193326Sed // If we haven't past the identifier yet (or where the identifier would be 4837193326Sed // stored, if this is an abstract declarator), then this is probably just 4838193326Sed // grouping parens. However, if this could be an abstract-declarator, then 4839193326Sed // this could also be the start of function arguments (consider 'void()'). 4840193326Sed bool isGrouping; 4841198092Srdivacky 4842193326Sed if (!D.mayOmitIdentifier()) { 4843193326Sed // If this can't be an abstract-declarator, this *must* be a grouping 4844193326Sed // paren, because we haven't seen the identifier yet. 4845193326Sed isGrouping = true; 4846193326Sed } else if (Tok.is(tok::r_paren) || // 'int()' is a function. 4847234353Sdim (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && 4848234353Sdim NextToken().is(tok::r_paren)) || // C++ int(...) 4849234353Sdim isDeclarationSpecifier() || // 'int(int)' is a function. 4850234353Sdim isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function. 4851193326Sed // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is 4852193326Sed // considered to be a type, not a K&R identifier-list. 4853193326Sed isGrouping = false; 4854193326Sed } else { 4855193326Sed // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'. 4856193326Sed isGrouping = true; 4857193326Sed } 4858198092Srdivacky 4859193326Sed // If this is a grouping paren, handle: 4860193326Sed // direct-declarator: '(' declarator ')' 4861193326Sed // direct-declarator: '(' attributes declarator ')' 4862193326Sed if (isGrouping) { 4863234353Sdim SourceLocation EllipsisLoc = D.getEllipsisLoc(); 4864234353Sdim D.setEllipsisLoc(SourceLocation()); 4865234353Sdim 4866193326Sed bool hadGroupingParens = D.hasGroupingParens(); 4867193326Sed D.setGroupingParens(true); 4868193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4869193326Sed // Match the ')'. 4870226633Sdim T.consumeClose(); 4871239462Sdim D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), 4872226633Sdim T.getCloseLocation()), 4873226633Sdim attrs, T.getCloseLocation()); 4874193326Sed 4875193326Sed D.setGroupingParens(hadGroupingParens); 4876234353Sdim 4877234353Sdim // An ellipsis cannot be placed outside parentheses. 4878234353Sdim if (EllipsisLoc.isValid()) 4879234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4880234353Sdim 4881193326Sed return; 4882193326Sed } 4883198092Srdivacky 4884193326Sed // Okay, if this wasn't a grouping paren, it must be the start of a function 4885193326Sed // argument list. Recognize that this declarator will never have an 4886193326Sed // identifier (and remember where it would have been), then call into 4887193326Sed // ParseFunctionDeclarator to handle of argument list. 4888193326Sed D.SetIdentifier(0, Tok.getLocation()); 4889193326Sed 4890234353Sdim // Enter function-declaration scope, limiting any declarators to the 4891234353Sdim // function prototype scope, including parameter declarators. 4892234353Sdim ParseScope PrototypeScope(this, 4893249423Sdim Scope::FunctionPrototypeScope | Scope::DeclScope | 4894249423Sdim (D.isFunctionDeclaratorAFunctionDeclaration() 4895249423Sdim ? Scope::FunctionDeclarationScope : 0)); 4896239462Sdim ParseFunctionDeclarator(D, attrs, T, false, RequiresArg); 4897234353Sdim PrototypeScope.Exit(); 4898193326Sed} 4899193326Sed 4900193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the 4901193326Sed/// declarator D up to a paren, which indicates that we are parsing function 4902193326Sed/// arguments. 4903193326Sed/// 4904234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments 4905234353Sdim/// immediately after the open paren - they should be considered to be the 4906234353Sdim/// first argument of a parameter. 4907193326Sed/// 4908234353Sdim/// If RequiresArg is true, then the first argument of the function is required 4909234353Sdim/// to be present and required to not be an identifier list. 4910193326Sed/// 4911234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt], 4912234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt], 4913234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt]. 4914234353Sdim/// 4915234353Sdim/// [C++11] exception-specification: 4916221345Sdim/// dynamic-exception-specification 4917221345Sdim/// noexcept-specification 4918221345Sdim/// 4919226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D, 4920234353Sdim ParsedAttributes &FirstArgAttrs, 4921226633Sdim BalancedDelimiterTracker &Tracker, 4922239462Sdim bool IsAmbiguous, 4923193326Sed bool RequiresArg) { 4924239462Sdim assert(getCurScope()->isFunctionPrototypeScope() && 4925234353Sdim "Should call from a Function scope"); 4926193326Sed // lparen is already consumed! 4927193326Sed assert(D.isPastIdentifier() && "Should not call before identifier!"); 4928198092Srdivacky 4929224145Sdim // This should be true when the function has typed arguments. 4930224145Sdim // Otherwise, it is treated as a K&R-style function. 4931224145Sdim bool HasProto = false; 4932224145Sdim // Build up an array of information about the parsed arguments. 4933226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 4934224145Sdim // Remember where we see an ellipsis, if any. 4935224145Sdim SourceLocation EllipsisLoc; 4936224145Sdim 4937224145Sdim DeclSpec DS(AttrFactory); 4938224145Sdim bool RefQualifierIsLValueRef = true; 4939224145Sdim SourceLocation RefQualifierLoc; 4940234353Sdim SourceLocation ConstQualifierLoc; 4941234353Sdim SourceLocation VolatileQualifierLoc; 4942224145Sdim ExceptionSpecificationType ESpecType = EST_None; 4943224145Sdim SourceRange ESpecRange; 4944226633Sdim SmallVector<ParsedType, 2> DynamicExceptions; 4945226633Sdim SmallVector<SourceRange, 2> DynamicExceptionRanges; 4946224145Sdim ExprResult NoexceptExpr; 4947234353Sdim ParsedAttributes FnAttrs(AttrFactory); 4948239462Sdim TypeResult TrailingReturnType; 4949234353Sdim 4950234353Sdim Actions.ActOnStartFunctionDeclarator(); 4951234353Sdim 4952243830Sdim /* LocalEndLoc is the end location for the local FunctionTypeLoc. 4953243830Sdim EndLoc is the end location for the function declarator. 4954243830Sdim They differ for trailing return types. */ 4955243830Sdim SourceLocation StartLoc, LocalEndLoc, EndLoc; 4956243830Sdim SourceLocation LParenLoc, RParenLoc; 4957243830Sdim LParenLoc = Tracker.getOpenLocation(); 4958243830Sdim StartLoc = LParenLoc; 4959243830Sdim 4960224145Sdim if (isFunctionDeclaratorIdentifierList()) { 4961218893Sdim if (RequiresArg) 4962193326Sed Diag(Tok, diag::err_argument_required_after_attribute); 4963193326Sed 4964224145Sdim ParseFunctionDeclaratorIdentifierList(D, ParamInfo); 4965193326Sed 4966226633Sdim Tracker.consumeClose(); 4967243830Sdim RParenLoc = Tracker.getCloseLocation(); 4968243830Sdim LocalEndLoc = RParenLoc; 4969243830Sdim EndLoc = RParenLoc; 4970224145Sdim } else { 4971224145Sdim if (Tok.isNot(tok::r_paren)) 4972234353Sdim ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc); 4973224145Sdim else if (RequiresArg) 4974224145Sdim Diag(Tok, diag::err_argument_required_after_attribute); 4975224145Sdim 4976234353Sdim HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; 4977224145Sdim 4978224145Sdim // If we have the closing ')', eat it. 4979226633Sdim Tracker.consumeClose(); 4980243830Sdim RParenLoc = Tracker.getCloseLocation(); 4981243830Sdim LocalEndLoc = RParenLoc; 4982243830Sdim EndLoc = RParenLoc; 4983224145Sdim 4984234353Sdim if (getLangOpts().CPlusPlus) { 4985234353Sdim // FIXME: Accept these components in any order, and produce fixits to 4986234353Sdim // correct the order if the user gets it wrong. Ideally we should deal 4987234353Sdim // with the virt-specifier-seq and pure-specifier in the same way. 4988218893Sdim 4989224145Sdim // Parse cv-qualifier-seq[opt]. 4990249423Sdim ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false, 4991249423Sdim /*CXX11AttributesAllowed*/ false, 4992249423Sdim /*AtomicAllowed*/ false); 4993234353Sdim if (!DS.getSourceRange().getEnd().isInvalid()) { 4994234353Sdim EndLoc = DS.getSourceRange().getEnd(); 4995234353Sdim ConstQualifierLoc = DS.getConstSpecLoc(); 4996234353Sdim VolatileQualifierLoc = DS.getVolatileSpecLoc(); 4997234353Sdim } 4998193326Sed 4999224145Sdim // Parse ref-qualifier[opt]. 5000218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) { 5001249423Sdim Diag(Tok, getLangOpts().CPlusPlus11 ? 5002234353Sdim diag::warn_cxx98_compat_ref_qualifier : 5003234353Sdim diag::ext_ref_qualifier); 5004234353Sdim 5005218893Sdim RefQualifierIsLValueRef = Tok.is(tok::amp); 5006218893Sdim RefQualifierLoc = ConsumeToken(); 5007218893Sdim EndLoc = RefQualifierLoc; 5008218893Sdim } 5009221345Sdim 5010234982Sdim // C++11 [expr.prim.general]p3: 5011239462Sdim // If a declaration declares a member function or member function 5012239462Sdim // template of a class X, the expression this is a prvalue of type 5013234982Sdim // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 5014239462Sdim // and the end of the function-definition, member-declarator, or 5015234982Sdim // declarator. 5016249423Sdim // FIXME: currently, "static" case isn't handled correctly. 5017239462Sdim bool IsCXX11MemberFunction = 5018249423Sdim getLangOpts().CPlusPlus11 && 5019249423Sdim (D.getContext() == Declarator::MemberContext 5020249423Sdim ? !D.getDeclSpec().isFriendSpecified() 5021249423Sdim : D.getContext() == Declarator::FileContext && 5022249423Sdim D.getCXXScopeSpec().isValid() && 5023249423Sdim Actions.CurContext->isRecord()); 5024234982Sdim Sema::CXXThisScopeRAII ThisScope(Actions, 5025234982Sdim dyn_cast<CXXRecordDecl>(Actions.CurContext), 5026249423Sdim DS.getTypeQualifiers() | 5027251662Sdim (D.getDeclSpec().isConstexprSpecified() && 5028251662Sdim !getLangOpts().CPlusPlus1y 5029249423Sdim ? Qualifiers::Const : 0), 5030234982Sdim IsCXX11MemberFunction); 5031235864Sdim 5032193326Sed // Parse exception-specification[opt]. 5033235864Sdim ESpecType = tryParseExceptionSpecification(ESpecRange, 5034234982Sdim DynamicExceptions, 5035234982Sdim DynamicExceptionRanges, 5036235864Sdim NoexceptExpr); 5037221345Sdim if (ESpecType != EST_None) 5038221345Sdim EndLoc = ESpecRange.getEnd(); 5039218893Sdim 5040234353Sdim // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes 5041234353Sdim // after the exception-specification. 5042249423Sdim MaybeParseCXX11Attributes(FnAttrs); 5043234353Sdim 5044224145Sdim // Parse trailing-return-type[opt]. 5045243830Sdim LocalEndLoc = EndLoc; 5046249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) { 5047234353Sdim Diag(Tok, diag::warn_cxx98_compat_trailing_return_type); 5048243830Sdim if (D.getDeclSpec().getTypeSpecType() == TST_auto) 5049243830Sdim StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); 5050243830Sdim LocalEndLoc = Tok.getLocation(); 5051226633Sdim SourceRange Range; 5052239462Sdim TrailingReturnType = ParseTrailingReturnType(Range); 5053243830Sdim EndLoc = Range.getEnd(); 5054218893Sdim } 5055193326Sed } 5056193326Sed } 5057193326Sed 5058224145Sdim // Remember that we parsed a function type, and remember the attributes. 5059224145Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, 5060243830Sdim IsAmbiguous, 5061243830Sdim LParenLoc, 5062224145Sdim ParamInfo.data(), ParamInfo.size(), 5063243830Sdim EllipsisLoc, RParenLoc, 5064224145Sdim DS.getTypeQualifiers(), 5065224145Sdim RefQualifierIsLValueRef, 5066234353Sdim RefQualifierLoc, ConstQualifierLoc, 5067234353Sdim VolatileQualifierLoc, 5068224145Sdim /*MutableLoc=*/SourceLocation(), 5069224145Sdim ESpecType, ESpecRange.getBegin(), 5070224145Sdim DynamicExceptions.data(), 5071224145Sdim DynamicExceptionRanges.data(), 5072224145Sdim DynamicExceptions.size(), 5073224145Sdim NoexceptExpr.isUsable() ? 5074224145Sdim NoexceptExpr.get() : 0, 5075243830Sdim StartLoc, LocalEndLoc, D, 5076224145Sdim TrailingReturnType), 5077234353Sdim FnAttrs, EndLoc); 5078234353Sdim 5079234353Sdim Actions.ActOnEndFunctionDeclarator(); 5080224145Sdim} 5081224145Sdim 5082224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an 5083224145Sdim/// identifier list form for a K&R-style function: void foo(a,b,c) 5084224145Sdim/// 5085224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for 5086224145Sdim/// abstract-declarators. 5087224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() { 5088234353Sdim return !getLangOpts().CPlusPlus 5089224145Sdim && Tok.is(tok::identifier) 5090224145Sdim && !TryAltiVecVectorToken() 5091224145Sdim // K&R identifier lists can't have typedefs as identifiers, per C99 5092224145Sdim // 6.7.5.3p11. 5093224145Sdim && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) 5094224145Sdim // Identifier lists follow a really simple grammar: the identifiers can 5095224145Sdim // be followed *only* by a ", identifier" or ")". However, K&R 5096224145Sdim // identifier lists are really rare in the brave new modern world, and 5097224145Sdim // it is very common for someone to typo a type in a non-K&R style 5098224145Sdim // list. If we are presented with something like: "void foo(intptr x, 5099224145Sdim // float y)", we don't want to start parsing the function declarator as 5100224145Sdim // though it is a K&R style declarator just because intptr is an 5101224145Sdim // invalid type. 5102224145Sdim // 5103224145Sdim // To handle this, we check to see if the token after the first 5104224145Sdim // identifier is a "," or ")". Only then do we parse it as an 5105224145Sdim // identifier list. 5106224145Sdim && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); 5107224145Sdim} 5108224145Sdim 5109224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator 5110224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list. 5111224145Sdim/// 5112224145Sdim/// After returning, ParamInfo will hold the parsed parameters. 5113224145Sdim/// 5114224145Sdim/// identifier-list: [C99 6.7.5] 5115224145Sdim/// identifier 5116224145Sdim/// identifier-list ',' identifier 5117224145Sdim/// 5118224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList( 5119224145Sdim Declarator &D, 5120226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) { 5121224145Sdim // If there was no identifier specified for the declarator, either we are in 5122224145Sdim // an abstract-declarator, or we are in a parameter declarator which was found 5123224145Sdim // to be abstract. In abstract-declarators, identifier lists are not valid: 5124224145Sdim // diagnose this. 5125224145Sdim if (!D.getIdentifier()) 5126224145Sdim Diag(Tok, diag::ext_ident_list_in_param); 5127224145Sdim 5128224145Sdim // Maintain an efficient lookup of params we have seen so far. 5129224145Sdim llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar; 5130224145Sdim 5131224145Sdim while (1) { 5132224145Sdim // If this isn't an identifier, report the error and skip until ')'. 5133224145Sdim if (Tok.isNot(tok::identifier)) { 5134224145Sdim Diag(Tok, diag::err_expected_ident); 5135224145Sdim SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true); 5136224145Sdim // Forget we parsed anything. 5137224145Sdim ParamInfo.clear(); 5138224145Sdim return; 5139193326Sed } 5140198092Srdivacky 5141224145Sdim IdentifierInfo *ParmII = Tok.getIdentifierInfo(); 5142198092Srdivacky 5143224145Sdim // Reject 'typedef int y; int test(x, y)', but continue parsing. 5144224145Sdim if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope())) 5145224145Sdim Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; 5146193326Sed 5147224145Sdim // Verify that the argument identifier has not already been mentioned. 5148224145Sdim if (!ParamsSoFar.insert(ParmII)) { 5149224145Sdim Diag(Tok, diag::err_param_redefinition) << ParmII; 5150224145Sdim } else { 5151224145Sdim // Remember this identifier in ParamInfo. 5152224145Sdim ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5153224145Sdim Tok.getLocation(), 5154224145Sdim 0)); 5155224145Sdim } 5156198092Srdivacky 5157224145Sdim // Eat the identifier. 5158224145Sdim ConsumeToken(); 5159224145Sdim 5160224145Sdim // The list continues if we see a comma. 5161224145Sdim if (Tok.isNot(tok::comma)) 5162224145Sdim break; 5163224145Sdim ConsumeToken(); 5164224145Sdim } 5165224145Sdim} 5166224145Sdim 5167224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list 5168224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style 5169224145Sdim/// identifier list. 5170224145Sdim/// 5171234353Sdim/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the 5172234353Sdim/// caller parsed those arguments immediately after the open paren - they should 5173234353Sdim/// be considered to be part of the first parameter. 5174224145Sdim/// 5175224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will 5176224145Sdim/// be the location of the ellipsis, if any was parsed. 5177224145Sdim/// 5178224145Sdim/// parameter-type-list: [C99 6.7.5] 5179224145Sdim/// parameter-list 5180224145Sdim/// parameter-list ',' '...' 5181224145Sdim/// [C++] parameter-list '...' 5182224145Sdim/// 5183224145Sdim/// parameter-list: [C99 6.7.5] 5184224145Sdim/// parameter-declaration 5185224145Sdim/// parameter-list ',' parameter-declaration 5186224145Sdim/// 5187224145Sdim/// parameter-declaration: [C99 6.7.5] 5188224145Sdim/// declaration-specifiers declarator 5189224145Sdim/// [C++] declaration-specifiers declarator '=' assignment-expression 5190234353Sdim/// [C++11] initializer-clause 5191224145Sdim/// [GNU] declaration-specifiers declarator attributes 5192224145Sdim/// declaration-specifiers abstract-declarator[opt] 5193224145Sdim/// [C++] declaration-specifiers abstract-declarator[opt] 5194224145Sdim/// '=' assignment-expression 5195224145Sdim/// [GNU] declaration-specifiers abstract-declarator[opt] attributes 5196234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration 5197224145Sdim/// 5198224145Sdimvoid Parser::ParseParameterDeclarationClause( 5199224145Sdim Declarator &D, 5200234353Sdim ParsedAttributes &FirstArgAttrs, 5201226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, 5202224145Sdim SourceLocation &EllipsisLoc) { 5203224145Sdim 5204193326Sed while (1) { 5205193326Sed if (Tok.is(tok::ellipsis)) { 5206234353Sdim // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq 5207234353Sdim // before deciding this was a parameter-declaration-clause. 5208193326Sed EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5209193326Sed break; 5210193326Sed } 5211198092Srdivacky 5212193326Sed // Parse the declaration-specifiers. 5213198893Srdivacky // Just use the ParsingDeclaration "scope" of the declarator. 5214221345Sdim DeclSpec DS(AttrFactory); 5215226633Sdim 5216234353Sdim // Parse any C++11 attributes. 5217249423Sdim MaybeParseCXX11Attributes(DS.getAttributes()); 5218234353Sdim 5219218893Sdim // Skip any Microsoft attributes before a param. 5220249423Sdim MaybeParseMicrosoftAttributes(DS.getAttributes()); 5221193326Sed 5222218893Sdim SourceLocation DSStart = Tok.getLocation(); 5223218893Sdim 5224193326Sed // If the caller parsed attributes for the first argument, add them now. 5225218893Sdim // Take them so that we only apply the attributes to the first parameter. 5226224145Sdim // FIXME: If we can leave the attributes in the token stream somehow, we can 5227234353Sdim // get rid of a parameter (FirstArgAttrs) and this statement. It might be 5228234353Sdim // too much hassle. 5229234353Sdim DS.takeAttributesFrom(FirstArgAttrs); 5230218893Sdim 5231193326Sed ParseDeclarationSpecifiers(DS); 5232198092Srdivacky 5233193326Sed // Parse the declarator. This is "PrototypeContext", because we must 5234193326Sed // accept either 'declarator' or 'abstract-declarator' here. 5235193326Sed Declarator ParmDecl(DS, Declarator::PrototypeContext); 5236193326Sed ParseDeclarator(ParmDecl); 5237193326Sed 5238193326Sed // Parse GNU attributes, if present. 5239218893Sdim MaybeParseGNUAttributes(ParmDecl); 5240198092Srdivacky 5241193326Sed // Remember this parsed parameter in ParamInfo. 5242193326Sed IdentifierInfo *ParmII = ParmDecl.getIdentifier(); 5243198092Srdivacky 5244193326Sed // DefArgToks is used when the parsing of default arguments needs 5245193326Sed // to be delayed. 5246193326Sed CachedTokens *DefArgToks = 0; 5247193326Sed 5248193326Sed // If no parameter was specified, verify that *something* was specified, 5249193326Sed // otherwise we have a missing type and identifier. 5250193326Sed if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 && 5251193326Sed ParmDecl.getNumTypeObjects() == 0) { 5252193326Sed // Completely missing, emit error. 5253193326Sed Diag(DSStart, diag::err_missing_param); 5254193326Sed } else { 5255193326Sed // Otherwise, we have something. Add it and let semantic analysis try 5256193326Sed // to grok it and add the result to the ParamInfo we are building. 5257198092Srdivacky 5258193326Sed // Inform the actions module about the parameter declarator, so it gets 5259193326Sed // added to the current scope. 5260212904Sdim Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); 5261193326Sed 5262193326Sed // Parse the default argument, if any. We parse the default 5263193326Sed // arguments in all dialects; the semantic analysis in 5264193326Sed // ActOnParamDefaultArgument will reject the default argument in 5265193326Sed // C. 5266193326Sed if (Tok.is(tok::equal)) { 5267193326Sed SourceLocation EqualLoc = Tok.getLocation(); 5268193326Sed 5269193326Sed // Parse the default argument 5270193326Sed if (D.getContext() == Declarator::MemberContext) { 5271193326Sed // If we're inside a class definition, cache the tokens 5272193326Sed // corresponding to the default argument. We'll actually parse 5273193326Sed // them when we see the end of the class definition. 5274193326Sed // FIXME: Can we use a smart pointer for Toks? 5275193326Sed DefArgToks = new CachedTokens; 5276193326Sed 5277198092Srdivacky if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks, 5278207619Srdivacky /*StopAtSemi=*/true, 5279207619Srdivacky /*ConsumeFinalToken=*/false)) { 5280193326Sed delete DefArgToks; 5281193326Sed DefArgToks = 0; 5282193326Sed Actions.ActOnParamDefaultArgumentError(Param); 5283212904Sdim } else { 5284212904Sdim // Mark the end of the default argument so that we know when to 5285212904Sdim // stop when we parse it later on. 5286212904Sdim Token DefArgEnd; 5287212904Sdim DefArgEnd.startToken(); 5288212904Sdim DefArgEnd.setKind(tok::cxx_defaultarg_end); 5289212904Sdim DefArgEnd.setLocation(Tok.getLocation()); 5290212904Sdim DefArgToks->push_back(DefArgEnd); 5291198092Srdivacky Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, 5292194179Sed (*DefArgToks)[1].getLocation()); 5293212904Sdim } 5294193326Sed } else { 5295193326Sed // Consume the '='. 5296193326Sed ConsumeToken(); 5297198092Srdivacky 5298239462Sdim // The argument isn't actually potentially evaluated unless it is 5299218893Sdim // used. 5300218893Sdim EnterExpressionEvaluationContext Eval(Actions, 5301234353Sdim Sema::PotentiallyEvaluatedIfUsed, 5302234353Sdim Param); 5303218893Sdim 5304234353Sdim ExprResult DefArgResult; 5305249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5306234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 5307234353Sdim DefArgResult = ParseBraceInitializer(); 5308234353Sdim } else 5309234353Sdim DefArgResult = ParseAssignmentExpression(); 5310193326Sed if (DefArgResult.isInvalid()) { 5311193326Sed Actions.ActOnParamDefaultArgumentError(Param); 5312193326Sed SkipUntil(tok::comma, tok::r_paren, true, true); 5313193326Sed } else { 5314193326Sed // Inform the actions module about the default argument 5315193326Sed Actions.ActOnParamDefaultArgument(Param, EqualLoc, 5316212904Sdim DefArgResult.take()); 5317193326Sed } 5318193326Sed } 5319193326Sed } 5320198092Srdivacky 5321198092Srdivacky ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 5322198092Srdivacky ParmDecl.getIdentifierLoc(), Param, 5323193326Sed DefArgToks)); 5324193326Sed } 5325193326Sed 5326193326Sed // If the next token is a comma, consume it and keep reading arguments. 5327198092Srdivacky if (Tok.isNot(tok::comma)) { 5328198092Srdivacky if (Tok.is(tok::ellipsis)) { 5329198092Srdivacky EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 5330239462Sdim 5331234353Sdim if (!getLangOpts().CPlusPlus) { 5332198092Srdivacky // We have ellipsis without a preceding ',', which is ill-formed 5333198092Srdivacky // in C. Complain and provide the fix. 5334198092Srdivacky Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis) 5335206084Srdivacky << FixItHint::CreateInsertion(EllipsisLoc, ", "); 5336198092Srdivacky } 5337198092Srdivacky } 5338239462Sdim 5339198092Srdivacky break; 5340198092Srdivacky } 5341198092Srdivacky 5342193326Sed // Consume the comma. 5343193326Sed ConsumeToken(); 5344193326Sed } 5345198092Srdivacky 5346193326Sed} 5347193326Sed 5348193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 5349193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 5350193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 5351193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 5352193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 5353234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 5354234353Sdim/// attribute-specifier-seq[opt] 5355193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) { 5356234353Sdim if (CheckProhibitedCXX11Attribute()) 5357234353Sdim return; 5358234353Sdim 5359226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 5360226633Sdim T.consumeOpen(); 5361198092Srdivacky 5362193326Sed // C array syntax has many features, but by-far the most common is [] and [4]. 5363193326Sed // This code does a fast path to handle some of the most obvious cases. 5364193326Sed if (Tok.getKind() == tok::r_square) { 5365226633Sdim T.consumeClose(); 5366221345Sdim ParsedAttributes attrs(AttrFactory); 5367249423Sdim MaybeParseCXX11Attributes(attrs); 5368239462Sdim 5369193326Sed // Remember that we parsed the empty array type. 5370212904Sdim ExprResult NumElements; 5371221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, 5372226633Sdim T.getOpenLocation(), 5373226633Sdim T.getCloseLocation()), 5374226633Sdim attrs, T.getCloseLocation()); 5375193326Sed return; 5376193326Sed } else if (Tok.getKind() == tok::numeric_constant && 5377193326Sed GetLookAheadToken(1).is(tok::r_square)) { 5378193326Sed // [4] is very common. Parse the numeric constant expression. 5379234353Sdim ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope())); 5380193326Sed ConsumeToken(); 5381193326Sed 5382226633Sdim T.consumeClose(); 5383221345Sdim ParsedAttributes attrs(AttrFactory); 5384249423Sdim MaybeParseCXX11Attributes(attrs); 5385193326Sed 5386193326Sed // Remember that we parsed a array type, and remember its features. 5387249423Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 5388218893Sdim ExprRes.release(), 5389226633Sdim T.getOpenLocation(), 5390226633Sdim T.getCloseLocation()), 5391226633Sdim attrs, T.getCloseLocation()); 5392193326Sed return; 5393193326Sed } 5394198092Srdivacky 5395193326Sed // If valid, this location is the position where we read the 'static' keyword. 5396193326Sed SourceLocation StaticLoc; 5397193326Sed if (Tok.is(tok::kw_static)) 5398193326Sed StaticLoc = ConsumeToken(); 5399198092Srdivacky 5400193326Sed // If there is a type-qualifier-list, read it now. 5401193326Sed // Type qualifiers in an array subscript are a C99 feature. 5402221345Sdim DeclSpec DS(AttrFactory); 5403193326Sed ParseTypeQualifierListOpt(DS, false /*no attributes*/); 5404198092Srdivacky 5405193326Sed // If we haven't already read 'static', check to see if there is one after the 5406193326Sed // type-qualifier-list. 5407193326Sed if (!StaticLoc.isValid() && Tok.is(tok::kw_static)) 5408193326Sed StaticLoc = ConsumeToken(); 5409198092Srdivacky 5410193326Sed // Handle "direct-declarator [ type-qual-list[opt] * ]". 5411193326Sed bool isStar = false; 5412212904Sdim ExprResult NumElements; 5413198092Srdivacky 5414193326Sed // Handle the case where we have '[*]' as the array size. However, a leading 5415193326Sed // star could be the start of an expression, for example 'X[*p + 4]'. Verify 5416239462Sdim // the token after the star is a ']'. Since stars in arrays are 5417193326Sed // infrequent, use of lookahead is not costly here. 5418193326Sed if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) { 5419193326Sed ConsumeToken(); // Eat the '*'. 5420193326Sed 5421193326Sed if (StaticLoc.isValid()) { 5422193326Sed Diag(StaticLoc, diag::err_unspecified_vla_size_with_static); 5423193326Sed StaticLoc = SourceLocation(); // Drop the static. 5424193326Sed } 5425193326Sed isStar = true; 5426193326Sed } else if (Tok.isNot(tok::r_square)) { 5427193326Sed // Note, in C89, this production uses the constant-expr production instead 5428193326Sed // of assignment-expr. The only difference is that assignment-expr allows 5429193326Sed // things like '=' and '*='. Sema rejects these in C89 mode because they 5430193326Sed // are not i-c-e's, so we don't need to distinguish between the two here. 5431198092Srdivacky 5432194613Sed // Parse the constant-expression or assignment-expression now (depending 5433194613Sed // on dialect). 5434234353Sdim if (getLangOpts().CPlusPlus) { 5435194613Sed NumElements = ParseConstantExpression(); 5436234353Sdim } else { 5437234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 5438234353Sdim Sema::ConstantEvaluated); 5439194613Sed NumElements = ParseAssignmentExpression(); 5440234353Sdim } 5441193326Sed } 5442198092Srdivacky 5443193326Sed // If there was an error parsing the assignment-expression, recover. 5444193326Sed if (NumElements.isInvalid()) { 5445193326Sed D.setInvalidType(true); 5446193326Sed // If the expression was invalid, skip it. 5447193326Sed SkipUntil(tok::r_square); 5448193326Sed return; 5449193326Sed } 5450193326Sed 5451226633Sdim T.consumeClose(); 5452193326Sed 5453221345Sdim ParsedAttributes attrs(AttrFactory); 5454249423Sdim MaybeParseCXX11Attributes(attrs); 5455199990Srdivacky 5456193326Sed // Remember that we parsed a array type, and remember its features. 5457221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), 5458193326Sed StaticLoc.isValid(), isStar, 5459198092Srdivacky NumElements.release(), 5460226633Sdim T.getOpenLocation(), 5461226633Sdim T.getCloseLocation()), 5462226633Sdim attrs, T.getCloseLocation()); 5463193326Sed} 5464193326Sed 5465193326Sed/// [GNU] typeof-specifier: 5466193326Sed/// typeof ( expressions ) 5467193326Sed/// typeof ( type-name ) 5468193326Sed/// [GNU/C++] typeof unary-expression 5469193326Sed/// 5470193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) { 5471193326Sed assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); 5472193326Sed Token OpTok = Tok; 5473193326Sed SourceLocation StartLoc = ConsumeToken(); 5474193326Sed 5475202379Srdivacky const bool hasParens = Tok.is(tok::l_paren); 5476202379Srdivacky 5477243830Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 5478243830Sdim Sema::ReuseLambdaContextDecl); 5479234353Sdim 5480193326Sed bool isCastExpr; 5481212904Sdim ParsedType CastTy; 5482193326Sed SourceRange CastRange; 5483221345Sdim ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, 5484221345Sdim CastTy, CastRange); 5485202379Srdivacky if (hasParens) 5486202379Srdivacky DS.setTypeofParensRange(CastRange); 5487193326Sed 5488193326Sed if (CastRange.getEnd().isInvalid()) 5489193326Sed // FIXME: Not accurate, the range gets one token more than it should. 5490193326Sed DS.SetRangeEnd(Tok.getLocation()); 5491193326Sed else 5492193326Sed DS.SetRangeEnd(CastRange.getEnd()); 5493198092Srdivacky 5494193326Sed if (isCastExpr) { 5495193326Sed if (!CastTy) { 5496193326Sed DS.SetTypeSpecError(); 5497193326Sed return; 5498193326Sed } 5499193326Sed 5500193326Sed const char *PrevSpec = 0; 5501198092Srdivacky unsigned DiagID; 5502193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5503193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 5504198092Srdivacky DiagID, CastTy)) 5505198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5506193326Sed return; 5507193326Sed } 5508193326Sed 5509193326Sed // If we get here, the operand to the typeof was an expresion. 5510193326Sed if (Operand.isInvalid()) { 5511193326Sed DS.SetTypeSpecError(); 5512193326Sed return; 5513193326Sed } 5514193326Sed 5515234353Sdim // We might need to transform the operand if it is potentially evaluated. 5516234353Sdim Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get()); 5517234353Sdim if (Operand.isInvalid()) { 5518234353Sdim DS.SetTypeSpecError(); 5519234353Sdim return; 5520234353Sdim } 5521234353Sdim 5522193326Sed const char *PrevSpec = 0; 5523198092Srdivacky unsigned DiagID; 5524193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5525193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 5526212904Sdim DiagID, Operand.get())) 5527198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5528193326Sed} 5529204643Srdivacky 5530234353Sdim/// [C11] atomic-specifier: 5531226633Sdim/// _Atomic ( type-name ) 5532226633Sdim/// 5533226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) { 5534249423Sdim assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) && 5535249423Sdim "Not an atomic specifier"); 5536204643Srdivacky 5537226633Sdim SourceLocation StartLoc = ConsumeToken(); 5538226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 5539249423Sdim if (T.consumeOpen()) 5540226633Sdim return; 5541226633Sdim 5542226633Sdim TypeResult Result = ParseTypeName(); 5543226633Sdim if (Result.isInvalid()) { 5544226633Sdim SkipUntil(tok::r_paren); 5545226633Sdim return; 5546226633Sdim } 5547226633Sdim 5548226633Sdim // Match the ')' 5549226633Sdim T.consumeClose(); 5550226633Sdim 5551226633Sdim if (T.getCloseLocation().isInvalid()) 5552226633Sdim return; 5553226633Sdim 5554226633Sdim DS.setTypeofParensRange(T.getRange()); 5555226633Sdim DS.SetRangeEnd(T.getCloseLocation()); 5556226633Sdim 5557226633Sdim const char *PrevSpec = 0; 5558226633Sdim unsigned DiagID; 5559226633Sdim if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec, 5560226633Sdim DiagID, Result.release())) 5561226633Sdim Diag(StartLoc, DiagID) << PrevSpec; 5562226633Sdim} 5563226633Sdim 5564226633Sdim 5565204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called 5566204643Srdivacky/// from TryAltiVecVectorToken. 5567204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() { 5568204643Srdivacky Token Next = NextToken(); 5569204643Srdivacky switch (Next.getKind()) { 5570204643Srdivacky default: return false; 5571204643Srdivacky case tok::kw_short: 5572204643Srdivacky case tok::kw_long: 5573204643Srdivacky case tok::kw_signed: 5574204643Srdivacky case tok::kw_unsigned: 5575204643Srdivacky case tok::kw_void: 5576204643Srdivacky case tok::kw_char: 5577204643Srdivacky case tok::kw_int: 5578204643Srdivacky case tok::kw_float: 5579204643Srdivacky case tok::kw_double: 5580204643Srdivacky case tok::kw_bool: 5581204643Srdivacky case tok::kw___pixel: 5582204643Srdivacky Tok.setKind(tok::kw___vector); 5583204643Srdivacky return true; 5584204643Srdivacky case tok::identifier: 5585204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5586204643Srdivacky Tok.setKind(tok::kw___vector); 5587204643Srdivacky return true; 5588204643Srdivacky } 5589204643Srdivacky return false; 5590204643Srdivacky } 5591204643Srdivacky} 5592204643Srdivacky 5593204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, 5594204643Srdivacky const char *&PrevSpec, unsigned &DiagID, 5595204643Srdivacky bool &isInvalid) { 5596204643Srdivacky if (Tok.getIdentifierInfo() == Ident_vector) { 5597204643Srdivacky Token Next = NextToken(); 5598204643Srdivacky switch (Next.getKind()) { 5599204643Srdivacky case tok::kw_short: 5600204643Srdivacky case tok::kw_long: 5601204643Srdivacky case tok::kw_signed: 5602204643Srdivacky case tok::kw_unsigned: 5603204643Srdivacky case tok::kw_void: 5604204643Srdivacky case tok::kw_char: 5605204643Srdivacky case tok::kw_int: 5606204643Srdivacky case tok::kw_float: 5607204643Srdivacky case tok::kw_double: 5608204643Srdivacky case tok::kw_bool: 5609204643Srdivacky case tok::kw___pixel: 5610204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5611204643Srdivacky return true; 5612204643Srdivacky case tok::identifier: 5613204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5614204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5615204643Srdivacky return true; 5616204643Srdivacky } 5617204643Srdivacky break; 5618204643Srdivacky default: 5619204643Srdivacky break; 5620204643Srdivacky } 5621210299Sed } else if ((Tok.getIdentifierInfo() == Ident_pixel) && 5622204643Srdivacky DS.isTypeAltiVecVector()) { 5623204643Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 5624204643Srdivacky return true; 5625204643Srdivacky } 5626204643Srdivacky return false; 5627204643Srdivacky} 5628