ParseDecl.cpp revision 239462
1193326Sed//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Declaration portions of the Parser interfaces. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Parse/Parser.h" 15193326Sed#include "clang/Parse/ParseDiagnostic.h" 16221345Sdim#include "clang/Basic/OpenCL.h" 17239462Sdim#include "clang/Sema/Lookup.h" 18212904Sdim#include "clang/Sema/Scope.h" 19212904Sdim#include "clang/Sema/ParsedTemplate.h" 20212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h" 21200583Srdivacky#include "RAIIObjectsForParser.h" 22193326Sed#include "llvm/ADT/SmallSet.h" 23234353Sdim#include "llvm/ADT/SmallString.h" 24226633Sdim#include "llvm/ADT/StringSwitch.h" 25193326Sedusing namespace clang; 26193326Sed 27193326Sed//===----------------------------------------------------------------------===// 28193326Sed// C99 6.7: Declarations. 29193326Sed//===----------------------------------------------------------------------===// 30193326Sed 31193326Sed/// ParseTypeName 32193326Sed/// type-name: [C99 6.7.6] 33193326Sed/// specifier-qualifier-list abstract-declarator[opt] 34193326Sed/// 35193326Sed/// Called type-id in C++. 36218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range, 37224145Sdim Declarator::TheContext Context, 38224145Sdim AccessSpecifier AS, 39224145Sdim Decl **OwnedType) { 40234353Sdim DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context); 41239462Sdim if (DSC == DSC_normal) 42239462Sdim DSC = DSC_type_specifier; 43234353Sdim 44193326Sed // Parse the common declaration-specifiers piece. 45221345Sdim DeclSpec DS(AttrFactory); 46234353Sdim ParseSpecifierQualifierList(DS, AS, DSC); 47224145Sdim if (OwnedType) 48224145Sdim *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; 49193326Sed 50193326Sed // Parse the abstract-declarator, if present. 51218893Sdim Declarator DeclaratorInfo(DS, Context); 52193326Sed ParseDeclarator(DeclaratorInfo); 53193326Sed if (Range) 54193326Sed *Range = DeclaratorInfo.getSourceRange(); 55193326Sed 56193326Sed if (DeclaratorInfo.isInvalidType()) 57193326Sed return true; 58193326Sed 59210299Sed return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 60193326Sed} 61193326Sed 62226633Sdim 63226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that 64226633Sdim/// require late parsing. 65226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) { 66226633Sdim return llvm::StringSwitch<bool>(II.getName()) 67226633Sdim#include "clang/Parse/AttrLateParsed.inc" 68226633Sdim .Default(false); 69226633Sdim} 70226633Sdim 71199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list. 72193326Sed/// 73193326Sed/// [GNU] attributes: 74193326Sed/// attribute 75193326Sed/// attributes attribute 76193326Sed/// 77193326Sed/// [GNU] attribute: 78193326Sed/// '__attribute__' '(' '(' attribute-list ')' ')' 79193326Sed/// 80193326Sed/// [GNU] attribute-list: 81193326Sed/// attrib 82193326Sed/// attribute_list ',' attrib 83193326Sed/// 84193326Sed/// [GNU] attrib: 85193326Sed/// empty 86193326Sed/// attrib-name 87193326Sed/// attrib-name '(' identifier ')' 88193326Sed/// attrib-name '(' identifier ',' nonempty-expr-list ')' 89193326Sed/// attrib-name '(' argument-expression-list [C99 6.5.2] ')' 90193326Sed/// 91193326Sed/// [GNU] attrib-name: 92193326Sed/// identifier 93193326Sed/// typespec 94193326Sed/// typequal 95193326Sed/// storageclass 96198092Srdivacky/// 97193326Sed/// FIXME: The GCC grammar/code for this construct implies we need two 98198092Srdivacky/// token lookahead. Comment from gcc: "If they start with an identifier 99198092Srdivacky/// which is followed by a comma or close parenthesis, then the arguments 100193326Sed/// start with that identifier; otherwise they are an expression list." 101193326Sed/// 102234353Sdim/// GCC does not require the ',' between attribs in an attribute-list. 103234353Sdim/// 104193326Sed/// At the moment, I am not doing 2 token lookahead. I am also unaware of 105193326Sed/// any attributes that don't work (based on my limited testing). Most 106193326Sed/// attributes are very simple in practice. Until we find a bug, I don't see 107193326Sed/// a pressing need to implement the 2 token lookahead. 108193326Sed 109218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs, 110226633Sdim SourceLocation *endLoc, 111226633Sdim LateParsedAttrList *LateAttrs) { 112199990Srdivacky assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); 113198092Srdivacky 114193326Sed while (Tok.is(tok::kw___attribute)) { 115193326Sed ConsumeToken(); 116193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 117193326Sed "attribute")) { 118193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 119218893Sdim return; 120193326Sed } 121193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { 122193326Sed SkipUntil(tok::r_paren, true); // skip until ) or ; 123218893Sdim return; 124193326Sed } 125193326Sed // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) 126193326Sed while (Tok.is(tok::identifier) || isDeclarationSpecifier() || 127193326Sed Tok.is(tok::comma)) { 128198092Srdivacky if (Tok.is(tok::comma)) { 129193326Sed // allows for empty/non-empty attributes. ((__vector_size__(16),,,,)) 130193326Sed ConsumeToken(); 131193326Sed continue; 132193326Sed } 133193326Sed // we have an identifier or declaration specifier (const, int, etc.) 134193326Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 135193326Sed SourceLocation AttrNameLoc = ConsumeToken(); 136198092Srdivacky 137226633Sdim if (Tok.is(tok::l_paren)) { 138226633Sdim // handle "parameterized" attributes 139234353Sdim if (LateAttrs && isAttributeLateParsed(*AttrName)) { 140226633Sdim LateParsedAttribute *LA = 141226633Sdim new LateParsedAttribute(this, *AttrName, AttrNameLoc); 142226633Sdim LateAttrs->push_back(LA); 143198092Srdivacky 144234353Sdim // Attributes in a class are parsed at the end of the class, along 145234353Sdim // with other late-parsed declarations. 146234353Sdim if (!ClassStack.empty()) 147234353Sdim getCurrentClass().LateParsedDeclarations.push_back(LA); 148234353Sdim 149226633Sdim // consume everything up to and including the matching right parens 150226633Sdim ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false); 151198092Srdivacky 152226633Sdim Token Eof; 153226633Sdim Eof.startToken(); 154226633Sdim Eof.setLocation(Tok.getLocation()); 155226633Sdim LA->Toks.push_back(Eof); 156226633Sdim } else { 157226633Sdim ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc); 158193326Sed } 159193326Sed } else { 160221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 161239462Sdim 0, SourceLocation(), 0, 0, AttributeList::AS_GNU); 162193326Sed } 163193326Sed } 164193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) 165193326Sed SkipUntil(tok::r_paren, false); 166199990Srdivacky SourceLocation Loc = Tok.getLocation(); 167193326Sed if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 168193326Sed SkipUntil(tok::r_paren, false); 169193326Sed } 170218893Sdim if (endLoc) 171218893Sdim *endLoc = Loc; 172193326Sed } 173193326Sed} 174193326Sed 175226633Sdim 176226633Sdim/// Parse the arguments to a parameterized GNU attribute 177226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, 178226633Sdim SourceLocation AttrNameLoc, 179226633Sdim ParsedAttributes &Attrs, 180226633Sdim SourceLocation *EndLoc) { 181226633Sdim 182226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 183226633Sdim 184226633Sdim // Availability attributes have their own grammar. 185226633Sdim if (AttrName->isStr("availability")) { 186226633Sdim ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 187226633Sdim return; 188226633Sdim } 189226633Sdim // Thread safety attributes fit into the FIXME case above, so we 190226633Sdim // just parse the arguments as a list of expressions 191226633Sdim if (IsThreadSafetyAttribute(AttrName->getName())) { 192226633Sdim ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 193226633Sdim return; 194226633Sdim } 195239462Sdim // Type safety attributes have their own grammar. 196239462Sdim if (AttrName->isStr("type_tag_for_datatype")) { 197239462Sdim ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 198239462Sdim return; 199239462Sdim } 200226633Sdim 201226633Sdim ConsumeParen(); // ignore the left paren loc for now 202226633Sdim 203234353Sdim IdentifierInfo *ParmName = 0; 204234353Sdim SourceLocation ParmLoc; 205234353Sdim bool BuiltinType = false; 206226633Sdim 207234353Sdim switch (Tok.getKind()) { 208234353Sdim case tok::kw_char: 209234353Sdim case tok::kw_wchar_t: 210234353Sdim case tok::kw_char16_t: 211234353Sdim case tok::kw_char32_t: 212234353Sdim case tok::kw_bool: 213234353Sdim case tok::kw_short: 214234353Sdim case tok::kw_int: 215234353Sdim case tok::kw_long: 216234353Sdim case tok::kw___int64: 217234353Sdim case tok::kw___int128: 218234353Sdim case tok::kw_signed: 219234353Sdim case tok::kw_unsigned: 220234353Sdim case tok::kw_float: 221234353Sdim case tok::kw_double: 222234353Sdim case tok::kw_void: 223234353Sdim case tok::kw_typeof: 224234353Sdim // __attribute__(( vec_type_hint(char) )) 225234353Sdim // FIXME: Don't just discard the builtin type token. 226234353Sdim ConsumeToken(); 227234353Sdim BuiltinType = true; 228234353Sdim break; 229234353Sdim 230234353Sdim case tok::identifier: 231234353Sdim ParmName = Tok.getIdentifierInfo(); 232234353Sdim ParmLoc = ConsumeToken(); 233234353Sdim break; 234234353Sdim 235234353Sdim default: 236234353Sdim break; 237234353Sdim } 238234353Sdim 239234353Sdim ExprVector ArgExprs(Actions); 240234353Sdim 241234353Sdim if (!BuiltinType && 242234353Sdim (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) { 243234353Sdim // Eat the comma. 244234353Sdim if (ParmLoc.isValid()) 245226633Sdim ConsumeToken(); 246226633Sdim 247234353Sdim // Parse the non-empty comma-separated list of expressions. 248234353Sdim while (1) { 249234353Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 250234353Sdim if (ArgExpr.isInvalid()) { 251234353Sdim SkipUntil(tok::r_paren); 252234353Sdim return; 253226633Sdim } 254234353Sdim ArgExprs.push_back(ArgExpr.release()); 255234353Sdim if (Tok.isNot(tok::comma)) 256234353Sdim break; 257234353Sdim ConsumeToken(); // Eat the comma, move to the next argument 258226633Sdim } 259234353Sdim } 260234353Sdim else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) { 261234353Sdim if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<", 262234353Sdim tok::greater)) { 263234353Sdim while (Tok.is(tok::identifier)) { 264234353Sdim ConsumeToken(); 265234353Sdim if (Tok.is(tok::greater)) 266226633Sdim break; 267234353Sdim if (Tok.is(tok::comma)) { 268234353Sdim ConsumeToken(); 269234353Sdim continue; 270226633Sdim } 271226633Sdim } 272234353Sdim if (Tok.isNot(tok::greater)) 273234353Sdim Diag(Tok, diag::err_iboutletcollection_with_protocol); 274234353Sdim SkipUntil(tok::r_paren, false, true); // skip until ')' 275226633Sdim } 276226633Sdim } 277234353Sdim 278234353Sdim SourceLocation RParen = Tok.getLocation(); 279234353Sdim if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) { 280234353Sdim AttributeList *attr = 281234353Sdim Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc, 282239462Sdim ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size(), 283239462Sdim AttributeList::AS_GNU); 284239462Sdim if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection) 285234353Sdim Diag(Tok, diag::err_iboutletcollection_builtintype); 286234353Sdim } 287226633Sdim} 288226633Sdim 289239462Sdim/// \brief Parses a single argument for a declspec, including the 290239462Sdim/// surrounding parens. 291239462Sdimvoid Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, 292239462Sdim SourceLocation AttrNameLoc, 293239462Sdim ParsedAttributes &Attrs) 294239462Sdim{ 295239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 296239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 297239462Sdim AttrName->getNameStart(), tok::r_paren)) 298239462Sdim return; 299226633Sdim 300239462Sdim ExprResult ArgExpr(ParseConstantExpression()); 301239462Sdim if (ArgExpr.isInvalid()) { 302239462Sdim T.skipToEnd(); 303239462Sdim return; 304239462Sdim } 305239462Sdim Expr *ExprList = ArgExpr.take(); 306239462Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 307239462Sdim &ExprList, 1, AttributeList::AS_Declspec); 308239462Sdim 309239462Sdim T.consumeClose(); 310239462Sdim} 311239462Sdim 312239462Sdim/// \brief Determines whether a declspec is a "simple" one requiring no 313239462Sdim/// arguments. 314239462Sdimbool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) { 315239462Sdim return llvm::StringSwitch<bool>(Ident->getName()) 316239462Sdim .Case("dllimport", true) 317239462Sdim .Case("dllexport", true) 318239462Sdim .Case("noreturn", true) 319239462Sdim .Case("nothrow", true) 320239462Sdim .Case("noinline", true) 321239462Sdim .Case("naked", true) 322239462Sdim .Case("appdomain", true) 323239462Sdim .Case("process", true) 324239462Sdim .Case("jitintrinsic", true) 325239462Sdim .Case("noalias", true) 326239462Sdim .Case("restrict", true) 327239462Sdim .Case("novtable", true) 328239462Sdim .Case("selectany", true) 329239462Sdim .Case("thread", true) 330239462Sdim .Default(false); 331239462Sdim} 332239462Sdim 333239462Sdim/// \brief Attempts to parse a declspec which is not simple (one that takes 334239462Sdim/// parameters). Will return false if we properly handled the declspec, or 335239462Sdim/// true if it is an unknown declspec. 336239462Sdimvoid Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, 337239462Sdim SourceLocation Loc, 338239462Sdim ParsedAttributes &Attrs) { 339239462Sdim // Try to handle the easy case first -- these declspecs all take a single 340239462Sdim // parameter as their argument. 341239462Sdim if (llvm::StringSwitch<bool>(Ident->getName()) 342239462Sdim .Case("uuid", true) 343239462Sdim .Case("align", true) 344239462Sdim .Case("allocate", true) 345239462Sdim .Default(false)) { 346239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 347239462Sdim } else if (Ident->getName() == "deprecated") { 348239462Sdim // The deprecated declspec has an optional single argument, so we will 349239462Sdim // check for a l-paren to decide whether we should parse an argument or 350239462Sdim // not. 351239462Sdim if (Tok.getKind() == tok::l_paren) 352239462Sdim ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs); 353239462Sdim else 354239462Sdim Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0, 355239462Sdim AttributeList::AS_Declspec); 356239462Sdim } else if (Ident->getName() == "property") { 357239462Sdim // The property declspec is more complex in that it can take one or two 358239462Sdim // assignment expressions as a parameter, but the lhs of the assignment 359239462Sdim // must be named get or put. 360239462Sdim // 361239462Sdim // For right now, we will just skip to the closing right paren of the 362239462Sdim // property expression. 363239462Sdim // 364239462Sdim // FIXME: we should deal with __declspec(property) at some point because it 365239462Sdim // is used in the platform SDK headers for the Parallel Patterns Library 366239462Sdim // and ATL. 367239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 368239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 369239462Sdim Ident->getNameStart(), tok::r_paren)) 370239462Sdim return; 371239462Sdim T.skipToEnd(); 372239462Sdim } else { 373239462Sdim // We don't recognize this as a valid declspec, but instead of creating the 374239462Sdim // attribute and allowing sema to warn about it, we will warn here instead. 375239462Sdim // This is because some attributes have multiple spellings, but we need to 376239462Sdim // disallow that for declspecs (such as align vs aligned). If we made the 377239462Sdim // attribute, we'd have to split the valid declspec spelling logic into 378239462Sdim // both locations. 379239462Sdim Diag(Loc, diag::warn_ms_declspec_unknown) << Ident; 380239462Sdim 381239462Sdim // If there's an open paren, we should eat the open and close parens under 382239462Sdim // the assumption that this unknown declspec has parameters. 383239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 384239462Sdim if (!T.consumeOpen()) 385239462Sdim T.skipToEnd(); 386239462Sdim } 387239462Sdim} 388239462Sdim 389193725Sed/// [MS] decl-specifier: 390193725Sed/// __declspec ( extended-decl-modifier-seq ) 391193725Sed/// 392193725Sed/// [MS] extended-decl-modifier-seq: 393193725Sed/// extended-decl-modifier[opt] 394193725Sed/// extended-decl-modifier extended-decl-modifier-seq 395239462Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) { 396193326Sed assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); 397193725Sed 398193326Sed ConsumeToken(); 399239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 400239462Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec", 401239462Sdim tok::r_paren)) 402218893Sdim return; 403223017Sdim 404239462Sdim // An empty declspec is perfectly legal and should not warn. Additionally, 405239462Sdim // you can specify multiple attributes per declspec. 406239462Sdim while (Tok.getKind() != tok::r_paren) { 407239462Sdim // We expect either a well-known identifier or a generic string. Anything 408239462Sdim // else is a malformed declspec. 409239462Sdim bool IsString = Tok.getKind() == tok::string_literal ? true : false; 410239462Sdim if (!IsString && Tok.getKind() != tok::identifier && 411239462Sdim Tok.getKind() != tok::kw_restrict) { 412239462Sdim Diag(Tok, diag::err_ms_declspec_type); 413239462Sdim T.skipToEnd(); 414239462Sdim return; 415223017Sdim } 416239462Sdim 417239462Sdim IdentifierInfo *AttrName; 418239462Sdim SourceLocation AttrNameLoc; 419239462Sdim if (IsString) { 420239462Sdim SmallString<8> StrBuffer; 421239462Sdim bool Invalid = false; 422239462Sdim StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid); 423239462Sdim if (Invalid) { 424239462Sdim T.skipToEnd(); 425239462Sdim return; 426193725Sed } 427239462Sdim AttrName = PP.getIdentifierInfo(Str); 428239462Sdim AttrNameLoc = ConsumeStringToken(); 429193725Sed } else { 430239462Sdim AttrName = Tok.getIdentifierInfo(); 431239462Sdim AttrNameLoc = ConsumeToken(); 432193725Sed } 433239462Sdim 434239462Sdim if (IsString || IsSimpleMicrosoftDeclSpec(AttrName)) 435239462Sdim // If we have a generic string, we will allow it because there is no 436239462Sdim // documented list of allowable string declspecs, but we know they exist 437239462Sdim // (for instance, SAL declspecs in older versions of MSVC). 438239462Sdim // 439239462Sdim // Alternatively, if the identifier is a simple one, then it requires no 440239462Sdim // arguments and can be turned into an attribute directly. 441239462Sdim Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 442239462Sdim 0, 0, AttributeList::AS_Declspec); 443239462Sdim else 444239462Sdim ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs); 445193725Sed } 446239462Sdim T.consumeClose(); 447193326Sed} 448193326Sed 449218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { 450194179Sed // Treat these like attributes 451194179Sed while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || 452208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) || 453226633Sdim Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) || 454226633Sdim Tok.is(tok::kw___ptr32) || 455226633Sdim Tok.is(tok::kw___unaligned)) { 456194179Sed IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 457194179Sed SourceLocation AttrNameLoc = ConsumeToken(); 458221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 459239462Sdim SourceLocation(), 0, 0, AttributeList::AS_MSTypespec); 460194179Sed } 461194179Sed} 462194179Sed 463218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { 464212904Sdim // Treat these like attributes 465212904Sdim while (Tok.is(tok::kw___pascal)) { 466212904Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 467212904Sdim SourceLocation AttrNameLoc = ConsumeToken(); 468221345Sdim attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 469239462Sdim SourceLocation(), 0, 0, AttributeList::AS_MSTypespec); 470212904Sdim } 471212904Sdim} 472212904Sdim 473218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { 474218893Sdim // Treat these like attributes 475218893Sdim while (Tok.is(tok::kw___kernel)) { 476218893Sdim SourceLocation AttrNameLoc = ConsumeToken(); 477221345Sdim attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"), 478221345Sdim AttrNameLoc, 0, AttrNameLoc, 0, 479239462Sdim SourceLocation(), 0, 0, AttributeList::AS_GNU); 480218893Sdim } 481218893Sdim} 482218893Sdim 483221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) { 484221345Sdim SourceLocation Loc = Tok.getLocation(); 485221345Sdim switch(Tok.getKind()) { 486221345Sdim // OpenCL qualifiers: 487221345Sdim case tok::kw___private: 488239462Sdim case tok::kw_private: 489221345Sdim DS.getAttributes().addNewInteger( 490239462Sdim Actions.getASTContext(), 491221345Sdim PP.getIdentifierInfo("address_space"), Loc, 0); 492221345Sdim break; 493239462Sdim 494221345Sdim case tok::kw___global: 495221345Sdim DS.getAttributes().addNewInteger( 496221345Sdim Actions.getASTContext(), 497221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global); 498221345Sdim break; 499239462Sdim 500221345Sdim case tok::kw___local: 501221345Sdim DS.getAttributes().addNewInteger( 502221345Sdim Actions.getASTContext(), 503221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local); 504221345Sdim break; 505239462Sdim 506221345Sdim case tok::kw___constant: 507221345Sdim DS.getAttributes().addNewInteger( 508221345Sdim Actions.getASTContext(), 509221345Sdim PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant); 510221345Sdim break; 511239462Sdim 512221345Sdim case tok::kw___read_only: 513221345Sdim DS.getAttributes().addNewInteger( 514239462Sdim Actions.getASTContext(), 515221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only); 516221345Sdim break; 517239462Sdim 518221345Sdim case tok::kw___write_only: 519221345Sdim DS.getAttributes().addNewInteger( 520239462Sdim Actions.getASTContext(), 521221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only); 522221345Sdim break; 523239462Sdim 524221345Sdim case tok::kw___read_write: 525221345Sdim DS.getAttributes().addNewInteger( 526221345Sdim Actions.getASTContext(), 527221345Sdim PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write); 528221345Sdim break; 529221345Sdim default: break; 530221345Sdim } 531221345Sdim} 532221345Sdim 533221345Sdim/// \brief Parse a version number. 534221345Sdim/// 535221345Sdim/// version: 536221345Sdim/// simple-integer 537221345Sdim/// simple-integer ',' simple-integer 538221345Sdim/// simple-integer ',' simple-integer ',' simple-integer 539221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) { 540221345Sdim Range = Tok.getLocation(); 541221345Sdim 542221345Sdim if (!Tok.is(tok::numeric_constant)) { 543221345Sdim Diag(Tok, diag::err_expected_version); 544221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 545221345Sdim return VersionTuple(); 546221345Sdim } 547221345Sdim 548221345Sdim // Parse the major (and possibly minor and subminor) versions, which 549221345Sdim // are stored in the numeric constant. We utilize a quirk of the 550221345Sdim // lexer, which is that it handles something like 1.2.3 as a single 551221345Sdim // numeric constant, rather than two separate tokens. 552234353Sdim SmallString<512> Buffer; 553221345Sdim Buffer.resize(Tok.getLength()+1); 554221345Sdim const char *ThisTokBegin = &Buffer[0]; 555221345Sdim 556221345Sdim // Get the spelling of the token, which eliminates trigraphs, etc. 557221345Sdim bool Invalid = false; 558221345Sdim unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid); 559221345Sdim if (Invalid) 560221345Sdim return VersionTuple(); 561221345Sdim 562221345Sdim // Parse the major version. 563221345Sdim unsigned AfterMajor = 0; 564221345Sdim unsigned Major = 0; 565221345Sdim while (AfterMajor < ActualLength && isdigit(ThisTokBegin[AfterMajor])) { 566221345Sdim Major = Major * 10 + ThisTokBegin[AfterMajor] - '0'; 567221345Sdim ++AfterMajor; 568221345Sdim } 569221345Sdim 570221345Sdim if (AfterMajor == 0) { 571221345Sdim Diag(Tok, diag::err_expected_version); 572221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 573221345Sdim return VersionTuple(); 574221345Sdim } 575221345Sdim 576221345Sdim if (AfterMajor == ActualLength) { 577221345Sdim ConsumeToken(); 578221345Sdim 579221345Sdim // We only had a single version component. 580221345Sdim if (Major == 0) { 581221345Sdim Diag(Tok, diag::err_zero_version); 582221345Sdim return VersionTuple(); 583221345Sdim } 584221345Sdim 585221345Sdim return VersionTuple(Major); 586221345Sdim } 587221345Sdim 588221345Sdim if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { 589221345Sdim Diag(Tok, diag::err_expected_version); 590221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 591221345Sdim return VersionTuple(); 592221345Sdim } 593221345Sdim 594221345Sdim // Parse the minor version. 595221345Sdim unsigned AfterMinor = AfterMajor + 1; 596221345Sdim unsigned Minor = 0; 597221345Sdim while (AfterMinor < ActualLength && isdigit(ThisTokBegin[AfterMinor])) { 598221345Sdim Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0'; 599221345Sdim ++AfterMinor; 600221345Sdim } 601221345Sdim 602221345Sdim if (AfterMinor == ActualLength) { 603221345Sdim ConsumeToken(); 604239462Sdim 605221345Sdim // We had major.minor. 606221345Sdim if (Major == 0 && Minor == 0) { 607221345Sdim Diag(Tok, diag::err_zero_version); 608221345Sdim return VersionTuple(); 609221345Sdim } 610221345Sdim 611239462Sdim return VersionTuple(Major, Minor); 612221345Sdim } 613221345Sdim 614221345Sdim // If what follows is not a '.', we have a problem. 615221345Sdim if (ThisTokBegin[AfterMinor] != '.') { 616221345Sdim Diag(Tok, diag::err_expected_version); 617221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 618239462Sdim return VersionTuple(); 619221345Sdim } 620221345Sdim 621221345Sdim // Parse the subminor version. 622221345Sdim unsigned AfterSubminor = AfterMinor + 1; 623221345Sdim unsigned Subminor = 0; 624221345Sdim while (AfterSubminor < ActualLength && isdigit(ThisTokBegin[AfterSubminor])) { 625221345Sdim Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0'; 626221345Sdim ++AfterSubminor; 627221345Sdim } 628221345Sdim 629221345Sdim if (AfterSubminor != ActualLength) { 630221345Sdim Diag(Tok, diag::err_expected_version); 631221345Sdim SkipUntil(tok::comma, tok::r_paren, true, true, true); 632221345Sdim return VersionTuple(); 633221345Sdim } 634221345Sdim ConsumeToken(); 635221345Sdim return VersionTuple(Major, Minor, Subminor); 636221345Sdim} 637221345Sdim 638221345Sdim/// \brief Parse the contents of the "availability" attribute. 639221345Sdim/// 640221345Sdim/// availability-attribute: 641234353Sdim/// 'availability' '(' platform ',' version-arg-list, opt-message')' 642221345Sdim/// 643221345Sdim/// platform: 644221345Sdim/// identifier 645221345Sdim/// 646221345Sdim/// version-arg-list: 647221345Sdim/// version-arg 648221345Sdim/// version-arg ',' version-arg-list 649221345Sdim/// 650221345Sdim/// version-arg: 651221345Sdim/// 'introduced' '=' version 652221345Sdim/// 'deprecated' '=' version 653234353Sdim/// 'obsoleted' = version 654221345Sdim/// 'unavailable' 655234353Sdim/// opt-message: 656234353Sdim/// 'message' '=' <string> 657221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, 658221345Sdim SourceLocation AvailabilityLoc, 659221345Sdim ParsedAttributes &attrs, 660221345Sdim SourceLocation *endLoc) { 661221345Sdim SourceLocation PlatformLoc; 662221345Sdim IdentifierInfo *Platform = 0; 663221345Sdim 664221345Sdim enum { Introduced, Deprecated, Obsoleted, Unknown }; 665221345Sdim AvailabilityChange Changes[Unknown]; 666234353Sdim ExprResult MessageExpr; 667221345Sdim 668221345Sdim // Opening '('. 669226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 670226633Sdim if (T.consumeOpen()) { 671221345Sdim Diag(Tok, diag::err_expected_lparen); 672221345Sdim return; 673221345Sdim } 674221345Sdim 675221345Sdim // Parse the platform name, 676221345Sdim if (Tok.isNot(tok::identifier)) { 677221345Sdim Diag(Tok, diag::err_availability_expected_platform); 678221345Sdim SkipUntil(tok::r_paren); 679221345Sdim return; 680221345Sdim } 681221345Sdim Platform = Tok.getIdentifierInfo(); 682221345Sdim PlatformLoc = ConsumeToken(); 683221345Sdim 684221345Sdim // Parse the ',' following the platform name. 685221345Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) 686221345Sdim return; 687221345Sdim 688221345Sdim // If we haven't grabbed the pointers for the identifiers 689221345Sdim // "introduced", "deprecated", and "obsoleted", do so now. 690221345Sdim if (!Ident_introduced) { 691221345Sdim Ident_introduced = PP.getIdentifierInfo("introduced"); 692221345Sdim Ident_deprecated = PP.getIdentifierInfo("deprecated"); 693221345Sdim Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); 694221345Sdim Ident_unavailable = PP.getIdentifierInfo("unavailable"); 695234353Sdim Ident_message = PP.getIdentifierInfo("message"); 696221345Sdim } 697221345Sdim 698221345Sdim // Parse the set of introductions/deprecations/removals. 699221345Sdim SourceLocation UnavailableLoc; 700221345Sdim do { 701221345Sdim if (Tok.isNot(tok::identifier)) { 702221345Sdim Diag(Tok, diag::err_availability_expected_change); 703221345Sdim SkipUntil(tok::r_paren); 704221345Sdim return; 705221345Sdim } 706221345Sdim IdentifierInfo *Keyword = Tok.getIdentifierInfo(); 707221345Sdim SourceLocation KeywordLoc = ConsumeToken(); 708221345Sdim 709221345Sdim if (Keyword == Ident_unavailable) { 710221345Sdim if (UnavailableLoc.isValid()) { 711221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 712221345Sdim << Keyword << SourceRange(UnavailableLoc); 713239462Sdim } 714221345Sdim UnavailableLoc = KeywordLoc; 715221345Sdim 716221345Sdim if (Tok.isNot(tok::comma)) 717221345Sdim break; 718221345Sdim 719221345Sdim ConsumeToken(); 720221345Sdim continue; 721239462Sdim } 722239462Sdim 723221345Sdim if (Tok.isNot(tok::equal)) { 724221345Sdim Diag(Tok, diag::err_expected_equal_after) 725221345Sdim << Keyword; 726221345Sdim SkipUntil(tok::r_paren); 727221345Sdim return; 728221345Sdim } 729221345Sdim ConsumeToken(); 730234353Sdim if (Keyword == Ident_message) { 731234353Sdim if (!isTokenStringLiteral()) { 732234353Sdim Diag(Tok, diag::err_expected_string_literal); 733234353Sdim SkipUntil(tok::r_paren); 734234353Sdim return; 735234353Sdim } 736234353Sdim MessageExpr = ParseStringLiteralExpression(); 737234353Sdim break; 738234353Sdim } 739239462Sdim 740221345Sdim SourceRange VersionRange; 741221345Sdim VersionTuple Version = ParseVersionTuple(VersionRange); 742239462Sdim 743221345Sdim if (Version.empty()) { 744221345Sdim SkipUntil(tok::r_paren); 745221345Sdim return; 746221345Sdim } 747221345Sdim 748221345Sdim unsigned Index; 749221345Sdim if (Keyword == Ident_introduced) 750221345Sdim Index = Introduced; 751221345Sdim else if (Keyword == Ident_deprecated) 752221345Sdim Index = Deprecated; 753221345Sdim else if (Keyword == Ident_obsoleted) 754221345Sdim Index = Obsoleted; 755239462Sdim else 756221345Sdim Index = Unknown; 757221345Sdim 758221345Sdim if (Index < Unknown) { 759221345Sdim if (!Changes[Index].KeywordLoc.isInvalid()) { 760221345Sdim Diag(KeywordLoc, diag::err_availability_redundant) 761239462Sdim << Keyword 762221345Sdim << SourceRange(Changes[Index].KeywordLoc, 763221345Sdim Changes[Index].VersionRange.getEnd()); 764221345Sdim } 765221345Sdim 766221345Sdim Changes[Index].KeywordLoc = KeywordLoc; 767221345Sdim Changes[Index].Version = Version; 768221345Sdim Changes[Index].VersionRange = VersionRange; 769221345Sdim } else { 770221345Sdim Diag(KeywordLoc, diag::err_availability_unknown_change) 771221345Sdim << Keyword << VersionRange; 772221345Sdim } 773221345Sdim 774221345Sdim if (Tok.isNot(tok::comma)) 775221345Sdim break; 776221345Sdim 777221345Sdim ConsumeToken(); 778221345Sdim } while (true); 779221345Sdim 780221345Sdim // Closing ')'. 781226633Sdim if (T.consumeClose()) 782221345Sdim return; 783221345Sdim 784221345Sdim if (endLoc) 785226633Sdim *endLoc = T.getCloseLocation(); 786221345Sdim 787221345Sdim // The 'unavailable' availability cannot be combined with any other 788221345Sdim // availability changes. Make sure that hasn't happened. 789221345Sdim if (UnavailableLoc.isValid()) { 790221345Sdim bool Complained = false; 791221345Sdim for (unsigned Index = Introduced; Index != Unknown; ++Index) { 792221345Sdim if (Changes[Index].KeywordLoc.isValid()) { 793221345Sdim if (!Complained) { 794221345Sdim Diag(UnavailableLoc, diag::warn_availability_and_unavailable) 795221345Sdim << SourceRange(Changes[Index].KeywordLoc, 796221345Sdim Changes[Index].VersionRange.getEnd()); 797221345Sdim Complained = true; 798221345Sdim } 799221345Sdim 800221345Sdim // Clear out the availability. 801221345Sdim Changes[Index] = AvailabilityChange(); 802221345Sdim } 803221345Sdim } 804221345Sdim } 805221345Sdim 806221345Sdim // Record this attribute 807239462Sdim attrs.addNew(&Availability, 808239462Sdim SourceRange(AvailabilityLoc, T.getCloseLocation()), 809234353Sdim 0, AvailabilityLoc, 810221345Sdim Platform, PlatformLoc, 811221345Sdim Changes[Introduced], 812221345Sdim Changes[Deprecated], 813239462Sdim Changes[Obsoleted], 814234353Sdim UnavailableLoc, MessageExpr.take(), 815239462Sdim AttributeList::AS_GNU); 816221345Sdim} 817221345Sdim 818226633Sdim 819226633Sdim// Late Parsed Attributes: 820226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods 821226633Sdim 822226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {} 823226633Sdim 824226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() { 825226633Sdim Self->ParseLexedAttributes(*Class); 826226633Sdim} 827226633Sdim 828226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() { 829234353Sdim Self->ParseLexedAttribute(*this, true, false); 830226633Sdim} 831226633Sdim 832226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the 833226633Sdim/// scope appropriately. 834226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) { 835226633Sdim // Deal with templates 836226633Sdim // FIXME: Test cases to make sure this does the right thing for templates. 837226633Sdim bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 838226633Sdim ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 839226633Sdim HasTemplateScope); 840226633Sdim if (HasTemplateScope) 841226633Sdim Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 842226633Sdim 843234982Sdim // Set or update the scope flags. 844226633Sdim bool AlreadyHasClassScope = Class.TopLevelClass; 845234982Sdim unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; 846226633Sdim ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 847226633Sdim ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 848226633Sdim 849234353Sdim // Enter the scope of nested classes 850234353Sdim if (!AlreadyHasClassScope) 851234353Sdim Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 852234353Sdim Class.TagOrTemplate); 853239462Sdim if (!Class.LateParsedDeclarations.empty()) { 854234982Sdim // Allow 'this' within late-parsed attributes. 855239462Sdim Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, 856234982Sdim /*TypeQuals=*/0); 857239462Sdim 858234982Sdim for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ 859234982Sdim Class.LateParsedDeclarations[i]->ParseLexedAttributes(); 860234982Sdim } 861226633Sdim } 862239462Sdim 863234353Sdim if (!AlreadyHasClassScope) 864234353Sdim Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 865234353Sdim Class.TagOrTemplate); 866226633Sdim} 867226633Sdim 868234353Sdim 869234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D. 870234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 871234353Sdim bool EnterScope, bool OnDefinition) { 872234353Sdim for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 873239462Sdim if (D) 874239462Sdim LAs[i]->addDecl(D); 875234353Sdim ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 876234982Sdim delete LAs[i]; 877234353Sdim } 878234353Sdim LAs.clear(); 879234353Sdim} 880234353Sdim 881234353Sdim 882226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed. 883226633Sdim/// This will be called at the end of parsing a class declaration 884226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and 885239462Sdim/// create an attribute with the arguments filled in. We add this 886226633Sdim/// to the Attribute list for the decl. 887234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA, 888234353Sdim bool EnterScope, bool OnDefinition) { 889226633Sdim // Save the current token position. 890226633Sdim SourceLocation OrigLoc = Tok.getLocation(); 891226633Sdim 892226633Sdim // Append the current token at the end of the new token stream so that it 893226633Sdim // doesn't get lost. 894226633Sdim LA.Toks.push_back(Tok); 895226633Sdim PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); 896226633Sdim // Consume the previously pushed token. 897226633Sdim ConsumeAnyToken(); 898226633Sdim 899234353Sdim if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) { 900234353Sdim Diag(Tok, diag::warn_attribute_on_function_definition) 901234353Sdim << LA.AttrName.getName(); 902234353Sdim } 903234353Sdim 904226633Sdim ParsedAttributes Attrs(AttrFactory); 905226633Sdim SourceLocation endLoc; 906226633Sdim 907234353Sdim if (LA.Decls.size() == 1) { 908234353Sdim Decl *D = LA.Decls[0]; 909226633Sdim 910234353Sdim // If the Decl is templatized, add template parameters to scope. 911234353Sdim bool HasTemplateScope = EnterScope && D->isTemplateDecl(); 912234353Sdim ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); 913234353Sdim if (HasTemplateScope) 914234353Sdim Actions.ActOnReenterTemplateScope(Actions.CurScope, D); 915226633Sdim 916234353Sdim // If the Decl is on a function, add function parameters to the scope. 917234353Sdim bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate(); 918234353Sdim ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope); 919234353Sdim if (HasFunctionScope) 920234353Sdim Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 921226633Sdim 922234353Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); 923234353Sdim 924234353Sdim if (HasFunctionScope) { 925234353Sdim Actions.ActOnExitFunctionContext(); 926234353Sdim FnScope.Exit(); // Pop scope, and remove Decls from IdResolver 927234353Sdim } 928234353Sdim if (HasTemplateScope) { 929234353Sdim TempScope.Exit(); 930234353Sdim } 931234353Sdim } else if (LA.Decls.size() > 0) { 932234353Sdim // If there are multiple decls, then the decl cannot be within the 933234353Sdim // function scope. 934234353Sdim ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); 935234353Sdim } else { 936234353Sdim Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 937226633Sdim } 938234353Sdim 939234353Sdim for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) { 940234353Sdim Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 941226633Sdim } 942226633Sdim 943226633Sdim if (Tok.getLocation() != OrigLoc) { 944226633Sdim // Due to a parsing error, we either went over the cached tokens or 945226633Sdim // there are still cached tokens left, so we skip the leftover tokens. 946226633Sdim // Since this is an uncommon situation that should be avoided, use the 947226633Sdim // expensive isBeforeInTranslationUnit call. 948226633Sdim if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 949226633Sdim OrigLoc)) 950226633Sdim while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 951234353Sdim ConsumeAnyToken(); 952226633Sdim } 953226633Sdim} 954226633Sdim 955226633Sdim/// \brief Wrapper around a case statement checking if AttrName is 956226633Sdim/// one of the thread safety attributes 957226633Sdimbool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){ 958226633Sdim return llvm::StringSwitch<bool>(AttrName) 959226633Sdim .Case("guarded_by", true) 960226633Sdim .Case("guarded_var", true) 961226633Sdim .Case("pt_guarded_by", true) 962226633Sdim .Case("pt_guarded_var", true) 963226633Sdim .Case("lockable", true) 964226633Sdim .Case("scoped_lockable", true) 965226633Sdim .Case("no_thread_safety_analysis", true) 966226633Sdim .Case("acquired_after", true) 967226633Sdim .Case("acquired_before", true) 968226633Sdim .Case("exclusive_lock_function", true) 969226633Sdim .Case("shared_lock_function", true) 970226633Sdim .Case("exclusive_trylock_function", true) 971226633Sdim .Case("shared_trylock_function", true) 972226633Sdim .Case("unlock_function", true) 973226633Sdim .Case("lock_returned", true) 974226633Sdim .Case("locks_excluded", true) 975226633Sdim .Case("exclusive_locks_required", true) 976226633Sdim .Case("shared_locks_required", true) 977226633Sdim .Default(false); 978226633Sdim} 979226633Sdim 980226633Sdim/// \brief Parse the contents of thread safety attributes. These 981226633Sdim/// should always be parsed as an expression list. 982226633Sdim/// 983226633Sdim/// We need to special case the parsing due to the fact that if the first token 984226633Sdim/// of the first argument is an identifier, the main parse loop will store 985226633Sdim/// that token as a "parameter" and the rest of 986226633Sdim/// the arguments will be added to a list of "arguments". However, 987226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each 988226633Sdim/// argument as an expression and add all arguments to the list of "arguments". 989226633Sdim/// In future, we will take advantage of this special case to also 990226633Sdim/// deal with some argument scoping issues here (for example, referring to a 991226633Sdim/// function parameter in the attribute on that function). 992226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName, 993226633Sdim SourceLocation AttrNameLoc, 994226633Sdim ParsedAttributes &Attrs, 995226633Sdim SourceLocation *EndLoc) { 996226633Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 997226633Sdim 998226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 999226633Sdim T.consumeOpen(); 1000239462Sdim 1001226633Sdim ExprVector ArgExprs(Actions); 1002226633Sdim bool ArgExprsOk = true; 1003239462Sdim 1004226633Sdim // now parse the list of expressions 1005234353Sdim while (Tok.isNot(tok::r_paren)) { 1006226633Sdim ExprResult ArgExpr(ParseAssignmentExpression()); 1007226633Sdim if (ArgExpr.isInvalid()) { 1008226633Sdim ArgExprsOk = false; 1009226633Sdim T.consumeClose(); 1010226633Sdim break; 1011226633Sdim } else { 1012226633Sdim ArgExprs.push_back(ArgExpr.release()); 1013226633Sdim } 1014226633Sdim if (Tok.isNot(tok::comma)) 1015226633Sdim break; 1016226633Sdim ConsumeToken(); // Eat the comma, move to the next argument 1017226633Sdim } 1018226633Sdim // Match the ')'. 1019226633Sdim if (ArgExprsOk && !T.consumeClose()) { 1020226633Sdim Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), 1021239462Sdim ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU); 1022226633Sdim } 1023226633Sdim if (EndLoc) 1024226633Sdim *EndLoc = T.getCloseLocation(); 1025226633Sdim} 1026226633Sdim 1027239462Sdimvoid Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 1028239462Sdim SourceLocation AttrNameLoc, 1029239462Sdim ParsedAttributes &Attrs, 1030239462Sdim SourceLocation *EndLoc) { 1031239462Sdim assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 1032239462Sdim 1033239462Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1034239462Sdim T.consumeOpen(); 1035239462Sdim 1036239462Sdim if (Tok.isNot(tok::identifier)) { 1037239462Sdim Diag(Tok, diag::err_expected_ident); 1038239462Sdim T.skipToEnd(); 1039239462Sdim return; 1040239462Sdim } 1041239462Sdim IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo(); 1042239462Sdim SourceLocation ArgumentKindLoc = ConsumeToken(); 1043239462Sdim 1044239462Sdim if (Tok.isNot(tok::comma)) { 1045239462Sdim Diag(Tok, diag::err_expected_comma); 1046239462Sdim T.skipToEnd(); 1047239462Sdim return; 1048239462Sdim } 1049239462Sdim ConsumeToken(); 1050239462Sdim 1051239462Sdim SourceRange MatchingCTypeRange; 1052239462Sdim TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange); 1053239462Sdim if (MatchingCType.isInvalid()) { 1054239462Sdim T.skipToEnd(); 1055239462Sdim return; 1056239462Sdim } 1057239462Sdim 1058239462Sdim bool LayoutCompatible = false; 1059239462Sdim bool MustBeNull = false; 1060239462Sdim while (Tok.is(tok::comma)) { 1061239462Sdim ConsumeToken(); 1062239462Sdim if (Tok.isNot(tok::identifier)) { 1063239462Sdim Diag(Tok, diag::err_expected_ident); 1064239462Sdim T.skipToEnd(); 1065239462Sdim return; 1066239462Sdim } 1067239462Sdim IdentifierInfo *Flag = Tok.getIdentifierInfo(); 1068239462Sdim if (Flag->isStr("layout_compatible")) 1069239462Sdim LayoutCompatible = true; 1070239462Sdim else if (Flag->isStr("must_be_null")) 1071239462Sdim MustBeNull = true; 1072239462Sdim else { 1073239462Sdim Diag(Tok, diag::err_type_safety_unknown_flag) << Flag; 1074239462Sdim T.skipToEnd(); 1075239462Sdim return; 1076239462Sdim } 1077239462Sdim ConsumeToken(); // consume flag 1078239462Sdim } 1079239462Sdim 1080239462Sdim if (!T.consumeClose()) { 1081239462Sdim Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc, 1082239462Sdim ArgumentKind, ArgumentKindLoc, 1083239462Sdim MatchingCType.release(), LayoutCompatible, 1084239462Sdim MustBeNull, AttributeList::AS_GNU); 1085239462Sdim } 1086239462Sdim 1087239462Sdim if (EndLoc) 1088239462Sdim *EndLoc = T.getCloseLocation(); 1089239462Sdim} 1090239462Sdim 1091234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 1092234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not 1093234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 1094234353Sdim/// situation. 1095234353Sdim/// 1096234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if 1097234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller 1098234353Sdim/// should try to parse it. 1099234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() { 1100234353Sdim assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 1101234353Sdim 1102234353Sdim switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) { 1103234353Sdim case CAK_NotAttributeSpecifier: 1104234353Sdim // No diagnostic: we're in Obj-C++11 and this is not actually an attribute. 1105234353Sdim return false; 1106234353Sdim 1107234353Sdim case CAK_InvalidAttributeSpecifier: 1108234353Sdim Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute); 1109234353Sdim return false; 1110234353Sdim 1111234353Sdim case CAK_AttributeSpecifier: 1112234353Sdim // Parse and discard the attributes. 1113234353Sdim SourceLocation BeginLoc = ConsumeBracket(); 1114234353Sdim ConsumeBracket(); 1115234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/ false); 1116234353Sdim assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); 1117234353Sdim SourceLocation EndLoc = ConsumeBracket(); 1118234353Sdim Diag(BeginLoc, diag::err_attributes_not_allowed) 1119234353Sdim << SourceRange(BeginLoc, EndLoc); 1120234353Sdim return true; 1121234353Sdim } 1122234353Sdim llvm_unreachable("All cases handled above."); 1123234353Sdim} 1124234353Sdim 1125218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { 1126218893Sdim Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) 1127218893Sdim << attrs.Range; 1128218893Sdim} 1129218893Sdim 1130193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of 1131193326Sed/// declaration-specifiers, some number of declarators, and a semicolon. 1132193326Sed/// 'Context' should be a Declarator::TheContext value. This returns the 1133193326Sed/// location of the semicolon in DeclEnd. 1134193326Sed/// 1135193326Sed/// declaration: [C99 6.7] 1136193326Sed/// block-declaration -> 1137193326Sed/// simple-declaration 1138193326Sed/// others [FIXME] 1139193326Sed/// [C++] template-declaration 1140193326Sed/// [C++] namespace-definition 1141193326Sed/// [C++] using-directive 1142194711Sed/// [C++] using-declaration 1143234982Sdim/// [C++11/C11] static_assert-declaration 1144193326Sed/// others... [FIXME] 1145193326Sed/// 1146218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, 1147218893Sdim unsigned Context, 1148199990Srdivacky SourceLocation &DeclEnd, 1149218893Sdim ParsedAttributesWithRange &attrs) { 1150210299Sed ParenBraceBracketBalancer BalancerRAIIObj(*this); 1151226633Sdim // Must temporarily exit the objective-c container scope for 1152226633Sdim // parsing c none objective-c decls. 1153226633Sdim ObjCDeclContextSwitch ObjCDC(*this); 1154239462Sdim 1155212904Sdim Decl *SingleDecl = 0; 1156224145Sdim Decl *OwnedType = 0; 1157193326Sed switch (Tok.getKind()) { 1158193326Sed case tok::kw_template: 1159193326Sed case tok::kw_export: 1160218893Sdim ProhibitAttributes(attrs); 1161193326Sed SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); 1162193326Sed break; 1163212904Sdim case tok::kw_inline: 1164212904Sdim // Could be the start of an inline namespace. Allowed as an ext in C++03. 1165234353Sdim if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { 1166218893Sdim ProhibitAttributes(attrs); 1167212904Sdim SourceLocation InlineLoc = ConsumeToken(); 1168212904Sdim SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); 1169212904Sdim break; 1170212904Sdim } 1171239462Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, 1172218893Sdim true); 1173193326Sed case tok::kw_namespace: 1174218893Sdim ProhibitAttributes(attrs); 1175193326Sed SingleDecl = ParseNamespace(Context, DeclEnd); 1176193326Sed break; 1177193326Sed case tok::kw_using: 1178218893Sdim SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), 1179224145Sdim DeclEnd, attrs, &OwnedType); 1180193326Sed break; 1181193326Sed case tok::kw_static_assert: 1182221345Sdim case tok::kw__Static_assert: 1183218893Sdim ProhibitAttributes(attrs); 1184193326Sed SingleDecl = ParseStaticAssertDeclaration(DeclEnd); 1185193326Sed break; 1186193326Sed default: 1187218893Sdim return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true); 1188193326Sed } 1189239462Sdim 1190193326Sed // This routine returns a DeclGroup, if the thing we parsed only contains a 1191224145Sdim // single decl, convert it now. Alias declarations can also declare a type; 1192224145Sdim // include that too if it is present. 1193224145Sdim return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType); 1194193326Sed} 1195193326Sed 1196193326Sed/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl] 1197193326Sed/// declaration-specifiers init-declarator-list[opt] ';' 1198239462Sdim/// [C++11] attribute-specifier-seq decl-specifier-seq[opt] 1199239462Sdim/// init-declarator-list ';' 1200193326Sed///[C90/C++]init-declarator-list ';' [TODO] 1201193326Sed/// [OMP] threadprivate-directive [TODO] 1202193326Sed/// 1203239462Sdim/// for-range-declaration: [C++11 6.5p1: stmt.ranged] 1204221345Sdim/// attribute-specifier-seq[opt] type-specifier-seq declarator 1205221345Sdim/// 1206193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the 1207206275Srdivacky/// declaration. If it is true, it checks for and eats it. 1208221345Sdim/// 1209221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead 1210221345Sdim/// of a simple-declaration. If we find that we are, we also parse the 1211221345Sdim/// for-range-initializer, and place it here. 1212239462SdimParser::DeclGroupPtrTy 1213239462SdimParser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context, 1214239462Sdim SourceLocation &DeclEnd, 1215239462Sdim ParsedAttributesWithRange &attrs, 1216239462Sdim bool RequireSemi, ForRangeInit *FRI) { 1217193326Sed // Parse the common declaration-specifiers piece. 1218198893Srdivacky ParsingDeclSpec DS(*this); 1219218893Sdim DS.takeAttributesFrom(attrs); 1220221345Sdim 1221202379Srdivacky ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, 1222218893Sdim getDeclSpecContextFromDeclaratorContext(Context)); 1223234353Sdim 1224193326Sed // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 1225193326Sed // declaration-specifiers init-declarator-list[opt] ';' 1226193326Sed if (Tok.is(tok::semi)) { 1227239462Sdim DeclEnd = Tok.getLocation(); 1228206275Srdivacky if (RequireSemi) ConsumeToken(); 1229212904Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 1230221345Sdim DS); 1231198893Srdivacky DS.complete(TheDecl); 1232193326Sed return Actions.ConvertDeclToDeclGroup(TheDecl); 1233193326Sed } 1234239462Sdim 1235239462Sdim return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI); 1236198893Srdivacky} 1237198092Srdivacky 1238234353Sdim/// Returns true if this might be the start of a declarator, or a common typo 1239234353Sdim/// for a declarator. 1240234353Sdimbool Parser::MightBeDeclarator(unsigned Context) { 1241234353Sdim switch (Tok.getKind()) { 1242234353Sdim case tok::annot_cxxscope: 1243234353Sdim case tok::annot_template_id: 1244234353Sdim case tok::caret: 1245234353Sdim case tok::code_completion: 1246234353Sdim case tok::coloncolon: 1247234353Sdim case tok::ellipsis: 1248234353Sdim case tok::kw___attribute: 1249234353Sdim case tok::kw_operator: 1250234353Sdim case tok::l_paren: 1251234353Sdim case tok::star: 1252234353Sdim return true; 1253234353Sdim 1254234353Sdim case tok::amp: 1255234353Sdim case tok::ampamp: 1256234353Sdim return getLangOpts().CPlusPlus; 1257234353Sdim 1258234353Sdim case tok::l_square: // Might be an attribute on an unnamed bit-field. 1259234353Sdim return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x && 1260234353Sdim NextToken().is(tok::l_square); 1261234353Sdim 1262234353Sdim case tok::colon: // Might be a typo for '::' or an unnamed bit-field. 1263234353Sdim return Context == Declarator::MemberContext || getLangOpts().CPlusPlus; 1264234353Sdim 1265234353Sdim case tok::identifier: 1266234353Sdim switch (NextToken().getKind()) { 1267234353Sdim case tok::code_completion: 1268234353Sdim case tok::coloncolon: 1269234353Sdim case tok::comma: 1270234353Sdim case tok::equal: 1271234353Sdim case tok::equalequal: // Might be a typo for '='. 1272234353Sdim case tok::kw_alignas: 1273234353Sdim case tok::kw_asm: 1274234353Sdim case tok::kw___attribute: 1275234353Sdim case tok::l_brace: 1276234353Sdim case tok::l_paren: 1277234353Sdim case tok::l_square: 1278234353Sdim case tok::less: 1279234353Sdim case tok::r_brace: 1280234353Sdim case tok::r_paren: 1281234353Sdim case tok::r_square: 1282234353Sdim case tok::semi: 1283234353Sdim return true; 1284234353Sdim 1285234353Sdim case tok::colon: 1286234353Sdim // At namespace scope, 'identifier:' is probably a typo for 'identifier::' 1287234353Sdim // and in block scope it's probably a label. Inside a class definition, 1288234353Sdim // this is a bit-field. 1289234353Sdim return Context == Declarator::MemberContext || 1290234353Sdim (getLangOpts().CPlusPlus && Context == Declarator::FileContext); 1291234353Sdim 1292234353Sdim case tok::identifier: // Possible virt-specifier. 1293234353Sdim return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken()); 1294234353Sdim 1295234353Sdim default: 1296234353Sdim return false; 1297234353Sdim } 1298234353Sdim 1299234353Sdim default: 1300234353Sdim return false; 1301234353Sdim } 1302234353Sdim} 1303234353Sdim 1304234353Sdim/// Skip until we reach something which seems like a sensible place to pick 1305234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner 1306234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later. 1307234353Sdimvoid Parser::SkipMalformedDecl() { 1308234353Sdim while (true) { 1309234353Sdim switch (Tok.getKind()) { 1310234353Sdim case tok::l_brace: 1311234353Sdim // Skip until matching }, then stop. We've probably skipped over 1312234353Sdim // a malformed class or function definition or similar. 1313234353Sdim ConsumeBrace(); 1314234353Sdim SkipUntil(tok::r_brace, /*StopAtSemi*/false); 1315234353Sdim if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { 1316234353Sdim // This declaration isn't over yet. Keep skipping. 1317234353Sdim continue; 1318234353Sdim } 1319234353Sdim if (Tok.is(tok::semi)) 1320234353Sdim ConsumeToken(); 1321234353Sdim return; 1322234353Sdim 1323234353Sdim case tok::l_square: 1324234353Sdim ConsumeBracket(); 1325234353Sdim SkipUntil(tok::r_square, /*StopAtSemi*/false); 1326234353Sdim continue; 1327234353Sdim 1328234353Sdim case tok::l_paren: 1329234353Sdim ConsumeParen(); 1330234353Sdim SkipUntil(tok::r_paren, /*StopAtSemi*/false); 1331234353Sdim continue; 1332234353Sdim 1333234353Sdim case tok::r_brace: 1334234353Sdim return; 1335234353Sdim 1336234353Sdim case tok::semi: 1337234353Sdim ConsumeToken(); 1338234353Sdim return; 1339234353Sdim 1340234353Sdim case tok::kw_inline: 1341234353Sdim // 'inline namespace' at the start of a line is almost certainly 1342239462Sdim // a good place to pick back up parsing, except in an Objective-C 1343239462Sdim // @interface context. 1344239462Sdim if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) && 1345239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1346234353Sdim return; 1347234353Sdim break; 1348234353Sdim 1349234353Sdim case tok::kw_namespace: 1350234353Sdim // 'namespace' at the start of a line is almost certainly a good 1351239462Sdim // place to pick back up parsing, except in an Objective-C 1352239462Sdim // @interface context. 1353239462Sdim if (Tok.isAtStartOfLine() && 1354239462Sdim (!ParsingInObjCContainer || CurParsedObjCImpl)) 1355234353Sdim return; 1356234353Sdim break; 1357234353Sdim 1358239462Sdim case tok::at: 1359239462Sdim // @end is very much like } in Objective-C contexts. 1360239462Sdim if (NextToken().isObjCAtKeyword(tok::objc_end) && 1361239462Sdim ParsingInObjCContainer) 1362239462Sdim return; 1363239462Sdim break; 1364239462Sdim 1365239462Sdim case tok::minus: 1366239462Sdim case tok::plus: 1367239462Sdim // - and + probably start new method declarations in Objective-C contexts. 1368239462Sdim if (Tok.isAtStartOfLine() && ParsingInObjCContainer) 1369239462Sdim return; 1370239462Sdim break; 1371239462Sdim 1372234353Sdim case tok::eof: 1373234353Sdim return; 1374234353Sdim 1375234353Sdim default: 1376234353Sdim break; 1377234353Sdim } 1378234353Sdim 1379234353Sdim ConsumeAnyToken(); 1380234353Sdim } 1381234353Sdim} 1382234353Sdim 1383198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function 1384198893Srdivacky/// definition or a group of object declarations, actually parse the 1385198893Srdivacky/// result. 1386198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, 1387198893Srdivacky unsigned Context, 1388198893Srdivacky bool AllowFunctionDefinitions, 1389221345Sdim SourceLocation *DeclEnd, 1390221345Sdim ForRangeInit *FRI) { 1391198893Srdivacky // Parse the first declarator. 1392198893Srdivacky ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context)); 1393198893Srdivacky ParseDeclarator(D); 1394193326Sed 1395198893Srdivacky // Bail out if the first declarator didn't seem well-formed. 1396198893Srdivacky if (!D.hasName() && !D.mayOmitIdentifier()) { 1397234353Sdim SkipMalformedDecl(); 1398198893Srdivacky return DeclGroupPtrTy(); 1399198893Srdivacky } 1400198092Srdivacky 1401234353Sdim // Save late-parsed attributes for now; they need to be parsed in the 1402234353Sdim // appropriate function scope after the function Decl has been constructed. 1403234353Sdim LateParsedAttrList LateParsedAttrs; 1404234353Sdim if (D.isFunctionDeclarator()) 1405234353Sdim MaybeParseGNUAttributes(D, &LateParsedAttrs); 1406234353Sdim 1407210299Sed // Check to see if we have a function *definition* which must have a body. 1408210299Sed if (AllowFunctionDefinitions && D.isFunctionDeclarator() && 1409210299Sed // Look at the next token to make sure that this isn't a function 1410210299Sed // declaration. We have to check this because __attribute__ might be the 1411210299Sed // start of a function definition in GCC-extended K&R C. 1412210299Sed !isDeclarationAfterDeclarator()) { 1413239462Sdim 1414210299Sed if (isStartOfFunctionDefinition(D)) { 1415198893Srdivacky if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 1416198893Srdivacky Diag(Tok, diag::err_function_declared_typedef); 1417198092Srdivacky 1418198893Srdivacky // Recover by treating the 'typedef' as spurious. 1419198893Srdivacky DS.ClearStorageClassSpecs(); 1420198893Srdivacky } 1421198893Srdivacky 1422234353Sdim Decl *TheDecl = 1423234353Sdim ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); 1424198893Srdivacky return Actions.ConvertDeclToDeclGroup(TheDecl); 1425210299Sed } 1426239462Sdim 1427210299Sed if (isDeclarationSpecifier()) { 1428210299Sed // If there is an invalid declaration specifier right after the function 1429210299Sed // prototype, then we must be in a missing semicolon case where this isn't 1430210299Sed // actually a body. Just fall through into the code that handles it as a 1431210299Sed // prototype, and let the top-level code handle the erroneous declspec 1432210299Sed // where it would otherwise expect a comma or semicolon. 1433198893Srdivacky } else { 1434198893Srdivacky Diag(Tok, diag::err_expected_fn_body); 1435198893Srdivacky SkipUntil(tok::semi); 1436198893Srdivacky return DeclGroupPtrTy(); 1437198893Srdivacky } 1438198893Srdivacky } 1439198893Srdivacky 1440234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1441221345Sdim return DeclGroupPtrTy(); 1442221345Sdim 1443221345Sdim // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we 1444221345Sdim // must parse and analyze the for-range-initializer before the declaration is 1445221345Sdim // analyzed. 1446221345Sdim if (FRI && Tok.is(tok::colon)) { 1447221345Sdim FRI->ColonLoc = ConsumeToken(); 1448223017Sdim if (Tok.is(tok::l_brace)) 1449223017Sdim FRI->RangeExpr = ParseBraceInitializer(); 1450223017Sdim else 1451223017Sdim FRI->RangeExpr = ParseExpression(); 1452221345Sdim Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1453221345Sdim Actions.ActOnCXXForRangeDecl(ThisDecl); 1454221345Sdim Actions.FinalizeDeclaration(ThisDecl); 1455234353Sdim D.complete(ThisDecl); 1456221345Sdim return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1); 1457221345Sdim } 1458221345Sdim 1459226633Sdim SmallVector<Decl *, 8> DeclsInGroup; 1460221345Sdim Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D); 1461234353Sdim if (LateParsedAttrs.size() > 0) 1462234353Sdim ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); 1463198893Srdivacky D.complete(FirstDecl); 1464212904Sdim if (FirstDecl) 1465198893Srdivacky DeclsInGroup.push_back(FirstDecl); 1466198893Srdivacky 1467234353Sdim bool ExpectSemi = Context != Declarator::ForContext; 1468239462Sdim 1469198893Srdivacky // If we don't have a comma, it is either the end of the list (a ';') or an 1470198893Srdivacky // error, bail out. 1471198893Srdivacky while (Tok.is(tok::comma)) { 1472234353Sdim SourceLocation CommaLoc = ConsumeToken(); 1473198893Srdivacky 1474234353Sdim if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) { 1475234353Sdim // This comma was followed by a line-break and something which can't be 1476234353Sdim // the start of a declarator. The comma was probably a typo for a 1477234353Sdim // semicolon. 1478234353Sdim Diag(CommaLoc, diag::err_expected_semi_declaration) 1479234353Sdim << FixItHint::CreateReplacement(CommaLoc, ";"); 1480234353Sdim ExpectSemi = false; 1481234353Sdim break; 1482234353Sdim } 1483234353Sdim 1484198893Srdivacky // Parse the next declarator. 1485198893Srdivacky D.clear(); 1486234353Sdim D.setCommaLoc(CommaLoc); 1487198893Srdivacky 1488198893Srdivacky // Accept attributes in an init-declarator. In the first declarator in a 1489198893Srdivacky // declaration, these would be part of the declspec. In subsequent 1490198893Srdivacky // declarators, they become part of the declarator itself, so that they 1491198893Srdivacky // don't apply to declarators after *this* one. Examples: 1492198893Srdivacky // short __attribute__((common)) var; -> declspec 1493198893Srdivacky // short var __attribute__((common)); -> declarator 1494198893Srdivacky // short x, __attribute__((common)) var; -> declarator 1495218893Sdim MaybeParseGNUAttributes(D); 1496198893Srdivacky 1497198893Srdivacky ParseDeclarator(D); 1498234353Sdim if (!D.isInvalidType()) { 1499234353Sdim Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); 1500234353Sdim D.complete(ThisDecl); 1501234353Sdim if (ThisDecl) 1502239462Sdim DeclsInGroup.push_back(ThisDecl); 1503234353Sdim } 1504193326Sed } 1505198092Srdivacky 1506198893Srdivacky if (DeclEnd) 1507198893Srdivacky *DeclEnd = Tok.getLocation(); 1508198893Srdivacky 1509234353Sdim if (ExpectSemi && 1510239462Sdim ExpectAndConsumeSemi(Context == Declarator::FileContext 1511239462Sdim ? diag::err_invalid_token_after_toplevel_declarator 1512239462Sdim : diag::err_expected_semi_declaration)) { 1513210299Sed // Okay, there was no semicolon and one was expected. If we see a 1514210299Sed // declaration specifier, just assume it was missing and continue parsing. 1515210299Sed // Otherwise things are very confused and we skip to recover. 1516210299Sed if (!isDeclarationSpecifier()) { 1517210299Sed SkipUntil(tok::r_brace, true, true); 1518210299Sed if (Tok.is(tok::semi)) 1519210299Sed ConsumeToken(); 1520210299Sed } 1521198893Srdivacky } 1522198893Srdivacky 1523210299Sed return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, 1524198893Srdivacky DeclsInGroup.data(), 1525198893Srdivacky DeclsInGroup.size()); 1526193326Sed} 1527193326Sed 1528221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a 1529221345Sdim/// declarator. Returns true on an error. 1530234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) { 1531221345Sdim // If a simple-asm-expr is present, parse it. 1532221345Sdim if (Tok.is(tok::kw_asm)) { 1533221345Sdim SourceLocation Loc; 1534221345Sdim ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1535221345Sdim if (AsmLabel.isInvalid()) { 1536221345Sdim SkipUntil(tok::semi, true, true); 1537221345Sdim return true; 1538221345Sdim } 1539221345Sdim 1540221345Sdim D.setAsmLabel(AsmLabel.release()); 1541221345Sdim D.SetRangeEnd(Loc); 1542221345Sdim } 1543221345Sdim 1544221345Sdim MaybeParseGNUAttributes(D); 1545221345Sdim return false; 1546221345Sdim} 1547221345Sdim 1548193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers 1549193326Sed/// declarator'. This method parses the remainder of the declaration 1550193326Sed/// (including any attributes or initializer, among other things) and 1551193326Sed/// finalizes the declaration. 1552193326Sed/// 1553193326Sed/// init-declarator: [C99 6.7] 1554193326Sed/// declarator 1555193326Sed/// declarator '=' initializer 1556193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] 1557193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer 1558193326Sed/// [C++] declarator initializer[opt] 1559193326Sed/// 1560193326Sed/// [C++] initializer: 1561193326Sed/// [C++] '=' initializer-clause 1562193326Sed/// [C++] '(' expression-list ')' 1563193326Sed/// [C++0x] '=' 'default' [TODO] 1564193326Sed/// [C++0x] '=' 'delete' 1565223017Sdim/// [C++0x] braced-init-list 1566193326Sed/// 1567193326Sed/// According to the standard grammar, =default and =delete are function 1568193326Sed/// definitions, but that definitely doesn't fit with the parser here. 1569193326Sed/// 1570212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, 1571195099Sed const ParsedTemplateInfo &TemplateInfo) { 1572234353Sdim if (ParseAsmAttributesAfterDeclarator(D)) 1573221345Sdim return 0; 1574198092Srdivacky 1575221345Sdim return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo); 1576221345Sdim} 1577198092Srdivacky 1578221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, 1579221345Sdim const ParsedTemplateInfo &TemplateInfo) { 1580193326Sed // Inform the current actions module that we just parsed this declarator. 1581212904Sdim Decl *ThisDecl = 0; 1582198092Srdivacky switch (TemplateInfo.Kind) { 1583198092Srdivacky case ParsedTemplateInfo::NonTemplate: 1584210299Sed ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); 1585198092Srdivacky break; 1586239462Sdim 1587198092Srdivacky case ParsedTemplateInfo::Template: 1588198092Srdivacky case ParsedTemplateInfo::ExplicitSpecialization: 1589210299Sed ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), 1590212904Sdim MultiTemplateParamsArg(Actions, 1591195099Sed TemplateInfo.TemplateParams->data(), 1592195099Sed TemplateInfo.TemplateParams->size()), 1593198092Srdivacky D); 1594198092Srdivacky break; 1595239462Sdim 1596198092Srdivacky case ParsedTemplateInfo::ExplicitInstantiation: { 1597239462Sdim DeclResult ThisRes 1598210299Sed = Actions.ActOnExplicitInstantiation(getCurScope(), 1599198092Srdivacky TemplateInfo.ExternLoc, 1600198092Srdivacky TemplateInfo.TemplateLoc, 1601198092Srdivacky D); 1602198092Srdivacky if (ThisRes.isInvalid()) { 1603198092Srdivacky SkipUntil(tok::semi, true, true); 1604212904Sdim return 0; 1605198092Srdivacky } 1606239462Sdim 1607198092Srdivacky ThisDecl = ThisRes.get(); 1608198092Srdivacky break; 1609198092Srdivacky } 1610198092Srdivacky } 1611198092Srdivacky 1612218893Sdim bool TypeContainsAuto = 1613218893Sdim D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; 1614218893Sdim 1615193326Sed // Parse declarator '=' initializer. 1616234353Sdim // If a '==' or '+=' is found, suggest a fixit to '='. 1617234353Sdim if (isTokenEqualOrEqualTypo()) { 1618193326Sed ConsumeToken(); 1619218893Sdim if (Tok.is(tok::kw_delete)) { 1620223017Sdim if (D.isFunctionDeclarator()) 1621223017Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1622223017Sdim << 1 /* delete */; 1623223017Sdim else 1624223017Sdim Diag(ConsumeToken(), diag::err_deleted_non_function); 1625223017Sdim } else if (Tok.is(tok::kw_default)) { 1626223017Sdim if (D.isFunctionDeclarator()) 1627234353Sdim Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 1628234353Sdim << 0 /* default */; 1629223017Sdim else 1630223017Sdim Diag(ConsumeToken(), diag::err_default_special_members); 1631193326Sed } else { 1632234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1633201361Srdivacky EnterScope(0); 1634210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1635201361Srdivacky } 1636194613Sed 1637210299Sed if (Tok.is(tok::code_completion)) { 1638210299Sed Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); 1639239462Sdim Actions.FinalizeDeclaration(ThisDecl); 1640226633Sdim cutOffParsing(); 1641226633Sdim return 0; 1642210299Sed } 1643239462Sdim 1644212904Sdim ExprResult Init(ParseInitializer()); 1645194613Sed 1646234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1647210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1648201361Srdivacky ExitScope(); 1649201361Srdivacky } 1650194613Sed 1651193326Sed if (Init.isInvalid()) { 1652204643Srdivacky SkipUntil(tok::comma, true, true); 1653204643Srdivacky Actions.ActOnInitializerError(ThisDecl); 1654204643Srdivacky } else 1655218893Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1656218893Sdim /*DirectInit=*/false, TypeContainsAuto); 1657193326Sed } 1658193326Sed } else if (Tok.is(tok::l_paren)) { 1659193326Sed // Parse C++ direct initializer: '(' expression-list ')' 1660226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1661226633Sdim T.consumeOpen(); 1662226633Sdim 1663193326Sed ExprVector Exprs(Actions); 1664193326Sed CommaLocsTy CommaLocs; 1665193326Sed 1666234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1667201361Srdivacky EnterScope(0); 1668210299Sed Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1669201361Srdivacky } 1670201361Srdivacky 1671193326Sed if (ParseExpressionList(Exprs, CommaLocs)) { 1672193326Sed SkipUntil(tok::r_paren); 1673201361Srdivacky 1674234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1675210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1676201361Srdivacky ExitScope(); 1677201361Srdivacky } 1678193326Sed } else { 1679193326Sed // Match the ')'. 1680226633Sdim T.consumeClose(); 1681193326Sed 1682193326Sed assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && 1683193326Sed "Unexpected number of commas!"); 1684201361Srdivacky 1685234353Sdim if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { 1686210299Sed Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1687201361Srdivacky ExitScope(); 1688201361Srdivacky } 1689201361Srdivacky 1690234353Sdim ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), 1691234353Sdim T.getCloseLocation(), 1692234353Sdim move_arg(Exprs)); 1693234353Sdim Actions.AddInitializerToDecl(ThisDecl, Initializer.take(), 1694234353Sdim /*DirectInit=*/true, TypeContainsAuto); 1695193326Sed } 1696239462Sdim } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) && 1697239462Sdim (!CurParsedObjCImpl || !D.isFunctionDeclarator())) { 1698223017Sdim // Parse C++0x braced-init-list. 1699234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1700234353Sdim 1701223017Sdim if (D.getCXXScopeSpec().isSet()) { 1702223017Sdim EnterScope(0); 1703223017Sdim Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); 1704223017Sdim } 1705223017Sdim 1706223017Sdim ExprResult Init(ParseBraceInitializer()); 1707223017Sdim 1708223017Sdim if (D.getCXXScopeSpec().isSet()) { 1709223017Sdim Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); 1710223017Sdim ExitScope(); 1711223017Sdim } 1712223017Sdim 1713223017Sdim if (Init.isInvalid()) { 1714223017Sdim Actions.ActOnInitializerError(ThisDecl); 1715223017Sdim } else 1716223017Sdim Actions.AddInitializerToDecl(ThisDecl, Init.take(), 1717223017Sdim /*DirectInit=*/true, TypeContainsAuto); 1718223017Sdim 1719193326Sed } else { 1720218893Sdim Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto); 1721193326Sed } 1722193326Sed 1723219077Sdim Actions.FinalizeDeclaration(ThisDecl); 1724219077Sdim 1725193326Sed return ThisDecl; 1726193326Sed} 1727193326Sed 1728193326Sed/// ParseSpecifierQualifierList 1729193326Sed/// specifier-qualifier-list: 1730193326Sed/// type-specifier specifier-qualifier-list[opt] 1731193326Sed/// type-qualifier specifier-qualifier-list[opt] 1732193326Sed/// [GNU] attributes specifier-qualifier-list[opt] 1733193326Sed/// 1734234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, 1735234353Sdim DeclSpecContext DSC) { 1736193326Sed /// specifier-qualifier-list is a subset of declaration-specifiers. Just 1737193326Sed /// parse declaration-specifiers and complain about extra stuff. 1738226633Sdim /// TODO: diagnose attribute-specifiers and alignment-specifiers. 1739234353Sdim ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC); 1740198092Srdivacky 1741193326Sed // Validate declspec for type-name. 1742193326Sed unsigned Specs = DS.getParsedSpecifiers(); 1743239462Sdim if ((DSC == DSC_type_specifier || DSC == DSC_trailing) && 1744239462Sdim !DS.hasTypeSpecifier()) { 1745234353Sdim Diag(Tok, diag::err_expected_type); 1746234353Sdim DS.SetTypeSpecError(); 1747234353Sdim } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && 1748234353Sdim !DS.hasAttributes()) { 1749193326Sed Diag(Tok, diag::err_typename_requires_specqual); 1750234353Sdim if (!DS.hasTypeSpecifier()) 1751234353Sdim DS.SetTypeSpecError(); 1752234353Sdim } 1753198092Srdivacky 1754193326Sed // Issue diagnostic and remove storage class if present. 1755193326Sed if (Specs & DeclSpec::PQ_StorageClassSpecifier) { 1756193326Sed if (DS.getStorageClassSpecLoc().isValid()) 1757193326Sed Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); 1758193326Sed else 1759193326Sed Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass); 1760193326Sed DS.ClearStorageClassSpecs(); 1761193326Sed } 1762198092Srdivacky 1763193326Sed // Issue diagnostic and remove function specfier if present. 1764193326Sed if (Specs & DeclSpec::PQ_FunctionSpecifier) { 1765193326Sed if (DS.isInlineSpecified()) 1766193326Sed Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); 1767193326Sed if (DS.isVirtualSpecified()) 1768193326Sed Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); 1769193326Sed if (DS.isExplicitSpecified()) 1770193326Sed Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); 1771193326Sed DS.ClearFunctionSpecs(); 1772193326Sed } 1773234353Sdim 1774234353Sdim // Issue diagnostic and remove constexpr specfier if present. 1775234353Sdim if (DS.isConstexprSpecified()) { 1776234353Sdim Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); 1777234353Sdim DS.ClearConstexprSpec(); 1778234353Sdim } 1779193326Sed} 1780193326Sed 1781193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the 1782193326Sed/// specified token is valid after the identifier in a declarator which 1783193326Sed/// immediately follows the declspec. For example, these things are valid: 1784193326Sed/// 1785193326Sed/// int x [ 4]; // direct-declarator 1786193326Sed/// int x ( int y); // direct-declarator 1787193326Sed/// int(int x ) // direct-declarator 1788193326Sed/// int x ; // simple-declaration 1789193326Sed/// int x = 17; // init-declarator-list 1790193326Sed/// int x , y; // init-declarator-list 1791193326Sed/// int x __asm__ ("foo"); // init-declarator-list 1792193326Sed/// int x : 4; // struct-declarator 1793193326Sed/// int x { 5}; // C++'0x unified initializers 1794193326Sed/// 1795193326Sed/// This is not, because 'x' does not immediately follow the declspec (though 1796193326Sed/// ')' happens to be valid anyway). 1797193326Sed/// int (x) 1798193326Sed/// 1799193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) { 1800193326Sed return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) || 1801193326Sed T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) || 1802193326Sed T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon); 1803193326Sed} 1804193326Sed 1805193326Sed 1806193326Sed/// ParseImplicitInt - This method is called when we have an non-typename 1807193326Sed/// identifier in a declspec (which normally terminates the decl spec) when 1808193326Sed/// the declspec has no type specifier. In this case, the declspec is either 1809193326Sed/// malformed or is "implicit int" (in K&R and C89). 1810193326Sed/// 1811193326Sed/// This method handles diagnosing this prettily and returns false if the 1812193326Sed/// declspec is done being processed. If it recovers and thinks there may be 1813193326Sed/// other pieces of declspec after it, it returns true. 1814193326Sed/// 1815193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, 1816193326Sed const ParsedTemplateInfo &TemplateInfo, 1817234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 1818193326Sed assert(Tok.is(tok::identifier) && "should have identifier"); 1819198092Srdivacky 1820193326Sed SourceLocation Loc = Tok.getLocation(); 1821193326Sed // If we see an identifier that is not a type name, we normally would 1822193326Sed // parse it as the identifer being declared. However, when a typename 1823193326Sed // is typo'd or the definition is not included, this will incorrectly 1824193326Sed // parse the typename as the identifier name and fall over misparsing 1825193326Sed // later parts of the diagnostic. 1826193326Sed // 1827193326Sed // As such, we try to do some look-ahead in cases where this would 1828193326Sed // otherwise be an "implicit-int" case to see if this is invalid. For 1829193326Sed // example: "static foo_t x = 4;" In this case, if we parsed foo_t as 1830193326Sed // an identifier with implicit int, we'd get a parse error because the 1831193326Sed // next token is obviously invalid for a type. Parse these as a case 1832193326Sed // with an invalid type specifier. 1833193326Sed assert(!DS.hasTypeSpecifier() && "Type specifier checked above"); 1834198092Srdivacky 1835193326Sed // Since we know that this either implicit int (which is rare) or an 1836239462Sdim // error, do lookahead to try to do better recovery. This never applies 1837239462Sdim // within a type specifier. Outside of C++, we allow this even if the 1838239462Sdim // language doesn't "officially" support implicit int -- we support 1839239462Sdim // implicit int as an extension in C99 and C11. Allegedly, MS also 1840239462Sdim // supports implicit int in C++ mode. 1841239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 1842239462Sdim (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) && 1843234353Sdim isValidAfterIdentifierInDeclarator(NextToken())) { 1844193326Sed // If this token is valid for implicit int, e.g. "static x = 4", then 1845193326Sed // we just avoid eating the identifier, so it will be parsed as the 1846193326Sed // identifier in the declarator. 1847193326Sed return false; 1848193326Sed } 1849198092Srdivacky 1850239462Sdim if (getLangOpts().CPlusPlus && 1851239462Sdim DS.getStorageClassSpec() == DeclSpec::SCS_auto) { 1852239462Sdim // Don't require a type specifier if we have the 'auto' storage class 1853239462Sdim // specifier in C++98 -- we'll promote it to a type specifier. 1854239462Sdim return false; 1855239462Sdim } 1856239462Sdim 1857193326Sed // Otherwise, if we don't consume this token, we are going to emit an 1858193326Sed // error anyway. Try to recover from various common problems. Check 1859193326Sed // to see if this was a reference to a tag name without a tag specified. 1860193326Sed // This is a common problem in C (saying 'foo' instead of 'struct foo'). 1861193326Sed // 1862193326Sed // C++ doesn't need this, and isTagName doesn't take SS. 1863193326Sed if (SS == 0) { 1864221345Sdim const char *TagName = 0, *FixitTagName = 0; 1865193326Sed tok::TokenKind TagKind = tok::unknown; 1866198092Srdivacky 1867210299Sed switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) { 1868193326Sed default: break; 1869221345Sdim case DeclSpec::TST_enum: 1870221345Sdim TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break; 1871221345Sdim case DeclSpec::TST_union: 1872221345Sdim TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break; 1873221345Sdim case DeclSpec::TST_struct: 1874221345Sdim TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break; 1875221345Sdim case DeclSpec::TST_class: 1876221345Sdim TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; 1877193326Sed } 1878198092Srdivacky 1879193326Sed if (TagName) { 1880239462Sdim IdentifierInfo *TokenName = Tok.getIdentifierInfo(); 1881239462Sdim LookupResult R(Actions, TokenName, SourceLocation(), 1882239462Sdim Sema::LookupOrdinaryName); 1883239462Sdim 1884193326Sed Diag(Loc, diag::err_use_of_tag_name_without_tag) 1885239462Sdim << TokenName << TagName << getLangOpts().CPlusPlus 1886239462Sdim << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName); 1887198092Srdivacky 1888239462Sdim if (Actions.LookupParsedName(R, getCurScope(), SS)) { 1889239462Sdim for (LookupResult::iterator I = R.begin(), IEnd = R.end(); 1890239462Sdim I != IEnd; ++I) 1891239462Sdim Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type) 1892239462Sdim << TokenName << TagName; 1893239462Sdim } 1894239462Sdim 1895193326Sed // Parse this as a tag as if the missing tag were present. 1896193326Sed if (TagKind == tok::kw_enum) 1897234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); 1898193326Sed else 1899234353Sdim ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, 1900234353Sdim /*EnteringContext*/ false, DSC_normal); 1901193326Sed return true; 1902193326Sed } 1903193326Sed } 1904198092Srdivacky 1905239462Sdim // Determine whether this identifier could plausibly be the name of something 1906239462Sdim // being declared (with a missing type). 1907239462Sdim if (DSC != DSC_type_specifier && DSC != DSC_trailing && 1908239462Sdim (!SS || DSC == DSC_top_level || DSC == DSC_class)) { 1909239462Sdim // Look ahead to the next token to try to figure out what this declaration 1910239462Sdim // was supposed to be. 1911239462Sdim switch (NextToken().getKind()) { 1912239462Sdim case tok::comma: 1913239462Sdim case tok::equal: 1914239462Sdim case tok::kw_asm: 1915239462Sdim case tok::l_brace: 1916239462Sdim case tok::l_square: 1917239462Sdim case tok::semi: 1918239462Sdim // This looks like a variable declaration. The type is probably missing. 1919239462Sdim // We're done parsing decl-specifiers. 1920239462Sdim return false; 1921239462Sdim 1922239462Sdim case tok::l_paren: { 1923239462Sdim // static x(4); // 'x' is not a type 1924239462Sdim // x(int n); // 'x' is not a type 1925239462Sdim // x (*p)[]; // 'x' is a type 1926239462Sdim // 1927239462Sdim // Since we're in an error case (or the rare 'implicit int in C++' MS 1928239462Sdim // extension), we can afford to perform a tentative parse to determine 1929239462Sdim // which case we're in. 1930239462Sdim TentativeParsingAction PA(*this); 1931239462Sdim ConsumeToken(); 1932239462Sdim TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false); 1933239462Sdim PA.Revert(); 1934239462Sdim if (TPR == TPResult::False()) 1935239462Sdim return false; 1936239462Sdim // The identifier is followed by a parenthesized declarator. 1937239462Sdim // It's supposed to be a type. 1938239462Sdim break; 1939239462Sdim } 1940239462Sdim 1941239462Sdim default: 1942239462Sdim // This is probably supposed to be a type. This includes cases like: 1943239462Sdim // int f(itn); 1944239462Sdim // struct S { unsinged : 4; }; 1945239462Sdim break; 1946239462Sdim } 1947239462Sdim } 1948239462Sdim 1949239462Sdim // This is almost certainly an invalid type name. Let the action emit a 1950198092Srdivacky // diagnostic and attempt to recover. 1951212904Sdim ParsedType T; 1952239462Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 1953239462Sdim if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) { 1954198092Srdivacky // The action emitted a diagnostic, so we don't have to. 1955198092Srdivacky if (T) { 1956198092Srdivacky // The action has suggested that the type T could be used. Set that as 1957198092Srdivacky // the type in the declaration specifiers, consume the would-be type 1958198092Srdivacky // name token, and we're done. 1959198092Srdivacky const char *PrevSpec; 1960198092Srdivacky unsigned DiagID; 1961212904Sdim DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); 1962198092Srdivacky DS.SetRangeEnd(Tok.getLocation()); 1963198092Srdivacky ConsumeToken(); 1964198092Srdivacky // There may be other declaration specifiers after this. 1965198092Srdivacky return true; 1966239462Sdim } else if (II != Tok.getIdentifierInfo()) { 1967239462Sdim // If no type was suggested, the correction is to a keyword 1968239462Sdim Tok.setKind(II->getTokenID()); 1969239462Sdim // There may be other declaration specifiers after this. 1970239462Sdim return true; 1971198092Srdivacky } 1972239462Sdim 1973198092Srdivacky // Fall through; the action had no suggestion for us. 1974198092Srdivacky } else { 1975198092Srdivacky // The action did not emit a diagnostic, so emit one now. 1976198092Srdivacky SourceRange R; 1977198092Srdivacky if (SS) R = SS->getRange(); 1978198092Srdivacky Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R; 1979198092Srdivacky } 1980198092Srdivacky 1981198092Srdivacky // Mark this as an error. 1982234353Sdim DS.SetTypeSpecError(); 1983193326Sed DS.SetRangeEnd(Tok.getLocation()); 1984193326Sed ConsumeToken(); 1985198092Srdivacky 1986193326Sed // TODO: Could inject an invalid typedef decl in an enclosing scope to 1987193326Sed // avoid rippling error messages on subsequent uses of the same type, 1988193326Sed // could be useful if #include was forgotten. 1989193326Sed return false; 1990193326Sed} 1991193326Sed 1992202379Srdivacky/// \brief Determine the declaration specifier context from the declarator 1993202379Srdivacky/// context. 1994202379Srdivacky/// 1995202379Srdivacky/// \param Context the declarator context, which is one of the 1996202379Srdivacky/// Declarator::TheContext enumerator values. 1997239462SdimParser::DeclSpecContext 1998202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { 1999202379Srdivacky if (Context == Declarator::MemberContext) 2000202379Srdivacky return DSC_class; 2001202379Srdivacky if (Context == Declarator::FileContext) 2002202379Srdivacky return DSC_top_level; 2003234353Sdim if (Context == Declarator::TrailingReturnContext) 2004234353Sdim return DSC_trailing; 2005202379Srdivacky return DSC_normal; 2006202379Srdivacky} 2007202379Srdivacky 2008226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier. 2009226633Sdim/// 2010226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a 2011226633Sdim/// type. Ideally, the type should be propagated directly into Sema. 2012226633Sdim/// 2013234353Sdim/// [C11] type-id 2014234353Sdim/// [C11] constant-expression 2015234353Sdim/// [C++0x] type-id ...[opt] 2016234353Sdim/// [C++0x] assignment-expression ...[opt] 2017234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start, 2018234353Sdim SourceLocation &EllipsisLoc) { 2019234353Sdim ExprResult ER; 2020226633Sdim if (isTypeIdInParens()) { 2021226633Sdim SourceLocation TypeLoc = Tok.getLocation(); 2022226633Sdim ParsedType Ty = ParseTypeName().get(); 2023226633Sdim SourceRange TypeRange(Start, Tok.getLocation()); 2024234353Sdim ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true, 2025234353Sdim Ty.getAsOpaquePtr(), TypeRange); 2026226633Sdim } else 2027234353Sdim ER = ParseConstantExpression(); 2028234353Sdim 2029234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis)) 2030234353Sdim EllipsisLoc = ConsumeToken(); 2031234353Sdim 2032234353Sdim return ER; 2033226633Sdim} 2034226633Sdim 2035226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the 2036226633Sdim/// attribute to Attrs. 2037226633Sdim/// 2038226633Sdim/// alignment-specifier: 2039234353Sdim/// [C11] '_Alignas' '(' type-id ')' 2040234353Sdim/// [C11] '_Alignas' '(' constant-expression ')' 2041234353Sdim/// [C++0x] 'alignas' '(' type-id ...[opt] ')' 2042234353Sdim/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')' 2043226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, 2044226633Sdim SourceLocation *endLoc) { 2045226633Sdim assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) && 2046226633Sdim "Not an alignment-specifier!"); 2047226633Sdim 2048226633Sdim SourceLocation KWLoc = Tok.getLocation(); 2049226633Sdim ConsumeToken(); 2050226633Sdim 2051226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2052226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2053226633Sdim return; 2054226633Sdim 2055234353Sdim SourceLocation EllipsisLoc; 2056234353Sdim ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); 2057226633Sdim if (ArgExpr.isInvalid()) { 2058226633Sdim SkipUntil(tok::r_paren); 2059226633Sdim return; 2060226633Sdim } 2061226633Sdim 2062226633Sdim T.consumeClose(); 2063226633Sdim if (endLoc) 2064226633Sdim *endLoc = T.getCloseLocation(); 2065226633Sdim 2066234353Sdim // FIXME: Handle pack-expansions here. 2067234353Sdim if (EllipsisLoc.isValid()) { 2068234353Sdim Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported); 2069234353Sdim return; 2070234353Sdim } 2071234353Sdim 2072226633Sdim ExprVector ArgExprs(Actions); 2073226633Sdim ArgExprs.push_back(ArgExpr.release()); 2074239462Sdim // FIXME: This should not be GNU, but we since the attribute used is 2075239462Sdim // based on the spelling, and there is no true spelling for 2076239462Sdim // C++11 attributes, this isn't accepted. 2077226633Sdim Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc, 2078239462Sdim 0, T.getOpenLocation(), ArgExprs.take(), 1, 2079239462Sdim AttributeList::AS_GNU); 2080226633Sdim} 2081226633Sdim 2082193326Sed/// ParseDeclarationSpecifiers 2083193326Sed/// declaration-specifiers: [C99 6.7] 2084193326Sed/// storage-class-specifier declaration-specifiers[opt] 2085193326Sed/// type-specifier declaration-specifiers[opt] 2086193326Sed/// [C99] function-specifier declaration-specifiers[opt] 2087234353Sdim/// [C11] alignment-specifier declaration-specifiers[opt] 2088193326Sed/// [GNU] attributes declaration-specifiers[opt] 2089226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt] 2090193326Sed/// 2091193326Sed/// storage-class-specifier: [C99 6.7.1] 2092193326Sed/// 'typedef' 2093193326Sed/// 'extern' 2094193326Sed/// 'static' 2095193326Sed/// 'auto' 2096193326Sed/// 'register' 2097193326Sed/// [C++] 'mutable' 2098193326Sed/// [GNU] '__thread' 2099193326Sed/// function-specifier: [C99 6.7.4] 2100193326Sed/// [C99] 'inline' 2101193326Sed/// [C++] 'virtual' 2102193326Sed/// [C++] 'explicit' 2103218893Sdim/// [OpenCL] '__kernel' 2104193326Sed/// 'friend': [C++ dcl.friend] 2105198954Srdivacky/// 'constexpr': [C++0x dcl.constexpr] 2106193326Sed 2107193326Sed/// 2108193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS, 2109193326Sed const ParsedTemplateInfo &TemplateInfo, 2110198092Srdivacky AccessSpecifier AS, 2111234353Sdim DeclSpecContext DSContext, 2112234353Sdim LateParsedAttrList *LateAttrs) { 2113221345Sdim if (DS.getSourceRange().isInvalid()) { 2114221345Sdim DS.SetRangeStart(Tok.getLocation()); 2115221345Sdim DS.SetRangeEnd(Tok.getLocation()); 2116221345Sdim } 2117239462Sdim 2118234353Sdim bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level); 2119239462Sdim bool AttrsLastTime = false; 2120239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 2121193326Sed while (1) { 2122198092Srdivacky bool isInvalid = false; 2123193326Sed const char *PrevSpec = 0; 2124198092Srdivacky unsigned DiagID = 0; 2125198092Srdivacky 2126193326Sed SourceLocation Loc = Tok.getLocation(); 2127193326Sed 2128193326Sed switch (Tok.getKind()) { 2129198092Srdivacky default: 2130193326Sed DoneWithDeclSpec: 2131239462Sdim if (!AttrsLastTime) 2132239462Sdim ProhibitAttributes(attrs); 2133239462Sdim else 2134239462Sdim DS.takeAttributesFrom(attrs); 2135226633Sdim 2136193326Sed // If this is not a declaration specifier token, we're done reading decl 2137193326Sed // specifiers. First verify that DeclSpec's are consistent. 2138193326Sed DS.Finish(Diags, PP); 2139193326Sed return; 2140198092Srdivacky 2141239462Sdim case tok::l_square: 2142239462Sdim case tok::kw_alignas: 2143239462Sdim if (!isCXX11AttributeSpecifier()) 2144239462Sdim goto DoneWithDeclSpec; 2145239462Sdim 2146239462Sdim ProhibitAttributes(attrs); 2147239462Sdim // FIXME: It would be good to recover by accepting the attributes, 2148239462Sdim // but attempting to do that now would cause serious 2149239462Sdim // madness in terms of diagnostics. 2150239462Sdim attrs.clear(); 2151239462Sdim attrs.Range = SourceRange(); 2152239462Sdim 2153239462Sdim ParseCXX11Attributes(attrs); 2154239462Sdim AttrsLastTime = true; 2155239462Sdim continue; 2156239462Sdim 2157212904Sdim case tok::code_completion: { 2158212904Sdim Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; 2159212904Sdim if (DS.hasTypeSpecifier()) { 2160212904Sdim bool AllowNonIdentifiers 2161212904Sdim = (getCurScope()->getFlags() & (Scope::ControlScope | 2162212904Sdim Scope::BlockScope | 2163212904Sdim Scope::TemplateParamScope | 2164212904Sdim Scope::FunctionPrototypeScope | 2165212904Sdim Scope::AtCatchScope)) == 0; 2166212904Sdim bool AllowNestedNameSpecifiers 2167239462Sdim = DSContext == DSC_top_level || 2168212904Sdim (DSContext == DSC_class && DS.isFriendSpecified()); 2169212904Sdim 2170218893Sdim Actions.CodeCompleteDeclSpec(getCurScope(), DS, 2171239462Sdim AllowNonIdentifiers, 2172218893Sdim AllowNestedNameSpecifiers); 2173226633Sdim return cutOffParsing(); 2174239462Sdim } 2175239462Sdim 2176218893Sdim if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) 2177218893Sdim CCC = Sema::PCC_LocalDeclarationSpecifiers; 2178218893Sdim else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) 2179239462Sdim CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 2180212904Sdim : Sema::PCC_Template; 2181212904Sdim else if (DSContext == DSC_class) 2182212904Sdim CCC = Sema::PCC_Class; 2183234353Sdim else if (CurParsedObjCImpl) 2184212904Sdim CCC = Sema::PCC_ObjCImplementation; 2185239462Sdim 2186212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); 2187226633Sdim return cutOffParsing(); 2188212904Sdim } 2189212904Sdim 2190193326Sed case tok::coloncolon: // ::foo::bar 2191204643Srdivacky // C++ scope specifier. Annotate and loop, or bail out on error. 2192204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 2193204643Srdivacky if (!DS.hasTypeSpecifier()) 2194204643Srdivacky DS.SetTypeSpecError(); 2195204643Srdivacky goto DoneWithDeclSpec; 2196204643Srdivacky } 2197204643Srdivacky if (Tok.is(tok::coloncolon)) // ::new or ::delete 2198204643Srdivacky goto DoneWithDeclSpec; 2199204643Srdivacky continue; 2200193326Sed 2201193326Sed case tok::annot_cxxscope: { 2202239462Sdim if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector()) 2203193326Sed goto DoneWithDeclSpec; 2204193326Sed 2205200583Srdivacky CXXScopeSpec SS; 2206219077Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 2207219077Sdim Tok.getAnnotationRange(), 2208219077Sdim SS); 2209200583Srdivacky 2210193326Sed // We are looking for a qualified typename. 2211193326Sed Token Next = NextToken(); 2212198092Srdivacky if (Next.is(tok::annot_template_id) && 2213193326Sed static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) 2214193326Sed ->Kind == TNK_Type_template) { 2215193326Sed // We have a qualified template-id, e.g., N::A<int> 2216202379Srdivacky 2217202379Srdivacky // C++ [class.qual]p2: 2218202379Srdivacky // In a lookup in which the constructor is an acceptable lookup 2219202379Srdivacky // result and the nested-name-specifier nominates a class C: 2220202379Srdivacky // 2221202379Srdivacky // - if the name specified after the 2222202379Srdivacky // nested-name-specifier, when looked up in C, is the 2223202379Srdivacky // injected-class-name of C (Clause 9), or 2224202379Srdivacky // 2225202379Srdivacky // - if the name specified after the nested-name-specifier 2226202379Srdivacky // is the same as the identifier or the 2227202379Srdivacky // simple-template-id's template-name in the last 2228202379Srdivacky // component of the nested-name-specifier, 2229202379Srdivacky // 2230202379Srdivacky // the name is instead considered to name the constructor of 2231202379Srdivacky // class C. 2232239462Sdim // 2233202379Srdivacky // Thus, if the template-name is actually the constructor 2234202379Srdivacky // name, then the code is ill-formed; this interpretation is 2235239462Sdim // reinforced by the NAD status of core issue 635. 2236224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 2237207619Srdivacky if ((DSContext == DSC_top_level || 2238207619Srdivacky (DSContext == DSC_class && DS.isFriendSpecified())) && 2239207619Srdivacky TemplateId->Name && 2240210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 2241202379Srdivacky if (isConstructorDeclarator()) { 2242202379Srdivacky // The user meant this to be an out-of-line constructor 2243202379Srdivacky // definition, but template arguments are not allowed 2244202379Srdivacky // there. Just allow this as a constructor; we'll 2245202379Srdivacky // complain about it later. 2246202379Srdivacky goto DoneWithDeclSpec; 2247202379Srdivacky } 2248202379Srdivacky 2249202379Srdivacky // The user meant this to name a type, but it actually names 2250202379Srdivacky // a constructor with some extraneous template 2251202379Srdivacky // arguments. Complain, then parse it as a type as the user 2252202379Srdivacky // intended. 2253202379Srdivacky Diag(TemplateId->TemplateNameLoc, 2254202379Srdivacky diag::err_out_of_line_template_id_names_constructor) 2255202379Srdivacky << TemplateId->Name; 2256202379Srdivacky } 2257202379Srdivacky 2258200583Srdivacky DS.getTypeSpecScope() = SS; 2259200583Srdivacky ConsumeToken(); // The C++ scope. 2260198092Srdivacky assert(Tok.is(tok::annot_template_id) && 2261193326Sed "ParseOptionalCXXScopeSpecifier not working"); 2262221345Sdim AnnotateTemplateIdTokenAsType(); 2263193326Sed continue; 2264193326Sed } 2265193326Sed 2266198092Srdivacky if (Next.is(tok::annot_typename)) { 2267200583Srdivacky DS.getTypeSpecScope() = SS; 2268200583Srdivacky ConsumeToken(); // The C++ scope. 2269212904Sdim if (Tok.getAnnotationValue()) { 2270212904Sdim ParsedType T = getTypeAnnotation(Tok); 2271218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, 2272239462Sdim Tok.getAnnotationEndLoc(), 2273212904Sdim PrevSpec, DiagID, T); 2274212904Sdim } 2275198092Srdivacky else 2276198092Srdivacky DS.SetTypeSpecError(); 2277198092Srdivacky DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2278198092Srdivacky ConsumeToken(); // The typename 2279198092Srdivacky } 2280198092Srdivacky 2281193326Sed if (Next.isNot(tok::identifier)) 2282193326Sed goto DoneWithDeclSpec; 2283193326Sed 2284202379Srdivacky // If we're in a context where the identifier could be a class name, 2285202379Srdivacky // check whether this is a constructor declaration. 2286207619Srdivacky if ((DSContext == DSC_top_level || 2287207619Srdivacky (DSContext == DSC_class && DS.isFriendSpecified())) && 2288239462Sdim Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 2289202379Srdivacky &SS)) { 2290202379Srdivacky if (isConstructorDeclarator()) 2291202379Srdivacky goto DoneWithDeclSpec; 2292193326Sed 2293202379Srdivacky // As noted in C++ [class.qual]p2 (cited above), when the name 2294202379Srdivacky // of the class is qualified in a context where it could name 2295202379Srdivacky // a constructor, its a constructor name. However, we've 2296202379Srdivacky // looked at the declarator, and the user probably meant this 2297202379Srdivacky // to be a type. Complain that it isn't supposed to be treated 2298202379Srdivacky // as a type, then proceed to parse it as a type. 2299202379Srdivacky Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) 2300202379Srdivacky << Next.getIdentifierInfo(); 2301202379Srdivacky } 2302202379Srdivacky 2303212904Sdim ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), 2304212904Sdim Next.getLocation(), 2305221345Sdim getCurScope(), &SS, 2306221345Sdim false, false, ParsedType(), 2307234353Sdim /*IsCtorOrDtorName=*/false, 2308221345Sdim /*NonTrivialSourceInfo=*/true); 2309193326Sed 2310193326Sed // If the referenced identifier is not a type, then this declspec is 2311193326Sed // erroneous: We already checked about that it has no type specifier, and 2312193326Sed // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the 2313198092Srdivacky // typename. 2314193326Sed if (TypeRep == 0) { 2315193326Sed ConsumeToken(); // Eat the scope spec so the identifier is current. 2316234353Sdim if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue; 2317193326Sed goto DoneWithDeclSpec; 2318193326Sed } 2319198092Srdivacky 2320200583Srdivacky DS.getTypeSpecScope() = SS; 2321193326Sed ConsumeToken(); // The C++ scope. 2322193326Sed 2323193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2324198092Srdivacky DiagID, TypeRep); 2325193326Sed if (isInvalid) 2326193326Sed break; 2327198092Srdivacky 2328193326Sed DS.SetRangeEnd(Tok.getLocation()); 2329193326Sed ConsumeToken(); // The typename. 2330193326Sed 2331193326Sed continue; 2332193326Sed } 2333198092Srdivacky 2334193326Sed case tok::annot_typename: { 2335212904Sdim if (Tok.getAnnotationValue()) { 2336212904Sdim ParsedType T = getTypeAnnotation(Tok); 2337193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2338212904Sdim DiagID, T); 2339212904Sdim } else 2340193326Sed DS.SetTypeSpecError(); 2341239462Sdim 2342206275Srdivacky if (isInvalid) 2343206275Srdivacky break; 2344206275Srdivacky 2345193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 2346193326Sed ConsumeToken(); // The typename 2347198092Srdivacky 2348193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2349193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2350239462Sdim // Objective-C interface. 2351234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2352218893Sdim ParseObjCProtocolQualifiers(DS); 2353239462Sdim 2354193326Sed continue; 2355193326Sed } 2356198092Srdivacky 2357221345Sdim case tok::kw___is_signed: 2358221345Sdim // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang 2359221345Sdim // typically treats it as a trait. If we see __is_signed as it appears 2360221345Sdim // in libstdc++, e.g., 2361221345Sdim // 2362221345Sdim // static const bool __is_signed; 2363221345Sdim // 2364221345Sdim // then treat __is_signed as an identifier rather than as a keyword. 2365221345Sdim if (DS.getTypeSpecType() == TST_bool && 2366221345Sdim DS.getTypeQualifiers() == DeclSpec::TQ_const && 2367221345Sdim DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2368221345Sdim Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 2369221345Sdim Tok.setKind(tok::identifier); 2370221345Sdim } 2371221345Sdim 2372221345Sdim // We're done with the declaration-specifiers. 2373221345Sdim goto DoneWithDeclSpec; 2374239462Sdim 2375193326Sed // typedef-name 2376234353Sdim case tok::kw_decltype: 2377193326Sed case tok::identifier: { 2378193326Sed // In C++, check to see if this is a scope specifier like foo::bar::, if 2379193326Sed // so handle it as such. This is important for ctor parsing. 2380234353Sdim if (getLangOpts().CPlusPlus) { 2381204643Srdivacky if (TryAnnotateCXXScopeToken(true)) { 2382204643Srdivacky if (!DS.hasTypeSpecifier()) 2383204643Srdivacky DS.SetTypeSpecError(); 2384204643Srdivacky goto DoneWithDeclSpec; 2385204643Srdivacky } 2386204643Srdivacky if (!Tok.is(tok::identifier)) 2387204643Srdivacky continue; 2388204643Srdivacky } 2389198092Srdivacky 2390193326Sed // This identifier can only be a typedef name if we haven't already seen 2391193326Sed // a type-specifier. Without this check we misparse: 2392193326Sed // typedef int X; struct Y { short X; }; as 'short int'. 2393193326Sed if (DS.hasTypeSpecifier()) 2394193326Sed goto DoneWithDeclSpec; 2395198092Srdivacky 2396203955Srdivacky // Check for need to substitute AltiVec keyword tokens. 2397203955Srdivacky if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) 2398203955Srdivacky break; 2399203955Srdivacky 2400239462Sdim // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not 2401239462Sdim // allow the use of a typedef name as a type specifier. 2402239462Sdim if (DS.isTypeAltiVecVector()) 2403239462Sdim goto DoneWithDeclSpec; 2404239462Sdim 2405212904Sdim ParsedType TypeRep = 2406212904Sdim Actions.getTypeName(*Tok.getIdentifierInfo(), 2407212904Sdim Tok.getLocation(), getCurScope()); 2408193326Sed 2409193326Sed // If this is not a typedef name, don't parse it as part of the declspec, 2410193326Sed // it must be an implicit int or an error. 2411212904Sdim if (!TypeRep) { 2412234353Sdim if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue; 2413193326Sed goto DoneWithDeclSpec; 2414193326Sed } 2415193326Sed 2416202379Srdivacky // If we're in a context where the identifier could be a class name, 2417202379Srdivacky // check whether this is a constructor declaration. 2418234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2419210299Sed Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) && 2420202379Srdivacky isConstructorDeclarator()) 2421193326Sed goto DoneWithDeclSpec; 2422193326Sed 2423193326Sed isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 2424198092Srdivacky DiagID, TypeRep); 2425193326Sed if (isInvalid) 2426193326Sed break; 2427198092Srdivacky 2428193326Sed DS.SetRangeEnd(Tok.getLocation()); 2429193326Sed ConsumeToken(); // The identifier 2430193326Sed 2431193326Sed // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 2432193326Sed // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 2433239462Sdim // Objective-C interface. 2434234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 2435218893Sdim ParseObjCProtocolQualifiers(DS); 2436239462Sdim 2437193326Sed // Need to support trailing type qualifiers (e.g. "id<p> const"). 2438193326Sed // If a type specifier follows, it will be diagnosed elsewhere. 2439193326Sed continue; 2440193326Sed } 2441193326Sed 2442193326Sed // type-name 2443193326Sed case tok::annot_template_id: { 2444224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2445193326Sed if (TemplateId->Kind != TNK_Type_template) { 2446193326Sed // This template-id does not refer to a type name, so we're 2447193326Sed // done with the type-specifiers. 2448193326Sed goto DoneWithDeclSpec; 2449193326Sed } 2450193326Sed 2451202379Srdivacky // If we're in a context where the template-id could be a 2452202379Srdivacky // constructor name or specialization, check whether this is a 2453202379Srdivacky // constructor declaration. 2454234353Sdim if (getLangOpts().CPlusPlus && DSContext == DSC_class && 2455210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) && 2456202379Srdivacky isConstructorDeclarator()) 2457202379Srdivacky goto DoneWithDeclSpec; 2458202379Srdivacky 2459193326Sed // Turn the template-id annotation token into a type annotation 2460193326Sed // token, then try again to parse it as a type-specifier. 2461193326Sed AnnotateTemplateIdTokenAsType(); 2462193326Sed continue; 2463193326Sed } 2464193326Sed 2465193326Sed // GNU attributes support. 2466193326Sed case tok::kw___attribute: 2467234353Sdim ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs); 2468193326Sed continue; 2469193326Sed 2470193326Sed // Microsoft declspec support. 2471193326Sed case tok::kw___declspec: 2472218893Sdim ParseMicrosoftDeclSpec(DS.getAttributes()); 2473193326Sed continue; 2474198092Srdivacky 2475193326Sed // Microsoft single token adornments. 2476239462Sdim case tok::kw___forceinline: { 2477239462Sdim isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID); 2478239462Sdim IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 2479239462Sdim SourceLocation AttrNameLoc = ConsumeToken(); 2480239462Sdim // FIXME: This does not work correctly if it is set to be a declspec 2481239462Sdim // attribute, and a GNU attribute is simply incorrect. 2482239462Sdim DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 2483239462Sdim SourceLocation(), 0, 0, AttributeList::AS_GNU); 2484239462Sdim continue; 2485239462Sdim } 2486194179Sed 2487194179Sed case tok::kw___ptr64: 2488226633Sdim case tok::kw___ptr32: 2489193326Sed case tok::kw___w64: 2490193326Sed case tok::kw___cdecl: 2491193326Sed case tok::kw___stdcall: 2492193326Sed case tok::kw___fastcall: 2493208600Srdivacky case tok::kw___thiscall: 2494226633Sdim case tok::kw___unaligned: 2495218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 2496194179Sed continue; 2497194179Sed 2498212904Sdim // Borland single token adornments. 2499212904Sdim case tok::kw___pascal: 2500218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 2501212904Sdim continue; 2502212904Sdim 2503218893Sdim // OpenCL single token adornments. 2504218893Sdim case tok::kw___kernel: 2505218893Sdim ParseOpenCLAttributes(DS.getAttributes()); 2506218893Sdim continue; 2507218893Sdim 2508193326Sed // storage-class-specifier 2509193326Sed case tok::kw_typedef: 2510226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, 2511226633Sdim PrevSpec, DiagID); 2512193326Sed break; 2513193326Sed case tok::kw_extern: 2514193326Sed if (DS.isThreadSpecified()) 2515193326Sed Diag(Tok, diag::ext_thread_before) << "extern"; 2516226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc, 2517226633Sdim PrevSpec, DiagID); 2518193326Sed break; 2519193326Sed case tok::kw___private_extern__: 2520226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern, 2521226633Sdim Loc, PrevSpec, DiagID); 2522193326Sed break; 2523193326Sed case tok::kw_static: 2524193326Sed if (DS.isThreadSpecified()) 2525193326Sed Diag(Tok, diag::ext_thread_before) << "static"; 2526226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc, 2527226633Sdim PrevSpec, DiagID); 2528193326Sed break; 2529193326Sed case tok::kw_auto: 2530234353Sdim if (getLangOpts().CPlusPlus0x) { 2531219077Sdim if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { 2532226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2533226633Sdim PrevSpec, DiagID); 2534219077Sdim if (!isInvalid) 2535226633Sdim Diag(Tok, diag::ext_auto_storage_class) 2536219077Sdim << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); 2537226633Sdim } else 2538219077Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, 2539219077Sdim DiagID); 2540226633Sdim } else 2541226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc, 2542226633Sdim PrevSpec, DiagID); 2543193326Sed break; 2544193326Sed case tok::kw_register: 2545226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, 2546226633Sdim PrevSpec, DiagID); 2547193326Sed break; 2548193326Sed case tok::kw_mutable: 2549226633Sdim isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc, 2550226633Sdim PrevSpec, DiagID); 2551193326Sed break; 2552193326Sed case tok::kw___thread: 2553198092Srdivacky isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID); 2554193326Sed break; 2555198092Srdivacky 2556193326Sed // function-specifier 2557193326Sed case tok::kw_inline: 2558198092Srdivacky isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID); 2559193326Sed break; 2560193326Sed case tok::kw_virtual: 2561198092Srdivacky isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID); 2562193326Sed break; 2563193326Sed case tok::kw_explicit: 2564198092Srdivacky isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID); 2565193326Sed break; 2566193326Sed 2567226633Sdim // alignment-specifier 2568226633Sdim case tok::kw__Alignas: 2569234353Sdim if (!getLangOpts().C11) 2570239462Sdim Diag(Tok, diag::ext_c11_alignment) << Tok.getName(); 2571226633Sdim ParseAlignmentSpecifier(DS.getAttributes()); 2572226633Sdim continue; 2573226633Sdim 2574193326Sed // friend 2575193326Sed case tok::kw_friend: 2576198092Srdivacky if (DSContext == DSC_class) 2577198092Srdivacky isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); 2578198092Srdivacky else { 2579198092Srdivacky PrevSpec = ""; // not actually used by the diagnostic 2580198092Srdivacky DiagID = diag::err_friend_invalid_in_context; 2581198092Srdivacky isInvalid = true; 2582198092Srdivacky } 2583193326Sed break; 2584198092Srdivacky 2585226633Sdim // Modules 2586226633Sdim case tok::kw___module_private__: 2587226633Sdim isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); 2588226633Sdim break; 2589239462Sdim 2590198954Srdivacky // constexpr 2591198954Srdivacky case tok::kw_constexpr: 2592198954Srdivacky isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); 2593198954Srdivacky break; 2594198954Srdivacky 2595193326Sed // type-specifier 2596193326Sed case tok::kw_short: 2597198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, 2598198092Srdivacky DiagID); 2599193326Sed break; 2600193326Sed case tok::kw_long: 2601193326Sed if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) 2602198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, 2603198092Srdivacky DiagID); 2604193326Sed else 2605198092Srdivacky isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2606198092Srdivacky DiagID); 2607193326Sed break; 2608221345Sdim case tok::kw___int64: 2609221345Sdim isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, 2610221345Sdim DiagID); 2611221345Sdim break; 2612193326Sed case tok::kw_signed: 2613198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, 2614198092Srdivacky DiagID); 2615193326Sed break; 2616193326Sed case tok::kw_unsigned: 2617198092Srdivacky isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, 2618198092Srdivacky DiagID); 2619193326Sed break; 2620193326Sed case tok::kw__Complex: 2621198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec, 2622198092Srdivacky DiagID); 2623193326Sed break; 2624193326Sed case tok::kw__Imaginary: 2625198092Srdivacky isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec, 2626198092Srdivacky DiagID); 2627193326Sed break; 2628193326Sed case tok::kw_void: 2629198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, 2630198092Srdivacky DiagID); 2631193326Sed break; 2632193326Sed case tok::kw_char: 2633198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, 2634198092Srdivacky DiagID); 2635193326Sed break; 2636193326Sed case tok::kw_int: 2637198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, 2638198092Srdivacky DiagID); 2639193326Sed break; 2640234353Sdim case tok::kw___int128: 2641234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, 2642234353Sdim DiagID); 2643234353Sdim break; 2644234353Sdim case tok::kw_half: 2645234353Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, 2646234353Sdim DiagID); 2647234353Sdim break; 2648193326Sed case tok::kw_float: 2649198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, 2650198092Srdivacky DiagID); 2651193326Sed break; 2652193326Sed case tok::kw_double: 2653198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, 2654198092Srdivacky DiagID); 2655193326Sed break; 2656193326Sed case tok::kw_wchar_t: 2657198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, 2658198092Srdivacky DiagID); 2659193326Sed break; 2660198092Srdivacky case tok::kw_char16_t: 2661198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, 2662198092Srdivacky DiagID); 2663198092Srdivacky break; 2664198092Srdivacky case tok::kw_char32_t: 2665198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, 2666198092Srdivacky DiagID); 2667198092Srdivacky break; 2668193326Sed case tok::kw_bool: 2669193326Sed case tok::kw__Bool: 2670218893Sdim if (Tok.is(tok::kw_bool) && 2671218893Sdim DS.getTypeSpecType() != DeclSpec::TST_unspecified && 2672218893Sdim DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 2673218893Sdim PrevSpec = ""; // Not used by the diagnostic. 2674218893Sdim DiagID = diag::err_bool_redeclaration; 2675221345Sdim // For better error recovery. 2676221345Sdim Tok.setKind(tok::identifier); 2677218893Sdim isInvalid = true; 2678218893Sdim } else { 2679218893Sdim isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, 2680218893Sdim DiagID); 2681218893Sdim } 2682193326Sed break; 2683193326Sed case tok::kw__Decimal32: 2684198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec, 2685198092Srdivacky DiagID); 2686193326Sed break; 2687193326Sed case tok::kw__Decimal64: 2688198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec, 2689198092Srdivacky DiagID); 2690193326Sed break; 2691193326Sed case tok::kw__Decimal128: 2692198092Srdivacky isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, 2693198092Srdivacky DiagID); 2694193326Sed break; 2695203955Srdivacky case tok::kw___vector: 2696203955Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 2697203955Srdivacky break; 2698203955Srdivacky case tok::kw___pixel: 2699203955Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 2700203955Srdivacky break; 2701221345Sdim case tok::kw___unknown_anytype: 2702221345Sdim isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, 2703221345Sdim PrevSpec, DiagID); 2704221345Sdim break; 2705193326Sed 2706193326Sed // class-specifier: 2707193326Sed case tok::kw_class: 2708193326Sed case tok::kw_struct: 2709193326Sed case tok::kw_union: { 2710193326Sed tok::TokenKind Kind = Tok.getKind(); 2711193326Sed ConsumeToken(); 2712234353Sdim ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, 2713234353Sdim EnteringContext, DSContext); 2714193326Sed continue; 2715193326Sed } 2716193326Sed 2717193326Sed // enum-specifier: 2718193326Sed case tok::kw_enum: 2719193326Sed ConsumeToken(); 2720234353Sdim ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext); 2721193326Sed continue; 2722193326Sed 2723193326Sed // cv-qualifier: 2724193326Sed case tok::kw_const: 2725198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID, 2726239462Sdim getLangOpts(), /*IsTypeSpec*/true); 2727193326Sed break; 2728193326Sed case tok::kw_volatile: 2729198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 2730239462Sdim getLangOpts(), /*IsTypeSpec*/true); 2731193326Sed break; 2732193326Sed case tok::kw_restrict: 2733198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 2734239462Sdim getLangOpts(), /*IsTypeSpec*/true); 2735193326Sed break; 2736193326Sed 2737193326Sed // C++ typename-specifier: 2738193326Sed case tok::kw_typename: 2739204643Srdivacky if (TryAnnotateTypeOrScopeToken()) { 2740204643Srdivacky DS.SetTypeSpecError(); 2741204643Srdivacky goto DoneWithDeclSpec; 2742204643Srdivacky } 2743204643Srdivacky if (!Tok.is(tok::kw_typename)) 2744193326Sed continue; 2745193326Sed break; 2746193326Sed 2747193326Sed // GNU typeof support. 2748193326Sed case tok::kw_typeof: 2749193326Sed ParseTypeofSpecifier(DS); 2750193326Sed continue; 2751193326Sed 2752234353Sdim case tok::annot_decltype: 2753195099Sed ParseDecltypeSpecifier(DS); 2754195099Sed continue; 2755195099Sed 2756223017Sdim case tok::kw___underlying_type: 2757223017Sdim ParseUnderlyingTypeSpecifier(DS); 2758226633Sdim continue; 2759223017Sdim 2760226633Sdim case tok::kw__Atomic: 2761226633Sdim ParseAtomicSpecifier(DS); 2762226633Sdim continue; 2763226633Sdim 2764221345Sdim // OpenCL qualifiers: 2765239462Sdim case tok::kw_private: 2766234353Sdim if (!getLangOpts().OpenCL) 2767221345Sdim goto DoneWithDeclSpec; 2768221345Sdim case tok::kw___private: 2769221345Sdim case tok::kw___global: 2770221345Sdim case tok::kw___local: 2771221345Sdim case tok::kw___constant: 2772221345Sdim case tok::kw___read_only: 2773221345Sdim case tok::kw___write_only: 2774221345Sdim case tok::kw___read_write: 2775221345Sdim ParseOpenCLQualifiers(DS); 2776221345Sdim break; 2777239462Sdim 2778193326Sed case tok::less: 2779193326Sed // GCC ObjC supports types like "<SomeProtocol>" as a synonym for 2780193326Sed // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous, 2781193326Sed // but we support it. 2782234353Sdim if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1) 2783193326Sed goto DoneWithDeclSpec; 2784198092Srdivacky 2785218893Sdim if (!ParseObjCProtocolQualifiers(DS)) 2786193326Sed Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) 2787206084Srdivacky << FixItHint::CreateInsertion(Loc, "id") 2788218893Sdim << SourceRange(Loc, DS.getSourceRange().getEnd()); 2789239462Sdim 2790218893Sdim // Need to support trailing type qualifiers (e.g. "id<p> const"). 2791218893Sdim // If a type specifier follows, it will be diagnosed elsewhere. 2792218893Sdim continue; 2793193326Sed } 2794198092Srdivacky // If the specifier wasn't legal, issue a diagnostic. 2795193326Sed if (isInvalid) { 2796193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 2797198092Srdivacky assert(DiagID); 2798239462Sdim 2799212904Sdim if (DiagID == diag::ext_duplicate_declspec) 2800212904Sdim Diag(Tok, DiagID) 2801212904Sdim << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); 2802212904Sdim else 2803212904Sdim Diag(Tok, DiagID) << PrevSpec; 2804193326Sed } 2805219077Sdim 2806193326Sed DS.SetRangeEnd(Tok.getLocation()); 2807221345Sdim if (DiagID != diag::err_bool_redeclaration) 2808221345Sdim ConsumeToken(); 2809239462Sdim 2810239462Sdim AttrsLastTime = false; 2811193326Sed } 2812193326Sed} 2813193326Sed 2814193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating 2815193326Sed/// semicolon. 2816193326Sed/// 2817193326Sed/// struct-declaration: 2818193326Sed/// specifier-qualifier-list struct-declarator-list 2819193326Sed/// [GNU] __extension__ struct-declaration 2820193326Sed/// [GNU] specifier-qualifier-list 2821193326Sed/// struct-declarator-list: 2822193326Sed/// struct-declarator 2823193326Sed/// struct-declarator-list ',' struct-declarator 2824193326Sed/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator 2825193326Sed/// struct-declarator: 2826193326Sed/// declarator 2827193326Sed/// [GNU] declarator attributes[opt] 2828193326Sed/// declarator[opt] ':' constant-expression 2829193326Sed/// [GNU] declarator[opt] ':' constant-expression attributes[opt] 2830193326Sed/// 2831193326Sedvoid Parser:: 2832239462SdimParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) { 2833239462Sdim 2834193326Sed if (Tok.is(tok::kw___extension__)) { 2835193326Sed // __extension__ silences extension warnings in the subexpression. 2836193326Sed ExtensionRAIIObject O(Diags); // Use RAII to do this. 2837193326Sed ConsumeToken(); 2838193326Sed return ParseStructDeclaration(DS, Fields); 2839193326Sed } 2840198092Srdivacky 2841193326Sed // Parse the common specifier-qualifiers-list piece. 2842193326Sed ParseSpecifierQualifierList(DS); 2843198092Srdivacky 2844193326Sed // If there are no declarators, this is a free-standing declaration 2845193326Sed // specifier. Let the actions module cope with it. 2846193326Sed if (Tok.is(tok::semi)) { 2847239462Sdim Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, 2848239462Sdim DS); 2849239462Sdim DS.complete(TheDecl); 2850193326Sed return; 2851193326Sed } 2852193326Sed 2853193326Sed // Read struct-declarators until we find the semicolon. 2854198893Srdivacky bool FirstDeclarator = true; 2855234353Sdim SourceLocation CommaLoc; 2856193326Sed while (1) { 2857239462Sdim ParsingFieldDeclarator DeclaratorInfo(*this, DS); 2858234353Sdim DeclaratorInfo.D.setCommaLoc(CommaLoc); 2859198092Srdivacky 2860198893Srdivacky // Attributes are only allowed here on successive declarators. 2861218893Sdim if (!FirstDeclarator) 2862218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 2863198893Srdivacky 2864193326Sed /// struct-declarator: declarator 2865193326Sed /// struct-declarator: declarator[opt] ':' constant-expression 2866200583Srdivacky if (Tok.isNot(tok::colon)) { 2867200583Srdivacky // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 2868200583Srdivacky ColonProtectionRAIIObject X(*this); 2869193326Sed ParseDeclarator(DeclaratorInfo.D); 2870200583Srdivacky } 2871198092Srdivacky 2872193326Sed if (Tok.is(tok::colon)) { 2873193326Sed ConsumeToken(); 2874212904Sdim ExprResult Res(ParseConstantExpression()); 2875193326Sed if (Res.isInvalid()) 2876193326Sed SkipUntil(tok::semi, true, true); 2877193326Sed else 2878193326Sed DeclaratorInfo.BitfieldSize = Res.release(); 2879193326Sed } 2880193326Sed 2881193326Sed // If attributes exist after the declarator, parse them. 2882218893Sdim MaybeParseGNUAttributes(DeclaratorInfo.D); 2883193326Sed 2884198893Srdivacky // We're done with this declarator; invoke the callback. 2885239462Sdim Fields.invoke(DeclaratorInfo); 2886198893Srdivacky 2887193326Sed // If we don't have a comma, it is either the end of the list (a ';') 2888193326Sed // or an error, bail out. 2889193326Sed if (Tok.isNot(tok::comma)) 2890193326Sed return; 2891193326Sed 2892193326Sed // Consume the comma. 2893234353Sdim CommaLoc = ConsumeToken(); 2894193326Sed 2895198893Srdivacky FirstDeclarator = false; 2896193326Sed } 2897193326Sed} 2898193326Sed 2899193326Sed/// ParseStructUnionBody 2900193326Sed/// struct-contents: 2901193326Sed/// struct-declaration-list 2902193326Sed/// [EXT] empty 2903193326Sed/// [GNU] "struct-declaration-list" without terminatoring ';' 2904193326Sed/// struct-declaration-list: 2905193326Sed/// struct-declaration 2906193326Sed/// struct-declaration-list struct-declaration 2907193326Sed/// [OBC] '@' 'defs' '(' class-name ')' 2908193326Sed/// 2909193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc, 2910212904Sdim unsigned TagType, Decl *TagDecl) { 2911212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2912212904Sdim "parsing struct/union body"); 2913198092Srdivacky 2914226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 2915226633Sdim if (T.consumeOpen()) 2916226633Sdim return; 2917198092Srdivacky 2918193326Sed ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); 2919210299Sed Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2920193326Sed 2921193326Sed // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in 2922193326Sed // C++. 2923234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) { 2924234353Sdim Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union); 2925234353Sdim Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union); 2926234353Sdim } 2927193326Sed 2928226633Sdim SmallVector<Decl *, 32> FieldDecls; 2929193326Sed 2930193326Sed // While we still have something to read, read the declarations in the struct. 2931193326Sed while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 2932193326Sed // Each iteration of this loop reads one struct-declaration. 2933198092Srdivacky 2934193326Sed // Check for extraneous top-level semicolon. 2935193326Sed if (Tok.is(tok::semi)) { 2936239462Sdim ConsumeExtraSemi(InsideStruct, TagType); 2937193326Sed continue; 2938193326Sed } 2939193326Sed 2940193326Sed if (!Tok.is(tok::at)) { 2941198893Srdivacky struct CFieldCallback : FieldCallback { 2942198893Srdivacky Parser &P; 2943212904Sdim Decl *TagDecl; 2944226633Sdim SmallVectorImpl<Decl *> &FieldDecls; 2945198092Srdivacky 2946212904Sdim CFieldCallback(Parser &P, Decl *TagDecl, 2947226633Sdim SmallVectorImpl<Decl *> &FieldDecls) : 2948198893Srdivacky P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} 2949198893Srdivacky 2950239462Sdim void invoke(ParsingFieldDeclarator &FD) { 2951198893Srdivacky // Install the declarator into the current TagDecl. 2952212904Sdim Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, 2953198893Srdivacky FD.D.getDeclSpec().getSourceRange().getBegin(), 2954198893Srdivacky FD.D, FD.BitfieldSize); 2955198893Srdivacky FieldDecls.push_back(Field); 2956239462Sdim FD.complete(Field); 2957198092Srdivacky } 2958198893Srdivacky } Callback(*this, TagDecl, FieldDecls); 2959198893Srdivacky 2960239462Sdim // Parse all the comma separated declarators. 2961239462Sdim ParsingDeclSpec DS(*this); 2962198893Srdivacky ParseStructDeclaration(DS, Callback); 2963193326Sed } else { // Handle @defs 2964193326Sed ConsumeToken(); 2965193326Sed if (!Tok.isObjCAtKeyword(tok::objc_defs)) { 2966193326Sed Diag(Tok, diag::err_unexpected_at); 2967203955Srdivacky SkipUntil(tok::semi, true); 2968193326Sed continue; 2969193326Sed } 2970193326Sed ConsumeToken(); 2971193326Sed ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); 2972193326Sed if (!Tok.is(tok::identifier)) { 2973193326Sed Diag(Tok, diag::err_expected_ident); 2974203955Srdivacky SkipUntil(tok::semi, true); 2975193326Sed continue; 2976193326Sed } 2977226633Sdim SmallVector<Decl *, 16> Fields; 2978210299Sed Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), 2979193326Sed Tok.getIdentifierInfo(), Fields); 2980193326Sed FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); 2981193326Sed ConsumeToken(); 2982193326Sed ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); 2983198092Srdivacky } 2984193326Sed 2985193326Sed if (Tok.is(tok::semi)) { 2986193326Sed ConsumeToken(); 2987193326Sed } else if (Tok.is(tok::r_brace)) { 2988203955Srdivacky ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); 2989193326Sed break; 2990193326Sed } else { 2991203955Srdivacky ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 2992203955Srdivacky // Skip to end of block or statement to avoid ext-warning on extra ';'. 2993193326Sed SkipUntil(tok::r_brace, true, true); 2994203955Srdivacky // If we stopped at a ';', eat it. 2995203955Srdivacky if (Tok.is(tok::semi)) ConsumeToken(); 2996193326Sed } 2997193326Sed } 2998198092Srdivacky 2999226633Sdim T.consumeClose(); 3000198092Srdivacky 3001221345Sdim ParsedAttributes attrs(AttrFactory); 3002193326Sed // If attributes exist after struct contents, parse them. 3003218893Sdim MaybeParseGNUAttributes(attrs); 3004193326Sed 3005210299Sed Actions.ActOnFields(getCurScope(), 3006226633Sdim RecordLoc, TagDecl, FieldDecls, 3007226633Sdim T.getOpenLocation(), T.getCloseLocation(), 3008218893Sdim attrs.getList()); 3009193326Sed StructScope.Exit(); 3010226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 3011226633Sdim T.getCloseLocation()); 3012193326Sed} 3013193326Sed 3014193326Sed/// ParseEnumSpecifier 3015193326Sed/// enum-specifier: [C99 6.7.2.2] 3016193326Sed/// 'enum' identifier[opt] '{' enumerator-list '}' 3017193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}' 3018193326Sed/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt] 3019193326Sed/// '}' attributes[opt] 3020234353Sdim/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt] 3021234353Sdim/// '}' 3022193326Sed/// 'enum' identifier 3023193326Sed/// [GNU] 'enum' attributes[opt] identifier 3024193326Sed/// 3025234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}' 3026234353Sdim/// [C++11] enum-head '{' enumerator-list ',' '}' 3027218893Sdim/// 3028234353Sdim/// enum-head: [C++11] 3029234353Sdim/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt] 3030234353Sdim/// enum-key attribute-specifier-seq[opt] nested-name-specifier 3031234353Sdim/// identifier enum-base[opt] 3032218893Sdim/// 3033234353Sdim/// enum-key: [C++11] 3034218893Sdim/// 'enum' 3035218893Sdim/// 'enum' 'class' 3036218893Sdim/// 'enum' 'struct' 3037218893Sdim/// 3038234353Sdim/// enum-base: [C++11] 3039218893Sdim/// ':' type-specifier-seq 3040218893Sdim/// 3041193326Sed/// [C++] elaborated-type-specifier: 3042193326Sed/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier 3043193326Sed/// 3044193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, 3045204643Srdivacky const ParsedTemplateInfo &TemplateInfo, 3046234353Sdim AccessSpecifier AS, DeclSpecContext DSC) { 3047193326Sed // Parse the tag portion of this. 3048198092Srdivacky if (Tok.is(tok::code_completion)) { 3049198092Srdivacky // Code completion for an enum name. 3050210299Sed Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); 3051226633Sdim return cutOffParsing(); 3052198092Srdivacky } 3053224145Sdim 3054239462Sdim // If attributes exist after tag, parse them. 3055239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3056239462Sdim MaybeParseGNUAttributes(attrs); 3057239462Sdim MaybeParseCXX0XAttributes(attrs); 3058239462Sdim 3059239462Sdim // If declspecs exist after tag, parse them. 3060239462Sdim while (Tok.is(tok::kw___declspec)) 3061239462Sdim ParseMicrosoftDeclSpec(attrs); 3062239462Sdim 3063234353Sdim SourceLocation ScopedEnumKWLoc; 3064224145Sdim bool IsScopedUsingClassTag = false; 3065224145Sdim 3066239462Sdim // In C++11, recognize 'enum class' and 'enum struct'. 3067234353Sdim if (getLangOpts().CPlusPlus0x && 3068224145Sdim (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) { 3069234353Sdim Diag(Tok, diag::warn_cxx98_compat_scoped_enum); 3070224145Sdim IsScopedUsingClassTag = Tok.is(tok::kw_class); 3071234353Sdim ScopedEnumKWLoc = ConsumeToken(); 3072234353Sdim 3073239462Sdim // Attributes are not allowed between these keywords. Diagnose, 3074239462Sdim // but then just treat them like they appeared in the right place. 3075239462Sdim ProhibitAttributes(attrs); 3076234353Sdim 3077239462Sdim // They are allowed afterwards, though. 3078239462Sdim MaybeParseGNUAttributes(attrs); 3079239462Sdim MaybeParseCXX0XAttributes(attrs); 3080239462Sdim while (Tok.is(tok::kw___declspec)) 3081239462Sdim ParseMicrosoftDeclSpec(attrs); 3082239462Sdim } 3083193326Sed 3084239462Sdim // C++11 [temp.explicit]p12: 3085239462Sdim // The usual access controls do not apply to names used to specify 3086239462Sdim // explicit instantiations. 3087239462Sdim // We extend this to also cover explicit specializations. Note that 3088239462Sdim // we don't suppress if this turns out to be an elaborated type 3089239462Sdim // specifier. 3090239462Sdim bool shouldDelayDiagsInTag = 3091239462Sdim (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 3092239462Sdim TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 3093239462Sdim SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 3094224145Sdim 3095234353Sdim // Enum definitions should not be parsed in a trailing-return-type. 3096234353Sdim bool AllowDeclaration = DSC != DSC_trailing; 3097234353Sdim 3098234353Sdim bool AllowFixedUnderlyingType = AllowDeclaration && 3099234353Sdim (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt || 3100234353Sdim getLangOpts().ObjC2); 3101234353Sdim 3102208600Srdivacky CXXScopeSpec &SS = DS.getTypeSpecScope(); 3103234353Sdim if (getLangOpts().CPlusPlus) { 3104224145Sdim // "enum foo : bar;" is not a potential typo for "enum foo::bar;" 3105224145Sdim // if a fixed underlying type is allowed. 3106224145Sdim ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); 3107239462Sdim 3108239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3109234353Sdim /*EnteringContext=*/false)) 3110204643Srdivacky return; 3111204643Srdivacky 3112204643Srdivacky if (SS.isSet() && Tok.isNot(tok::identifier)) { 3113193326Sed Diag(Tok, diag::err_expected_ident); 3114193326Sed if (Tok.isNot(tok::l_brace)) { 3115193326Sed // Has no name and is not a definition. 3116193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3117193326Sed SkipUntil(tok::comma, true); 3118193326Sed return; 3119193326Sed } 3120193326Sed } 3121193326Sed } 3122198092Srdivacky 3123193326Sed // Must have either 'enum name' or 'enum {...}'. 3124219077Sdim if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && 3125234353Sdim !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { 3126193326Sed Diag(Tok, diag::err_expected_ident_lbrace); 3127198092Srdivacky 3128193326Sed // Skip the rest of this declarator, up until the comma or semicolon. 3129193326Sed SkipUntil(tok::comma, true); 3130193326Sed return; 3131193326Sed } 3132198092Srdivacky 3133193326Sed // If an identifier is present, consume and remember it. 3134193326Sed IdentifierInfo *Name = 0; 3135193326Sed SourceLocation NameLoc; 3136193326Sed if (Tok.is(tok::identifier)) { 3137193326Sed Name = Tok.getIdentifierInfo(); 3138193326Sed NameLoc = ConsumeToken(); 3139193326Sed } 3140198092Srdivacky 3141234353Sdim if (!Name && ScopedEnumKWLoc.isValid()) { 3142218893Sdim // C++0x 7.2p2: The optional identifier shall not be omitted in the 3143218893Sdim // declaration of a scoped enumeration. 3144218893Sdim Diag(Tok, diag::err_scoped_enum_missing_identifier); 3145234353Sdim ScopedEnumKWLoc = SourceLocation(); 3146218893Sdim IsScopedUsingClassTag = false; 3147218893Sdim } 3148218893Sdim 3149239462Sdim // Okay, end the suppression area. We'll decide whether to emit the 3150239462Sdim // diagnostics in a second. 3151239462Sdim if (shouldDelayDiagsInTag) 3152239462Sdim diagsFromTag.done(); 3153234353Sdim 3154218893Sdim TypeResult BaseType; 3155218893Sdim 3156218893Sdim // Parse the fixed underlying type. 3157239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3158219077Sdim if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { 3159218893Sdim bool PossibleBitfield = false; 3160239462Sdim if (CanBeBitfield) { 3161218893Sdim // If we're in class scope, this can either be an enum declaration with 3162218893Sdim // an underlying type, or a declaration of a bitfield member. We try to 3163218893Sdim // use a simple disambiguation scheme first to catch the common cases 3164239462Sdim // (integer literal, sizeof); if it's still ambiguous, we then consider 3165239462Sdim // anything that's a simple-type-specifier followed by '(' as an 3166239462Sdim // expression. This suffices because function types are not valid 3167218893Sdim // underlying types anyway. 3168218893Sdim TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind()); 3169239462Sdim // If the next token starts an expression, we know we're parsing a 3170218893Sdim // bit-field. This is the common case. 3171218893Sdim if (TPR == TPResult::True()) 3172218893Sdim PossibleBitfield = true; 3173218893Sdim // If the next token starts a type-specifier-seq, it may be either a 3174218893Sdim // a fixed underlying type or the start of a function-style cast in C++; 3175239462Sdim // lookahead one more token to see if it's obvious that we have a 3176218893Sdim // fixed underlying type. 3177239462Sdim else if (TPR == TPResult::False() && 3178218893Sdim GetLookAheadToken(2).getKind() == tok::semi) { 3179218893Sdim // Consume the ':'. 3180218893Sdim ConsumeToken(); 3181218893Sdim } else { 3182218893Sdim // We have the start of a type-specifier-seq, so we have to perform 3183218893Sdim // tentative parsing to determine whether we have an expression or a 3184218893Sdim // type. 3185218893Sdim TentativeParsingAction TPA(*this); 3186218893Sdim 3187218893Sdim // Consume the ':'. 3188218893Sdim ConsumeToken(); 3189234353Sdim 3190234353Sdim // If we see a type specifier followed by an open-brace, we have an 3191234353Sdim // ambiguity between an underlying type and a C++11 braced 3192234353Sdim // function-style cast. Resolve this by always treating it as an 3193234353Sdim // underlying type. 3194234353Sdim // FIXME: The standard is not entirely clear on how to disambiguate in 3195234353Sdim // this case. 3196234353Sdim if ((getLangOpts().CPlusPlus && 3197234353Sdim isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) || 3198234353Sdim (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) { 3199218893Sdim // We'll parse this as a bitfield later. 3200218893Sdim PossibleBitfield = true; 3201218893Sdim TPA.Revert(); 3202218893Sdim } else { 3203218893Sdim // We have a type-specifier-seq. 3204218893Sdim TPA.Commit(); 3205218893Sdim } 3206218893Sdim } 3207218893Sdim } else { 3208218893Sdim // Consume the ':'. 3209218893Sdim ConsumeToken(); 3210218893Sdim } 3211218893Sdim 3212218893Sdim if (!PossibleBitfield) { 3213218893Sdim SourceRange Range; 3214218893Sdim BaseType = ParseTypeName(&Range); 3215239462Sdim 3216234353Sdim if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2) 3217219077Sdim Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type) 3218219077Sdim << Range; 3219234353Sdim if (getLangOpts().CPlusPlus0x) 3220234353Sdim Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type); 3221218893Sdim } 3222218893Sdim } 3223218893Sdim 3224234353Sdim // There are four options here. If we have 'friend enum foo;' then this is a 3225234353Sdim // friend declaration, and cannot have an accompanying definition. If we have 3226234353Sdim // 'enum foo;', then this is a forward declaration. If we have 3227234353Sdim // 'enum foo {...' then this is a definition. Otherwise we have something 3228234353Sdim // like 'enum foo xyz', a reference. 3229193326Sed // 3230193326Sed // This is needed to handle stuff like this right (C99 6.7.2.3p11): 3231193326Sed // enum foo {..}; void bar() { enum foo; } <- new foo in bar. 3232193326Sed // enum foo {..}; void bar() { enum foo x; } <- use of old foo. 3233193326Sed // 3234212904Sdim Sema::TagUseKind TUK; 3235239462Sdim if (!AllowDeclaration) { 3236234353Sdim TUK = Sema::TUK_Reference; 3237239462Sdim } else if (Tok.is(tok::l_brace)) { 3238239462Sdim if (DS.isFriendSpecified()) { 3239239462Sdim Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 3240239462Sdim << SourceRange(DS.getFriendSpecLoc()); 3241239462Sdim ConsumeBrace(); 3242239462Sdim SkipUntil(tok::r_brace); 3243239462Sdim TUK = Sema::TUK_Friend; 3244239462Sdim } else { 3245239462Sdim TUK = Sema::TUK_Definition; 3246239462Sdim } 3247239462Sdim } else if (DSC != DSC_type_specifier && 3248239462Sdim (Tok.is(tok::semi) || 3249239462Sdim (Tok.isAtStartOfLine() && 3250239462Sdim !isValidAfterTypeSpecifier(CanBeBitfield)))) { 3251239462Sdim TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 3252239462Sdim if (Tok.isNot(tok::semi)) { 3253239462Sdim // A semicolon was missing after this declaration. Diagnose and recover. 3254239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 3255239462Sdim "enum"); 3256239462Sdim PP.EnterToken(Tok); 3257239462Sdim Tok.setKind(tok::semi); 3258239462Sdim } 3259239462Sdim } else { 3260212904Sdim TUK = Sema::TUK_Reference; 3261239462Sdim } 3262234353Sdim 3263239462Sdim // If this is an elaborated type specifier, and we delayed 3264239462Sdim // diagnostics before, just merge them into the current pool. 3265239462Sdim if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) { 3266239462Sdim diagsFromTag.redelay(); 3267239462Sdim } 3268239462Sdim 3269234353Sdim MultiTemplateParamsArg TParams; 3270207619Srdivacky if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 3271212904Sdim TUK != Sema::TUK_Reference) { 3272234353Sdim if (!getLangOpts().CPlusPlus0x || !SS.isSet()) { 3273234353Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3274234353Sdim Diag(Tok, diag::err_enum_template); 3275234353Sdim SkipUntil(tok::comma, true); 3276234353Sdim return; 3277234353Sdim } 3278234353Sdim 3279234353Sdim if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 3280234353Sdim // Enumerations can't be explicitly instantiated. 3281234353Sdim DS.SetTypeSpecError(); 3282234353Sdim Diag(StartLoc, diag::err_explicit_instantiation_enum); 3283234353Sdim return; 3284234353Sdim } 3285234353Sdim 3286234353Sdim assert(TemplateInfo.TemplateParams && "no template parameters"); 3287234353Sdim TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(), 3288234353Sdim TemplateInfo.TemplateParams->size()); 3289207619Srdivacky } 3290234353Sdim 3291239462Sdim if (TUK == Sema::TUK_Reference) 3292239462Sdim ProhibitAttributes(attrs); 3293239462Sdim 3294219077Sdim if (!Name && TUK != Sema::TUK_Definition) { 3295219077Sdim Diag(Tok, diag::err_enumerator_unnamed_no_def); 3296234353Sdim 3297219077Sdim // Skip the rest of this declarator, up until the comma or semicolon. 3298219077Sdim SkipUntil(tok::comma, true); 3299219077Sdim return; 3300219077Sdim } 3301234353Sdim 3302193326Sed bool Owned = false; 3303198092Srdivacky bool IsDependent = false; 3304207619Srdivacky const char *PrevSpec = 0; 3305207619Srdivacky unsigned DiagID; 3306212904Sdim Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, 3307218893Sdim StartLoc, SS, Name, NameLoc, attrs.getList(), 3308234353Sdim AS, DS.getModulePrivateSpecLoc(), TParams, 3309234353Sdim Owned, IsDependent, ScopedEnumKWLoc, 3310218893Sdim IsScopedUsingClassTag, BaseType); 3311218893Sdim 3312207619Srdivacky if (IsDependent) { 3313239462Sdim // This enum has a dependent nested-name-specifier. Handle it as a 3314207619Srdivacky // dependent tag. 3315207619Srdivacky if (!Name) { 3316207619Srdivacky DS.SetTypeSpecError(); 3317207619Srdivacky Diag(Tok, diag::err_expected_type_name_after_typename); 3318207619Srdivacky return; 3319207619Srdivacky } 3320239462Sdim 3321210299Sed TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum, 3322239462Sdim TUK, SS, Name, StartLoc, 3323207619Srdivacky NameLoc); 3324207619Srdivacky if (Type.isInvalid()) { 3325207619Srdivacky DS.SetTypeSpecError(); 3326207619Srdivacky return; 3327207619Srdivacky } 3328239462Sdim 3329221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 3330221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3331221345Sdim PrevSpec, DiagID, Type.get())) 3332207619Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3333239462Sdim 3334207619Srdivacky return; 3335207619Srdivacky } 3336198092Srdivacky 3337212904Sdim if (!TagDecl) { 3338239462Sdim // The action failed to produce an enumeration tag. If this is a 3339207619Srdivacky // definition, consume the entire definition. 3340234353Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { 3341207619Srdivacky ConsumeBrace(); 3342207619Srdivacky SkipUntil(tok::r_brace); 3343207619Srdivacky } 3344239462Sdim 3345207619Srdivacky DS.SetTypeSpecError(); 3346207619Srdivacky return; 3347207619Srdivacky } 3348198092Srdivacky 3349239462Sdim if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) 3350239462Sdim ParseEnumBody(StartLoc, TagDecl); 3351234353Sdim 3352221345Sdim if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, 3353221345Sdim NameLoc.isValid() ? NameLoc : StartLoc, 3354221345Sdim PrevSpec, DiagID, TagDecl, Owned)) 3355198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 3356193326Sed} 3357193326Sed 3358193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list. 3359193326Sed/// enumerator-list: 3360193326Sed/// enumerator 3361193326Sed/// enumerator-list ',' enumerator 3362193326Sed/// enumerator: 3363193326Sed/// enumeration-constant 3364193326Sed/// enumeration-constant '=' constant-expression 3365193326Sed/// enumeration-constant: 3366193326Sed/// identifier 3367193326Sed/// 3368212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { 3369193326Sed // Enter the scope of the enum body and start the definition. 3370193326Sed ParseScope EnumScope(this, Scope::DeclScope); 3371210299Sed Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); 3372193326Sed 3373226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 3374226633Sdim T.consumeOpen(); 3375198092Srdivacky 3376193326Sed // C does not allow an empty enumerator-list, C++ does [dcl.enum]. 3377234353Sdim if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) 3378210299Sed Diag(Tok, diag::error_empty_enum); 3379198092Srdivacky 3380226633Sdim SmallVector<Decl *, 32> EnumConstantDecls; 3381193326Sed 3382212904Sdim Decl *LastEnumConstDecl = 0; 3383198092Srdivacky 3384193326Sed // Parse the enumerator-list. 3385193326Sed while (Tok.is(tok::identifier)) { 3386193326Sed IdentifierInfo *Ident = Tok.getIdentifierInfo(); 3387193326Sed SourceLocation IdentLoc = ConsumeToken(); 3388198092Srdivacky 3389218893Sdim // If attributes exist after the enumerator, parse them. 3390239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 3391218893Sdim MaybeParseGNUAttributes(attrs); 3392239462Sdim MaybeParseCXX0XAttributes(attrs); 3393239462Sdim ProhibitAttributes(attrs); 3394218893Sdim 3395193326Sed SourceLocation EqualLoc; 3396212904Sdim ExprResult AssignedVal; 3397239462Sdim ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); 3398239462Sdim 3399193326Sed if (Tok.is(tok::equal)) { 3400193326Sed EqualLoc = ConsumeToken(); 3401193326Sed AssignedVal = ParseConstantExpression(); 3402193326Sed if (AssignedVal.isInvalid()) 3403193326Sed SkipUntil(tok::comma, tok::r_brace, true, true); 3404193326Sed } 3405198092Srdivacky 3406193326Sed // Install the enumerator constant into EnumDecl. 3407212904Sdim Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, 3408212904Sdim LastEnumConstDecl, 3409212904Sdim IdentLoc, Ident, 3410218893Sdim attrs.getList(), EqualLoc, 3411212904Sdim AssignedVal.release()); 3412234353Sdim PD.complete(EnumConstDecl); 3413239462Sdim 3414193326Sed EnumConstantDecls.push_back(EnumConstDecl); 3415193326Sed LastEnumConstDecl = EnumConstDecl; 3416198092Srdivacky 3417218893Sdim if (Tok.is(tok::identifier)) { 3418218893Sdim // We're missing a comma between enumerators. 3419218893Sdim SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 3420239462Sdim Diag(Loc, diag::err_enumerator_list_missing_comma) 3421218893Sdim << FixItHint::CreateInsertion(Loc, ", "); 3422218893Sdim continue; 3423218893Sdim } 3424239462Sdim 3425193326Sed if (Tok.isNot(tok::comma)) 3426193326Sed break; 3427193326Sed SourceLocation CommaLoc = ConsumeToken(); 3428198092Srdivacky 3429234353Sdim if (Tok.isNot(tok::identifier)) { 3430234353Sdim if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x) 3431239462Sdim Diag(CommaLoc, getLangOpts().CPlusPlus ? 3432239462Sdim diag::ext_enumerator_list_comma_cxx : 3433239462Sdim diag::ext_enumerator_list_comma_c) 3434234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3435234353Sdim else if (getLangOpts().CPlusPlus0x) 3436234353Sdim Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma) 3437234353Sdim << FixItHint::CreateRemoval(CommaLoc); 3438234353Sdim } 3439193326Sed } 3440198092Srdivacky 3441193326Sed // Eat the }. 3442226633Sdim T.consumeClose(); 3443193326Sed 3444193326Sed // If attributes exist after the identifier list, parse them. 3445221345Sdim ParsedAttributes attrs(AttrFactory); 3446218893Sdim MaybeParseGNUAttributes(attrs); 3447193326Sed 3448226633Sdim Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), 3449226633Sdim EnumDecl, EnumConstantDecls.data(), 3450226633Sdim EnumConstantDecls.size(), getCurScope(), 3451226633Sdim attrs.getList()); 3452198092Srdivacky 3453193326Sed EnumScope.Exit(); 3454226633Sdim Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, 3455226633Sdim T.getCloseLocation()); 3456239462Sdim 3457239462Sdim // The next token must be valid after an enum definition. If not, a ';' 3458239462Sdim // was probably forgotten. 3459239462Sdim bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope; 3460239462Sdim if (!isValidAfterTypeSpecifier(CanBeBitfield)) { 3461239462Sdim ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum"); 3462239462Sdim // Push this token back into the preprocessor and change our current token 3463239462Sdim // to ';' so that the rest of the code recovers as though there were an 3464239462Sdim // ';' after the definition. 3465239462Sdim PP.EnterToken(Tok); 3466239462Sdim Tok.setKind(tok::semi); 3467239462Sdim } 3468193326Sed} 3469193326Sed 3470193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3471193326Sed/// start of a type-qualifier-list. 3472193326Sedbool Parser::isTypeQualifier() const { 3473193326Sed switch (Tok.getKind()) { 3474193326Sed default: return false; 3475221345Sdim 3476221345Sdim // type-qualifier only in OpenCL 3477221345Sdim case tok::kw_private: 3478234353Sdim return getLangOpts().OpenCL; 3479221345Sdim 3480193326Sed // type-qualifier 3481193326Sed case tok::kw_const: 3482193326Sed case tok::kw_volatile: 3483193326Sed case tok::kw_restrict: 3484221345Sdim case tok::kw___private: 3485221345Sdim case tok::kw___local: 3486221345Sdim case tok::kw___global: 3487221345Sdim case tok::kw___constant: 3488221345Sdim case tok::kw___read_only: 3489221345Sdim case tok::kw___read_write: 3490221345Sdim case tok::kw___write_only: 3491193326Sed return true; 3492193326Sed } 3493193326Sed} 3494193326Sed 3495204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token 3496204643Srdivacky/// is definitely a type-specifier. Return false if it isn't part of a type 3497204643Srdivacky/// specifier or if we're not sure. 3498204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { 3499204643Srdivacky switch (Tok.getKind()) { 3500204643Srdivacky default: return false; 3501204643Srdivacky // type-specifiers 3502204643Srdivacky case tok::kw_short: 3503204643Srdivacky case tok::kw_long: 3504221345Sdim case tok::kw___int64: 3505234353Sdim case tok::kw___int128: 3506204643Srdivacky case tok::kw_signed: 3507204643Srdivacky case tok::kw_unsigned: 3508204643Srdivacky case tok::kw__Complex: 3509204643Srdivacky case tok::kw__Imaginary: 3510204643Srdivacky case tok::kw_void: 3511204643Srdivacky case tok::kw_char: 3512204643Srdivacky case tok::kw_wchar_t: 3513204643Srdivacky case tok::kw_char16_t: 3514204643Srdivacky case tok::kw_char32_t: 3515204643Srdivacky case tok::kw_int: 3516226633Sdim case tok::kw_half: 3517204643Srdivacky case tok::kw_float: 3518204643Srdivacky case tok::kw_double: 3519204643Srdivacky case tok::kw_bool: 3520204643Srdivacky case tok::kw__Bool: 3521204643Srdivacky case tok::kw__Decimal32: 3522204643Srdivacky case tok::kw__Decimal64: 3523204643Srdivacky case tok::kw__Decimal128: 3524204643Srdivacky case tok::kw___vector: 3525239462Sdim 3526204643Srdivacky // struct-or-union-specifier (C99) or class-specifier (C++) 3527204643Srdivacky case tok::kw_class: 3528204643Srdivacky case tok::kw_struct: 3529204643Srdivacky case tok::kw_union: 3530204643Srdivacky // enum-specifier 3531204643Srdivacky case tok::kw_enum: 3532239462Sdim 3533204643Srdivacky // typedef-name 3534204643Srdivacky case tok::annot_typename: 3535204643Srdivacky return true; 3536204643Srdivacky } 3537204643Srdivacky} 3538204643Srdivacky 3539193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the 3540193326Sed/// start of a specifier-qualifier-list. 3541193326Sedbool Parser::isTypeSpecifierQualifier() { 3542193326Sed switch (Tok.getKind()) { 3543193326Sed default: return false; 3544198092Srdivacky 3545193326Sed case tok::identifier: // foo::bar 3546203955Srdivacky if (TryAltiVecVectorToken()) 3547203955Srdivacky return true; 3548203955Srdivacky // Fall through. 3549193326Sed case tok::kw_typename: // typename T::type 3550193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3551193326Sed // recurse to handle whatever we get. 3552193326Sed if (TryAnnotateTypeOrScopeToken()) 3553204643Srdivacky return true; 3554204643Srdivacky if (Tok.is(tok::identifier)) 3555204643Srdivacky return false; 3556204643Srdivacky return isTypeSpecifierQualifier(); 3557193326Sed 3558193326Sed case tok::coloncolon: // ::foo::bar 3559193326Sed if (NextToken().is(tok::kw_new) || // ::new 3560193326Sed NextToken().is(tok::kw_delete)) // ::delete 3561193326Sed return false; 3562193326Sed 3563193326Sed if (TryAnnotateTypeOrScopeToken()) 3564204643Srdivacky return true; 3565204643Srdivacky return isTypeSpecifierQualifier(); 3566198092Srdivacky 3567193326Sed // GNU attributes support. 3568193326Sed case tok::kw___attribute: 3569193326Sed // GNU typeof support. 3570193326Sed case tok::kw_typeof: 3571198092Srdivacky 3572193326Sed // type-specifiers 3573193326Sed case tok::kw_short: 3574193326Sed case tok::kw_long: 3575221345Sdim case tok::kw___int64: 3576234353Sdim case tok::kw___int128: 3577193326Sed case tok::kw_signed: 3578193326Sed case tok::kw_unsigned: 3579193326Sed case tok::kw__Complex: 3580193326Sed case tok::kw__Imaginary: 3581193326Sed case tok::kw_void: 3582193326Sed case tok::kw_char: 3583193326Sed case tok::kw_wchar_t: 3584198092Srdivacky case tok::kw_char16_t: 3585198092Srdivacky case tok::kw_char32_t: 3586193326Sed case tok::kw_int: 3587226633Sdim case tok::kw_half: 3588193326Sed case tok::kw_float: 3589193326Sed case tok::kw_double: 3590193326Sed case tok::kw_bool: 3591193326Sed case tok::kw__Bool: 3592193326Sed case tok::kw__Decimal32: 3593193326Sed case tok::kw__Decimal64: 3594193326Sed case tok::kw__Decimal128: 3595203955Srdivacky case tok::kw___vector: 3596198092Srdivacky 3597193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 3598193326Sed case tok::kw_class: 3599193326Sed case tok::kw_struct: 3600193326Sed case tok::kw_union: 3601193326Sed // enum-specifier 3602193326Sed case tok::kw_enum: 3603198092Srdivacky 3604193326Sed // type-qualifier 3605193326Sed case tok::kw_const: 3606193326Sed case tok::kw_volatile: 3607193326Sed case tok::kw_restrict: 3608193326Sed 3609193326Sed // typedef-name 3610193326Sed case tok::annot_typename: 3611193326Sed return true; 3612198092Srdivacky 3613193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 3614193326Sed case tok::less: 3615234353Sdim return getLangOpts().ObjC1; 3616198092Srdivacky 3617193326Sed case tok::kw___cdecl: 3618193326Sed case tok::kw___stdcall: 3619193326Sed case tok::kw___fastcall: 3620208600Srdivacky case tok::kw___thiscall: 3621194179Sed case tok::kw___w64: 3622194179Sed case tok::kw___ptr64: 3623226633Sdim case tok::kw___ptr32: 3624212904Sdim case tok::kw___pascal: 3625226633Sdim case tok::kw___unaligned: 3626221345Sdim 3627221345Sdim case tok::kw___private: 3628221345Sdim case tok::kw___local: 3629221345Sdim case tok::kw___global: 3630221345Sdim case tok::kw___constant: 3631221345Sdim case tok::kw___read_only: 3632221345Sdim case tok::kw___read_write: 3633221345Sdim case tok::kw___write_only: 3634221345Sdim 3635194179Sed return true; 3636221345Sdim 3637221345Sdim case tok::kw_private: 3638234353Sdim return getLangOpts().OpenCL; 3639226633Sdim 3640234353Sdim // C11 _Atomic() 3641226633Sdim case tok::kw__Atomic: 3642226633Sdim return true; 3643193326Sed } 3644193326Sed} 3645193326Sed 3646193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a 3647193326Sed/// declaration specifier. 3648218893Sdim/// 3649218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of 3650218893Sdim/// this check is to disambiguate between an expression and a declaration. 3651218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { 3652193326Sed switch (Tok.getKind()) { 3653193326Sed default: return false; 3654198092Srdivacky 3655221345Sdim case tok::kw_private: 3656234353Sdim return getLangOpts().OpenCL; 3657221345Sdim 3658193326Sed case tok::identifier: // foo::bar 3659193326Sed // Unfortunate hack to support "Class.factoryMethod" notation. 3660234353Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::period)) 3661193326Sed return false; 3662203955Srdivacky if (TryAltiVecVectorToken()) 3663203955Srdivacky return true; 3664203955Srdivacky // Fall through. 3665234353Sdim case tok::kw_decltype: // decltype(T())::type 3666193326Sed case tok::kw_typename: // typename T::type 3667193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3668193326Sed // recurse to handle whatever we get. 3669193326Sed if (TryAnnotateTypeOrScopeToken()) 3670204643Srdivacky return true; 3671204643Srdivacky if (Tok.is(tok::identifier)) 3672204643Srdivacky return false; 3673239462Sdim 3674218893Sdim // If we're in Objective-C and we have an Objective-C class type followed 3675239462Sdim // by an identifier and then either ':' or ']', in a place where an 3676218893Sdim // expression is permitted, then this is probably a class message send 3677218893Sdim // missing the initial '['. In this case, we won't consider this to be 3678218893Sdim // the start of a declaration. 3679239462Sdim if (DisambiguatingWithExpression && 3680218893Sdim isStartOfObjCClassMessageMissingOpenBracket()) 3681218893Sdim return false; 3682239462Sdim 3683204643Srdivacky return isDeclarationSpecifier(); 3684204643Srdivacky 3685193326Sed case tok::coloncolon: // ::foo::bar 3686193326Sed if (NextToken().is(tok::kw_new) || // ::new 3687193326Sed NextToken().is(tok::kw_delete)) // ::delete 3688193326Sed return false; 3689198092Srdivacky 3690193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 3691193326Sed // recurse to handle whatever we get. 3692193326Sed if (TryAnnotateTypeOrScopeToken()) 3693204643Srdivacky return true; 3694204643Srdivacky return isDeclarationSpecifier(); 3695198092Srdivacky 3696193326Sed // storage-class-specifier 3697193326Sed case tok::kw_typedef: 3698193326Sed case tok::kw_extern: 3699193326Sed case tok::kw___private_extern__: 3700193326Sed case tok::kw_static: 3701193326Sed case tok::kw_auto: 3702193326Sed case tok::kw_register: 3703193326Sed case tok::kw___thread: 3704198092Srdivacky 3705226633Sdim // Modules 3706226633Sdim case tok::kw___module_private__: 3707239462Sdim 3708193326Sed // type-specifiers 3709193326Sed case tok::kw_short: 3710193326Sed case tok::kw_long: 3711221345Sdim case tok::kw___int64: 3712234353Sdim case tok::kw___int128: 3713193326Sed case tok::kw_signed: 3714193326Sed case tok::kw_unsigned: 3715193326Sed case tok::kw__Complex: 3716193326Sed case tok::kw__Imaginary: 3717193326Sed case tok::kw_void: 3718193326Sed case tok::kw_char: 3719193326Sed case tok::kw_wchar_t: 3720198092Srdivacky case tok::kw_char16_t: 3721198092Srdivacky case tok::kw_char32_t: 3722198092Srdivacky 3723193326Sed case tok::kw_int: 3724226633Sdim case tok::kw_half: 3725193326Sed case tok::kw_float: 3726193326Sed case tok::kw_double: 3727193326Sed case tok::kw_bool: 3728193326Sed case tok::kw__Bool: 3729193326Sed case tok::kw__Decimal32: 3730193326Sed case tok::kw__Decimal64: 3731193326Sed case tok::kw__Decimal128: 3732203955Srdivacky case tok::kw___vector: 3733198092Srdivacky 3734193326Sed // struct-or-union-specifier (C99) or class-specifier (C++) 3735193326Sed case tok::kw_class: 3736193326Sed case tok::kw_struct: 3737193326Sed case tok::kw_union: 3738193326Sed // enum-specifier 3739193326Sed case tok::kw_enum: 3740198092Srdivacky 3741193326Sed // type-qualifier 3742193326Sed case tok::kw_const: 3743193326Sed case tok::kw_volatile: 3744193326Sed case tok::kw_restrict: 3745193326Sed 3746193326Sed // function-specifier 3747193326Sed case tok::kw_inline: 3748193326Sed case tok::kw_virtual: 3749193326Sed case tok::kw_explicit: 3750193326Sed 3751221345Sdim // static_assert-declaration 3752221345Sdim case tok::kw__Static_assert: 3753193326Sed 3754193326Sed // GNU typeof support. 3755193326Sed case tok::kw_typeof: 3756198092Srdivacky 3757193326Sed // GNU attributes. 3758193326Sed case tok::kw___attribute: 3759193326Sed return true; 3760198092Srdivacky 3761224145Sdim // C++0x decltype. 3762234353Sdim case tok::annot_decltype: 3763224145Sdim return true; 3764224145Sdim 3765234353Sdim // C11 _Atomic() 3766226633Sdim case tok::kw__Atomic: 3767226633Sdim return true; 3768226633Sdim 3769193326Sed // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. 3770193326Sed case tok::less: 3771234353Sdim return getLangOpts().ObjC1; 3772198092Srdivacky 3773221345Sdim // typedef-name 3774221345Sdim case tok::annot_typename: 3775221345Sdim return !DisambiguatingWithExpression || 3776221345Sdim !isStartOfObjCClassMessageMissingOpenBracket(); 3777239462Sdim 3778193326Sed case tok::kw___declspec: 3779193326Sed case tok::kw___cdecl: 3780193326Sed case tok::kw___stdcall: 3781193326Sed case tok::kw___fastcall: 3782208600Srdivacky case tok::kw___thiscall: 3783194179Sed case tok::kw___w64: 3784194179Sed case tok::kw___ptr64: 3785226633Sdim case tok::kw___ptr32: 3786194179Sed case tok::kw___forceinline: 3787212904Sdim case tok::kw___pascal: 3788226633Sdim case tok::kw___unaligned: 3789221345Sdim 3790221345Sdim case tok::kw___private: 3791221345Sdim case tok::kw___local: 3792221345Sdim case tok::kw___global: 3793221345Sdim case tok::kw___constant: 3794221345Sdim case tok::kw___read_only: 3795221345Sdim case tok::kw___read_write: 3796221345Sdim case tok::kw___write_only: 3797221345Sdim 3798194179Sed return true; 3799193326Sed } 3800193326Sed} 3801193326Sed 3802202379Srdivackybool Parser::isConstructorDeclarator() { 3803202379Srdivacky TentativeParsingAction TPA(*this); 3804193326Sed 3805202379Srdivacky // Parse the C++ scope specifier. 3806202379Srdivacky CXXScopeSpec SS; 3807239462Sdim if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 3808234353Sdim /*EnteringContext=*/true)) { 3809204643Srdivacky TPA.Revert(); 3810204643Srdivacky return false; 3811204643Srdivacky } 3812202379Srdivacky 3813202379Srdivacky // Parse the constructor name. 3814202379Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { 3815202379Srdivacky // We already know that we have a constructor name; just consume 3816202379Srdivacky // the token. 3817202379Srdivacky ConsumeToken(); 3818202379Srdivacky } else { 3819202379Srdivacky TPA.Revert(); 3820202379Srdivacky return false; 3821202379Srdivacky } 3822202379Srdivacky 3823234353Sdim // Current class name must be followed by a left parenthesis. 3824202379Srdivacky if (Tok.isNot(tok::l_paren)) { 3825202379Srdivacky TPA.Revert(); 3826202379Srdivacky return false; 3827202379Srdivacky } 3828202379Srdivacky ConsumeParen(); 3829202379Srdivacky 3830234353Sdim // A right parenthesis, or ellipsis followed by a right parenthesis signals 3831234353Sdim // that we have a constructor. 3832234353Sdim if (Tok.is(tok::r_paren) || 3833234353Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) { 3834202379Srdivacky TPA.Revert(); 3835202379Srdivacky return true; 3836202379Srdivacky } 3837202379Srdivacky 3838202379Srdivacky // If we need to, enter the specified scope. 3839202379Srdivacky DeclaratorScopeObj DeclScopeObj(*this, SS); 3840210299Sed if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 3841202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 3842202379Srdivacky 3843218893Sdim // Optionally skip Microsoft attributes. 3844221345Sdim ParsedAttributes Attrs(AttrFactory); 3845218893Sdim MaybeParseMicrosoftAttributes(Attrs); 3846218893Sdim 3847202379Srdivacky // Check whether the next token(s) are part of a declaration 3848202379Srdivacky // specifier, in which case we have the start of a parameter and, 3849202379Srdivacky // therefore, we know that this is a constructor. 3850234353Sdim bool IsConstructor = false; 3851234353Sdim if (isDeclarationSpecifier()) 3852234353Sdim IsConstructor = true; 3853234353Sdim else if (Tok.is(tok::identifier) || 3854234353Sdim (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) { 3855234353Sdim // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type. 3856234353Sdim // This might be a parenthesized member name, but is more likely to 3857234353Sdim // be a constructor declaration with an invalid argument type. Keep 3858234353Sdim // looking. 3859234353Sdim if (Tok.is(tok::annot_cxxscope)) 3860234353Sdim ConsumeToken(); 3861234353Sdim ConsumeToken(); 3862234353Sdim 3863234353Sdim // If this is not a constructor, we must be parsing a declarator, 3864234353Sdim // which must have one of the following syntactic forms (see the 3865234353Sdim // grammar extract at the start of ParseDirectDeclarator): 3866234353Sdim switch (Tok.getKind()) { 3867234353Sdim case tok::l_paren: 3868234353Sdim // C(X ( int)); 3869234353Sdim case tok::l_square: 3870234353Sdim // C(X [ 5]); 3871234353Sdim // C(X [ [attribute]]); 3872234353Sdim case tok::coloncolon: 3873234353Sdim // C(X :: Y); 3874234353Sdim // C(X :: *p); 3875234353Sdim case tok::r_paren: 3876234353Sdim // C(X ) 3877234353Sdim // Assume this isn't a constructor, rather than assuming it's a 3878234353Sdim // constructor with an unnamed parameter of an ill-formed type. 3879234353Sdim break; 3880234353Sdim 3881234353Sdim default: 3882234353Sdim IsConstructor = true; 3883234353Sdim break; 3884234353Sdim } 3885234353Sdim } 3886234353Sdim 3887202379Srdivacky TPA.Revert(); 3888202379Srdivacky return IsConstructor; 3889202379Srdivacky} 3890202379Srdivacky 3891193326Sed/// ParseTypeQualifierListOpt 3892212904Sdim/// type-qualifier-list: [C99 6.7.5] 3893212904Sdim/// type-qualifier 3894239462Sdim/// [vendor] attributes 3895212904Sdim/// [ only if VendorAttributesAllowed=true ] 3896212904Sdim/// type-qualifier-list type-qualifier 3897239462Sdim/// [vendor] type-qualifier-list attributes 3898212904Sdim/// [ only if VendorAttributesAllowed=true ] 3899212904Sdim/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq 3900212904Sdim/// [ only if CXX0XAttributesAllowed=true ] 3901212904Sdim/// Note: vendor can be GNU, MS, etc. 3902193326Sed/// 3903212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS, 3904212904Sdim bool VendorAttributesAllowed, 3905234353Sdim bool CXX11AttributesAllowed) { 3906234353Sdim if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed && 3907234353Sdim isCXX11AttributeSpecifier()) { 3908221345Sdim ParsedAttributesWithRange attrs(AttrFactory); 3909234353Sdim ParseCXX11Attributes(attrs); 3910234353Sdim DS.takeAttributesFrom(attrs); 3911199990Srdivacky } 3912221345Sdim 3913221345Sdim SourceLocation EndLoc; 3914221345Sdim 3915193326Sed while (1) { 3916198092Srdivacky bool isInvalid = false; 3917193326Sed const char *PrevSpec = 0; 3918198092Srdivacky unsigned DiagID = 0; 3919193326Sed SourceLocation Loc = Tok.getLocation(); 3920193326Sed 3921193326Sed switch (Tok.getKind()) { 3922212904Sdim case tok::code_completion: 3923212904Sdim Actions.CodeCompleteTypeQualifiers(DS); 3924226633Sdim return cutOffParsing(); 3925239462Sdim 3926193326Sed case tok::kw_const: 3927198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, 3928239462Sdim getLangOpts(), /*IsTypeSpec*/false); 3929193326Sed break; 3930193326Sed case tok::kw_volatile: 3931198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID, 3932239462Sdim getLangOpts(), /*IsTypeSpec*/false); 3933193326Sed break; 3934193326Sed case tok::kw_restrict: 3935198092Srdivacky isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, 3936239462Sdim getLangOpts(), /*IsTypeSpec*/false); 3937193326Sed break; 3938221345Sdim 3939221345Sdim // OpenCL qualifiers: 3940239462Sdim case tok::kw_private: 3941234353Sdim if (!getLangOpts().OpenCL) 3942221345Sdim goto DoneWithTypeQuals; 3943221345Sdim case tok::kw___private: 3944221345Sdim case tok::kw___global: 3945221345Sdim case tok::kw___local: 3946221345Sdim case tok::kw___constant: 3947221345Sdim case tok::kw___read_only: 3948221345Sdim case tok::kw___write_only: 3949221345Sdim case tok::kw___read_write: 3950221345Sdim ParseOpenCLQualifiers(DS); 3951221345Sdim break; 3952221345Sdim 3953194179Sed case tok::kw___w64: 3954193326Sed case tok::kw___ptr64: 3955226633Sdim case tok::kw___ptr32: 3956193326Sed case tok::kw___cdecl: 3957193326Sed case tok::kw___stdcall: 3958193326Sed case tok::kw___fastcall: 3959208600Srdivacky case tok::kw___thiscall: 3960226633Sdim case tok::kw___unaligned: 3961212904Sdim if (VendorAttributesAllowed) { 3962218893Sdim ParseMicrosoftTypeAttributes(DS.getAttributes()); 3963194179Sed continue; 3964194179Sed } 3965194179Sed goto DoneWithTypeQuals; 3966212904Sdim case tok::kw___pascal: 3967212904Sdim if (VendorAttributesAllowed) { 3968218893Sdim ParseBorlandTypeAttributes(DS.getAttributes()); 3969212904Sdim continue; 3970212904Sdim } 3971212904Sdim goto DoneWithTypeQuals; 3972193326Sed case tok::kw___attribute: 3973212904Sdim if (VendorAttributesAllowed) { 3974218893Sdim ParseGNUAttributes(DS.getAttributes()); 3975193326Sed continue; // do *not* consume the next token! 3976193326Sed } 3977193326Sed // otherwise, FALL THROUGH! 3978193326Sed default: 3979193326Sed DoneWithTypeQuals: 3980193326Sed // If this is not a type-qualifier token, we're done reading type 3981193326Sed // qualifiers. First verify that DeclSpec's are consistent. 3982193326Sed DS.Finish(Diags, PP); 3983221345Sdim if (EndLoc.isValid()) 3984221345Sdim DS.SetRangeEnd(EndLoc); 3985193326Sed return; 3986193326Sed } 3987193326Sed 3988193326Sed // If the specifier combination wasn't legal, issue a diagnostic. 3989193326Sed if (isInvalid) { 3990193326Sed assert(PrevSpec && "Method did not return previous specifier!"); 3991193326Sed Diag(Tok, DiagID) << PrevSpec; 3992193326Sed } 3993221345Sdim EndLoc = ConsumeToken(); 3994193326Sed } 3995193326Sed} 3996193326Sed 3997193326Sed 3998193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator. 3999193326Sed/// 4000193326Sedvoid Parser::ParseDeclarator(Declarator &D) { 4001193326Sed /// This implements the 'declarator' production in the C grammar, then checks 4002193326Sed /// for well-formedness and issues diagnostics. 4003193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4004193326Sed} 4005193326Sed 4006234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { 4007234353Sdim if (Kind == tok::star || Kind == tok::caret) 4008234353Sdim return true; 4009234353Sdim 4010234353Sdim // We parse rvalue refs in C++03, because otherwise the errors are scary. 4011234353Sdim if (!Lang.CPlusPlus) 4012234353Sdim return false; 4013234353Sdim 4014234353Sdim return Kind == tok::amp || Kind == tok::ampamp; 4015234353Sdim} 4016234353Sdim 4017193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator 4018193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator 4019193326Sed/// isn't parsed at all, making this function effectively parse the C++ 4020193326Sed/// ptr-operator production. 4021193326Sed/// 4022234353Sdim/// If the grammar of this construct is extended, matching changes must also be 4023234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to 4024234353Sdim/// isConstructorDeclarator. 4025234353Sdim/// 4026193326Sed/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] 4027193326Sed/// [C] pointer[opt] direct-declarator 4028193326Sed/// [C++] direct-declarator 4029193326Sed/// [C++] ptr-operator declarator 4030193326Sed/// 4031193326Sed/// pointer: [C99 6.7.5] 4032193326Sed/// '*' type-qualifier-list[opt] 4033193326Sed/// '*' type-qualifier-list[opt] pointer 4034193326Sed/// 4035193326Sed/// ptr-operator: 4036193326Sed/// '*' cv-qualifier-seq[opt] 4037193326Sed/// '&' 4038193326Sed/// [C++0x] '&&' 4039193326Sed/// [GNU] '&' restrict[opt] attributes[opt] 4040193326Sed/// [GNU?] '&&' restrict[opt] attributes[opt] 4041193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4042193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D, 4043193326Sed DirectDeclParseFunction DirectDeclParser) { 4044198092Srdivacky if (Diags.hasAllExtensionsSilenced()) 4045198092Srdivacky D.setExtension(); 4046239462Sdim 4047193326Sed // C++ member pointers start with a '::' or a nested-name. 4048193326Sed // Member pointers get special handling, since there's no place for the 4049193326Sed // scope spec in the generic path below. 4050234353Sdim if (getLangOpts().CPlusPlus && 4051193326Sed (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || 4052193326Sed Tok.is(tok::annot_cxxscope))) { 4053234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4054234353Sdim D.getContext() == Declarator::MemberContext; 4055193326Sed CXXScopeSpec SS; 4056234353Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); 4057204643Srdivacky 4058207619Srdivacky if (SS.isNotEmpty()) { 4059198092Srdivacky if (Tok.isNot(tok::star)) { 4060193326Sed // The scope spec really belongs to the direct-declarator. 4061193326Sed D.getCXXScopeSpec() = SS; 4062193326Sed if (DirectDeclParser) 4063193326Sed (this->*DirectDeclParser)(D); 4064193326Sed return; 4065193326Sed } 4066193326Sed 4067193326Sed SourceLocation Loc = ConsumeToken(); 4068193326Sed D.SetRangeEnd(Loc); 4069221345Sdim DeclSpec DS(AttrFactory); 4070193326Sed ParseTypeQualifierListOpt(DS); 4071193326Sed D.ExtendWithDeclSpec(DS); 4072193326Sed 4073193326Sed // Recurse to parse whatever is left. 4074193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4075193326Sed 4076193326Sed // Sema will have to catch (syntactically invalid) pointers into global 4077193326Sed // scope. It has to catch pointers into namespace scope anyway. 4078193326Sed D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), 4079221345Sdim Loc), 4080221345Sdim DS.getAttributes(), 4081193326Sed /* Don't replace range end. */SourceLocation()); 4082193326Sed return; 4083193326Sed } 4084193326Sed } 4085193326Sed 4086193326Sed tok::TokenKind Kind = Tok.getKind(); 4087193326Sed // Not a pointer, C++ reference, or block. 4088234353Sdim if (!isPtrOperatorToken(Kind, getLangOpts())) { 4089193326Sed if (DirectDeclParser) 4090193326Sed (this->*DirectDeclParser)(D); 4091193326Sed return; 4092193326Sed } 4093193326Sed 4094193326Sed // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference, 4095193326Sed // '&&' -> rvalue reference 4096193326Sed SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. 4097193326Sed D.SetRangeEnd(Loc); 4098193326Sed 4099193326Sed if (Kind == tok::star || Kind == tok::caret) { 4100193326Sed // Is a pointer. 4101221345Sdim DeclSpec DS(AttrFactory); 4102193326Sed 4103234353Sdim // FIXME: GNU attributes are not allowed here in a new-type-id. 4104193326Sed ParseTypeQualifierListOpt(DS); 4105193326Sed D.ExtendWithDeclSpec(DS); 4106193326Sed 4107193326Sed // Recursively parse the declarator. 4108193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4109193326Sed if (Kind == tok::star) 4110193326Sed // Remember that we parsed a pointer type, and remember the type-quals. 4111193326Sed D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, 4112219077Sdim DS.getConstSpecLoc(), 4113219077Sdim DS.getVolatileSpecLoc(), 4114221345Sdim DS.getRestrictSpecLoc()), 4115221345Sdim DS.getAttributes(), 4116193326Sed SourceLocation()); 4117193326Sed else 4118193326Sed // Remember that we parsed a Block type, and remember the type-quals. 4119198092Srdivacky D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), 4120221345Sdim Loc), 4121221345Sdim DS.getAttributes(), 4122193326Sed SourceLocation()); 4123193326Sed } else { 4124193326Sed // Is a reference 4125221345Sdim DeclSpec DS(AttrFactory); 4126193326Sed 4127193326Sed // Complain about rvalue references in C++03, but then go on and build 4128193326Sed // the declarator. 4129234353Sdim if (Kind == tok::ampamp) 4130234353Sdim Diag(Loc, getLangOpts().CPlusPlus0x ? 4131234353Sdim diag::warn_cxx98_compat_rvalue_reference : 4132234353Sdim diag::ext_rvalue_reference); 4133193326Sed 4134234353Sdim // GNU-style and C++11 attributes are allowed here, as is restrict. 4135234353Sdim ParseTypeQualifierListOpt(DS); 4136234353Sdim D.ExtendWithDeclSpec(DS); 4137234353Sdim 4138193326Sed // C++ 8.3.2p1: cv-qualified references are ill-formed except when the 4139193326Sed // cv-qualifiers are introduced through the use of a typedef or of a 4140193326Sed // template type argument, in which case the cv-qualifiers are ignored. 4141193326Sed if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { 4142193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 4143193326Sed Diag(DS.getConstSpecLoc(), 4144193326Sed diag::err_invalid_reference_qualifier_application) << "const"; 4145193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) 4146193326Sed Diag(DS.getVolatileSpecLoc(), 4147193326Sed diag::err_invalid_reference_qualifier_application) << "volatile"; 4148193326Sed } 4149193326Sed 4150193326Sed // Recursively parse the declarator. 4151193326Sed ParseDeclaratorInternal(D, DirectDeclParser); 4152193326Sed 4153193326Sed if (D.getNumTypeObjects() > 0) { 4154193326Sed // C++ [dcl.ref]p4: There shall be no references to references. 4155193326Sed DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1); 4156193326Sed if (InnerChunk.Kind == DeclaratorChunk::Reference) { 4157193326Sed if (const IdentifierInfo *II = D.getIdentifier()) 4158193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4159193326Sed << II; 4160193326Sed else 4161193326Sed Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference) 4162193326Sed << "type name"; 4163193326Sed 4164193326Sed // Once we've complained about the reference-to-reference, we 4165193326Sed // can go ahead and build the (technically ill-formed) 4166193326Sed // declarator: reference collapsing will take care of it. 4167193326Sed } 4168193326Sed } 4169193326Sed 4170193326Sed // Remember that we parsed a reference type. It doesn't have type-quals. 4171193326Sed D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, 4172193326Sed Kind == tok::amp), 4173221345Sdim DS.getAttributes(), 4174193326Sed SourceLocation()); 4175193326Sed } 4176193326Sed} 4177193326Sed 4178234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D, 4179234353Sdim SourceLocation EllipsisLoc) { 4180234353Sdim if (EllipsisLoc.isValid()) { 4181234353Sdim FixItHint Insertion; 4182234353Sdim if (!D.getEllipsisLoc().isValid()) { 4183234353Sdim Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "..."); 4184234353Sdim D.setEllipsisLoc(EllipsisLoc); 4185234353Sdim } 4186234353Sdim P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration) 4187234353Sdim << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName(); 4188234353Sdim } 4189234353Sdim} 4190234353Sdim 4191193326Sed/// ParseDirectDeclarator 4192193326Sed/// direct-declarator: [C99 6.7.5] 4193193326Sed/// [C99] identifier 4194193326Sed/// '(' declarator ')' 4195193326Sed/// [GNU] '(' attributes declarator ')' 4196193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 4197193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4198193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4199193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4200193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4201234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 4202234353Sdim/// attribute-specifier-seq[opt] 4203193326Sed/// direct-declarator '(' parameter-type-list ')' 4204193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4205193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4206193326Sed/// parameter-type-list[opt] ')' 4207193326Sed/// [C++] direct-declarator '(' parameter-declaration-clause ')' 4208193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 4209234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')' 4210234353Sdim/// attribute-specifier-seq[opt] cv-qualifier-seq[opt] 4211234353Sdim/// ref-qualifier[opt] exception-specification[opt] 4212193326Sed/// [C++] declarator-id 4213234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt] 4214193326Sed/// 4215193326Sed/// declarator-id: [C++ 8] 4216218893Sdim/// '...'[opt] id-expression 4217193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 4218193326Sed/// 4219193326Sed/// id-expression: [C++ 5.1] 4220193326Sed/// unqualified-id 4221198092Srdivacky/// qualified-id 4222193326Sed/// 4223193326Sed/// unqualified-id: [C++ 5.1] 4224198092Srdivacky/// identifier 4225193326Sed/// operator-function-id 4226198092Srdivacky/// conversion-function-id 4227198092Srdivacky/// '~' class-name 4228193326Sed/// template-id 4229193326Sed/// 4230234353Sdim/// Note, any additional constructs added here may need corresponding changes 4231234353Sdim/// in isConstructorDeclarator. 4232193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) { 4233193326Sed DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); 4234193326Sed 4235234353Sdim if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) { 4236198893Srdivacky // ParseDeclaratorInternal might already have parsed the scope. 4237207619Srdivacky if (D.getCXXScopeSpec().isEmpty()) { 4238234353Sdim bool EnteringContext = D.getContext() == Declarator::FileContext || 4239234353Sdim D.getContext() == Declarator::MemberContext; 4240239462Sdim ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), 4241234353Sdim EnteringContext); 4242204643Srdivacky } 4243204643Srdivacky 4244207619Srdivacky if (D.getCXXScopeSpec().isValid()) { 4245210299Sed if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4246200583Srdivacky // Change the declaration context for name lookup, until this function 4247200583Srdivacky // is exited (and the declarator has been parsed). 4248200583Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4249207619Srdivacky } 4250207619Srdivacky 4251218893Sdim // C++0x [dcl.fct]p14: 4252218893Sdim // There is a syntactic ambiguity when an ellipsis occurs at the end 4253239462Sdim // of a parameter-declaration-clause without a preceding comma. In 4254239462Sdim // this case, the ellipsis is parsed as part of the 4255239462Sdim // abstract-declarator if the type of the parameter names a template 4256218893Sdim // parameter pack that has not been expanded; otherwise, it is parsed 4257218893Sdim // as part of the parameter-declaration-clause. 4258234353Sdim if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && 4259218893Sdim !((D.getContext() == Declarator::PrototypeContext || 4260218893Sdim D.getContext() == Declarator::BlockLiteralContext) && 4261218893Sdim NextToken().is(tok::r_paren) && 4262234353Sdim !Actions.containsUnexpandedParameterPacks(D))) { 4263234353Sdim SourceLocation EllipsisLoc = ConsumeToken(); 4264234353Sdim if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { 4265234353Sdim // The ellipsis was put in the wrong place. Recover, and explain to 4266234353Sdim // the user what they should have done. 4267234353Sdim ParseDeclarator(D); 4268234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4269234353Sdim return; 4270234353Sdim } else 4271234353Sdim D.setEllipsisLoc(EllipsisLoc); 4272234353Sdim 4273234353Sdim // The ellipsis can't be followed by a parenthesized declarator. We 4274234353Sdim // check for that in ParseParenDeclarator, after we have disambiguated 4275234353Sdim // the l_paren token. 4276234353Sdim } 4277234353Sdim 4278198893Srdivacky if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 4279198893Srdivacky Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { 4280198893Srdivacky // We found something that indicates the start of an unqualified-id. 4281198893Srdivacky // Parse that unqualified-id. 4282207619Srdivacky bool AllowConstructorName; 4283207619Srdivacky if (D.getDeclSpec().hasTypeSpecifier()) 4284207619Srdivacky AllowConstructorName = false; 4285207619Srdivacky else if (D.getCXXScopeSpec().isSet()) 4286207619Srdivacky AllowConstructorName = 4287207619Srdivacky (D.getContext() == Declarator::FileContext || 4288207619Srdivacky (D.getContext() == Declarator::MemberContext && 4289207619Srdivacky D.getDeclSpec().isFriendSpecified())); 4290207619Srdivacky else 4291207619Srdivacky AllowConstructorName = (D.getContext() == Declarator::MemberContext); 4292207619Srdivacky 4293234353Sdim SourceLocation TemplateKWLoc; 4294239462Sdim if (ParseUnqualifiedId(D.getCXXScopeSpec(), 4295239462Sdim /*EnteringContext=*/true, 4296239462Sdim /*AllowDestructorName=*/true, 4297202379Srdivacky AllowConstructorName, 4298212904Sdim ParsedType(), 4299234353Sdim TemplateKWLoc, 4300207619Srdivacky D.getName()) || 4301207619Srdivacky // Once we're past the identifier, if the scope was bad, mark the 4302207619Srdivacky // whole declarator bad. 4303207619Srdivacky D.getCXXScopeSpec().isInvalid()) { 4304193326Sed D.SetIdentifier(0, Tok.getLocation()); 4305193326Sed D.setInvalidType(true); 4306198893Srdivacky } else { 4307198893Srdivacky // Parsed the unqualified-id; update range information and move along. 4308198893Srdivacky if (D.getSourceRange().getBegin().isInvalid()) 4309198893Srdivacky D.SetRangeBegin(D.getName().getSourceRange().getBegin()); 4310198893Srdivacky D.SetRangeEnd(D.getName().getSourceRange().getEnd()); 4311193326Sed } 4312198893Srdivacky goto PastIdentifier; 4313193326Sed } 4314198893Srdivacky } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { 4315234353Sdim assert(!getLangOpts().CPlusPlus && 4316193326Sed "There's a C++-specific check for tok::identifier above"); 4317193326Sed assert(Tok.getIdentifierInfo() && "Not an identifier?"); 4318193326Sed D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 4319193326Sed ConsumeToken(); 4320198893Srdivacky goto PastIdentifier; 4321198893Srdivacky } 4322234353Sdim 4323198893Srdivacky if (Tok.is(tok::l_paren)) { 4324193326Sed // direct-declarator: '(' declarator ')' 4325193326Sed // direct-declarator: '(' attributes declarator ')' 4326193326Sed // Example: 'char (*X)' or 'int (*XX)(void)' 4327193326Sed ParseParenDeclarator(D); 4328202379Srdivacky 4329202379Srdivacky // If the declarator was parenthesized, we entered the declarator 4330202379Srdivacky // scope when parsing the parenthesized declarator, then exited 4331202379Srdivacky // the scope already. Re-enter the scope, if we need to. 4332202379Srdivacky if (D.getCXXScopeSpec().isSet()) { 4333212904Sdim // If there was an error parsing parenthesized declarator, declarator 4334234353Sdim // scope may have been entered before. Don't do it again. 4335212904Sdim if (!D.isInvalidType() && 4336212904Sdim Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) 4337202379Srdivacky // Change the declaration context for name lookup, until this function 4338202379Srdivacky // is exited (and the declarator has been parsed). 4339202379Srdivacky DeclScopeObj.EnterDeclaratorScope(); 4340202379Srdivacky } 4341193326Sed } else if (D.mayOmitIdentifier()) { 4342193326Sed // This could be something simple like "int" (in which case the declarator 4343193326Sed // portion is empty), if an abstract-declarator is allowed. 4344193326Sed D.SetIdentifier(0, Tok.getLocation()); 4345193326Sed } else { 4346239462Sdim if (Tok.getKind() == tok::annot_pragma_parser_crash) 4347239462Sdim *(volatile int*) 0x11 = 0; 4348193326Sed if (D.getContext() == Declarator::MemberContext) 4349193326Sed Diag(Tok, diag::err_expected_member_name_or_semi) 4350193326Sed << D.getDeclSpec().getSourceRange(); 4351234353Sdim else if (getLangOpts().CPlusPlus) 4352234353Sdim Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus; 4353193326Sed else 4354193326Sed Diag(Tok, diag::err_expected_ident_lparen); 4355193326Sed D.SetIdentifier(0, Tok.getLocation()); 4356193326Sed D.setInvalidType(true); 4357193326Sed } 4358198092Srdivacky 4359193326Sed PastIdentifier: 4360193326Sed assert(D.isPastIdentifier() && 4361193326Sed "Haven't past the location of the identifier yet?"); 4362198092Srdivacky 4363234353Sdim // Don't parse attributes unless we have parsed an unparenthesized name. 4364234353Sdim if (D.hasName() && !D.getNumTypeObjects()) 4365218893Sdim MaybeParseCXX0XAttributes(D); 4366199990Srdivacky 4367193326Sed while (1) { 4368193326Sed if (Tok.is(tok::l_paren)) { 4369234353Sdim // Enter function-declaration scope, limiting any declarators to the 4370234353Sdim // function prototype scope, including parameter declarators. 4371234353Sdim ParseScope PrototypeScope(this, 4372234353Sdim Scope::FunctionPrototypeScope|Scope::DeclScope); 4373193326Sed // The paren may be part of a C++ direct initializer, eg. "int x(1);". 4374193326Sed // In such a case, check if we actually have a function declarator; if it 4375193326Sed // is not, the declarator has been fully parsed. 4376239462Sdim bool IsAmbiguous = false; 4377239462Sdim if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit() && 4378239462Sdim !isCXXFunctionDeclarator(&IsAmbiguous)) 4379239462Sdim break; 4380221345Sdim ParsedAttributes attrs(AttrFactory); 4381226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4382226633Sdim T.consumeOpen(); 4383239462Sdim ParseFunctionDeclarator(D, attrs, T, IsAmbiguous); 4384234353Sdim PrototypeScope.Exit(); 4385193326Sed } else if (Tok.is(tok::l_square)) { 4386193326Sed ParseBracketDeclarator(D); 4387193326Sed } else { 4388193326Sed break; 4389193326Sed } 4390193326Sed } 4391239462Sdim} 4392193326Sed 4393193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is 4394193326Sed/// only called before the identifier, so these are most likely just grouping 4395198092Srdivacky/// parens for precedence. If we find that these are actually function 4396193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator. 4397193326Sed/// 4398193326Sed/// direct-declarator: 4399193326Sed/// '(' declarator ')' 4400193326Sed/// [GNU] '(' attributes declarator ')' 4401193326Sed/// direct-declarator '(' parameter-type-list ')' 4402193326Sed/// direct-declarator '(' identifier-list[opt] ')' 4403193326Sed/// [GNU] direct-declarator '(' parameter-forward-declarations 4404193326Sed/// parameter-type-list[opt] ')' 4405193326Sed/// 4406193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) { 4407226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 4408226633Sdim T.consumeOpen(); 4409226633Sdim 4410193326Sed assert(!D.isPastIdentifier() && "Should be called before passing identifier"); 4411198092Srdivacky 4412193326Sed // Eat any attributes before we look at whether this is a grouping or function 4413193326Sed // declarator paren. If this is a grouping paren, the attribute applies to 4414193326Sed // the type being built up, for example: 4415193326Sed // int (__attribute__(()) *x)(long y) 4416193326Sed // If this ends up not being a grouping paren, the attribute applies to the 4417193326Sed // first argument, for example: 4418193326Sed // int (__attribute__(()) int x) 4419193326Sed // In either case, we need to eat any attributes to be able to determine what 4420193326Sed // sort of paren this is. 4421193326Sed // 4422221345Sdim ParsedAttributes attrs(AttrFactory); 4423193326Sed bool RequiresArg = false; 4424193326Sed if (Tok.is(tok::kw___attribute)) { 4425218893Sdim ParseGNUAttributes(attrs); 4426198092Srdivacky 4427193326Sed // We require that the argument list (if this is a non-grouping paren) be 4428193326Sed // present even if the attribute list was empty. 4429193326Sed RequiresArg = true; 4430193326Sed } 4431193326Sed // Eat any Microsoft extensions. 4432194179Sed if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) || 4433208600Srdivacky Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) || 4434226633Sdim Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) || 4435226633Sdim Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) { 4436218893Sdim ParseMicrosoftTypeAttributes(attrs); 4437194179Sed } 4438212904Sdim // Eat any Borland extensions. 4439218893Sdim if (Tok.is(tok::kw___pascal)) 4440218893Sdim ParseBorlandTypeAttributes(attrs); 4441198092Srdivacky 4442193326Sed // If we haven't past the identifier yet (or where the identifier would be 4443193326Sed // stored, if this is an abstract declarator), then this is probably just 4444193326Sed // grouping parens. However, if this could be an abstract-declarator, then 4445193326Sed // this could also be the start of function arguments (consider 'void()'). 4446193326Sed bool isGrouping; 4447198092Srdivacky 4448193326Sed if (!D.mayOmitIdentifier()) { 4449193326Sed // If this can't be an abstract-declarator, this *must* be a grouping 4450193326Sed // paren, because we haven't seen the identifier yet. 4451193326Sed isGrouping = true; 4452193326Sed } else if (Tok.is(tok::r_paren) || // 'int()' is a function. 4453234353Sdim (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && 4454234353Sdim NextToken().is(tok::r_paren)) || // C++ int(...) 4455234353Sdim isDeclarationSpecifier() || // 'int(int)' is a function. 4456234353Sdim isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function. 4457193326Sed // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is 4458193326Sed // considered to be a type, not a K&R identifier-list. 4459193326Sed isGrouping = false; 4460193326Sed } else { 4461193326Sed // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'. 4462193326Sed isGrouping = true; 4463193326Sed } 4464198092Srdivacky 4465193326Sed // If this is a grouping paren, handle: 4466193326Sed // direct-declarator: '(' declarator ')' 4467193326Sed // direct-declarator: '(' attributes declarator ')' 4468193326Sed if (isGrouping) { 4469234353Sdim SourceLocation EllipsisLoc = D.getEllipsisLoc(); 4470234353Sdim D.setEllipsisLoc(SourceLocation()); 4471234353Sdim 4472193326Sed bool hadGroupingParens = D.hasGroupingParens(); 4473193326Sed D.setGroupingParens(true); 4474193326Sed ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); 4475193326Sed // Match the ')'. 4476226633Sdim T.consumeClose(); 4477239462Sdim D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), 4478226633Sdim T.getCloseLocation()), 4479226633Sdim attrs, T.getCloseLocation()); 4480193326Sed 4481193326Sed D.setGroupingParens(hadGroupingParens); 4482234353Sdim 4483234353Sdim // An ellipsis cannot be placed outside parentheses. 4484234353Sdim if (EllipsisLoc.isValid()) 4485234353Sdim diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); 4486234353Sdim 4487193326Sed return; 4488193326Sed } 4489198092Srdivacky 4490193326Sed // Okay, if this wasn't a grouping paren, it must be the start of a function 4491193326Sed // argument list. Recognize that this declarator will never have an 4492193326Sed // identifier (and remember where it would have been), then call into 4493193326Sed // ParseFunctionDeclarator to handle of argument list. 4494193326Sed D.SetIdentifier(0, Tok.getLocation()); 4495193326Sed 4496234353Sdim // Enter function-declaration scope, limiting any declarators to the 4497234353Sdim // function prototype scope, including parameter declarators. 4498234353Sdim ParseScope PrototypeScope(this, 4499234353Sdim Scope::FunctionPrototypeScope|Scope::DeclScope); 4500239462Sdim ParseFunctionDeclarator(D, attrs, T, false, RequiresArg); 4501234353Sdim PrototypeScope.Exit(); 4502193326Sed} 4503193326Sed 4504193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the 4505193326Sed/// declarator D up to a paren, which indicates that we are parsing function 4506193326Sed/// arguments. 4507193326Sed/// 4508234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments 4509234353Sdim/// immediately after the open paren - they should be considered to be the 4510234353Sdim/// first argument of a parameter. 4511193326Sed/// 4512234353Sdim/// If RequiresArg is true, then the first argument of the function is required 4513234353Sdim/// to be present and required to not be an identifier list. 4514193326Sed/// 4515234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt], 4516234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt], 4517234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt]. 4518234353Sdim/// 4519234353Sdim/// [C++11] exception-specification: 4520221345Sdim/// dynamic-exception-specification 4521221345Sdim/// noexcept-specification 4522221345Sdim/// 4523226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D, 4524234353Sdim ParsedAttributes &FirstArgAttrs, 4525226633Sdim BalancedDelimiterTracker &Tracker, 4526239462Sdim bool IsAmbiguous, 4527193326Sed bool RequiresArg) { 4528239462Sdim assert(getCurScope()->isFunctionPrototypeScope() && 4529234353Sdim "Should call from a Function scope"); 4530193326Sed // lparen is already consumed! 4531193326Sed assert(D.isPastIdentifier() && "Should not call before identifier!"); 4532198092Srdivacky 4533224145Sdim // This should be true when the function has typed arguments. 4534224145Sdim // Otherwise, it is treated as a K&R-style function. 4535224145Sdim bool HasProto = false; 4536224145Sdim // Build up an array of information about the parsed arguments. 4537226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 4538224145Sdim // Remember where we see an ellipsis, if any. 4539224145Sdim SourceLocation EllipsisLoc; 4540224145Sdim 4541224145Sdim DeclSpec DS(AttrFactory); 4542224145Sdim bool RefQualifierIsLValueRef = true; 4543224145Sdim SourceLocation RefQualifierLoc; 4544234353Sdim SourceLocation ConstQualifierLoc; 4545234353Sdim SourceLocation VolatileQualifierLoc; 4546224145Sdim ExceptionSpecificationType ESpecType = EST_None; 4547224145Sdim SourceRange ESpecRange; 4548226633Sdim SmallVector<ParsedType, 2> DynamicExceptions; 4549226633Sdim SmallVector<SourceRange, 2> DynamicExceptionRanges; 4550224145Sdim ExprResult NoexceptExpr; 4551234353Sdim ParsedAttributes FnAttrs(AttrFactory); 4552239462Sdim TypeResult TrailingReturnType; 4553234353Sdim 4554234353Sdim Actions.ActOnStartFunctionDeclarator(); 4555234353Sdim 4556224145Sdim SourceLocation EndLoc; 4557224145Sdim if (isFunctionDeclaratorIdentifierList()) { 4558218893Sdim if (RequiresArg) 4559193326Sed Diag(Tok, diag::err_argument_required_after_attribute); 4560193326Sed 4561224145Sdim ParseFunctionDeclaratorIdentifierList(D, ParamInfo); 4562193326Sed 4563226633Sdim Tracker.consumeClose(); 4564226633Sdim EndLoc = Tracker.getCloseLocation(); 4565224145Sdim } else { 4566224145Sdim if (Tok.isNot(tok::r_paren)) 4567234353Sdim ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc); 4568224145Sdim else if (RequiresArg) 4569224145Sdim Diag(Tok, diag::err_argument_required_after_attribute); 4570224145Sdim 4571234353Sdim HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; 4572224145Sdim 4573224145Sdim // If we have the closing ')', eat it. 4574226633Sdim Tracker.consumeClose(); 4575226633Sdim EndLoc = Tracker.getCloseLocation(); 4576224145Sdim 4577234353Sdim if (getLangOpts().CPlusPlus) { 4578234353Sdim // FIXME: Accept these components in any order, and produce fixits to 4579234353Sdim // correct the order if the user gets it wrong. Ideally we should deal 4580234353Sdim // with the virt-specifier-seq and pure-specifier in the same way. 4581218893Sdim 4582224145Sdim // Parse cv-qualifier-seq[opt]. 4583234353Sdim ParseTypeQualifierListOpt(DS, false /*no attributes*/, false); 4584234353Sdim if (!DS.getSourceRange().getEnd().isInvalid()) { 4585234353Sdim EndLoc = DS.getSourceRange().getEnd(); 4586234353Sdim ConstQualifierLoc = DS.getConstSpecLoc(); 4587234353Sdim VolatileQualifierLoc = DS.getVolatileSpecLoc(); 4588234353Sdim } 4589193326Sed 4590224145Sdim // Parse ref-qualifier[opt]. 4591218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) { 4592234353Sdim Diag(Tok, getLangOpts().CPlusPlus0x ? 4593234353Sdim diag::warn_cxx98_compat_ref_qualifier : 4594234353Sdim diag::ext_ref_qualifier); 4595234353Sdim 4596218893Sdim RefQualifierIsLValueRef = Tok.is(tok::amp); 4597218893Sdim RefQualifierLoc = ConsumeToken(); 4598218893Sdim EndLoc = RefQualifierLoc; 4599218893Sdim } 4600221345Sdim 4601234982Sdim // C++11 [expr.prim.general]p3: 4602239462Sdim // If a declaration declares a member function or member function 4603239462Sdim // template of a class X, the expression this is a prvalue of type 4604234982Sdim // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 4605239462Sdim // and the end of the function-definition, member-declarator, or 4606234982Sdim // declarator. 4607239462Sdim bool IsCXX11MemberFunction = 4608234982Sdim getLangOpts().CPlusPlus0x && 4609234982Sdim (D.getContext() == Declarator::MemberContext || 4610234982Sdim (D.getContext() == Declarator::FileContext && 4611239462Sdim D.getCXXScopeSpec().isValid() && 4612234982Sdim Actions.CurContext->isRecord())); 4613234982Sdim Sema::CXXThisScopeRAII ThisScope(Actions, 4614234982Sdim dyn_cast<CXXRecordDecl>(Actions.CurContext), 4615234982Sdim DS.getTypeQualifiers(), 4616234982Sdim IsCXX11MemberFunction); 4617235864Sdim 4618193326Sed // Parse exception-specification[opt]. 4619235864Sdim ESpecType = tryParseExceptionSpecification(ESpecRange, 4620234982Sdim DynamicExceptions, 4621234982Sdim DynamicExceptionRanges, 4622235864Sdim NoexceptExpr); 4623221345Sdim if (ESpecType != EST_None) 4624221345Sdim EndLoc = ESpecRange.getEnd(); 4625218893Sdim 4626234353Sdim // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes 4627234353Sdim // after the exception-specification. 4628234353Sdim MaybeParseCXX0XAttributes(FnAttrs); 4629234353Sdim 4630224145Sdim // Parse trailing-return-type[opt]. 4631234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) { 4632234353Sdim Diag(Tok, diag::warn_cxx98_compat_trailing_return_type); 4633226633Sdim SourceRange Range; 4634239462Sdim TrailingReturnType = ParseTrailingReturnType(Range); 4635226633Sdim if (Range.getEnd().isValid()) 4636226633Sdim EndLoc = Range.getEnd(); 4637218893Sdim } 4638193326Sed } 4639193326Sed } 4640193326Sed 4641224145Sdim // Remember that we parsed a function type, and remember the attributes. 4642224145Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, 4643224145Sdim /*isVariadic=*/EllipsisLoc.isValid(), 4644239462Sdim IsAmbiguous, EllipsisLoc, 4645224145Sdim ParamInfo.data(), ParamInfo.size(), 4646224145Sdim DS.getTypeQualifiers(), 4647224145Sdim RefQualifierIsLValueRef, 4648234353Sdim RefQualifierLoc, ConstQualifierLoc, 4649234353Sdim VolatileQualifierLoc, 4650224145Sdim /*MutableLoc=*/SourceLocation(), 4651224145Sdim ESpecType, ESpecRange.getBegin(), 4652224145Sdim DynamicExceptions.data(), 4653224145Sdim DynamicExceptionRanges.data(), 4654224145Sdim DynamicExceptions.size(), 4655224145Sdim NoexceptExpr.isUsable() ? 4656224145Sdim NoexceptExpr.get() : 0, 4657239462Sdim Tracker.getOpenLocation(), 4658226633Sdim EndLoc, D, 4659224145Sdim TrailingReturnType), 4660234353Sdim FnAttrs, EndLoc); 4661234353Sdim 4662234353Sdim Actions.ActOnEndFunctionDeclarator(); 4663224145Sdim} 4664224145Sdim 4665224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an 4666224145Sdim/// identifier list form for a K&R-style function: void foo(a,b,c) 4667224145Sdim/// 4668224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for 4669224145Sdim/// abstract-declarators. 4670224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() { 4671234353Sdim return !getLangOpts().CPlusPlus 4672224145Sdim && Tok.is(tok::identifier) 4673224145Sdim && !TryAltiVecVectorToken() 4674224145Sdim // K&R identifier lists can't have typedefs as identifiers, per C99 4675224145Sdim // 6.7.5.3p11. 4676224145Sdim && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) 4677224145Sdim // Identifier lists follow a really simple grammar: the identifiers can 4678224145Sdim // be followed *only* by a ", identifier" or ")". However, K&R 4679224145Sdim // identifier lists are really rare in the brave new modern world, and 4680224145Sdim // it is very common for someone to typo a type in a non-K&R style 4681224145Sdim // list. If we are presented with something like: "void foo(intptr x, 4682224145Sdim // float y)", we don't want to start parsing the function declarator as 4683224145Sdim // though it is a K&R style declarator just because intptr is an 4684224145Sdim // invalid type. 4685224145Sdim // 4686224145Sdim // To handle this, we check to see if the token after the first 4687224145Sdim // identifier is a "," or ")". Only then do we parse it as an 4688224145Sdim // identifier list. 4689224145Sdim && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); 4690224145Sdim} 4691224145Sdim 4692224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator 4693224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list. 4694224145Sdim/// 4695224145Sdim/// After returning, ParamInfo will hold the parsed parameters. 4696224145Sdim/// 4697224145Sdim/// identifier-list: [C99 6.7.5] 4698224145Sdim/// identifier 4699224145Sdim/// identifier-list ',' identifier 4700224145Sdim/// 4701224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList( 4702224145Sdim Declarator &D, 4703226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) { 4704224145Sdim // If there was no identifier specified for the declarator, either we are in 4705224145Sdim // an abstract-declarator, or we are in a parameter declarator which was found 4706224145Sdim // to be abstract. In abstract-declarators, identifier lists are not valid: 4707224145Sdim // diagnose this. 4708224145Sdim if (!D.getIdentifier()) 4709224145Sdim Diag(Tok, diag::ext_ident_list_in_param); 4710224145Sdim 4711224145Sdim // Maintain an efficient lookup of params we have seen so far. 4712224145Sdim llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar; 4713224145Sdim 4714224145Sdim while (1) { 4715224145Sdim // If this isn't an identifier, report the error and skip until ')'. 4716224145Sdim if (Tok.isNot(tok::identifier)) { 4717224145Sdim Diag(Tok, diag::err_expected_ident); 4718224145Sdim SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true); 4719224145Sdim // Forget we parsed anything. 4720224145Sdim ParamInfo.clear(); 4721224145Sdim return; 4722193326Sed } 4723198092Srdivacky 4724224145Sdim IdentifierInfo *ParmII = Tok.getIdentifierInfo(); 4725198092Srdivacky 4726224145Sdim // Reject 'typedef int y; int test(x, y)', but continue parsing. 4727224145Sdim if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope())) 4728224145Sdim Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; 4729193326Sed 4730224145Sdim // Verify that the argument identifier has not already been mentioned. 4731224145Sdim if (!ParamsSoFar.insert(ParmII)) { 4732224145Sdim Diag(Tok, diag::err_param_redefinition) << ParmII; 4733224145Sdim } else { 4734224145Sdim // Remember this identifier in ParamInfo. 4735224145Sdim ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 4736224145Sdim Tok.getLocation(), 4737224145Sdim 0)); 4738224145Sdim } 4739198092Srdivacky 4740224145Sdim // Eat the identifier. 4741224145Sdim ConsumeToken(); 4742224145Sdim 4743224145Sdim // The list continues if we see a comma. 4744224145Sdim if (Tok.isNot(tok::comma)) 4745224145Sdim break; 4746224145Sdim ConsumeToken(); 4747224145Sdim } 4748224145Sdim} 4749224145Sdim 4750224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list 4751224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style 4752224145Sdim/// identifier list. 4753224145Sdim/// 4754234353Sdim/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the 4755234353Sdim/// caller parsed those arguments immediately after the open paren - they should 4756234353Sdim/// be considered to be part of the first parameter. 4757224145Sdim/// 4758224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will 4759224145Sdim/// be the location of the ellipsis, if any was parsed. 4760224145Sdim/// 4761224145Sdim/// parameter-type-list: [C99 6.7.5] 4762224145Sdim/// parameter-list 4763224145Sdim/// parameter-list ',' '...' 4764224145Sdim/// [C++] parameter-list '...' 4765224145Sdim/// 4766224145Sdim/// parameter-list: [C99 6.7.5] 4767224145Sdim/// parameter-declaration 4768224145Sdim/// parameter-list ',' parameter-declaration 4769224145Sdim/// 4770224145Sdim/// parameter-declaration: [C99 6.7.5] 4771224145Sdim/// declaration-specifiers declarator 4772224145Sdim/// [C++] declaration-specifiers declarator '=' assignment-expression 4773234353Sdim/// [C++11] initializer-clause 4774224145Sdim/// [GNU] declaration-specifiers declarator attributes 4775224145Sdim/// declaration-specifiers abstract-declarator[opt] 4776224145Sdim/// [C++] declaration-specifiers abstract-declarator[opt] 4777224145Sdim/// '=' assignment-expression 4778224145Sdim/// [GNU] declaration-specifiers abstract-declarator[opt] attributes 4779234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration 4780224145Sdim/// 4781224145Sdimvoid Parser::ParseParameterDeclarationClause( 4782224145Sdim Declarator &D, 4783234353Sdim ParsedAttributes &FirstArgAttrs, 4784226633Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, 4785224145Sdim SourceLocation &EllipsisLoc) { 4786224145Sdim 4787193326Sed while (1) { 4788193326Sed if (Tok.is(tok::ellipsis)) { 4789234353Sdim // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq 4790234353Sdim // before deciding this was a parameter-declaration-clause. 4791193326Sed EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 4792193326Sed break; 4793193326Sed } 4794198092Srdivacky 4795193326Sed // Parse the declaration-specifiers. 4796198893Srdivacky // Just use the ParsingDeclaration "scope" of the declarator. 4797221345Sdim DeclSpec DS(AttrFactory); 4798226633Sdim 4799234353Sdim // Parse any C++11 attributes. 4800234353Sdim MaybeParseCXX0XAttributes(DS.getAttributes()); 4801234353Sdim 4802218893Sdim // Skip any Microsoft attributes before a param. 4803234353Sdim if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square)) 4804218893Sdim ParseMicrosoftAttributes(DS.getAttributes()); 4805193326Sed 4806218893Sdim SourceLocation DSStart = Tok.getLocation(); 4807218893Sdim 4808193326Sed // If the caller parsed attributes for the first argument, add them now. 4809218893Sdim // Take them so that we only apply the attributes to the first parameter. 4810224145Sdim // FIXME: If we can leave the attributes in the token stream somehow, we can 4811234353Sdim // get rid of a parameter (FirstArgAttrs) and this statement. It might be 4812234353Sdim // too much hassle. 4813234353Sdim DS.takeAttributesFrom(FirstArgAttrs); 4814218893Sdim 4815193326Sed ParseDeclarationSpecifiers(DS); 4816198092Srdivacky 4817193326Sed // Parse the declarator. This is "PrototypeContext", because we must 4818193326Sed // accept either 'declarator' or 'abstract-declarator' here. 4819193326Sed Declarator ParmDecl(DS, Declarator::PrototypeContext); 4820193326Sed ParseDeclarator(ParmDecl); 4821193326Sed 4822193326Sed // Parse GNU attributes, if present. 4823218893Sdim MaybeParseGNUAttributes(ParmDecl); 4824198092Srdivacky 4825193326Sed // Remember this parsed parameter in ParamInfo. 4826193326Sed IdentifierInfo *ParmII = ParmDecl.getIdentifier(); 4827198092Srdivacky 4828193326Sed // DefArgToks is used when the parsing of default arguments needs 4829193326Sed // to be delayed. 4830193326Sed CachedTokens *DefArgToks = 0; 4831193326Sed 4832193326Sed // If no parameter was specified, verify that *something* was specified, 4833193326Sed // otherwise we have a missing type and identifier. 4834193326Sed if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 && 4835193326Sed ParmDecl.getNumTypeObjects() == 0) { 4836193326Sed // Completely missing, emit error. 4837193326Sed Diag(DSStart, diag::err_missing_param); 4838193326Sed } else { 4839193326Sed // Otherwise, we have something. Add it and let semantic analysis try 4840193326Sed // to grok it and add the result to the ParamInfo we are building. 4841198092Srdivacky 4842193326Sed // Inform the actions module about the parameter declarator, so it gets 4843193326Sed // added to the current scope. 4844212904Sdim Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); 4845193326Sed 4846193326Sed // Parse the default argument, if any. We parse the default 4847193326Sed // arguments in all dialects; the semantic analysis in 4848193326Sed // ActOnParamDefaultArgument will reject the default argument in 4849193326Sed // C. 4850193326Sed if (Tok.is(tok::equal)) { 4851193326Sed SourceLocation EqualLoc = Tok.getLocation(); 4852193326Sed 4853193326Sed // Parse the default argument 4854193326Sed if (D.getContext() == Declarator::MemberContext) { 4855193326Sed // If we're inside a class definition, cache the tokens 4856193326Sed // corresponding to the default argument. We'll actually parse 4857193326Sed // them when we see the end of the class definition. 4858193326Sed // FIXME: Can we use a smart pointer for Toks? 4859193326Sed DefArgToks = new CachedTokens; 4860193326Sed 4861198092Srdivacky if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks, 4862207619Srdivacky /*StopAtSemi=*/true, 4863207619Srdivacky /*ConsumeFinalToken=*/false)) { 4864193326Sed delete DefArgToks; 4865193326Sed DefArgToks = 0; 4866193326Sed Actions.ActOnParamDefaultArgumentError(Param); 4867212904Sdim } else { 4868212904Sdim // Mark the end of the default argument so that we know when to 4869212904Sdim // stop when we parse it later on. 4870212904Sdim Token DefArgEnd; 4871212904Sdim DefArgEnd.startToken(); 4872212904Sdim DefArgEnd.setKind(tok::cxx_defaultarg_end); 4873212904Sdim DefArgEnd.setLocation(Tok.getLocation()); 4874212904Sdim DefArgToks->push_back(DefArgEnd); 4875198092Srdivacky Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, 4876194179Sed (*DefArgToks)[1].getLocation()); 4877212904Sdim } 4878193326Sed } else { 4879193326Sed // Consume the '='. 4880193326Sed ConsumeToken(); 4881198092Srdivacky 4882239462Sdim // The argument isn't actually potentially evaluated unless it is 4883218893Sdim // used. 4884218893Sdim EnterExpressionEvaluationContext Eval(Actions, 4885234353Sdim Sema::PotentiallyEvaluatedIfUsed, 4886234353Sdim Param); 4887218893Sdim 4888234353Sdim ExprResult DefArgResult; 4889234353Sdim if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 4890234353Sdim Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 4891234353Sdim DefArgResult = ParseBraceInitializer(); 4892234353Sdim } else 4893234353Sdim DefArgResult = ParseAssignmentExpression(); 4894193326Sed if (DefArgResult.isInvalid()) { 4895193326Sed Actions.ActOnParamDefaultArgumentError(Param); 4896193326Sed SkipUntil(tok::comma, tok::r_paren, true, true); 4897193326Sed } else { 4898193326Sed // Inform the actions module about the default argument 4899193326Sed Actions.ActOnParamDefaultArgument(Param, EqualLoc, 4900212904Sdim DefArgResult.take()); 4901193326Sed } 4902193326Sed } 4903193326Sed } 4904198092Srdivacky 4905198092Srdivacky ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 4906198092Srdivacky ParmDecl.getIdentifierLoc(), Param, 4907193326Sed DefArgToks)); 4908193326Sed } 4909193326Sed 4910193326Sed // If the next token is a comma, consume it and keep reading arguments. 4911198092Srdivacky if (Tok.isNot(tok::comma)) { 4912198092Srdivacky if (Tok.is(tok::ellipsis)) { 4913198092Srdivacky EllipsisLoc = ConsumeToken(); // Consume the ellipsis. 4914239462Sdim 4915234353Sdim if (!getLangOpts().CPlusPlus) { 4916198092Srdivacky // We have ellipsis without a preceding ',', which is ill-formed 4917198092Srdivacky // in C. Complain and provide the fix. 4918198092Srdivacky Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis) 4919206084Srdivacky << FixItHint::CreateInsertion(EllipsisLoc, ", "); 4920198092Srdivacky } 4921198092Srdivacky } 4922239462Sdim 4923198092Srdivacky break; 4924198092Srdivacky } 4925198092Srdivacky 4926193326Sed // Consume the comma. 4927193326Sed ConsumeToken(); 4928193326Sed } 4929198092Srdivacky 4930193326Sed} 4931193326Sed 4932193326Sed/// [C90] direct-declarator '[' constant-expression[opt] ']' 4933193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']' 4934193326Sed/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']' 4935193326Sed/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']' 4936193326Sed/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']' 4937234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']' 4938234353Sdim/// attribute-specifier-seq[opt] 4939193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) { 4940234353Sdim if (CheckProhibitedCXX11Attribute()) 4941234353Sdim return; 4942234353Sdim 4943226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 4944226633Sdim T.consumeOpen(); 4945198092Srdivacky 4946193326Sed // C array syntax has many features, but by-far the most common is [] and [4]. 4947193326Sed // This code does a fast path to handle some of the most obvious cases. 4948193326Sed if (Tok.getKind() == tok::r_square) { 4949226633Sdim T.consumeClose(); 4950221345Sdim ParsedAttributes attrs(AttrFactory); 4951218893Sdim MaybeParseCXX0XAttributes(attrs); 4952239462Sdim 4953193326Sed // Remember that we parsed the empty array type. 4954212904Sdim ExprResult NumElements; 4955221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, 4956226633Sdim T.getOpenLocation(), 4957226633Sdim T.getCloseLocation()), 4958226633Sdim attrs, T.getCloseLocation()); 4959193326Sed return; 4960193326Sed } else if (Tok.getKind() == tok::numeric_constant && 4961193326Sed GetLookAheadToken(1).is(tok::r_square)) { 4962193326Sed // [4] is very common. Parse the numeric constant expression. 4963234353Sdim ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope())); 4964193326Sed ConsumeToken(); 4965193326Sed 4966226633Sdim T.consumeClose(); 4967221345Sdim ParsedAttributes attrs(AttrFactory); 4968218893Sdim MaybeParseCXX0XAttributes(attrs); 4969193326Sed 4970193326Sed // Remember that we parsed a array type, and remember its features. 4971221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, 4972218893Sdim ExprRes.release(), 4973226633Sdim T.getOpenLocation(), 4974226633Sdim T.getCloseLocation()), 4975226633Sdim attrs, T.getCloseLocation()); 4976193326Sed return; 4977193326Sed } 4978198092Srdivacky 4979193326Sed // If valid, this location is the position where we read the 'static' keyword. 4980193326Sed SourceLocation StaticLoc; 4981193326Sed if (Tok.is(tok::kw_static)) 4982193326Sed StaticLoc = ConsumeToken(); 4983198092Srdivacky 4984193326Sed // If there is a type-qualifier-list, read it now. 4985193326Sed // Type qualifiers in an array subscript are a C99 feature. 4986221345Sdim DeclSpec DS(AttrFactory); 4987193326Sed ParseTypeQualifierListOpt(DS, false /*no attributes*/); 4988198092Srdivacky 4989193326Sed // If we haven't already read 'static', check to see if there is one after the 4990193326Sed // type-qualifier-list. 4991193326Sed if (!StaticLoc.isValid() && Tok.is(tok::kw_static)) 4992193326Sed StaticLoc = ConsumeToken(); 4993198092Srdivacky 4994193326Sed // Handle "direct-declarator [ type-qual-list[opt] * ]". 4995193326Sed bool isStar = false; 4996212904Sdim ExprResult NumElements; 4997198092Srdivacky 4998193326Sed // Handle the case where we have '[*]' as the array size. However, a leading 4999193326Sed // star could be the start of an expression, for example 'X[*p + 4]'. Verify 5000239462Sdim // the token after the star is a ']'. Since stars in arrays are 5001193326Sed // infrequent, use of lookahead is not costly here. 5002193326Sed if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) { 5003193326Sed ConsumeToken(); // Eat the '*'. 5004193326Sed 5005193326Sed if (StaticLoc.isValid()) { 5006193326Sed Diag(StaticLoc, diag::err_unspecified_vla_size_with_static); 5007193326Sed StaticLoc = SourceLocation(); // Drop the static. 5008193326Sed } 5009193326Sed isStar = true; 5010193326Sed } else if (Tok.isNot(tok::r_square)) { 5011193326Sed // Note, in C89, this production uses the constant-expr production instead 5012193326Sed // of assignment-expr. The only difference is that assignment-expr allows 5013193326Sed // things like '=' and '*='. Sema rejects these in C89 mode because they 5014193326Sed // are not i-c-e's, so we don't need to distinguish between the two here. 5015198092Srdivacky 5016194613Sed // Parse the constant-expression or assignment-expression now (depending 5017194613Sed // on dialect). 5018234353Sdim if (getLangOpts().CPlusPlus) { 5019194613Sed NumElements = ParseConstantExpression(); 5020234353Sdim } else { 5021234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, 5022234353Sdim Sema::ConstantEvaluated); 5023194613Sed NumElements = ParseAssignmentExpression(); 5024234353Sdim } 5025193326Sed } 5026198092Srdivacky 5027193326Sed // If there was an error parsing the assignment-expression, recover. 5028193326Sed if (NumElements.isInvalid()) { 5029193326Sed D.setInvalidType(true); 5030193326Sed // If the expression was invalid, skip it. 5031193326Sed SkipUntil(tok::r_square); 5032193326Sed return; 5033193326Sed } 5034193326Sed 5035226633Sdim T.consumeClose(); 5036193326Sed 5037221345Sdim ParsedAttributes attrs(AttrFactory); 5038218893Sdim MaybeParseCXX0XAttributes(attrs); 5039199990Srdivacky 5040193326Sed // Remember that we parsed a array type, and remember its features. 5041221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), 5042193326Sed StaticLoc.isValid(), isStar, 5043198092Srdivacky NumElements.release(), 5044226633Sdim T.getOpenLocation(), 5045226633Sdim T.getCloseLocation()), 5046226633Sdim attrs, T.getCloseLocation()); 5047193326Sed} 5048193326Sed 5049193326Sed/// [GNU] typeof-specifier: 5050193326Sed/// typeof ( expressions ) 5051193326Sed/// typeof ( type-name ) 5052193326Sed/// [GNU/C++] typeof unary-expression 5053193326Sed/// 5054193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) { 5055193326Sed assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); 5056193326Sed Token OpTok = Tok; 5057193326Sed SourceLocation StartLoc = ConsumeToken(); 5058193326Sed 5059202379Srdivacky const bool hasParens = Tok.is(tok::l_paren); 5060202379Srdivacky 5061234353Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 5062234353Sdim 5063193326Sed bool isCastExpr; 5064212904Sdim ParsedType CastTy; 5065193326Sed SourceRange CastRange; 5066221345Sdim ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, 5067221345Sdim CastTy, CastRange); 5068202379Srdivacky if (hasParens) 5069202379Srdivacky DS.setTypeofParensRange(CastRange); 5070193326Sed 5071193326Sed if (CastRange.getEnd().isInvalid()) 5072193326Sed // FIXME: Not accurate, the range gets one token more than it should. 5073193326Sed DS.SetRangeEnd(Tok.getLocation()); 5074193326Sed else 5075193326Sed DS.SetRangeEnd(CastRange.getEnd()); 5076198092Srdivacky 5077193326Sed if (isCastExpr) { 5078193326Sed if (!CastTy) { 5079193326Sed DS.SetTypeSpecError(); 5080193326Sed return; 5081193326Sed } 5082193326Sed 5083193326Sed const char *PrevSpec = 0; 5084198092Srdivacky unsigned DiagID; 5085193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5086193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 5087198092Srdivacky DiagID, CastTy)) 5088198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5089193326Sed return; 5090193326Sed } 5091193326Sed 5092193326Sed // If we get here, the operand to the typeof was an expresion. 5093193326Sed if (Operand.isInvalid()) { 5094193326Sed DS.SetTypeSpecError(); 5095193326Sed return; 5096193326Sed } 5097193326Sed 5098234353Sdim // We might need to transform the operand if it is potentially evaluated. 5099234353Sdim Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get()); 5100234353Sdim if (Operand.isInvalid()) { 5101234353Sdim DS.SetTypeSpecError(); 5102234353Sdim return; 5103234353Sdim } 5104234353Sdim 5105193326Sed const char *PrevSpec = 0; 5106198092Srdivacky unsigned DiagID; 5107193326Sed // Check for duplicate type specifiers (e.g. "int typeof(int)"). 5108193326Sed if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 5109212904Sdim DiagID, Operand.get())) 5110198092Srdivacky Diag(StartLoc, DiagID) << PrevSpec; 5111193326Sed} 5112204643Srdivacky 5113234353Sdim/// [C11] atomic-specifier: 5114226633Sdim/// _Atomic ( type-name ) 5115226633Sdim/// 5116226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) { 5117226633Sdim assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier"); 5118204643Srdivacky 5119226633Sdim SourceLocation StartLoc = ConsumeToken(); 5120226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 5121226633Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) { 5122226633Sdim SkipUntil(tok::r_paren); 5123226633Sdim return; 5124226633Sdim } 5125226633Sdim 5126226633Sdim TypeResult Result = ParseTypeName(); 5127226633Sdim if (Result.isInvalid()) { 5128226633Sdim SkipUntil(tok::r_paren); 5129226633Sdim return; 5130226633Sdim } 5131226633Sdim 5132226633Sdim // Match the ')' 5133226633Sdim T.consumeClose(); 5134226633Sdim 5135226633Sdim if (T.getCloseLocation().isInvalid()) 5136226633Sdim return; 5137226633Sdim 5138226633Sdim DS.setTypeofParensRange(T.getRange()); 5139226633Sdim DS.SetRangeEnd(T.getCloseLocation()); 5140226633Sdim 5141226633Sdim const char *PrevSpec = 0; 5142226633Sdim unsigned DiagID; 5143226633Sdim if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec, 5144226633Sdim DiagID, Result.release())) 5145226633Sdim Diag(StartLoc, DiagID) << PrevSpec; 5146226633Sdim} 5147226633Sdim 5148226633Sdim 5149204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called 5150204643Srdivacky/// from TryAltiVecVectorToken. 5151204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() { 5152204643Srdivacky Token Next = NextToken(); 5153204643Srdivacky switch (Next.getKind()) { 5154204643Srdivacky default: return false; 5155204643Srdivacky case tok::kw_short: 5156204643Srdivacky case tok::kw_long: 5157204643Srdivacky case tok::kw_signed: 5158204643Srdivacky case tok::kw_unsigned: 5159204643Srdivacky case tok::kw_void: 5160204643Srdivacky case tok::kw_char: 5161204643Srdivacky case tok::kw_int: 5162204643Srdivacky case tok::kw_float: 5163204643Srdivacky case tok::kw_double: 5164204643Srdivacky case tok::kw_bool: 5165204643Srdivacky case tok::kw___pixel: 5166204643Srdivacky Tok.setKind(tok::kw___vector); 5167204643Srdivacky return true; 5168204643Srdivacky case tok::identifier: 5169204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5170204643Srdivacky Tok.setKind(tok::kw___vector); 5171204643Srdivacky return true; 5172204643Srdivacky } 5173204643Srdivacky return false; 5174204643Srdivacky } 5175204643Srdivacky} 5176204643Srdivacky 5177204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, 5178204643Srdivacky const char *&PrevSpec, unsigned &DiagID, 5179204643Srdivacky bool &isInvalid) { 5180204643Srdivacky if (Tok.getIdentifierInfo() == Ident_vector) { 5181204643Srdivacky Token Next = NextToken(); 5182204643Srdivacky switch (Next.getKind()) { 5183204643Srdivacky case tok::kw_short: 5184204643Srdivacky case tok::kw_long: 5185204643Srdivacky case tok::kw_signed: 5186204643Srdivacky case tok::kw_unsigned: 5187204643Srdivacky case tok::kw_void: 5188204643Srdivacky case tok::kw_char: 5189204643Srdivacky case tok::kw_int: 5190204643Srdivacky case tok::kw_float: 5191204643Srdivacky case tok::kw_double: 5192204643Srdivacky case tok::kw_bool: 5193204643Srdivacky case tok::kw___pixel: 5194204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5195204643Srdivacky return true; 5196204643Srdivacky case tok::identifier: 5197204643Srdivacky if (Next.getIdentifierInfo() == Ident_pixel) { 5198204643Srdivacky isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); 5199204643Srdivacky return true; 5200204643Srdivacky } 5201204643Srdivacky break; 5202204643Srdivacky default: 5203204643Srdivacky break; 5204204643Srdivacky } 5205210299Sed } else if ((Tok.getIdentifierInfo() == Ident_pixel) && 5206204643Srdivacky DS.isTypeAltiVecVector()) { 5207204643Srdivacky isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); 5208204643Srdivacky return true; 5209204643Srdivacky } 5210204643Srdivacky return false; 5211204643Srdivacky} 5212