1193326Sed//===--- ParseExprCXX.cpp - C++ Expression 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 Expression parsing implementation for C++. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13263508Sdim#include "clang/AST/DeclTemplate.h" 14193326Sed#include "clang/Parse/Parser.h" 15218893Sdim#include "RAIIObjectsForParser.h" 16234353Sdim#include "clang/Basic/PrettyStackTrace.h" 17234353Sdim#include "clang/Lex/LiteralSupport.h" 18249423Sdim#include "clang/Parse/ParseDiagnostic.h" 19212904Sdim#include "clang/Sema/DeclSpec.h" 20249423Sdim#include "clang/Sema/ParsedTemplate.h" 21226633Sdim#include "clang/Sema/Scope.h" 22198893Srdivacky#include "llvm/Support/ErrorHandling.h" 23198893Srdivacky 24263508Sdim 25193326Sedusing namespace clang; 26193326Sed 27221345Sdimstatic int SelectDigraphErrorMessage(tok::TokenKind Kind) { 28221345Sdim switch (Kind) { 29221345Sdim case tok::kw_template: return 0; 30221345Sdim case tok::kw_const_cast: return 1; 31221345Sdim case tok::kw_dynamic_cast: return 2; 32221345Sdim case tok::kw_reinterpret_cast: return 3; 33221345Sdim case tok::kw_static_cast: return 4; 34221345Sdim default: 35226633Sdim llvm_unreachable("Unknown type for digraph error message."); 36221345Sdim } 37221345Sdim} 38221345Sdim 39221345Sdim// Are the two tokens adjacent in the same source file? 40239462Sdimbool Parser::areTokensAdjacent(const Token &First, const Token &Second) { 41221345Sdim SourceManager &SM = PP.getSourceManager(); 42221345Sdim SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation()); 43226633Sdim SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength()); 44221345Sdim return FirstEnd == SM.getSpellingLoc(Second.getLocation()); 45221345Sdim} 46221345Sdim 47221345Sdim// Suggest fixit for "<::" after a cast. 48221345Sdimstatic void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, 49221345Sdim Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) { 50221345Sdim // Pull '<:' and ':' off token stream. 51221345Sdim if (!AtDigraph) 52221345Sdim PP.Lex(DigraphToken); 53221345Sdim PP.Lex(ColonToken); 54221345Sdim 55221345Sdim SourceRange Range; 56221345Sdim Range.setBegin(DigraphToken.getLocation()); 57221345Sdim Range.setEnd(ColonToken.getLocation()); 58221345Sdim P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph) 59221345Sdim << SelectDigraphErrorMessage(Kind) 60221345Sdim << FixItHint::CreateReplacement(Range, "< ::"); 61221345Sdim 62221345Sdim // Update token information to reflect their change in token type. 63221345Sdim ColonToken.setKind(tok::coloncolon); 64226633Sdim ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1)); 65221345Sdim ColonToken.setLength(2); 66221345Sdim DigraphToken.setKind(tok::less); 67221345Sdim DigraphToken.setLength(1); 68221345Sdim 69221345Sdim // Push new tokens back to token stream. 70221345Sdim PP.EnterToken(ColonToken); 71221345Sdim if (!AtDigraph) 72221345Sdim PP.EnterToken(DigraphToken); 73221345Sdim} 74221345Sdim 75226633Sdim// Check for '<::' which should be '< ::' instead of '[:' when following 76226633Sdim// a template name. 77226633Sdimvoid Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, 78226633Sdim bool EnteringContext, 79226633Sdim IdentifierInfo &II, CXXScopeSpec &SS) { 80226633Sdim if (!Next.is(tok::l_square) || Next.getLength() != 2) 81226633Sdim return; 82226633Sdim 83226633Sdim Token SecondToken = GetLookAheadToken(2); 84239462Sdim if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken)) 85226633Sdim return; 86226633Sdim 87226633Sdim TemplateTy Template; 88226633Sdim UnqualifiedId TemplateName; 89226633Sdim TemplateName.setIdentifier(&II, Tok.getLocation()); 90226633Sdim bool MemberOfUnknownSpecialization; 91226633Sdim if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, 92226633Sdim TemplateName, ObjectType, EnteringContext, 93226633Sdim Template, MemberOfUnknownSpecialization)) 94226633Sdim return; 95226633Sdim 96226633Sdim FixDigraph(*this, PP, Next, SecondToken, tok::kw_template, 97226633Sdim /*AtDigraph*/false); 98226633Sdim} 99226633Sdim 100243830Sdim/// \brief Emits an error for a left parentheses after a double colon. 101243830Sdim/// 102243830Sdim/// When a '(' is found after a '::', emit an error. Attempt to fix the token 103249423Sdim/// stream by removing the '(', and the matching ')' if found. 104243830Sdimvoid Parser::CheckForLParenAfterColonColon() { 105243830Sdim if (!Tok.is(tok::l_paren)) 106243830Sdim return; 107243830Sdim 108243830Sdim SourceLocation l_parenLoc = ConsumeParen(), r_parenLoc; 109243830Sdim Token Tok1 = getCurToken(); 110243830Sdim if (!Tok1.is(tok::identifier) && !Tok1.is(tok::star)) 111243830Sdim return; 112243830Sdim 113243830Sdim if (Tok1.is(tok::identifier)) { 114243830Sdim Token Tok2 = GetLookAheadToken(1); 115243830Sdim if (Tok2.is(tok::r_paren)) { 116243830Sdim ConsumeToken(); 117243830Sdim PP.EnterToken(Tok1); 118243830Sdim r_parenLoc = ConsumeParen(); 119243830Sdim } 120243830Sdim } else if (Tok1.is(tok::star)) { 121243830Sdim Token Tok2 = GetLookAheadToken(1); 122243830Sdim if (Tok2.is(tok::identifier)) { 123243830Sdim Token Tok3 = GetLookAheadToken(2); 124243830Sdim if (Tok3.is(tok::r_paren)) { 125243830Sdim ConsumeToken(); 126243830Sdim ConsumeToken(); 127243830Sdim PP.EnterToken(Tok2); 128243830Sdim PP.EnterToken(Tok1); 129243830Sdim r_parenLoc = ConsumeParen(); 130243830Sdim } 131243830Sdim } 132243830Sdim } 133243830Sdim 134243830Sdim Diag(l_parenLoc, diag::err_paren_after_colon_colon) 135243830Sdim << FixItHint::CreateRemoval(l_parenLoc) 136243830Sdim << FixItHint::CreateRemoval(r_parenLoc); 137243830Sdim} 138243830Sdim 139198092Srdivacky/// \brief Parse global scope or nested-name-specifier if present. 140193326Sed/// 141198092Srdivacky/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 142198092Srdivacky/// may be preceded by '::'). Note that this routine will not parse ::new or 143198092Srdivacky/// ::delete; it will just leave them in the token stream. 144198092Srdivacky/// 145193326Sed/// '::'[opt] nested-name-specifier 146193326Sed/// '::' 147193326Sed/// 148193326Sed/// nested-name-specifier: 149193326Sed/// type-name '::' 150193326Sed/// namespace-name '::' 151193326Sed/// nested-name-specifier identifier '::' 152198092Srdivacky/// nested-name-specifier 'template'[opt] simple-template-id '::' 153193326Sed/// 154198092Srdivacky/// 155198092Srdivacky/// \param SS the scope specifier that will be set to the parsed 156198092Srdivacky/// nested-name-specifier (or empty) 157198092Srdivacky/// 158198092Srdivacky/// \param ObjectType if this nested-name-specifier is being parsed following 159198092Srdivacky/// the "." or "->" of a member access expression, this parameter provides the 160198092Srdivacky/// type of the object whose members are being accessed. 161198092Srdivacky/// 162198092Srdivacky/// \param EnteringContext whether we will be entering into the context of 163198092Srdivacky/// the nested-name-specifier after parsing it. 164198092Srdivacky/// 165204643Srdivacky/// \param MayBePseudoDestructor When non-NULL, points to a flag that 166204643Srdivacky/// indicates whether this nested-name-specifier may be part of a 167204643Srdivacky/// pseudo-destructor name. In this case, the flag will be set false 168204643Srdivacky/// if we don't actually end up parsing a destructor name. Moreorover, 169204643Srdivacky/// if we do end up determining that we are parsing a destructor name, 170204643Srdivacky/// the last component of the nested-name-specifier is not parsed as 171204643Srdivacky/// part of the scope specifier. 172204643Srdivacky/// 173249423Sdim/// \param IsTypename If \c true, this nested-name-specifier is known to be 174249423Sdim/// part of a type name. This is used to improve error recovery. 175249423Sdim/// 176249423Sdim/// \param LastII When non-NULL, points to an IdentifierInfo* that will be 177249423Sdim/// filled in with the leading identifier in the last component of the 178249423Sdim/// nested-name-specifier, if any. 179249423Sdim/// 180204643Srdivacky/// \returns true if there was an error parsing a scope specifier 181198092Srdivackybool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 182212904Sdim ParsedType ObjectType, 183204643Srdivacky bool EnteringContext, 184221345Sdim bool *MayBePseudoDestructor, 185249423Sdim bool IsTypename, 186249423Sdim IdentifierInfo **LastII) { 187234353Sdim assert(getLangOpts().CPlusPlus && 188193326Sed "Call sites of this function should be guarded by checking for C++"); 189193326Sed 190193326Sed if (Tok.is(tok::annot_cxxscope)) { 191249423Sdim assert(!LastII && "want last identifier but have already annotated scope"); 192219077Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 193219077Sdim Tok.getAnnotationRange(), 194219077Sdim SS); 195193326Sed ConsumeToken(); 196204643Srdivacky return false; 197193326Sed } 198193326Sed 199263508Sdim if (Tok.is(tok::annot_template_id)) { 200263508Sdim // If the current token is an annotated template id, it may already have 201263508Sdim // a scope specifier. Restore it. 202263508Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 203263508Sdim SS = TemplateId->SS; 204263508Sdim } 205263508Sdim 206249423Sdim if (LastII) 207249423Sdim *LastII = 0; 208249423Sdim 209193326Sed bool HasScopeSpecifier = false; 210193326Sed 211193326Sed if (Tok.is(tok::coloncolon)) { 212193326Sed // ::new and ::delete aren't nested-name-specifiers. 213193326Sed tok::TokenKind NextKind = NextToken().getKind(); 214193326Sed if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 215193326Sed return false; 216198092Srdivacky 217193326Sed // '::' - Global scope qualifier. 218219077Sdim if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS)) 219219077Sdim return true; 220243830Sdim 221243830Sdim CheckForLParenAfterColonColon(); 222243830Sdim 223193326Sed HasScopeSpecifier = true; 224193326Sed } 225193326Sed 226204643Srdivacky bool CheckForDestructor = false; 227204643Srdivacky if (MayBePseudoDestructor && *MayBePseudoDestructor) { 228204643Srdivacky CheckForDestructor = true; 229204643Srdivacky *MayBePseudoDestructor = false; 230204643Srdivacky } 231204643Srdivacky 232234353Sdim if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 233234353Sdim DeclSpec DS(AttrFactory); 234234353Sdim SourceLocation DeclLoc = Tok.getLocation(); 235234353Sdim SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 236234353Sdim if (Tok.isNot(tok::coloncolon)) { 237234353Sdim AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc); 238234353Sdim return false; 239234353Sdim } 240234353Sdim 241234353Sdim SourceLocation CCLoc = ConsumeToken(); 242234353Sdim if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc)) 243234353Sdim SS.SetInvalid(SourceRange(DeclLoc, CCLoc)); 244234353Sdim 245234353Sdim HasScopeSpecifier = true; 246234353Sdim } 247234353Sdim 248193326Sed while (true) { 249198092Srdivacky if (HasScopeSpecifier) { 250198092Srdivacky // C++ [basic.lookup.classref]p5: 251198092Srdivacky // If the qualified-id has the form 252198092Srdivacky // 253198092Srdivacky // ::class-name-or-namespace-name::... 254198092Srdivacky // 255198092Srdivacky // the class-name-or-namespace-name is looked up in global scope as a 256198092Srdivacky // class-name or namespace-name. 257198092Srdivacky // 258198092Srdivacky // To implement this, we clear out the object type as soon as we've 259198092Srdivacky // seen a leading '::' or part of a nested-name-specifier. 260212904Sdim ObjectType = ParsedType(); 261198092Srdivacky 262198092Srdivacky if (Tok.is(tok::code_completion)) { 263198092Srdivacky // Code completion for a nested-name-specifier, where the code 264198092Srdivacky // code completion token follows the '::'. 265210299Sed Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext); 266221345Sdim // Include code completion token into the range of the scope otherwise 267221345Sdim // when we try to annotate the scope tokens the dangling code completion 268221345Sdim // token will cause assertion in 269221345Sdim // Preprocessor::AnnotatePreviousCachedTokens. 270226633Sdim SS.setEndLoc(Tok.getLocation()); 271226633Sdim cutOffParsing(); 272226633Sdim return true; 273198092Srdivacky } 274198092Srdivacky } 275198092Srdivacky 276193326Sed // nested-name-specifier: 277195099Sed // nested-name-specifier 'template'[opt] simple-template-id '::' 278195099Sed 279195099Sed // Parse the optional 'template' keyword, then make sure we have 280195099Sed // 'identifier <' after it. 281195099Sed if (Tok.is(tok::kw_template)) { 282198092Srdivacky // If we don't have a scope specifier or an object type, this isn't a 283198092Srdivacky // nested-name-specifier, since they aren't allowed to start with 284198092Srdivacky // 'template'. 285198092Srdivacky if (!HasScopeSpecifier && !ObjectType) 286198092Srdivacky break; 287198092Srdivacky 288199482Srdivacky TentativeParsingAction TPA(*this); 289195099Sed SourceLocation TemplateKWLoc = ConsumeToken(); 290198893Srdivacky 291198893Srdivacky UnqualifiedId TemplateName; 292198893Srdivacky if (Tok.is(tok::identifier)) { 293199482Srdivacky // Consume the identifier. 294198893Srdivacky TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 295198893Srdivacky ConsumeToken(); 296198893Srdivacky } else if (Tok.is(tok::kw_operator)) { 297198893Srdivacky if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 298199482Srdivacky TemplateName)) { 299199482Srdivacky TPA.Commit(); 300198893Srdivacky break; 301199482Srdivacky } 302198893Srdivacky 303199990Srdivacky if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId && 304199990Srdivacky TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) { 305198893Srdivacky Diag(TemplateName.getSourceRange().getBegin(), 306198893Srdivacky diag::err_id_after_template_in_nested_name_spec) 307198893Srdivacky << TemplateName.getSourceRange(); 308199482Srdivacky TPA.Commit(); 309198893Srdivacky break; 310198893Srdivacky } 311198893Srdivacky } else { 312199482Srdivacky TPA.Revert(); 313195099Sed break; 314193326Sed } 315198092Srdivacky 316199482Srdivacky // If the next token is not '<', we have a qualified-id that refers 317199482Srdivacky // to a template name, such as T::template apply, but is not a 318199482Srdivacky // template-id. 319199482Srdivacky if (Tok.isNot(tok::less)) { 320199482Srdivacky TPA.Revert(); 321199482Srdivacky break; 322199482Srdivacky } 323199482Srdivacky 324199482Srdivacky // Commit to parsing the template-id. 325199482Srdivacky TPA.Commit(); 326210299Sed TemplateTy Template; 327234353Sdim if (TemplateNameKind TNK 328234353Sdim = Actions.ActOnDependentTemplateName(getCurScope(), 329234353Sdim SS, TemplateKWLoc, TemplateName, 330234353Sdim ObjectType, EnteringContext, 331234353Sdim Template)) { 332234353Sdim if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc, 333234353Sdim TemplateName, false)) 334210299Sed return true; 335210299Sed } else 336204643Srdivacky return true; 337198092Srdivacky 338193326Sed continue; 339193326Sed } 340198092Srdivacky 341193326Sed if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 342198092Srdivacky // We have 343193326Sed // 344193326Sed // simple-template-id '::' 345193326Sed // 346193326Sed // So we need to check whether the simple-template-id is of the 347193326Sed // right kind (it should name a type or be dependent), and then 348193326Sed // convert it into a type within the nested-name-specifier. 349224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 350204643Srdivacky if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 351204643Srdivacky *MayBePseudoDestructor = true; 352204643Srdivacky return false; 353204643Srdivacky } 354193326Sed 355249423Sdim if (LastII) 356249423Sdim *LastII = TemplateId->Name; 357249423Sdim 358221345Sdim // Consume the template-id token. 359221345Sdim ConsumeToken(); 360221345Sdim 361221345Sdim assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 362221345Sdim SourceLocation CCLoc = ConsumeToken(); 363193326Sed 364234353Sdim HasScopeSpecifier = true; 365221345Sdim 366243830Sdim ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 367221345Sdim TemplateId->NumArgs); 368221345Sdim 369221345Sdim if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), 370234353Sdim SS, 371234353Sdim TemplateId->TemplateKWLoc, 372221345Sdim TemplateId->Template, 373221345Sdim TemplateId->TemplateNameLoc, 374221345Sdim TemplateId->LAngleLoc, 375221345Sdim TemplateArgsPtr, 376221345Sdim TemplateId->RAngleLoc, 377221345Sdim CCLoc, 378221345Sdim EnteringContext)) { 379221345Sdim SourceLocation StartLoc 380221345Sdim = SS.getBeginLoc().isValid()? SS.getBeginLoc() 381221345Sdim : TemplateId->TemplateNameLoc; 382221345Sdim SS.SetInvalid(SourceRange(StartLoc, CCLoc)); 383195099Sed } 384223017Sdim 385221345Sdim continue; 386193326Sed } 387193326Sed 388195099Sed 389195099Sed // The rest of the nested-name-specifier possibilities start with 390195099Sed // tok::identifier. 391195099Sed if (Tok.isNot(tok::identifier)) 392195099Sed break; 393195099Sed 394195099Sed IdentifierInfo &II = *Tok.getIdentifierInfo(); 395195099Sed 396195099Sed // nested-name-specifier: 397195099Sed // type-name '::' 398195099Sed // namespace-name '::' 399195099Sed // nested-name-specifier identifier '::' 400195099Sed Token Next = NextToken(); 401200583Srdivacky 402200583Srdivacky // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 403200583Srdivacky // and emit a fixit hint for it. 404204643Srdivacky if (Next.is(tok::colon) && !ColonIsSacred) { 405219077Sdim if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II, 406219077Sdim Tok.getLocation(), 407219077Sdim Next.getLocation(), ObjectType, 408204643Srdivacky EnteringContext) && 409204643Srdivacky // If the token after the colon isn't an identifier, it's still an 410204643Srdivacky // error, but they probably meant something else strange so don't 411204643Srdivacky // recover like this. 412204643Srdivacky PP.LookAhead(1).is(tok::identifier)) { 413204643Srdivacky Diag(Next, diag::err_unexected_colon_in_nested_name_spec) 414206084Srdivacky << FixItHint::CreateReplacement(Next.getLocation(), "::"); 415204643Srdivacky 416204643Srdivacky // Recover as if the user wrote '::'. 417204643Srdivacky Next.setKind(tok::coloncolon); 418204643Srdivacky } 419200583Srdivacky } 420200583Srdivacky 421195099Sed if (Next.is(tok::coloncolon)) { 422204643Srdivacky if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && 423210299Sed !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, Tok.getLocation(), 424204643Srdivacky II, ObjectType)) { 425204643Srdivacky *MayBePseudoDestructor = true; 426204643Srdivacky return false; 427204643Srdivacky } 428204643Srdivacky 429249423Sdim if (LastII) 430249423Sdim *LastII = &II; 431249423Sdim 432195099Sed // We have an identifier followed by a '::'. Lookup this name 433195099Sed // as the name in a nested-name-specifier. 434195099Sed SourceLocation IdLoc = ConsumeToken(); 435200583Srdivacky assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) && 436200583Srdivacky "NextToken() not working properly!"); 437195099Sed SourceLocation CCLoc = ConsumeToken(); 438198092Srdivacky 439243830Sdim CheckForLParenAfterColonColon(); 440243830Sdim 441219077Sdim HasScopeSpecifier = true; 442219077Sdim if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc, 443219077Sdim ObjectType, EnteringContext, SS)) 444219077Sdim SS.SetInvalid(SourceRange(IdLoc, CCLoc)); 445219077Sdim 446195099Sed continue; 447195099Sed } 448198092Srdivacky 449226633Sdim CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS); 450221345Sdim 451195099Sed // nested-name-specifier: 452195099Sed // type-name '<' 453195099Sed if (Next.is(tok::less)) { 454195099Sed TemplateTy Template; 455198893Srdivacky UnqualifiedId TemplateName; 456198893Srdivacky TemplateName.setIdentifier(&II, Tok.getLocation()); 457208600Srdivacky bool MemberOfUnknownSpecialization; 458210299Sed if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 459212904Sdim /*hasTemplateKeyword=*/false, 460198893Srdivacky TemplateName, 461198092Srdivacky ObjectType, 462198092Srdivacky EnteringContext, 463208600Srdivacky Template, 464208600Srdivacky MemberOfUnknownSpecialization)) { 465234353Sdim // We have found a template name, so annotate this token 466195099Sed // with a template-id annotation. We do not permit the 467195099Sed // template-id to be translated into a type annotation, 468195099Sed // because some clients (e.g., the parsing of class template 469195099Sed // specializations) still want to see the original template-id 470195099Sed // token. 471198893Srdivacky ConsumeToken(); 472234353Sdim if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 473234353Sdim TemplateName, false)) 474204643Srdivacky return true; 475195099Sed continue; 476263508Sdim } 477263508Sdim 478208600Srdivacky if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 479221345Sdim (IsTypename || IsTemplateArgumentList(1))) { 480208600Srdivacky // We have something like t::getAs<T>, where getAs is a 481208600Srdivacky // member of an unknown specialization. However, this will only 482208600Srdivacky // parse correctly as a template, so suggest the keyword 'template' 483208600Srdivacky // before 'getAs' and treat this as a dependent template name. 484221345Sdim unsigned DiagID = diag::err_missing_dependent_template_keyword; 485234353Sdim if (getLangOpts().MicrosoftExt) 486221345Sdim DiagID = diag::warn_missing_dependent_template_keyword; 487221345Sdim 488221345Sdim Diag(Tok.getLocation(), DiagID) 489208600Srdivacky << II.getName() 490208600Srdivacky << FixItHint::CreateInsertion(Tok.getLocation(), "template "); 491208600Srdivacky 492210299Sed if (TemplateNameKind TNK 493210299Sed = Actions.ActOnDependentTemplateName(getCurScope(), 494234353Sdim SS, SourceLocation(), 495210299Sed TemplateName, ObjectType, 496210299Sed EnteringContext, Template)) { 497210299Sed // Consume the identifier. 498210299Sed ConsumeToken(); 499234353Sdim if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 500234353Sdim TemplateName, false)) 501234353Sdim return true; 502210299Sed } 503210299Sed else 504208600Srdivacky return true; 505210299Sed 506208600Srdivacky continue; 507195099Sed } 508195099Sed } 509195099Sed 510193326Sed // We don't have any tokens that form the beginning of a 511193326Sed // nested-name-specifier, so we're done. 512193326Sed break; 513193326Sed } 514198092Srdivacky 515204643Srdivacky // Even if we didn't see any pieces of a nested-name-specifier, we 516204643Srdivacky // still check whether there is a tilde in this position, which 517204643Srdivacky // indicates a potential pseudo-destructor. 518204643Srdivacky if (CheckForDestructor && Tok.is(tok::tilde)) 519204643Srdivacky *MayBePseudoDestructor = true; 520204643Srdivacky 521204643Srdivacky return false; 522193326Sed} 523193326Sed 524193326Sed/// ParseCXXIdExpression - Handle id-expression. 525193326Sed/// 526193326Sed/// id-expression: 527193326Sed/// unqualified-id 528193326Sed/// qualified-id 529193326Sed/// 530193326Sed/// qualified-id: 531193326Sed/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 532193326Sed/// '::' identifier 533193326Sed/// '::' operator-function-id 534195341Sed/// '::' template-id 535193326Sed/// 536193326Sed/// NOTE: The standard specifies that, for qualified-id, the parser does not 537193326Sed/// expect: 538193326Sed/// 539193326Sed/// '::' conversion-function-id 540193326Sed/// '::' '~' class-name 541193326Sed/// 542193326Sed/// This may cause a slight inconsistency on diagnostics: 543193326Sed/// 544193326Sed/// class C {}; 545193326Sed/// namespace A {} 546193326Sed/// void f() { 547193326Sed/// :: A :: ~ C(); // Some Sema error about using destructor with a 548193326Sed/// // namespace. 549193326Sed/// :: ~ C(); // Some Parser error like 'unexpected ~'. 550193326Sed/// } 551193326Sed/// 552193326Sed/// We simplify the parser a bit and make it work like: 553193326Sed/// 554193326Sed/// qualified-id: 555193326Sed/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 556193326Sed/// '::' unqualified-id 557193326Sed/// 558193326Sed/// That way Sema can handle and report similar errors for namespaces and the 559193326Sed/// global scope. 560193326Sed/// 561193326Sed/// The isAddressOfOperand parameter indicates that this id-expression is a 562193326Sed/// direct operand of the address-of operator. This is, besides member contexts, 563193326Sed/// the only place where a qualified-id naming a non-static class member may 564193326Sed/// appear. 565193326Sed/// 566212904SdimExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 567193326Sed // qualified-id: 568193326Sed // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 569193326Sed // '::' unqualified-id 570193326Sed // 571193326Sed CXXScopeSpec SS; 572234353Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 573234353Sdim 574234353Sdim SourceLocation TemplateKWLoc; 575198893Srdivacky UnqualifiedId Name; 576234353Sdim if (ParseUnqualifiedId(SS, 577234353Sdim /*EnteringContext=*/false, 578234353Sdim /*AllowDestructorName=*/false, 579234353Sdim /*AllowConstructorName=*/false, 580212904Sdim /*ObjectType=*/ ParsedType(), 581234353Sdim TemplateKWLoc, 582198893Srdivacky Name)) 583193326Sed return ExprError(); 584199990Srdivacky 585199990Srdivacky // This is only the direct operand of an & operator if it is not 586199990Srdivacky // followed by a postfix-expression suffix. 587212904Sdim if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 588212904Sdim isAddressOfOperand = false; 589234353Sdim 590234353Sdim return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, 591234353Sdim Tok.is(tok::l_paren), isAddressOfOperand); 592193326Sed} 593193326Sed 594263508Sdim/// ParseLambdaExpression - Parse a C++11 lambda expression. 595226633Sdim/// 596226633Sdim/// lambda-expression: 597226633Sdim/// lambda-introducer lambda-declarator[opt] compound-statement 598226633Sdim/// 599226633Sdim/// lambda-introducer: 600226633Sdim/// '[' lambda-capture[opt] ']' 601226633Sdim/// 602226633Sdim/// lambda-capture: 603226633Sdim/// capture-default 604226633Sdim/// capture-list 605226633Sdim/// capture-default ',' capture-list 606226633Sdim/// 607226633Sdim/// capture-default: 608226633Sdim/// '&' 609226633Sdim/// '=' 610226633Sdim/// 611226633Sdim/// capture-list: 612226633Sdim/// capture 613226633Sdim/// capture-list ',' capture 614226633Sdim/// 615226633Sdim/// capture: 616263508Sdim/// simple-capture 617263508Sdim/// init-capture [C++1y] 618263508Sdim/// 619263508Sdim/// simple-capture: 620226633Sdim/// identifier 621226633Sdim/// '&' identifier 622226633Sdim/// 'this' 623226633Sdim/// 624263508Sdim/// init-capture: [C++1y] 625263508Sdim/// identifier initializer 626263508Sdim/// '&' identifier initializer 627263508Sdim/// 628226633Sdim/// lambda-declarator: 629226633Sdim/// '(' parameter-declaration-clause ')' attribute-specifier[opt] 630226633Sdim/// 'mutable'[opt] exception-specification[opt] 631226633Sdim/// trailing-return-type[opt] 632226633Sdim/// 633226633SdimExprResult Parser::ParseLambdaExpression() { 634226633Sdim // Parse lambda-introducer. 635226633Sdim LambdaIntroducer Intro; 636263508Sdim Optional<unsigned> DiagID = ParseLambdaIntroducer(Intro); 637226633Sdim if (DiagID) { 638226633Sdim Diag(Tok, DiagID.getValue()); 639263508Sdim SkipUntil(tok::r_square, StopAtSemi); 640263508Sdim SkipUntil(tok::l_brace, StopAtSemi); 641263508Sdim SkipUntil(tok::r_brace, StopAtSemi); 642234353Sdim return ExprError(); 643226633Sdim } 644226633Sdim 645226633Sdim return ParseLambdaExpressionAfterIntroducer(Intro); 646226633Sdim} 647226633Sdim 648226633Sdim/// TryParseLambdaExpression - Use lookahead and potentially tentative 649226633Sdim/// parsing to determine if we are looking at a C++0x lambda expression, and parse 650226633Sdim/// it if we are. 651226633Sdim/// 652226633Sdim/// If we are not looking at a lambda expression, returns ExprError(). 653226633SdimExprResult Parser::TryParseLambdaExpression() { 654249423Sdim assert(getLangOpts().CPlusPlus11 655226633Sdim && Tok.is(tok::l_square) 656226633Sdim && "Not at the start of a possible lambda expression."); 657226633Sdim 658226633Sdim const Token Next = NextToken(), After = GetLookAheadToken(2); 659226633Sdim 660226633Sdim // If lookahead indicates this is a lambda... 661226633Sdim if (Next.is(tok::r_square) || // [] 662226633Sdim Next.is(tok::equal) || // [= 663226633Sdim (Next.is(tok::amp) && // [&] or [&, 664226633Sdim (After.is(tok::r_square) || 665226633Sdim After.is(tok::comma))) || 666226633Sdim (Next.is(tok::identifier) && // [identifier] 667226633Sdim After.is(tok::r_square))) { 668226633Sdim return ParseLambdaExpression(); 669226633Sdim } 670226633Sdim 671234353Sdim // If lookahead indicates an ObjC message send... 672234353Sdim // [identifier identifier 673226633Sdim if (Next.is(tok::identifier) && After.is(tok::identifier)) { 674234353Sdim return ExprEmpty(); 675226633Sdim } 676263508Sdim 677234353Sdim // Here, we're stuck: lambda introducers and Objective-C message sends are 678234353Sdim // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a 679234353Sdim // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of 680234353Sdim // writing two routines to parse a lambda introducer, just try to parse 681234353Sdim // a lambda introducer first, and fall back if that fails. 682234353Sdim // (TryParseLambdaIntroducer never produces any diagnostic output.) 683226633Sdim LambdaIntroducer Intro; 684226633Sdim if (TryParseLambdaIntroducer(Intro)) 685234353Sdim return ExprEmpty(); 686263508Sdim 687226633Sdim return ParseLambdaExpressionAfterIntroducer(Intro); 688226633Sdim} 689226633Sdim 690263508Sdim/// \brief Parse a lambda introducer. 691263508Sdim/// \param Intro A LambdaIntroducer filled in with information about the 692263508Sdim/// contents of the lambda-introducer. 693263508Sdim/// \param SkippedInits If non-null, we are disambiguating between an Obj-C 694263508Sdim/// message send and a lambda expression. In this mode, we will 695263508Sdim/// sometimes skip the initializers for init-captures and not fully 696263508Sdim/// populate \p Intro. This flag will be set to \c true if we do so. 697263508Sdim/// \return A DiagnosticID if it hit something unexpected. The location for 698263508Sdim/// for the diagnostic is that of the current token. 699263508SdimOptional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, 700263508Sdim bool *SkippedInits) { 701249423Sdim typedef Optional<unsigned> DiagResult; 702226633Sdim 703226633Sdim assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); 704226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 705226633Sdim T.consumeOpen(); 706226633Sdim 707226633Sdim Intro.Range.setBegin(T.getOpenLocation()); 708226633Sdim 709226633Sdim bool first = true; 710226633Sdim 711226633Sdim // Parse capture-default. 712226633Sdim if (Tok.is(tok::amp) && 713226633Sdim (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) { 714226633Sdim Intro.Default = LCD_ByRef; 715234353Sdim Intro.DefaultLoc = ConsumeToken(); 716226633Sdim first = false; 717226633Sdim } else if (Tok.is(tok::equal)) { 718226633Sdim Intro.Default = LCD_ByCopy; 719234353Sdim Intro.DefaultLoc = ConsumeToken(); 720226633Sdim first = false; 721226633Sdim } 722226633Sdim 723226633Sdim while (Tok.isNot(tok::r_square)) { 724226633Sdim if (!first) { 725234353Sdim if (Tok.isNot(tok::comma)) { 726239462Sdim // Provide a completion for a lambda introducer here. Except 727239462Sdim // in Objective-C, where this is Almost Surely meant to be a message 728239462Sdim // send. In that case, fail here and let the ObjC message 729239462Sdim // expression parser perform the completion. 730239462Sdim if (Tok.is(tok::code_completion) && 731239462Sdim !(getLangOpts().ObjC1 && Intro.Default == LCD_None && 732239462Sdim !Intro.Captures.empty())) { 733234353Sdim Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 734234353Sdim /*AfterAmpersand=*/false); 735234353Sdim ConsumeCodeCompletionToken(); 736234353Sdim break; 737234353Sdim } 738234353Sdim 739226633Sdim return DiagResult(diag::err_expected_comma_or_rsquare); 740234353Sdim } 741226633Sdim ConsumeToken(); 742226633Sdim } 743226633Sdim 744234353Sdim if (Tok.is(tok::code_completion)) { 745234353Sdim // If we're in Objective-C++ and we have a bare '[', then this is more 746234353Sdim // likely to be a message receiver. 747234353Sdim if (getLangOpts().ObjC1 && first) 748234353Sdim Actions.CodeCompleteObjCMessageReceiver(getCurScope()); 749234353Sdim else 750234353Sdim Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 751234353Sdim /*AfterAmpersand=*/false); 752234353Sdim ConsumeCodeCompletionToken(); 753234353Sdim break; 754234353Sdim } 755234353Sdim 756226633Sdim first = false; 757234353Sdim 758226633Sdim // Parse capture. 759226633Sdim LambdaCaptureKind Kind = LCK_ByCopy; 760226633Sdim SourceLocation Loc; 761226633Sdim IdentifierInfo* Id = 0; 762234353Sdim SourceLocation EllipsisLoc; 763263508Sdim ExprResult Init; 764234353Sdim 765226633Sdim if (Tok.is(tok::kw_this)) { 766226633Sdim Kind = LCK_This; 767226633Sdim Loc = ConsumeToken(); 768226633Sdim } else { 769226633Sdim if (Tok.is(tok::amp)) { 770226633Sdim Kind = LCK_ByRef; 771226633Sdim ConsumeToken(); 772234353Sdim 773234353Sdim if (Tok.is(tok::code_completion)) { 774234353Sdim Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 775234353Sdim /*AfterAmpersand=*/true); 776234353Sdim ConsumeCodeCompletionToken(); 777234353Sdim break; 778234353Sdim } 779226633Sdim } 780226633Sdim 781226633Sdim if (Tok.is(tok::identifier)) { 782226633Sdim Id = Tok.getIdentifierInfo(); 783226633Sdim Loc = ConsumeToken(); 784226633Sdim } else if (Tok.is(tok::kw_this)) { 785226633Sdim // FIXME: If we want to suggest a fixit here, will need to return more 786226633Sdim // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be 787226633Sdim // Clear()ed to prevent emission in case of tentative parsing? 788226633Sdim return DiagResult(diag::err_this_captured_by_reference); 789226633Sdim } else { 790226633Sdim return DiagResult(diag::err_expected_capture); 791226633Sdim } 792263508Sdim 793263508Sdim if (Tok.is(tok::l_paren)) { 794263508Sdim BalancedDelimiterTracker Parens(*this, tok::l_paren); 795263508Sdim Parens.consumeOpen(); 796263508Sdim 797263508Sdim ExprVector Exprs; 798263508Sdim CommaLocsTy Commas; 799263508Sdim if (SkippedInits) { 800263508Sdim Parens.skipToEnd(); 801263508Sdim *SkippedInits = true; 802263508Sdim } else if (ParseExpressionList(Exprs, Commas)) { 803263508Sdim Parens.skipToEnd(); 804263508Sdim Init = ExprError(); 805263508Sdim } else { 806263508Sdim Parens.consumeClose(); 807263508Sdim Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(), 808263508Sdim Parens.getCloseLocation(), 809263508Sdim Exprs); 810263508Sdim } 811263508Sdim } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) { 812263508Sdim // Each lambda init-capture forms its own full expression, which clears 813263508Sdim // Actions.MaybeODRUseExprs. So create an expression evaluation context 814263508Sdim // to save the necessary state, and restore it later. 815263508Sdim EnterExpressionEvaluationContext EC(Actions, 816263508Sdim Sema::PotentiallyEvaluated); 817263508Sdim if (Tok.is(tok::equal)) 818263508Sdim ConsumeToken(); 819263508Sdim 820263508Sdim if (!SkippedInits) 821263508Sdim Init = ParseInitializer(); 822263508Sdim else if (Tok.is(tok::l_brace)) { 823263508Sdim BalancedDelimiterTracker Braces(*this, tok::l_brace); 824263508Sdim Braces.consumeOpen(); 825263508Sdim Braces.skipToEnd(); 826263508Sdim *SkippedInits = true; 827263508Sdim } else { 828263508Sdim // We're disambiguating this: 829263508Sdim // 830263508Sdim // [..., x = expr 831263508Sdim // 832263508Sdim // We need to find the end of the following expression in order to 833263508Sdim // determine whether this is an Obj-C message send's receiver, or a 834263508Sdim // lambda init-capture. 835263508Sdim // 836263508Sdim // Parse the expression to find where it ends, and annotate it back 837263508Sdim // onto the tokens. We would have parsed this expression the same way 838263508Sdim // in either case: both the RHS of an init-capture and the RHS of an 839263508Sdim // assignment expression are parsed as an initializer-clause, and in 840263508Sdim // neither case can anything be added to the scope between the '[' and 841263508Sdim // here. 842263508Sdim // 843263508Sdim // FIXME: This is horrible. Adding a mechanism to skip an expression 844263508Sdim // would be much cleaner. 845263508Sdim // FIXME: If there is a ',' before the next ']' or ':', we can skip to 846263508Sdim // that instead. (And if we see a ':' with no matching '?', we can 847263508Sdim // classify this as an Obj-C message send.) 848263508Sdim SourceLocation StartLoc = Tok.getLocation(); 849263508Sdim InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true); 850263508Sdim Init = ParseInitializer(); 851263508Sdim 852263508Sdim if (Tok.getLocation() != StartLoc) { 853263508Sdim // Back out the lexing of the token after the initializer. 854263508Sdim PP.RevertCachedTokens(1); 855263508Sdim 856263508Sdim // Replace the consumed tokens with an appropriate annotation. 857263508Sdim Tok.setLocation(StartLoc); 858263508Sdim Tok.setKind(tok::annot_primary_expr); 859263508Sdim setExprAnnotation(Tok, Init); 860263508Sdim Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation()); 861263508Sdim PP.AnnotateCachedTokens(Tok); 862263508Sdim 863263508Sdim // Consume the annotated initializer. 864263508Sdim ConsumeToken(); 865263508Sdim } 866263508Sdim } 867263508Sdim } else if (Tok.is(tok::ellipsis)) 868263508Sdim EllipsisLoc = ConsumeToken(); 869226633Sdim } 870263508Sdim // If this is an init capture, process the initialization expression 871263508Sdim // right away. For lambda init-captures such as the following: 872263508Sdim // const int x = 10; 873263508Sdim // auto L = [i = x+1](int a) { 874263508Sdim // return [j = x+2, 875263508Sdim // &k = x](char b) { }; 876263508Sdim // }; 877263508Sdim // keep in mind that each lambda init-capture has to have: 878263508Sdim // - its initialization expression executed in the context 879263508Sdim // of the enclosing/parent decl-context. 880263508Sdim // - but the variable itself has to be 'injected' into the 881263508Sdim // decl-context of its lambda's call-operator (which has 882263508Sdim // not yet been created). 883263508Sdim // Each init-expression is a full-expression that has to get 884263508Sdim // Sema-analyzed (for capturing etc.) before its lambda's 885263508Sdim // call-operator's decl-context, scope & scopeinfo are pushed on their 886263508Sdim // respective stacks. Thus if any variable is odr-used in the init-capture 887263508Sdim // it will correctly get captured in the enclosing lambda, if one exists. 888263508Sdim // The init-variables above are created later once the lambdascope and 889263508Sdim // call-operators decl-context is pushed onto its respective stack. 890226633Sdim 891263508Sdim // Since the lambda init-capture's initializer expression occurs in the 892263508Sdim // context of the enclosing function or lambda, therefore we can not wait 893263508Sdim // till a lambda scope has been pushed on before deciding whether the 894263508Sdim // variable needs to be captured. We also need to process all 895263508Sdim // lvalue-to-rvalue conversions and discarded-value conversions, 896263508Sdim // so that we can avoid capturing certain constant variables. 897263508Sdim // For e.g., 898263508Sdim // void test() { 899263508Sdim // const int x = 10; 900263508Sdim // auto L = [&z = x](char a) { <-- don't capture by the current lambda 901263508Sdim // return [y = x](int i) { <-- don't capture by enclosing lambda 902263508Sdim // return y; 903263508Sdim // } 904263508Sdim // }; 905263508Sdim // If x was not const, the second use would require 'L' to capture, and 906263508Sdim // that would be an error. 907263508Sdim 908263508Sdim ParsedType InitCaptureParsedType; 909263508Sdim if (Init.isUsable()) { 910263508Sdim // Get the pointer and store it in an lvalue, so we can use it as an 911263508Sdim // out argument. 912263508Sdim Expr *InitExpr = Init.get(); 913263508Sdim // This performs any lvalue-to-rvalue conversions if necessary, which 914263508Sdim // can affect what gets captured in the containing decl-context. 915263508Sdim QualType InitCaptureType = Actions.performLambdaInitCaptureInitialization( 916263508Sdim Loc, Kind == LCK_ByRef, Id, InitExpr); 917263508Sdim Init = InitExpr; 918263508Sdim InitCaptureParsedType.set(InitCaptureType); 919263508Sdim } 920263508Sdim Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init, InitCaptureParsedType); 921226633Sdim } 922226633Sdim 923226633Sdim T.consumeClose(); 924226633Sdim Intro.Range.setEnd(T.getCloseLocation()); 925226633Sdim return DiagResult(); 926226633Sdim} 927226633Sdim 928234353Sdim/// TryParseLambdaIntroducer - Tentatively parse a lambda introducer. 929226633Sdim/// 930226633Sdim/// Returns true if it hit something unexpected. 931226633Sdimbool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { 932226633Sdim TentativeParsingAction PA(*this); 933226633Sdim 934263508Sdim bool SkippedInits = false; 935263508Sdim Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits)); 936226633Sdim 937226633Sdim if (DiagID) { 938226633Sdim PA.Revert(); 939226633Sdim return true; 940226633Sdim } 941226633Sdim 942263508Sdim if (SkippedInits) { 943263508Sdim // Parse it again, but this time parse the init-captures too. 944263508Sdim PA.Revert(); 945263508Sdim Intro = LambdaIntroducer(); 946263508Sdim DiagID = ParseLambdaIntroducer(Intro); 947263508Sdim assert(!DiagID && "parsing lambda-introducer failed on reparse"); 948263508Sdim return false; 949263508Sdim } 950263508Sdim 951226633Sdim PA.Commit(); 952226633Sdim return false; 953226633Sdim} 954226633Sdim 955226633Sdim/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda 956226633Sdim/// expression. 957226633SdimExprResult Parser::ParseLambdaExpressionAfterIntroducer( 958226633Sdim LambdaIntroducer &Intro) { 959234353Sdim SourceLocation LambdaBeginLoc = Intro.Range.getBegin(); 960234353Sdim Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda); 961234353Sdim 962234353Sdim PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, 963234353Sdim "lambda expression parsing"); 964234353Sdim 965263508Sdim 966263508Sdim 967263508Sdim // FIXME: Call into Actions to add any init-capture declarations to the 968263508Sdim // scope while parsing the lambda-declarator and compound-statement. 969263508Sdim 970226633Sdim // Parse lambda-declarator[opt]. 971226633Sdim DeclSpec DS(AttrFactory); 972234353Sdim Declarator D(DS, Declarator::LambdaExprContext); 973263508Sdim TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); 974263508Sdim Actions.PushLambdaScope(); 975226633Sdim 976226633Sdim if (Tok.is(tok::l_paren)) { 977226633Sdim ParseScope PrototypeScope(this, 978226633Sdim Scope::FunctionPrototypeScope | 979249423Sdim Scope::FunctionDeclarationScope | 980226633Sdim Scope::DeclScope); 981226633Sdim 982243830Sdim SourceLocation DeclEndLoc; 983226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 984226633Sdim T.consumeOpen(); 985243830Sdim SourceLocation LParenLoc = T.getOpenLocation(); 986226633Sdim 987226633Sdim // Parse parameter-declaration-clause. 988226633Sdim ParsedAttributes Attr(AttrFactory); 989249423Sdim SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 990226633Sdim SourceLocation EllipsisLoc; 991226633Sdim 992263508Sdim 993263508Sdim if (Tok.isNot(tok::r_paren)) { 994263508Sdim Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth); 995226633Sdim ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); 996263508Sdim // For a generic lambda, each 'auto' within the parameter declaration 997263508Sdim // clause creates a template type parameter, so increment the depth. 998263508Sdim if (Actions.getCurGenericLambda()) 999263508Sdim ++CurTemplateDepthTracker; 1000263508Sdim } 1001226633Sdim T.consumeClose(); 1002243830Sdim SourceLocation RParenLoc = T.getCloseLocation(); 1003243830Sdim DeclEndLoc = RParenLoc; 1004226633Sdim 1005226633Sdim // Parse 'mutable'[opt]. 1006226633Sdim SourceLocation MutableLoc; 1007226633Sdim if (Tok.is(tok::kw_mutable)) { 1008226633Sdim MutableLoc = ConsumeToken(); 1009226633Sdim DeclEndLoc = MutableLoc; 1010226633Sdim } 1011226633Sdim 1012226633Sdim // Parse exception-specification[opt]. 1013226633Sdim ExceptionSpecificationType ESpecType = EST_None; 1014226633Sdim SourceRange ESpecRange; 1015249423Sdim SmallVector<ParsedType, 2> DynamicExceptions; 1016249423Sdim SmallVector<SourceRange, 2> DynamicExceptionRanges; 1017226633Sdim ExprResult NoexceptExpr; 1018235864Sdim ESpecType = tryParseExceptionSpecification(ESpecRange, 1019234982Sdim DynamicExceptions, 1020234982Sdim DynamicExceptionRanges, 1021235864Sdim NoexceptExpr); 1022226633Sdim 1023226633Sdim if (ESpecType != EST_None) 1024226633Sdim DeclEndLoc = ESpecRange.getEnd(); 1025226633Sdim 1026226633Sdim // Parse attribute-specifier[opt]. 1027249423Sdim MaybeParseCXX11Attributes(Attr, &DeclEndLoc); 1028226633Sdim 1029243830Sdim SourceLocation FunLocalRangeEnd = DeclEndLoc; 1030243830Sdim 1031226633Sdim // Parse trailing-return-type[opt]. 1032239462Sdim TypeResult TrailingReturnType; 1033226633Sdim if (Tok.is(tok::arrow)) { 1034243830Sdim FunLocalRangeEnd = Tok.getLocation(); 1035226633Sdim SourceRange Range; 1036239462Sdim TrailingReturnType = ParseTrailingReturnType(Range); 1037226633Sdim if (Range.getEnd().isValid()) 1038226633Sdim DeclEndLoc = Range.getEnd(); 1039226633Sdim } 1040226633Sdim 1041226633Sdim PrototypeScope.Exit(); 1042226633Sdim 1043243830Sdim SourceLocation NoLoc; 1044226633Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, 1045243830Sdim /*isAmbiguous=*/false, 1046243830Sdim LParenLoc, 1047226633Sdim ParamInfo.data(), ParamInfo.size(), 1048243830Sdim EllipsisLoc, RParenLoc, 1049226633Sdim DS.getTypeQualifiers(), 1050226633Sdim /*RefQualifierIsLValueRef=*/true, 1051243830Sdim /*RefQualifierLoc=*/NoLoc, 1052243830Sdim /*ConstQualifierLoc=*/NoLoc, 1053243830Sdim /*VolatileQualifierLoc=*/NoLoc, 1054226633Sdim MutableLoc, 1055226633Sdim ESpecType, ESpecRange.getBegin(), 1056226633Sdim DynamicExceptions.data(), 1057226633Sdim DynamicExceptionRanges.data(), 1058226633Sdim DynamicExceptions.size(), 1059226633Sdim NoexceptExpr.isUsable() ? 1060226633Sdim NoexceptExpr.get() : 0, 1061243830Sdim LParenLoc, FunLocalRangeEnd, D, 1062226633Sdim TrailingReturnType), 1063226633Sdim Attr, DeclEndLoc); 1064234353Sdim } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) { 1065234353Sdim // It's common to forget that one needs '()' before 'mutable' or the 1066234353Sdim // result type. Deal with this. 1067234353Sdim Diag(Tok, diag::err_lambda_missing_parens) 1068234353Sdim << Tok.is(tok::arrow) 1069234353Sdim << FixItHint::CreateInsertion(Tok.getLocation(), "() "); 1070234353Sdim SourceLocation DeclLoc = Tok.getLocation(); 1071234353Sdim SourceLocation DeclEndLoc = DeclLoc; 1072234353Sdim 1073234353Sdim // Parse 'mutable', if it's there. 1074234353Sdim SourceLocation MutableLoc; 1075234353Sdim if (Tok.is(tok::kw_mutable)) { 1076234353Sdim MutableLoc = ConsumeToken(); 1077234353Sdim DeclEndLoc = MutableLoc; 1078234353Sdim } 1079234353Sdim 1080234353Sdim // Parse the return type, if there is one. 1081239462Sdim TypeResult TrailingReturnType; 1082234353Sdim if (Tok.is(tok::arrow)) { 1083234353Sdim SourceRange Range; 1084239462Sdim TrailingReturnType = ParseTrailingReturnType(Range); 1085234353Sdim if (Range.getEnd().isValid()) 1086234353Sdim DeclEndLoc = Range.getEnd(); 1087234353Sdim } 1088234353Sdim 1089234353Sdim ParsedAttributes Attr(AttrFactory); 1090243830Sdim SourceLocation NoLoc; 1091234353Sdim D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, 1092243830Sdim /*isAmbiguous=*/false, 1093243830Sdim /*LParenLoc=*/NoLoc, 1094243830Sdim /*Params=*/0, 1095243830Sdim /*NumParams=*/0, 1096243830Sdim /*EllipsisLoc=*/NoLoc, 1097243830Sdim /*RParenLoc=*/NoLoc, 1098243830Sdim /*TypeQuals=*/0, 1099243830Sdim /*RefQualifierIsLValueRef=*/true, 1100243830Sdim /*RefQualifierLoc=*/NoLoc, 1101243830Sdim /*ConstQualifierLoc=*/NoLoc, 1102243830Sdim /*VolatileQualifierLoc=*/NoLoc, 1103243830Sdim MutableLoc, 1104243830Sdim EST_None, 1105243830Sdim /*ESpecLoc=*/NoLoc, 1106243830Sdim /*Exceptions=*/0, 1107243830Sdim /*ExceptionRanges=*/0, 1108243830Sdim /*NumExceptions=*/0, 1109243830Sdim /*NoexceptExpr=*/0, 1110243830Sdim DeclLoc, DeclEndLoc, D, 1111243830Sdim TrailingReturnType), 1112234353Sdim Attr, DeclEndLoc); 1113226633Sdim } 1114234353Sdim 1115226633Sdim 1116234353Sdim // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using 1117234353Sdim // it. 1118234353Sdim unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope; 1119234353Sdim ParseScope BodyScope(this, ScopeFlags); 1120226633Sdim 1121234353Sdim Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope()); 1122226633Sdim 1123234353Sdim // Parse compound-statement. 1124234353Sdim if (!Tok.is(tok::l_brace)) { 1125226633Sdim Diag(Tok, diag::err_expected_lambda_body); 1126234353Sdim Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 1127234353Sdim return ExprError(); 1128226633Sdim } 1129226633Sdim 1130234353Sdim StmtResult Stmt(ParseCompoundStatementBody()); 1131234353Sdim BodyScope.Exit(); 1132234353Sdim 1133234353Sdim if (!Stmt.isInvalid()) 1134234353Sdim return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(), getCurScope()); 1135234353Sdim 1136234353Sdim Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 1137234353Sdim return ExprError(); 1138226633Sdim} 1139226633Sdim 1140193326Sed/// ParseCXXCasts - This handles the various ways to cast expressions to another 1141193326Sed/// type. 1142193326Sed/// 1143193326Sed/// postfix-expression: [C++ 5.2p1] 1144193326Sed/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 1145193326Sed/// 'static_cast' '<' type-name '>' '(' expression ')' 1146193326Sed/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 1147193326Sed/// 'const_cast' '<' type-name '>' '(' expression ')' 1148193326Sed/// 1149212904SdimExprResult Parser::ParseCXXCasts() { 1150193326Sed tok::TokenKind Kind = Tok.getKind(); 1151193326Sed const char *CastName = 0; // For error messages 1152193326Sed 1153193326Sed switch (Kind) { 1154226633Sdim default: llvm_unreachable("Unknown C++ cast!"); 1155193326Sed case tok::kw_const_cast: CastName = "const_cast"; break; 1156193326Sed case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 1157193326Sed case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 1158193326Sed case tok::kw_static_cast: CastName = "static_cast"; break; 1159193326Sed } 1160193326Sed 1161193326Sed SourceLocation OpLoc = ConsumeToken(); 1162193326Sed SourceLocation LAngleBracketLoc = Tok.getLocation(); 1163193326Sed 1164221345Sdim // Check for "<::" which is parsed as "[:". If found, fix token stream, 1165221345Sdim // diagnose error, suggest fix, and recover parsing. 1166243830Sdim if (Tok.is(tok::l_square) && Tok.getLength() == 2) { 1167243830Sdim Token Next = NextToken(); 1168243830Sdim if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next)) 1169243830Sdim FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); 1170243830Sdim } 1171221345Sdim 1172193326Sed if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 1173193326Sed return ExprError(); 1174193326Sed 1175224145Sdim // Parse the common declaration-specifiers piece. 1176224145Sdim DeclSpec DS(AttrFactory); 1177224145Sdim ParseSpecifierQualifierList(DS); 1178224145Sdim 1179224145Sdim // Parse the abstract-declarator, if present. 1180224145Sdim Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1181224145Sdim ParseDeclarator(DeclaratorInfo); 1182224145Sdim 1183193326Sed SourceLocation RAngleBracketLoc = Tok.getLocation(); 1184193326Sed 1185193326Sed if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 1186193326Sed return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 1187193326Sed 1188226633Sdim SourceLocation LParenLoc, RParenLoc; 1189226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1190193326Sed 1191226633Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) 1192193326Sed return ExprError(); 1193193326Sed 1194212904Sdim ExprResult Result = ParseExpression(); 1195198092Srdivacky 1196193326Sed // Match the ')'. 1197226633Sdim T.consumeClose(); 1198198092Srdivacky 1199224145Sdim if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) 1200193326Sed Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 1201224145Sdim LAngleBracketLoc, DeclaratorInfo, 1202193326Sed RAngleBracketLoc, 1203226633Sdim T.getOpenLocation(), Result.take(), 1204226633Sdim T.getCloseLocation()); 1205193326Sed 1206243830Sdim return Result; 1207193326Sed} 1208193326Sed 1209193326Sed/// ParseCXXTypeid - This handles the C++ typeid expression. 1210193326Sed/// 1211193326Sed/// postfix-expression: [C++ 5.2p1] 1212193326Sed/// 'typeid' '(' expression ')' 1213193326Sed/// 'typeid' '(' type-id ')' 1214193326Sed/// 1215212904SdimExprResult Parser::ParseCXXTypeid() { 1216193326Sed assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 1217193326Sed 1218193326Sed SourceLocation OpLoc = ConsumeToken(); 1219226633Sdim SourceLocation LParenLoc, RParenLoc; 1220226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1221193326Sed 1222193326Sed // typeid expressions are always parenthesized. 1223226633Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) 1224193326Sed return ExprError(); 1225226633Sdim LParenLoc = T.getOpenLocation(); 1226193326Sed 1227212904Sdim ExprResult Result; 1228193326Sed 1229243830Sdim // C++0x [expr.typeid]p3: 1230243830Sdim // When typeid is applied to an expression other than an lvalue of a 1231243830Sdim // polymorphic class type [...] The expression is an unevaluated 1232243830Sdim // operand (Clause 5). 1233243830Sdim // 1234243830Sdim // Note that we can't tell whether the expression is an lvalue of a 1235243830Sdim // polymorphic class type until after we've parsed the expression; we 1236243830Sdim // speculatively assume the subexpression is unevaluated, and fix it up 1237243830Sdim // later. 1238243830Sdim // 1239243830Sdim // We enter the unevaluated context before trying to determine whether we 1240243830Sdim // have a type-id, because the tentative parse logic will try to resolve 1241243830Sdim // names, and must treat them as unevaluated. 1242243830Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 1243243830Sdim Sema::ReuseLambdaContextDecl); 1244243830Sdim 1245193326Sed if (isTypeIdInParens()) { 1246193326Sed TypeResult Ty = ParseTypeName(); 1247193326Sed 1248193326Sed // Match the ')'. 1249226633Sdim T.consumeClose(); 1250226633Sdim RParenLoc = T.getCloseLocation(); 1251218893Sdim if (Ty.isInvalid() || RParenLoc.isInvalid()) 1252193326Sed return ExprError(); 1253193326Sed 1254193326Sed Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 1255212904Sdim Ty.get().getAsOpaquePtr(), RParenLoc); 1256193326Sed } else { 1257193326Sed Result = ParseExpression(); 1258193326Sed 1259193326Sed // Match the ')'. 1260193326Sed if (Result.isInvalid()) 1261263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 1262193326Sed else { 1263226633Sdim T.consumeClose(); 1264226633Sdim RParenLoc = T.getCloseLocation(); 1265218893Sdim if (RParenLoc.isInvalid()) 1266218893Sdim return ExprError(); 1267221345Sdim 1268193326Sed Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 1269193326Sed Result.release(), RParenLoc); 1270193326Sed } 1271193326Sed } 1272193326Sed 1273243830Sdim return Result; 1274193326Sed} 1275193326Sed 1276218893Sdim/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. 1277218893Sdim/// 1278218893Sdim/// '__uuidof' '(' expression ')' 1279218893Sdim/// '__uuidof' '(' type-id ')' 1280218893Sdim/// 1281218893SdimExprResult Parser::ParseCXXUuidof() { 1282218893Sdim assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); 1283218893Sdim 1284218893Sdim SourceLocation OpLoc = ConsumeToken(); 1285226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1286218893Sdim 1287218893Sdim // __uuidof expressions are always parenthesized. 1288226633Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) 1289218893Sdim return ExprError(); 1290218893Sdim 1291218893Sdim ExprResult Result; 1292218893Sdim 1293218893Sdim if (isTypeIdInParens()) { 1294218893Sdim TypeResult Ty = ParseTypeName(); 1295218893Sdim 1296218893Sdim // Match the ')'. 1297226633Sdim T.consumeClose(); 1298218893Sdim 1299218893Sdim if (Ty.isInvalid()) 1300218893Sdim return ExprError(); 1301218893Sdim 1302226633Sdim Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, 1303226633Sdim Ty.get().getAsOpaquePtr(), 1304226633Sdim T.getCloseLocation()); 1305218893Sdim } else { 1306218893Sdim EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 1307218893Sdim Result = ParseExpression(); 1308218893Sdim 1309218893Sdim // Match the ')'. 1310218893Sdim if (Result.isInvalid()) 1311263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 1312218893Sdim else { 1313226633Sdim T.consumeClose(); 1314218893Sdim 1315226633Sdim Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), 1316226633Sdim /*isType=*/false, 1317226633Sdim Result.release(), T.getCloseLocation()); 1318218893Sdim } 1319218893Sdim } 1320218893Sdim 1321243830Sdim return Result; 1322218893Sdim} 1323218893Sdim 1324204643Srdivacky/// \brief Parse a C++ pseudo-destructor expression after the base, 1325204643Srdivacky/// . or -> operator, and nested-name-specifier have already been 1326204643Srdivacky/// parsed. 1327204643Srdivacky/// 1328204643Srdivacky/// postfix-expression: [C++ 5.2] 1329204643Srdivacky/// postfix-expression . pseudo-destructor-name 1330204643Srdivacky/// postfix-expression -> pseudo-destructor-name 1331204643Srdivacky/// 1332204643Srdivacky/// pseudo-destructor-name: 1333204643Srdivacky/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name 1334204643Srdivacky/// ::[opt] nested-name-specifier template simple-template-id :: 1335204643Srdivacky/// ~type-name 1336204643Srdivacky/// ::[opt] nested-name-specifier[opt] ~type-name 1337204643Srdivacky/// 1338212904SdimExprResult 1339204643SrdivackyParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, 1340204643Srdivacky tok::TokenKind OpKind, 1341204643Srdivacky CXXScopeSpec &SS, 1342212904Sdim ParsedType ObjectType) { 1343204643Srdivacky // We're parsing either a pseudo-destructor-name or a dependent 1344204643Srdivacky // member access that has the same form as a 1345204643Srdivacky // pseudo-destructor-name. We parse both in the same way and let 1346204643Srdivacky // the action model sort them out. 1347204643Srdivacky // 1348204643Srdivacky // Note that the ::[opt] nested-name-specifier[opt] has already 1349204643Srdivacky // been parsed, and if there was a simple-template-id, it has 1350204643Srdivacky // been coalesced into a template-id annotation token. 1351204643Srdivacky UnqualifiedId FirstTypeName; 1352204643Srdivacky SourceLocation CCLoc; 1353204643Srdivacky if (Tok.is(tok::identifier)) { 1354204643Srdivacky FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 1355204643Srdivacky ConsumeToken(); 1356204643Srdivacky assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 1357204643Srdivacky CCLoc = ConsumeToken(); 1358204643Srdivacky } else if (Tok.is(tok::annot_template_id)) { 1359234353Sdim // FIXME: retrieve TemplateKWLoc from template-id annotation and 1360234353Sdim // store it in the pseudo-dtor node (to be used when instantiating it). 1361204643Srdivacky FirstTypeName.setTemplateId( 1362204643Srdivacky (TemplateIdAnnotation *)Tok.getAnnotationValue()); 1363204643Srdivacky ConsumeToken(); 1364204643Srdivacky assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 1365204643Srdivacky CCLoc = ConsumeToken(); 1366204643Srdivacky } else { 1367204643Srdivacky FirstTypeName.setIdentifier(0, SourceLocation()); 1368204643Srdivacky } 1369204643Srdivacky 1370204643Srdivacky // Parse the tilde. 1371204643Srdivacky assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 1372204643Srdivacky SourceLocation TildeLoc = ConsumeToken(); 1373234353Sdim 1374234353Sdim if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) { 1375234353Sdim DeclSpec DS(AttrFactory); 1376234353Sdim ParseDecltypeSpecifier(DS); 1377234353Sdim if (DS.getTypeSpecType() == TST_error) 1378234353Sdim return ExprError(); 1379234353Sdim return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, 1380234353Sdim OpKind, TildeLoc, DS, 1381234353Sdim Tok.is(tok::l_paren)); 1382234353Sdim } 1383234353Sdim 1384204643Srdivacky if (!Tok.is(tok::identifier)) { 1385204643Srdivacky Diag(Tok, diag::err_destructor_tilde_identifier); 1386204643Srdivacky return ExprError(); 1387204643Srdivacky } 1388204643Srdivacky 1389204643Srdivacky // Parse the second type. 1390204643Srdivacky UnqualifiedId SecondTypeName; 1391204643Srdivacky IdentifierInfo *Name = Tok.getIdentifierInfo(); 1392204643Srdivacky SourceLocation NameLoc = ConsumeToken(); 1393204643Srdivacky SecondTypeName.setIdentifier(Name, NameLoc); 1394204643Srdivacky 1395204643Srdivacky // If there is a '<', the second type name is a template-id. Parse 1396204643Srdivacky // it as such. 1397204643Srdivacky if (Tok.is(tok::less) && 1398234353Sdim ParseUnqualifiedIdTemplateId(SS, SourceLocation(), 1399234353Sdim Name, NameLoc, 1400234353Sdim false, ObjectType, SecondTypeName, 1401234353Sdim /*AssumeTemplateName=*/true)) 1402204643Srdivacky return ExprError(); 1403204643Srdivacky 1404212904Sdim return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, 1405212904Sdim OpLoc, OpKind, 1406204643Srdivacky SS, FirstTypeName, CCLoc, 1407204643Srdivacky TildeLoc, SecondTypeName, 1408204643Srdivacky Tok.is(tok::l_paren)); 1409204643Srdivacky} 1410204643Srdivacky 1411193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 1412193326Sed/// 1413193326Sed/// boolean-literal: [C++ 2.13.5] 1414193326Sed/// 'true' 1415193326Sed/// 'false' 1416212904SdimExprResult Parser::ParseCXXBoolLiteral() { 1417193326Sed tok::TokenKind Kind = Tok.getKind(); 1418193326Sed return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 1419193326Sed} 1420193326Sed 1421193326Sed/// ParseThrowExpression - This handles the C++ throw expression. 1422193326Sed/// 1423193326Sed/// throw-expression: [C++ 15] 1424193326Sed/// 'throw' assignment-expression[opt] 1425212904SdimExprResult Parser::ParseThrowExpression() { 1426193326Sed assert(Tok.is(tok::kw_throw) && "Not throw!"); 1427193326Sed SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 1428193326Sed 1429193326Sed // If the current token isn't the start of an assignment-expression, 1430193326Sed // then the expression is not present. This handles things like: 1431193326Sed // "C ? throw : (void)42", which is crazy but legal. 1432193326Sed switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 1433193326Sed case tok::semi: 1434193326Sed case tok::r_paren: 1435193326Sed case tok::r_square: 1436193326Sed case tok::r_brace: 1437193326Sed case tok::colon: 1438193326Sed case tok::comma: 1439224145Sdim return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, 0); 1440193326Sed 1441193326Sed default: 1442212904Sdim ExprResult Expr(ParseAssignmentExpression()); 1443243830Sdim if (Expr.isInvalid()) return Expr; 1444224145Sdim return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take()); 1445193326Sed } 1446193326Sed} 1447193326Sed 1448193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer. 1449193326Sed/// 1450193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 1451193326Sed/// a non-lvalue expression whose value is the address of the object for which 1452193326Sed/// the function is called. 1453212904SdimExprResult Parser::ParseCXXThis() { 1454193326Sed assert(Tok.is(tok::kw_this) && "Not 'this'!"); 1455193326Sed SourceLocation ThisLoc = ConsumeToken(); 1456193326Sed return Actions.ActOnCXXThis(ThisLoc); 1457193326Sed} 1458193326Sed 1459193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 1460193326Sed/// Can be interpreted either as function-style casting ("int(x)") 1461193326Sed/// or class type construction ("ClassType(x,y,z)") 1462193326Sed/// or creation of a value-initialized type ("int()"). 1463223017Sdim/// See [C++ 5.2.3]. 1464193326Sed/// 1465193326Sed/// postfix-expression: [C++ 5.2p1] 1466223017Sdim/// simple-type-specifier '(' expression-list[opt] ')' 1467223017Sdim/// [C++0x] simple-type-specifier braced-init-list 1468223017Sdim/// typename-specifier '(' expression-list[opt] ')' 1469223017Sdim/// [C++0x] typename-specifier braced-init-list 1470193326Sed/// 1471212904SdimExprResult 1472193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 1473193326Sed Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1474212904Sdim ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); 1475193326Sed 1476223017Sdim assert((Tok.is(tok::l_paren) || 1477249423Sdim (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) 1478223017Sdim && "Expected '(' or '{'!"); 1479218893Sdim 1480223017Sdim if (Tok.is(tok::l_brace)) { 1481234353Sdim ExprResult Init = ParseBraceInitializer(); 1482234353Sdim if (Init.isInvalid()) 1483234353Sdim return Init; 1484234353Sdim Expr *InitList = Init.take(); 1485234353Sdim return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(), 1486234353Sdim MultiExprArg(&InitList, 1), 1487234353Sdim SourceLocation()); 1488223017Sdim } else { 1489226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1490226633Sdim T.consumeOpen(); 1491223017Sdim 1492243830Sdim ExprVector Exprs; 1493223017Sdim CommaLocsTy CommaLocs; 1494223017Sdim 1495223017Sdim if (Tok.isNot(tok::r_paren)) { 1496223017Sdim if (ParseExpressionList(Exprs, CommaLocs)) { 1497263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 1498223017Sdim return ExprError(); 1499223017Sdim } 1500193326Sed } 1501193326Sed 1502223017Sdim // Match the ')'. 1503226633Sdim T.consumeClose(); 1504193326Sed 1505223017Sdim // TypeRep could be null, if it references an invalid typedef. 1506223017Sdim if (!TypeRep) 1507223017Sdim return ExprError(); 1508198092Srdivacky 1509223017Sdim assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 1510223017Sdim "Unexpected number of commas!"); 1511226633Sdim return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), 1512243830Sdim Exprs, 1513226633Sdim T.getCloseLocation()); 1514223017Sdim } 1515193326Sed} 1516193326Sed 1517199990Srdivacky/// ParseCXXCondition - if/switch/while condition expression. 1518193326Sed/// 1519193326Sed/// condition: 1520193326Sed/// expression 1521193326Sed/// type-specifier-seq declarator '=' assignment-expression 1522234353Sdim/// [C++11] type-specifier-seq declarator '=' initializer-clause 1523234353Sdim/// [C++11] type-specifier-seq declarator braced-init-list 1524193326Sed/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 1525193326Sed/// '=' assignment-expression 1526193326Sed/// 1527243830Sdim/// \param ExprOut if the condition was parsed as an expression, the parsed 1528243830Sdim/// expression. 1529199990Srdivacky/// 1530243830Sdim/// \param DeclOut if the condition was parsed as a declaration, the parsed 1531243830Sdim/// declaration. 1532199990Srdivacky/// 1533208600Srdivacky/// \param Loc The location of the start of the statement that requires this 1534208600Srdivacky/// condition, e.g., the "for" in a for loop. 1535208600Srdivacky/// 1536208600Srdivacky/// \param ConvertToBoolean Whether the condition expression should be 1537208600Srdivacky/// converted to a boolean value. 1538208600Srdivacky/// 1539199990Srdivacky/// \returns true if there was a parsing, false otherwise. 1540212904Sdimbool Parser::ParseCXXCondition(ExprResult &ExprOut, 1541212904Sdim Decl *&DeclOut, 1542208600Srdivacky SourceLocation Loc, 1543208600Srdivacky bool ConvertToBoolean) { 1544202379Srdivacky if (Tok.is(tok::code_completion)) { 1545212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); 1546226633Sdim cutOffParsing(); 1547226633Sdim return true; 1548202379Srdivacky } 1549202379Srdivacky 1550239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 1551249423Sdim MaybeParseCXX11Attributes(attrs); 1552239462Sdim 1553199990Srdivacky if (!isCXXConditionDeclaration()) { 1554239462Sdim ProhibitAttributes(attrs); 1555239462Sdim 1556208600Srdivacky // Parse the expression. 1557212904Sdim ExprOut = ParseExpression(); // expression 1558212904Sdim DeclOut = 0; 1559212904Sdim if (ExprOut.isInvalid()) 1560208600Srdivacky return true; 1561208600Srdivacky 1562208600Srdivacky // If required, convert to a boolean value. 1563208600Srdivacky if (ConvertToBoolean) 1564212904Sdim ExprOut 1565212904Sdim = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get()); 1566212904Sdim return ExprOut.isInvalid(); 1567199990Srdivacky } 1568193326Sed 1569193326Sed // type-specifier-seq 1570221345Sdim DeclSpec DS(AttrFactory); 1571249423Sdim DS.takeAttributesFrom(attrs); 1572193326Sed ParseSpecifierQualifierList(DS); 1573193326Sed 1574193326Sed // declarator 1575193326Sed Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 1576193326Sed ParseDeclarator(DeclaratorInfo); 1577193326Sed 1578193326Sed // simple-asm-expr[opt] 1579193326Sed if (Tok.is(tok::kw_asm)) { 1580193326Sed SourceLocation Loc; 1581212904Sdim ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1582193326Sed if (AsmLabel.isInvalid()) { 1583263508Sdim SkipUntil(tok::semi, StopAtSemi); 1584199990Srdivacky return true; 1585193326Sed } 1586193326Sed DeclaratorInfo.setAsmLabel(AsmLabel.release()); 1587193326Sed DeclaratorInfo.SetRangeEnd(Loc); 1588193326Sed } 1589193326Sed 1590193326Sed // If attributes are present, parse them. 1591218893Sdim MaybeParseGNUAttributes(DeclaratorInfo); 1592193326Sed 1593199990Srdivacky // Type-check the declaration itself. 1594212904Sdim DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 1595218893Sdim DeclaratorInfo); 1596212904Sdim DeclOut = Dcl.get(); 1597212904Sdim ExprOut = ExprError(); 1598218893Sdim 1599193326Sed // '=' assignment-expression 1600234353Sdim // If a '==' or '+=' is found, suggest a fixit to '='. 1601234353Sdim bool CopyInitialization = isTokenEqualOrEqualTypo(); 1602234353Sdim if (CopyInitialization) 1603218893Sdim ConsumeToken(); 1604234353Sdim 1605234353Sdim ExprResult InitExpr = ExprError(); 1606249423Sdim if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 1607234353Sdim Diag(Tok.getLocation(), 1608234353Sdim diag::warn_cxx98_compat_generalized_initializer_lists); 1609234353Sdim InitExpr = ParseBraceInitializer(); 1610234353Sdim } else if (CopyInitialization) { 1611234353Sdim InitExpr = ParseAssignmentExpression(); 1612234353Sdim } else if (Tok.is(tok::l_paren)) { 1613234353Sdim // This was probably an attempt to initialize the variable. 1614234353Sdim SourceLocation LParen = ConsumeParen(), RParen = LParen; 1615263508Sdim if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) 1616234353Sdim RParen = ConsumeParen(); 1617234353Sdim Diag(DeclOut ? DeclOut->getLocation() : LParen, 1618234353Sdim diag::err_expected_init_in_condition_lparen) 1619234353Sdim << SourceRange(LParen, RParen); 1620199990Srdivacky } else { 1621234353Sdim Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(), 1622234353Sdim diag::err_expected_init_in_condition); 1623199990Srdivacky } 1624234353Sdim 1625234353Sdim if (!InitExpr.isInvalid()) 1626234353Sdim Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization, 1627251662Sdim DS.containsPlaceholderType()); 1628251662Sdim else 1629251662Sdim Actions.ActOnInitializerError(DeclOut); 1630234353Sdim 1631208600Srdivacky // FIXME: Build a reference to this declaration? Convert it to bool? 1632208600Srdivacky // (This is currently handled by Sema). 1633219077Sdim 1634219077Sdim Actions.FinalizeDeclaration(DeclOut); 1635208600Srdivacky 1636199990Srdivacky return false; 1637193326Sed} 1638193326Sed 1639193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 1640193326Sed/// This should only be called when the current token is known to be part of 1641193326Sed/// simple-type-specifier. 1642193326Sed/// 1643193326Sed/// simple-type-specifier: 1644193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 1645193326Sed/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 1646193326Sed/// char 1647193326Sed/// wchar_t 1648193326Sed/// bool 1649193326Sed/// short 1650193326Sed/// int 1651193326Sed/// long 1652193326Sed/// signed 1653193326Sed/// unsigned 1654193326Sed/// float 1655193326Sed/// double 1656193326Sed/// void 1657193326Sed/// [GNU] typeof-specifier 1658193326Sed/// [C++0x] auto [TODO] 1659193326Sed/// 1660193326Sed/// type-name: 1661193326Sed/// class-name 1662193326Sed/// enum-name 1663193326Sed/// typedef-name 1664193326Sed/// 1665193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 1666193326Sed DS.SetRangeStart(Tok.getLocation()); 1667193326Sed const char *PrevSpec; 1668198092Srdivacky unsigned DiagID; 1669193326Sed SourceLocation Loc = Tok.getLocation(); 1670198092Srdivacky 1671193326Sed switch (Tok.getKind()) { 1672193326Sed case tok::identifier: // foo::bar 1673193326Sed case tok::coloncolon: // ::foo::bar 1674226633Sdim llvm_unreachable("Annotation token should already be formed!"); 1675198092Srdivacky default: 1676226633Sdim llvm_unreachable("Not a simple-type-specifier token!"); 1677193326Sed 1678193326Sed // type-name 1679193326Sed case tok::annot_typename: { 1680218893Sdim if (getTypeAnnotation(Tok)) 1681218893Sdim DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 1682218893Sdim getTypeAnnotation(Tok)); 1683218893Sdim else 1684218893Sdim DS.SetTypeSpecError(); 1685218893Sdim 1686218893Sdim DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 1687218893Sdim ConsumeToken(); 1688218893Sdim 1689218893Sdim // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 1690218893Sdim // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 1691218893Sdim // Objective-C interface. If we don't have Objective-C or a '<', this is 1692218893Sdim // just a normal reference to a typedef name. 1693234353Sdim if (Tok.is(tok::less) && getLangOpts().ObjC1) 1694218893Sdim ParseObjCProtocolQualifiers(DS); 1695218893Sdim 1696218893Sdim DS.Finish(Diags, PP); 1697218893Sdim return; 1698193326Sed } 1699198092Srdivacky 1700193326Sed // builtin types 1701193326Sed case tok::kw_short: 1702198092Srdivacky DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 1703193326Sed break; 1704193326Sed case tok::kw_long: 1705198092Srdivacky DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 1706193326Sed break; 1707221345Sdim case tok::kw___int64: 1708221345Sdim DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID); 1709221345Sdim break; 1710193326Sed case tok::kw_signed: 1711198092Srdivacky DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 1712193326Sed break; 1713193326Sed case tok::kw_unsigned: 1714198092Srdivacky DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 1715193326Sed break; 1716193326Sed case tok::kw_void: 1717198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 1718193326Sed break; 1719193326Sed case tok::kw_char: 1720198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 1721193326Sed break; 1722193326Sed case tok::kw_int: 1723198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 1724193326Sed break; 1725234353Sdim case tok::kw___int128: 1726234353Sdim DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID); 1727234353Sdim break; 1728226633Sdim case tok::kw_half: 1729226633Sdim DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID); 1730226633Sdim break; 1731193326Sed case tok::kw_float: 1732198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 1733193326Sed break; 1734193326Sed case tok::kw_double: 1735198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 1736193326Sed break; 1737193326Sed case tok::kw_wchar_t: 1738198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 1739193326Sed break; 1740198092Srdivacky case tok::kw_char16_t: 1741198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 1742198092Srdivacky break; 1743198092Srdivacky case tok::kw_char32_t: 1744198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 1745198092Srdivacky break; 1746193326Sed case tok::kw_bool: 1747198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 1748193326Sed break; 1749234353Sdim case tok::annot_decltype: 1750234353Sdim case tok::kw_decltype: 1751234353Sdim DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); 1752234353Sdim return DS.Finish(Diags, PP); 1753198092Srdivacky 1754193326Sed // GNU typeof support. 1755193326Sed case tok::kw_typeof: 1756193326Sed ParseTypeofSpecifier(DS); 1757193326Sed DS.Finish(Diags, PP); 1758193326Sed return; 1759193326Sed } 1760193326Sed if (Tok.is(tok::annot_typename)) 1761193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 1762193326Sed else 1763193326Sed DS.SetRangeEnd(Tok.getLocation()); 1764193326Sed ConsumeToken(); 1765193326Sed DS.Finish(Diags, PP); 1766193326Sed} 1767193326Sed 1768193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 1769193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers, 1770193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished 1771193326Sed/// by parsing the type-specifier-seq, because these sequences are 1772193326Sed/// typically followed by some form of declarator. Returns true and 1773193326Sed/// emits diagnostics if this is not a type-specifier-seq, false 1774193326Sed/// otherwise. 1775193326Sed/// 1776193326Sed/// type-specifier-seq: [C++ 8.1] 1777193326Sed/// type-specifier type-specifier-seq[opt] 1778193326Sed/// 1779193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 1780234353Sdim ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier); 1781204643Srdivacky DS.Finish(Diags, PP); 1782193326Sed return false; 1783193326Sed} 1784193326Sed 1785198893Srdivacky/// \brief Finish parsing a C++ unqualified-id that is a template-id of 1786198893Srdivacky/// some form. 1787198893Srdivacky/// 1788198893Srdivacky/// This routine is invoked when a '<' is encountered after an identifier or 1789198893Srdivacky/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 1790198893Srdivacky/// whether the unqualified-id is actually a template-id. This routine will 1791198893Srdivacky/// then parse the template arguments and form the appropriate template-id to 1792198893Srdivacky/// return to the caller. 1793198893Srdivacky/// 1794198893Srdivacky/// \param SS the nested-name-specifier that precedes this template-id, if 1795198893Srdivacky/// we're actually parsing a qualified-id. 1796198893Srdivacky/// 1797198893Srdivacky/// \param Name for constructor and destructor names, this is the actual 1798198893Srdivacky/// identifier that may be a template-name. 1799198893Srdivacky/// 1800198893Srdivacky/// \param NameLoc the location of the class-name in a constructor or 1801198893Srdivacky/// destructor. 1802198893Srdivacky/// 1803198893Srdivacky/// \param EnteringContext whether we're entering the scope of the 1804198893Srdivacky/// nested-name-specifier. 1805198893Srdivacky/// 1806198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 1807198893Srdivacky/// expression, the type of the base object whose member is being accessed. 1808198893Srdivacky/// 1809198893Srdivacky/// \param Id as input, describes the template-name or operator-function-id 1810198893Srdivacky/// that precedes the '<'. If template arguments were parsed successfully, 1811198893Srdivacky/// will be updated with the template-id. 1812198893Srdivacky/// 1813204643Srdivacky/// \param AssumeTemplateId When true, this routine will assume that the name 1814204643Srdivacky/// refers to a template without performing name lookup to verify. 1815204643Srdivacky/// 1816198893Srdivacky/// \returns true if a parse error occurred, false otherwise. 1817198893Srdivackybool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 1818234353Sdim SourceLocation TemplateKWLoc, 1819198893Srdivacky IdentifierInfo *Name, 1820198893Srdivacky SourceLocation NameLoc, 1821198893Srdivacky bool EnteringContext, 1822212904Sdim ParsedType ObjectType, 1823204643Srdivacky UnqualifiedId &Id, 1824234353Sdim bool AssumeTemplateId) { 1825208600Srdivacky assert((AssumeTemplateId || Tok.is(tok::less)) && 1826208600Srdivacky "Expected '<' to finish parsing a template-id"); 1827198893Srdivacky 1828198893Srdivacky TemplateTy Template; 1829198893Srdivacky TemplateNameKind TNK = TNK_Non_template; 1830198893Srdivacky switch (Id.getKind()) { 1831198893Srdivacky case UnqualifiedId::IK_Identifier: 1832198893Srdivacky case UnqualifiedId::IK_OperatorFunctionId: 1833199990Srdivacky case UnqualifiedId::IK_LiteralOperatorId: 1834204643Srdivacky if (AssumeTemplateId) { 1835234353Sdim TNK = Actions.ActOnDependentTemplateName(getCurScope(), SS, TemplateKWLoc, 1836210299Sed Id, ObjectType, EnteringContext, 1837210299Sed Template); 1838210299Sed if (TNK == TNK_Non_template) 1839210299Sed return true; 1840208600Srdivacky } else { 1841208600Srdivacky bool MemberOfUnknownSpecialization; 1842212904Sdim TNK = Actions.isTemplateName(getCurScope(), SS, 1843212904Sdim TemplateKWLoc.isValid(), Id, 1844212904Sdim ObjectType, EnteringContext, Template, 1845208600Srdivacky MemberOfUnknownSpecialization); 1846208600Srdivacky 1847208600Srdivacky if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && 1848208600Srdivacky ObjectType && IsTemplateArgumentList()) { 1849208600Srdivacky // We have something like t->getAs<T>(), where getAs is a 1850208600Srdivacky // member of an unknown specialization. However, this will only 1851208600Srdivacky // parse correctly as a template, so suggest the keyword 'template' 1852208600Srdivacky // before 'getAs' and treat this as a dependent template name. 1853208600Srdivacky std::string Name; 1854208600Srdivacky if (Id.getKind() == UnqualifiedId::IK_Identifier) 1855208600Srdivacky Name = Id.Identifier->getName(); 1856208600Srdivacky else { 1857208600Srdivacky Name = "operator "; 1858208600Srdivacky if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) 1859208600Srdivacky Name += getOperatorSpelling(Id.OperatorFunctionId.Operator); 1860208600Srdivacky else 1861208600Srdivacky Name += Id.Identifier->getName(); 1862208600Srdivacky } 1863208600Srdivacky Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) 1864208600Srdivacky << Name 1865208600Srdivacky << FixItHint::CreateInsertion(Id.StartLocation, "template "); 1866234353Sdim TNK = Actions.ActOnDependentTemplateName(getCurScope(), 1867234353Sdim SS, TemplateKWLoc, Id, 1868234353Sdim ObjectType, EnteringContext, 1869234353Sdim Template); 1870210299Sed if (TNK == TNK_Non_template) 1871208600Srdivacky return true; 1872208600Srdivacky } 1873208600Srdivacky } 1874198893Srdivacky break; 1875198893Srdivacky 1876198893Srdivacky case UnqualifiedId::IK_ConstructorName: { 1877198893Srdivacky UnqualifiedId TemplateName; 1878208600Srdivacky bool MemberOfUnknownSpecialization; 1879198893Srdivacky TemplateName.setIdentifier(Name, NameLoc); 1880212904Sdim TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 1881212904Sdim TemplateName, ObjectType, 1882208600Srdivacky EnteringContext, Template, 1883208600Srdivacky MemberOfUnknownSpecialization); 1884198893Srdivacky break; 1885198893Srdivacky } 1886198893Srdivacky 1887198893Srdivacky case UnqualifiedId::IK_DestructorName: { 1888198893Srdivacky UnqualifiedId TemplateName; 1889208600Srdivacky bool MemberOfUnknownSpecialization; 1890198893Srdivacky TemplateName.setIdentifier(Name, NameLoc); 1891198893Srdivacky if (ObjectType) { 1892234353Sdim TNK = Actions.ActOnDependentTemplateName(getCurScope(), 1893234353Sdim SS, TemplateKWLoc, TemplateName, 1894234353Sdim ObjectType, EnteringContext, 1895234353Sdim Template); 1896210299Sed if (TNK == TNK_Non_template) 1897198893Srdivacky return true; 1898198893Srdivacky } else { 1899212904Sdim TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 1900212904Sdim TemplateName, ObjectType, 1901208600Srdivacky EnteringContext, Template, 1902208600Srdivacky MemberOfUnknownSpecialization); 1903198893Srdivacky 1904212904Sdim if (TNK == TNK_Non_template && !Id.DestructorName.get()) { 1905204643Srdivacky Diag(NameLoc, diag::err_destructor_template_id) 1906204643Srdivacky << Name << SS.getRange(); 1907198893Srdivacky return true; 1908198893Srdivacky } 1909198893Srdivacky } 1910198893Srdivacky break; 1911198893Srdivacky } 1912198893Srdivacky 1913198893Srdivacky default: 1914198893Srdivacky return false; 1915198893Srdivacky } 1916198893Srdivacky 1917198893Srdivacky if (TNK == TNK_Non_template) 1918198893Srdivacky return false; 1919198893Srdivacky 1920198893Srdivacky // Parse the enclosed template argument list. 1921198893Srdivacky SourceLocation LAngleLoc, RAngleLoc; 1922198893Srdivacky TemplateArgList TemplateArgs; 1923208600Srdivacky if (Tok.is(tok::less) && 1924208600Srdivacky ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, 1925221345Sdim SS, true, LAngleLoc, 1926198893Srdivacky TemplateArgs, 1927198893Srdivacky RAngleLoc)) 1928198893Srdivacky return true; 1929198893Srdivacky 1930198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_Identifier || 1931199990Srdivacky Id.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1932199990Srdivacky Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) { 1933198893Srdivacky // Form a parsed representation of the template-id to be stored in the 1934198893Srdivacky // UnqualifiedId. 1935198893Srdivacky TemplateIdAnnotation *TemplateId 1936234982Sdim = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds); 1937198893Srdivacky 1938198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_Identifier) { 1939198893Srdivacky TemplateId->Name = Id.Identifier; 1940198893Srdivacky TemplateId->Operator = OO_None; 1941198893Srdivacky TemplateId->TemplateNameLoc = Id.StartLocation; 1942198893Srdivacky } else { 1943198893Srdivacky TemplateId->Name = 0; 1944198893Srdivacky TemplateId->Operator = Id.OperatorFunctionId.Operator; 1945198893Srdivacky TemplateId->TemplateNameLoc = Id.StartLocation; 1946198893Srdivacky } 1947198893Srdivacky 1948221345Sdim TemplateId->SS = SS; 1949234353Sdim TemplateId->TemplateKWLoc = TemplateKWLoc; 1950212904Sdim TemplateId->Template = Template; 1951198893Srdivacky TemplateId->Kind = TNK; 1952198893Srdivacky TemplateId->LAngleLoc = LAngleLoc; 1953198893Srdivacky TemplateId->RAngleLoc = RAngleLoc; 1954199482Srdivacky ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); 1955198893Srdivacky for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 1956199482Srdivacky Arg != ArgEnd; ++Arg) 1957198893Srdivacky Args[Arg] = TemplateArgs[Arg]; 1958198893Srdivacky 1959198893Srdivacky Id.setTemplateId(TemplateId); 1960198893Srdivacky return false; 1961198893Srdivacky } 1962198893Srdivacky 1963198893Srdivacky // Bundle the template arguments together. 1964243830Sdim ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); 1965234353Sdim 1966198893Srdivacky // Constructor and destructor names. 1967212904Sdim TypeResult Type 1968234353Sdim = Actions.ActOnTemplateIdType(SS, TemplateKWLoc, 1969234353Sdim Template, NameLoc, 1970234353Sdim LAngleLoc, TemplateArgsPtr, RAngleLoc, 1971234353Sdim /*IsCtorOrDtorName=*/true); 1972198893Srdivacky if (Type.isInvalid()) 1973198893Srdivacky return true; 1974198893Srdivacky 1975198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_ConstructorName) 1976198893Srdivacky Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 1977198893Srdivacky else 1978198893Srdivacky Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 1979198893Srdivacky 1980198893Srdivacky return false; 1981198893Srdivacky} 1982198893Srdivacky 1983198893Srdivacky/// \brief Parse an operator-function-id or conversion-function-id as part 1984198893Srdivacky/// of a C++ unqualified-id. 1985198893Srdivacky/// 1986198893Srdivacky/// This routine is responsible only for parsing the operator-function-id or 1987198893Srdivacky/// conversion-function-id; it does not handle template arguments in any way. 1988198893Srdivacky/// 1989198893Srdivacky/// \code 1990198893Srdivacky/// operator-function-id: [C++ 13.5] 1991198893Srdivacky/// 'operator' operator 1992198893Srdivacky/// 1993198893Srdivacky/// operator: one of 1994198893Srdivacky/// new delete new[] delete[] 1995198893Srdivacky/// + - * / % ^ & | ~ 1996198893Srdivacky/// ! = < > += -= *= /= %= 1997198893Srdivacky/// ^= &= |= << >> >>= <<= == != 1998198893Srdivacky/// <= >= && || ++ -- , ->* -> 1999198893Srdivacky/// () [] 2000198893Srdivacky/// 2001198893Srdivacky/// conversion-function-id: [C++ 12.3.2] 2002198893Srdivacky/// operator conversion-type-id 2003198893Srdivacky/// 2004198893Srdivacky/// conversion-type-id: 2005198893Srdivacky/// type-specifier-seq conversion-declarator[opt] 2006198893Srdivacky/// 2007198893Srdivacky/// conversion-declarator: 2008198893Srdivacky/// ptr-operator conversion-declarator[opt] 2009198893Srdivacky/// \endcode 2010198893Srdivacky/// 2011243830Sdim/// \param SS The nested-name-specifier that preceded this unqualified-id. If 2012198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id. 2013198893Srdivacky/// 2014198893Srdivacky/// \param EnteringContext whether we are entering the scope of the 2015198893Srdivacky/// nested-name-specifier. 2016198893Srdivacky/// 2017198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 2018198893Srdivacky/// expression, the type of the base object whose member is being accessed. 2019198893Srdivacky/// 2020198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id. 2021198893Srdivacky/// 2022198893Srdivacky/// \returns true if parsing fails, false otherwise. 2023198893Srdivackybool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 2024212904Sdim ParsedType ObjectType, 2025198893Srdivacky UnqualifiedId &Result) { 2026198893Srdivacky assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 2027198893Srdivacky 2028198893Srdivacky // Consume the 'operator' keyword. 2029198893Srdivacky SourceLocation KeywordLoc = ConsumeToken(); 2030198893Srdivacky 2031198893Srdivacky // Determine what kind of operator name we have. 2032198893Srdivacky unsigned SymbolIdx = 0; 2033198893Srdivacky SourceLocation SymbolLocations[3]; 2034198893Srdivacky OverloadedOperatorKind Op = OO_None; 2035198893Srdivacky switch (Tok.getKind()) { 2036198893Srdivacky case tok::kw_new: 2037198893Srdivacky case tok::kw_delete: { 2038198893Srdivacky bool isNew = Tok.getKind() == tok::kw_new; 2039198893Srdivacky // Consume the 'new' or 'delete'. 2040198893Srdivacky SymbolLocations[SymbolIdx++] = ConsumeToken(); 2041234353Sdim // Check for array new/delete. 2042234353Sdim if (Tok.is(tok::l_square) && 2043249423Sdim (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) { 2044226633Sdim // Consume the '[' and ']'. 2045226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 2046226633Sdim T.consumeOpen(); 2047226633Sdim T.consumeClose(); 2048226633Sdim if (T.getCloseLocation().isInvalid()) 2049198893Srdivacky return true; 2050198893Srdivacky 2051226633Sdim SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 2052226633Sdim SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 2053198893Srdivacky Op = isNew? OO_Array_New : OO_Array_Delete; 2054198893Srdivacky } else { 2055198893Srdivacky Op = isNew? OO_New : OO_Delete; 2056198893Srdivacky } 2057198893Srdivacky break; 2058198893Srdivacky } 2059198893Srdivacky 2060198893Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 2061198893Srdivacky case tok::Token: \ 2062198893Srdivacky SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 2063198893Srdivacky Op = OO_##Name; \ 2064198893Srdivacky break; 2065198893Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 2066198893Srdivacky#include "clang/Basic/OperatorKinds.def" 2067198893Srdivacky 2068198893Srdivacky case tok::l_paren: { 2069226633Sdim // Consume the '(' and ')'. 2070226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2071226633Sdim T.consumeOpen(); 2072226633Sdim T.consumeClose(); 2073226633Sdim if (T.getCloseLocation().isInvalid()) 2074198893Srdivacky return true; 2075198893Srdivacky 2076226633Sdim SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 2077226633Sdim SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 2078198893Srdivacky Op = OO_Call; 2079198893Srdivacky break; 2080198893Srdivacky } 2081198893Srdivacky 2082198893Srdivacky case tok::l_square: { 2083226633Sdim // Consume the '[' and ']'. 2084226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 2085226633Sdim T.consumeOpen(); 2086226633Sdim T.consumeClose(); 2087226633Sdim if (T.getCloseLocation().isInvalid()) 2088198893Srdivacky return true; 2089198893Srdivacky 2090226633Sdim SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 2091226633Sdim SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 2092198893Srdivacky Op = OO_Subscript; 2093198893Srdivacky break; 2094198893Srdivacky } 2095198893Srdivacky 2096198893Srdivacky case tok::code_completion: { 2097198893Srdivacky // Code completion for the operator name. 2098210299Sed Actions.CodeCompleteOperatorName(getCurScope()); 2099226633Sdim cutOffParsing(); 2100198893Srdivacky // Don't try to parse any further. 2101198893Srdivacky return true; 2102198893Srdivacky } 2103198893Srdivacky 2104198893Srdivacky default: 2105198893Srdivacky break; 2106198893Srdivacky } 2107198893Srdivacky 2108198893Srdivacky if (Op != OO_None) { 2109198893Srdivacky // We have parsed an operator-function-id. 2110198893Srdivacky Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 2111198893Srdivacky return false; 2112198893Srdivacky } 2113199990Srdivacky 2114199990Srdivacky // Parse a literal-operator-id. 2115199990Srdivacky // 2116243830Sdim // literal-operator-id: C++11 [over.literal] 2117243830Sdim // operator string-literal identifier 2118243830Sdim // operator user-defined-string-literal 2119199990Srdivacky 2120249423Sdim if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) { 2121234353Sdim Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); 2122199990Srdivacky 2123234353Sdim SourceLocation DiagLoc; 2124234353Sdim unsigned DiagId = 0; 2125234353Sdim 2126234353Sdim // We're past translation phase 6, so perform string literal concatenation 2127234353Sdim // before checking for "". 2128249423Sdim SmallVector<Token, 4> Toks; 2129249423Sdim SmallVector<SourceLocation, 4> TokLocs; 2130234353Sdim while (isTokenStringLiteral()) { 2131234353Sdim if (!Tok.is(tok::string_literal) && !DiagId) { 2132243830Sdim // C++11 [over.literal]p1: 2133243830Sdim // The string-literal or user-defined-string-literal in a 2134243830Sdim // literal-operator-id shall have no encoding-prefix [...]. 2135234353Sdim DiagLoc = Tok.getLocation(); 2136234353Sdim DiagId = diag::err_literal_operator_string_prefix; 2137234353Sdim } 2138234353Sdim Toks.push_back(Tok); 2139234353Sdim TokLocs.push_back(ConsumeStringToken()); 2140234353Sdim } 2141234353Sdim 2142234353Sdim StringLiteralParser Literal(Toks.data(), Toks.size(), PP); 2143234353Sdim if (Literal.hadError) 2144234353Sdim return true; 2145234353Sdim 2146234353Sdim // Grab the literal operator's suffix, which will be either the next token 2147234353Sdim // or a ud-suffix from the string literal. 2148234353Sdim IdentifierInfo *II = 0; 2149234353Sdim SourceLocation SuffixLoc; 2150234353Sdim if (!Literal.getUDSuffix().empty()) { 2151234353Sdim II = &PP.getIdentifierTable().get(Literal.getUDSuffix()); 2152234353Sdim SuffixLoc = 2153234353Sdim Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()], 2154234353Sdim Literal.getUDSuffixOffset(), 2155234353Sdim PP.getSourceManager(), getLangOpts()); 2156234353Sdim } else if (Tok.is(tok::identifier)) { 2157234353Sdim II = Tok.getIdentifierInfo(); 2158234353Sdim SuffixLoc = ConsumeToken(); 2159234353Sdim TokLocs.push_back(SuffixLoc); 2160234353Sdim } else { 2161199990Srdivacky Diag(Tok.getLocation(), diag::err_expected_ident); 2162199990Srdivacky return true; 2163199990Srdivacky } 2164199990Srdivacky 2165234353Sdim // The string literal must be empty. 2166234353Sdim if (!Literal.GetString().empty() || Literal.Pascal) { 2167243830Sdim // C++11 [over.literal]p1: 2168243830Sdim // The string-literal or user-defined-string-literal in a 2169243830Sdim // literal-operator-id shall [...] contain no characters 2170243830Sdim // other than the implicit terminating '\0'. 2171234353Sdim DiagLoc = TokLocs.front(); 2172234353Sdim DiagId = diag::err_literal_operator_string_not_empty; 2173234353Sdim } 2174234353Sdim 2175234353Sdim if (DiagId) { 2176234353Sdim // This isn't a valid literal-operator-id, but we think we know 2177234353Sdim // what the user meant. Tell them what they should have written. 2178249423Sdim SmallString<32> Str; 2179234353Sdim Str += "\"\" "; 2180234353Sdim Str += II->getName(); 2181234353Sdim Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement( 2182234353Sdim SourceRange(TokLocs.front(), TokLocs.back()), Str); 2183234353Sdim } 2184234353Sdim 2185234353Sdim Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc); 2186199990Srdivacky return false; 2187199990Srdivacky } 2188198893Srdivacky 2189198893Srdivacky // Parse a conversion-function-id. 2190198893Srdivacky // 2191198893Srdivacky // conversion-function-id: [C++ 12.3.2] 2192198893Srdivacky // operator conversion-type-id 2193198893Srdivacky // 2194198893Srdivacky // conversion-type-id: 2195198893Srdivacky // type-specifier-seq conversion-declarator[opt] 2196198893Srdivacky // 2197198893Srdivacky // conversion-declarator: 2198198893Srdivacky // ptr-operator conversion-declarator[opt] 2199198893Srdivacky 2200198893Srdivacky // Parse the type-specifier-seq. 2201221345Sdim DeclSpec DS(AttrFactory); 2202199990Srdivacky if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? 2203198893Srdivacky return true; 2204198893Srdivacky 2205198893Srdivacky // Parse the conversion-declarator, which is merely a sequence of 2206198893Srdivacky // ptr-operators. 2207251662Sdim Declarator D(DS, Declarator::ConversionIdContext); 2208198893Srdivacky ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 2209198893Srdivacky 2210198893Srdivacky // Finish up the type. 2211212904Sdim TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); 2212198893Srdivacky if (Ty.isInvalid()) 2213198893Srdivacky return true; 2214198893Srdivacky 2215198893Srdivacky // Note that this is a conversion-function-id. 2216198893Srdivacky Result.setConversionFunctionId(KeywordLoc, Ty.get(), 2217198893Srdivacky D.getSourceRange().getEnd()); 2218198893Srdivacky return false; 2219198893Srdivacky} 2220198893Srdivacky 2221198893Srdivacky/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the 2222198893Srdivacky/// name of an entity. 2223198893Srdivacky/// 2224198893Srdivacky/// \code 2225198893Srdivacky/// unqualified-id: [C++ expr.prim.general] 2226198893Srdivacky/// identifier 2227198893Srdivacky/// operator-function-id 2228198893Srdivacky/// conversion-function-id 2229198893Srdivacky/// [C++0x] literal-operator-id [TODO] 2230198893Srdivacky/// ~ class-name 2231198893Srdivacky/// template-id 2232198893Srdivacky/// 2233198893Srdivacky/// \endcode 2234198893Srdivacky/// 2235243830Sdim/// \param SS The nested-name-specifier that preceded this unqualified-id. If 2236198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id. 2237198893Srdivacky/// 2238198893Srdivacky/// \param EnteringContext whether we are entering the scope of the 2239198893Srdivacky/// nested-name-specifier. 2240198893Srdivacky/// 2241198893Srdivacky/// \param AllowDestructorName whether we allow parsing of a destructor name. 2242198893Srdivacky/// 2243198893Srdivacky/// \param AllowConstructorName whether we allow parsing a constructor name. 2244198893Srdivacky/// 2245198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 2246198893Srdivacky/// expression, the type of the base object whose member is being accessed. 2247198893Srdivacky/// 2248198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id. 2249198893Srdivacky/// 2250198893Srdivacky/// \returns true if parsing fails, false otherwise. 2251198893Srdivackybool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 2252198893Srdivacky bool AllowDestructorName, 2253198893Srdivacky bool AllowConstructorName, 2254212904Sdim ParsedType ObjectType, 2255234353Sdim SourceLocation& TemplateKWLoc, 2256198893Srdivacky UnqualifiedId &Result) { 2257208600Srdivacky 2258208600Srdivacky // Handle 'A::template B'. This is for template-ids which have not 2259208600Srdivacky // already been annotated by ParseOptionalCXXScopeSpecifier(). 2260208600Srdivacky bool TemplateSpecified = false; 2261234353Sdim if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) && 2262208600Srdivacky (ObjectType || SS.isSet())) { 2263208600Srdivacky TemplateSpecified = true; 2264208600Srdivacky TemplateKWLoc = ConsumeToken(); 2265208600Srdivacky } 2266208600Srdivacky 2267198893Srdivacky // unqualified-id: 2268198893Srdivacky // identifier 2269198893Srdivacky // template-id (when it hasn't already been annotated) 2270198893Srdivacky if (Tok.is(tok::identifier)) { 2271198893Srdivacky // Consume the identifier. 2272198893Srdivacky IdentifierInfo *Id = Tok.getIdentifierInfo(); 2273198893Srdivacky SourceLocation IdLoc = ConsumeToken(); 2274198893Srdivacky 2275234353Sdim if (!getLangOpts().CPlusPlus) { 2276202379Srdivacky // If we're not in C++, only identifiers matter. Record the 2277202379Srdivacky // identifier and return. 2278202379Srdivacky Result.setIdentifier(Id, IdLoc); 2279202379Srdivacky return false; 2280202379Srdivacky } 2281202379Srdivacky 2282198893Srdivacky if (AllowConstructorName && 2283210299Sed Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { 2284198893Srdivacky // We have parsed a constructor name. 2285234353Sdim ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(), 2286234353Sdim &SS, false, false, 2287234353Sdim ParsedType(), 2288234353Sdim /*IsCtorOrDtorName=*/true, 2289234353Sdim /*NonTrivialTypeSourceInfo=*/true); 2290234353Sdim Result.setConstructorName(Ty, IdLoc, IdLoc); 2291198893Srdivacky } else { 2292198893Srdivacky // We have parsed an identifier. 2293198893Srdivacky Result.setIdentifier(Id, IdLoc); 2294198893Srdivacky } 2295198893Srdivacky 2296198893Srdivacky // If the next token is a '<', we may have a template. 2297208600Srdivacky if (TemplateSpecified || Tok.is(tok::less)) 2298234353Sdim return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc, 2299234353Sdim EnteringContext, ObjectType, 2300234353Sdim Result, TemplateSpecified); 2301198893Srdivacky 2302198893Srdivacky return false; 2303198893Srdivacky } 2304198893Srdivacky 2305198893Srdivacky // unqualified-id: 2306198893Srdivacky // template-id (already parsed and annotated) 2307198893Srdivacky if (Tok.is(tok::annot_template_id)) { 2308224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2309202379Srdivacky 2310202379Srdivacky // If the template-name names the current class, then this is a constructor 2311202379Srdivacky if (AllowConstructorName && TemplateId->Name && 2312210299Sed Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 2313202379Srdivacky if (SS.isSet()) { 2314202379Srdivacky // C++ [class.qual]p2 specifies that a qualified template-name 2315202379Srdivacky // is taken as the constructor name where a constructor can be 2316202379Srdivacky // declared. Thus, the template arguments are extraneous, so 2317202379Srdivacky // complain about them and remove them entirely. 2318202379Srdivacky Diag(TemplateId->TemplateNameLoc, 2319202379Srdivacky diag::err_out_of_line_constructor_template_id) 2320202379Srdivacky << TemplateId->Name 2321206084Srdivacky << FixItHint::CreateRemoval( 2322202379Srdivacky SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 2323234353Sdim ParsedType Ty = Actions.getTypeName(*TemplateId->Name, 2324234353Sdim TemplateId->TemplateNameLoc, 2325234353Sdim getCurScope(), 2326234353Sdim &SS, false, false, 2327234353Sdim ParsedType(), 2328234353Sdim /*IsCtorOrDtorName=*/true, 2329234353Sdim /*NontrivialTypeSourceInfo=*/true); 2330234353Sdim Result.setConstructorName(Ty, TemplateId->TemplateNameLoc, 2331202379Srdivacky TemplateId->RAngleLoc); 2332202379Srdivacky ConsumeToken(); 2333202379Srdivacky return false; 2334202379Srdivacky } 2335202379Srdivacky 2336202379Srdivacky Result.setConstructorTemplateId(TemplateId); 2337202379Srdivacky ConsumeToken(); 2338202379Srdivacky return false; 2339202379Srdivacky } 2340202379Srdivacky 2341198893Srdivacky // We have already parsed a template-id; consume the annotation token as 2342198893Srdivacky // our unqualified-id. 2343202379Srdivacky Result.setTemplateId(TemplateId); 2344234353Sdim TemplateKWLoc = TemplateId->TemplateKWLoc; 2345198893Srdivacky ConsumeToken(); 2346198893Srdivacky return false; 2347198893Srdivacky } 2348198893Srdivacky 2349198893Srdivacky // unqualified-id: 2350198893Srdivacky // operator-function-id 2351198893Srdivacky // conversion-function-id 2352198893Srdivacky if (Tok.is(tok::kw_operator)) { 2353198893Srdivacky if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 2354198893Srdivacky return true; 2355198893Srdivacky 2356199990Srdivacky // If we have an operator-function-id or a literal-operator-id and the next 2357199990Srdivacky // token is a '<', we may have a 2358198893Srdivacky // 2359198893Srdivacky // template-id: 2360198893Srdivacky // operator-function-id < template-argument-list[opt] > 2361199990Srdivacky if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || 2362199990Srdivacky Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && 2363208600Srdivacky (TemplateSpecified || Tok.is(tok::less))) 2364234353Sdim return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, 2365234353Sdim 0, SourceLocation(), 2366234353Sdim EnteringContext, ObjectType, 2367234353Sdim Result, TemplateSpecified); 2368198893Srdivacky 2369198893Srdivacky return false; 2370198893Srdivacky } 2371198893Srdivacky 2372234353Sdim if (getLangOpts().CPlusPlus && 2373202379Srdivacky (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 2374198893Srdivacky // C++ [expr.unary.op]p10: 2375198893Srdivacky // There is an ambiguity in the unary-expression ~X(), where X is a 2376198893Srdivacky // class-name. The ambiguity is resolved in favor of treating ~ as a 2377198893Srdivacky // unary complement rather than treating ~X as referring to a destructor. 2378198893Srdivacky 2379198893Srdivacky // Parse the '~'. 2380198893Srdivacky SourceLocation TildeLoc = ConsumeToken(); 2381234353Sdim 2382234353Sdim if (SS.isEmpty() && Tok.is(tok::kw_decltype)) { 2383234353Sdim DeclSpec DS(AttrFactory); 2384234353Sdim SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 2385234353Sdim if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) { 2386234353Sdim Result.setDestructorName(TildeLoc, Type, EndLoc); 2387234353Sdim return false; 2388234353Sdim } 2389234353Sdim return true; 2390234353Sdim } 2391198893Srdivacky 2392198893Srdivacky // Parse the class-name. 2393198893Srdivacky if (Tok.isNot(tok::identifier)) { 2394204643Srdivacky Diag(Tok, diag::err_destructor_tilde_identifier); 2395198893Srdivacky return true; 2396198893Srdivacky } 2397198893Srdivacky 2398198893Srdivacky // Parse the class-name (or template-name in a simple-template-id). 2399198893Srdivacky IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 2400198893Srdivacky SourceLocation ClassNameLoc = ConsumeToken(); 2401198893Srdivacky 2402208600Srdivacky if (TemplateSpecified || Tok.is(tok::less)) { 2403212904Sdim Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc); 2404234353Sdim return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, 2405234353Sdim ClassName, ClassNameLoc, 2406234353Sdim EnteringContext, ObjectType, 2407234353Sdim Result, TemplateSpecified); 2408198893Srdivacky } 2409198893Srdivacky 2410198893Srdivacky // Note that this is a destructor name. 2411212904Sdim ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 2412212904Sdim ClassNameLoc, getCurScope(), 2413212904Sdim SS, ObjectType, 2414212904Sdim EnteringContext); 2415204643Srdivacky if (!Ty) 2416198893Srdivacky return true; 2417204643Srdivacky 2418198893Srdivacky Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 2419198893Srdivacky return false; 2420198893Srdivacky } 2421198893Srdivacky 2422198893Srdivacky Diag(Tok, diag::err_expected_unqualified_id) 2423234353Sdim << getLangOpts().CPlusPlus; 2424198893Srdivacky return true; 2425198893Srdivacky} 2426198893Srdivacky 2427193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 2428193326Sed/// memory in a typesafe manner and call constructors. 2429198092Srdivacky/// 2430193326Sed/// This method is called to parse the new expression after the optional :: has 2431193326Sed/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 2432193326Sed/// is its location. Otherwise, "Start" is the location of the 'new' token. 2433193326Sed/// 2434193326Sed/// new-expression: 2435193326Sed/// '::'[opt] 'new' new-placement[opt] new-type-id 2436193326Sed/// new-initializer[opt] 2437193326Sed/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 2438193326Sed/// new-initializer[opt] 2439193326Sed/// 2440193326Sed/// new-placement: 2441193326Sed/// '(' expression-list ')' 2442193326Sed/// 2443193326Sed/// new-type-id: 2444193326Sed/// type-specifier-seq new-declarator[opt] 2445221345Sdim/// [GNU] attributes type-specifier-seq new-declarator[opt] 2446193326Sed/// 2447193326Sed/// new-declarator: 2448193326Sed/// ptr-operator new-declarator[opt] 2449193326Sed/// direct-new-declarator 2450193326Sed/// 2451193326Sed/// new-initializer: 2452193326Sed/// '(' expression-list[opt] ')' 2453223017Sdim/// [C++0x] braced-init-list 2454193326Sed/// 2455212904SdimExprResult 2456193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 2457193326Sed assert(Tok.is(tok::kw_new) && "expected 'new' token"); 2458193326Sed ConsumeToken(); // Consume 'new' 2459193326Sed 2460193326Sed // A '(' now can be a new-placement or the '(' wrapping the type-id in the 2461193326Sed // second form of new-expression. It can't be a new-type-id. 2462193326Sed 2463243830Sdim ExprVector PlacementArgs; 2464193326Sed SourceLocation PlacementLParen, PlacementRParen; 2465193326Sed 2466210299Sed SourceRange TypeIdParens; 2467221345Sdim DeclSpec DS(AttrFactory); 2468224145Sdim Declarator DeclaratorInfo(DS, Declarator::CXXNewContext); 2469193326Sed if (Tok.is(tok::l_paren)) { 2470193326Sed // If it turns out to be a placement, we change the type location. 2471226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2472226633Sdim T.consumeOpen(); 2473226633Sdim PlacementLParen = T.getOpenLocation(); 2474193326Sed if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 2475263508Sdim SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 2476193326Sed return ExprError(); 2477193326Sed } 2478193326Sed 2479226633Sdim T.consumeClose(); 2480226633Sdim PlacementRParen = T.getCloseLocation(); 2481193326Sed if (PlacementRParen.isInvalid()) { 2482263508Sdim SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 2483193326Sed return ExprError(); 2484193326Sed } 2485193326Sed 2486193326Sed if (PlacementArgs.empty()) { 2487193326Sed // Reset the placement locations. There was no placement. 2488226633Sdim TypeIdParens = T.getRange(); 2489193326Sed PlacementLParen = PlacementRParen = SourceLocation(); 2490193326Sed } else { 2491193326Sed // We still need the type. 2492193326Sed if (Tok.is(tok::l_paren)) { 2493226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2494226633Sdim T.consumeOpen(); 2495221345Sdim MaybeParseGNUAttributes(DeclaratorInfo); 2496193326Sed ParseSpecifierQualifierList(DS); 2497193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2498193326Sed ParseDeclarator(DeclaratorInfo); 2499226633Sdim T.consumeClose(); 2500226633Sdim TypeIdParens = T.getRange(); 2501193326Sed } else { 2502221345Sdim MaybeParseGNUAttributes(DeclaratorInfo); 2503193326Sed if (ParseCXXTypeSpecifierSeq(DS)) 2504193326Sed DeclaratorInfo.setInvalidType(true); 2505193326Sed else { 2506193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2507193326Sed ParseDeclaratorInternal(DeclaratorInfo, 2508193326Sed &Parser::ParseDirectNewDeclarator); 2509193326Sed } 2510193326Sed } 2511193326Sed } 2512193326Sed } else { 2513193326Sed // A new-type-id is a simplified type-id, where essentially the 2514193326Sed // direct-declarator is replaced by a direct-new-declarator. 2515221345Sdim MaybeParseGNUAttributes(DeclaratorInfo); 2516193326Sed if (ParseCXXTypeSpecifierSeq(DS)) 2517193326Sed DeclaratorInfo.setInvalidType(true); 2518193326Sed else { 2519193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2520193326Sed ParseDeclaratorInternal(DeclaratorInfo, 2521193326Sed &Parser::ParseDirectNewDeclarator); 2522193326Sed } 2523193326Sed } 2524193326Sed if (DeclaratorInfo.isInvalidType()) { 2525263508Sdim SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 2526193326Sed return ExprError(); 2527193326Sed } 2528193326Sed 2529234353Sdim ExprResult Initializer; 2530193326Sed 2531193326Sed if (Tok.is(tok::l_paren)) { 2532234353Sdim SourceLocation ConstructorLParen, ConstructorRParen; 2533243830Sdim ExprVector ConstructorArgs; 2534226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2535226633Sdim T.consumeOpen(); 2536226633Sdim ConstructorLParen = T.getOpenLocation(); 2537193326Sed if (Tok.isNot(tok::r_paren)) { 2538193326Sed CommaLocsTy CommaLocs; 2539193326Sed if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 2540263508Sdim SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 2541193326Sed return ExprError(); 2542193326Sed } 2543193326Sed } 2544226633Sdim T.consumeClose(); 2545226633Sdim ConstructorRParen = T.getCloseLocation(); 2546193326Sed if (ConstructorRParen.isInvalid()) { 2547263508Sdim SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 2548193326Sed return ExprError(); 2549193326Sed } 2550234353Sdim Initializer = Actions.ActOnParenListExpr(ConstructorLParen, 2551234353Sdim ConstructorRParen, 2552243830Sdim ConstructorArgs); 2553249423Sdim } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) { 2554234353Sdim Diag(Tok.getLocation(), 2555234353Sdim diag::warn_cxx98_compat_generalized_initializer_lists); 2556234353Sdim Initializer = ParseBraceInitializer(); 2557193326Sed } 2558234353Sdim if (Initializer.isInvalid()) 2559234353Sdim return Initializer; 2560193326Sed 2561193326Sed return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 2562243830Sdim PlacementArgs, PlacementRParen, 2563234353Sdim TypeIdParens, DeclaratorInfo, Initializer.take()); 2564193326Sed} 2565193326Sed 2566193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 2567193326Sed/// passed to ParseDeclaratorInternal. 2568193326Sed/// 2569193326Sed/// direct-new-declarator: 2570193326Sed/// '[' expression ']' 2571193326Sed/// direct-new-declarator '[' constant-expression ']' 2572193326Sed/// 2573193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) { 2574193326Sed // Parse the array dimensions. 2575193326Sed bool first = true; 2576193326Sed while (Tok.is(tok::l_square)) { 2577234353Sdim // An array-size expression can't start with a lambda. 2578234353Sdim if (CheckProhibitedCXX11Attribute()) 2579234353Sdim continue; 2580234353Sdim 2581226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 2582226633Sdim T.consumeOpen(); 2583226633Sdim 2584212904Sdim ExprResult Size(first ? ParseExpression() 2585193326Sed : ParseConstantExpression()); 2586193326Sed if (Size.isInvalid()) { 2587193326Sed // Recover 2588263508Sdim SkipUntil(tok::r_square, StopAtSemi); 2589193326Sed return; 2590193326Sed } 2591193326Sed first = false; 2592193326Sed 2593226633Sdim T.consumeClose(); 2594221345Sdim 2595234353Sdim // Attributes here appertain to the array type. C++11 [expr.new]p5. 2596234353Sdim ParsedAttributes Attrs(AttrFactory); 2597249423Sdim MaybeParseCXX11Attributes(Attrs); 2598234353Sdim 2599221345Sdim D.AddTypeInfo(DeclaratorChunk::getArray(0, 2600218893Sdim /*static=*/false, /*star=*/false, 2601226633Sdim Size.release(), 2602226633Sdim T.getOpenLocation(), 2603226633Sdim T.getCloseLocation()), 2604234353Sdim Attrs, T.getCloseLocation()); 2605193326Sed 2606226633Sdim if (T.getCloseLocation().isInvalid()) 2607193326Sed return; 2608193326Sed } 2609193326Sed} 2610193326Sed 2611193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 2612193326Sed/// This ambiguity appears in the syntax of the C++ new operator. 2613193326Sed/// 2614193326Sed/// new-expression: 2615193326Sed/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 2616193326Sed/// new-initializer[opt] 2617193326Sed/// 2618193326Sed/// new-placement: 2619193326Sed/// '(' expression-list ')' 2620193326Sed/// 2621212904Sdimbool Parser::ParseExpressionListOrTypeId( 2622226633Sdim SmallVectorImpl<Expr*> &PlacementArgs, 2623193326Sed Declarator &D) { 2624193326Sed // The '(' was already consumed. 2625193326Sed if (isTypeIdInParens()) { 2626193326Sed ParseSpecifierQualifierList(D.getMutableDeclSpec()); 2627193326Sed D.SetSourceRange(D.getDeclSpec().getSourceRange()); 2628193326Sed ParseDeclarator(D); 2629193326Sed return D.isInvalidType(); 2630193326Sed } 2631193326Sed 2632193326Sed // It's not a type, it has to be an expression list. 2633193326Sed // Discard the comma locations - ActOnCXXNew has enough parameters. 2634193326Sed CommaLocsTy CommaLocs; 2635193326Sed return ParseExpressionList(PlacementArgs, CommaLocs); 2636193326Sed} 2637193326Sed 2638193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 2639193326Sed/// to free memory allocated by new. 2640193326Sed/// 2641193326Sed/// This method is called to parse the 'delete' expression after the optional 2642193326Sed/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 2643193326Sed/// and "Start" is its location. Otherwise, "Start" is the location of the 2644193326Sed/// 'delete' token. 2645193326Sed/// 2646193326Sed/// delete-expression: 2647193326Sed/// '::'[opt] 'delete' cast-expression 2648193326Sed/// '::'[opt] 'delete' '[' ']' cast-expression 2649212904SdimExprResult 2650193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 2651193326Sed assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 2652193326Sed ConsumeToken(); // Consume 'delete' 2653193326Sed 2654193326Sed // Array delete? 2655193326Sed bool ArrayDelete = false; 2656234353Sdim if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) { 2657239462Sdim // C++11 [expr.delete]p1: 2658239462Sdim // Whenever the delete keyword is followed by empty square brackets, it 2659239462Sdim // shall be interpreted as [array delete]. 2660239462Sdim // [Footnote: A lambda expression with a lambda-introducer that consists 2661239462Sdim // of empty square brackets can follow the delete keyword if 2662239462Sdim // the lambda expression is enclosed in parentheses.] 2663239462Sdim // FIXME: Produce a better diagnostic if the '[]' is unambiguously a 2664239462Sdim // lambda-introducer. 2665193326Sed ArrayDelete = true; 2666226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 2667226633Sdim 2668226633Sdim T.consumeOpen(); 2669226633Sdim T.consumeClose(); 2670226633Sdim if (T.getCloseLocation().isInvalid()) 2671193326Sed return ExprError(); 2672193326Sed } 2673193326Sed 2674212904Sdim ExprResult Operand(ParseCastExpression(false)); 2675193326Sed if (Operand.isInvalid()) 2676243830Sdim return Operand; 2677193326Sed 2678212904Sdim return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take()); 2679193326Sed} 2680193326Sed 2681198092Srdivackystatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { 2682193326Sed switch(kind) { 2683226633Sdim default: llvm_unreachable("Not a known unary type trait."); 2684193326Sed case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 2685249423Sdim case tok::kw___has_nothrow_move_assign: return UTT_HasNothrowMoveAssign; 2686193326Sed case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 2687221345Sdim case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 2688193326Sed case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 2689249423Sdim case tok::kw___has_trivial_move_assign: return UTT_HasTrivialMoveAssign; 2690223017Sdim case tok::kw___has_trivial_constructor: 2691223017Sdim return UTT_HasTrivialDefaultConstructor; 2692249423Sdim case tok::kw___has_trivial_move_constructor: 2693249423Sdim return UTT_HasTrivialMoveConstructor; 2694221345Sdim case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 2695193326Sed case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 2696193326Sed case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 2697193326Sed case tok::kw___is_abstract: return UTT_IsAbstract; 2698221345Sdim case tok::kw___is_arithmetic: return UTT_IsArithmetic; 2699221345Sdim case tok::kw___is_array: return UTT_IsArray; 2700193326Sed case tok::kw___is_class: return UTT_IsClass; 2701221345Sdim case tok::kw___is_complete_type: return UTT_IsCompleteType; 2702221345Sdim case tok::kw___is_compound: return UTT_IsCompound; 2703221345Sdim case tok::kw___is_const: return UTT_IsConst; 2704193326Sed case tok::kw___is_empty: return UTT_IsEmpty; 2705193326Sed case tok::kw___is_enum: return UTT_IsEnum; 2706234353Sdim case tok::kw___is_final: return UTT_IsFinal; 2707221345Sdim case tok::kw___is_floating_point: return UTT_IsFloatingPoint; 2708221345Sdim case tok::kw___is_function: return UTT_IsFunction; 2709221345Sdim case tok::kw___is_fundamental: return UTT_IsFundamental; 2710221345Sdim case tok::kw___is_integral: return UTT_IsIntegral; 2711243830Sdim case tok::kw___is_interface_class: return UTT_IsInterfaceClass; 2712221345Sdim case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference; 2713221345Sdim case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer; 2714221345Sdim case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer; 2715221345Sdim case tok::kw___is_member_pointer: return UTT_IsMemberPointer; 2716221345Sdim case tok::kw___is_object: return UTT_IsObject; 2717221345Sdim case tok::kw___is_literal: return UTT_IsLiteral; 2718221345Sdim case tok::kw___is_literal_type: return UTT_IsLiteral; 2719193326Sed case tok::kw___is_pod: return UTT_IsPOD; 2720221345Sdim case tok::kw___is_pointer: return UTT_IsPointer; 2721193326Sed case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 2722221345Sdim case tok::kw___is_reference: return UTT_IsReference; 2723221345Sdim case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference; 2724221345Sdim case tok::kw___is_scalar: return UTT_IsScalar; 2725263508Sdim case tok::kw___is_sealed: return UTT_IsSealed; 2726221345Sdim case tok::kw___is_signed: return UTT_IsSigned; 2727221345Sdim case tok::kw___is_standard_layout: return UTT_IsStandardLayout; 2728221345Sdim case tok::kw___is_trivial: return UTT_IsTrivial; 2729223017Sdim case tok::kw___is_trivially_copyable: return UTT_IsTriviallyCopyable; 2730193326Sed case tok::kw___is_union: return UTT_IsUnion; 2731221345Sdim case tok::kw___is_unsigned: return UTT_IsUnsigned; 2732221345Sdim case tok::kw___is_void: return UTT_IsVoid; 2733221345Sdim case tok::kw___is_volatile: return UTT_IsVolatile; 2734193326Sed } 2735193326Sed} 2736193326Sed 2737218893Sdimstatic BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) { 2738218893Sdim switch(kind) { 2739218893Sdim default: llvm_unreachable("Not a known binary type trait"); 2740218893Sdim case tok::kw___is_base_of: return BTT_IsBaseOf; 2741221345Sdim case tok::kw___is_convertible: return BTT_IsConvertible; 2742221345Sdim case tok::kw___is_same: return BTT_IsSame; 2743218893Sdim case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible; 2744218893Sdim case tok::kw___is_convertible_to: return BTT_IsConvertibleTo; 2745234353Sdim case tok::kw___is_trivially_assignable: return BTT_IsTriviallyAssignable; 2746218893Sdim } 2747218893Sdim} 2748218893Sdim 2749234353Sdimstatic TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) { 2750234353Sdim switch (kind) { 2751234353Sdim default: llvm_unreachable("Not a known type trait"); 2752234353Sdim case tok::kw___is_trivially_constructible: 2753234353Sdim return TT_IsTriviallyConstructible; 2754234353Sdim } 2755234353Sdim} 2756234353Sdim 2757221345Sdimstatic ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { 2758221345Sdim switch(kind) { 2759221345Sdim default: llvm_unreachable("Not a known binary type trait"); 2760221345Sdim case tok::kw___array_rank: return ATT_ArrayRank; 2761221345Sdim case tok::kw___array_extent: return ATT_ArrayExtent; 2762221345Sdim } 2763221345Sdim} 2764221345Sdim 2765221345Sdimstatic ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { 2766221345Sdim switch(kind) { 2767226633Sdim default: llvm_unreachable("Not a known unary expression trait."); 2768221345Sdim case tok::kw___is_lvalue_expr: return ET_IsLValueExpr; 2769221345Sdim case tok::kw___is_rvalue_expr: return ET_IsRValueExpr; 2770221345Sdim } 2771221345Sdim} 2772221345Sdim 2773193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 2774193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits 2775193326Sed/// templates. 2776193326Sed/// 2777193326Sed/// primary-expression: 2778193326Sed/// [GNU] unary-type-trait '(' type-id ')' 2779193326Sed/// 2780212904SdimExprResult Parser::ParseUnaryTypeTrait() { 2781193326Sed UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 2782193326Sed SourceLocation Loc = ConsumeToken(); 2783193326Sed 2784226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2785226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2786193326Sed return ExprError(); 2787193326Sed 2788193326Sed // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 2789193326Sed // there will be cryptic errors about mismatched parentheses and missing 2790193326Sed // specifiers. 2791193326Sed TypeResult Ty = ParseTypeName(); 2792193326Sed 2793226633Sdim T.consumeClose(); 2794193326Sed 2795193326Sed if (Ty.isInvalid()) 2796193326Sed return ExprError(); 2797193326Sed 2798226633Sdim return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation()); 2799193326Sed} 2800193326Sed 2801218893Sdim/// ParseBinaryTypeTrait - Parse the built-in binary type-trait 2802218893Sdim/// pseudo-functions that allow implementation of the TR1/C++0x type traits 2803218893Sdim/// templates. 2804218893Sdim/// 2805218893Sdim/// primary-expression: 2806218893Sdim/// [GNU] binary-type-trait '(' type-id ',' type-id ')' 2807218893Sdim/// 2808218893SdimExprResult Parser::ParseBinaryTypeTrait() { 2809218893Sdim BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind()); 2810218893Sdim SourceLocation Loc = ConsumeToken(); 2811218893Sdim 2812226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2813226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2814218893Sdim return ExprError(); 2815218893Sdim 2816218893Sdim TypeResult LhsTy = ParseTypeName(); 2817218893Sdim if (LhsTy.isInvalid()) { 2818263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2819218893Sdim return ExprError(); 2820218893Sdim } 2821218893Sdim 2822218893Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 2823263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2824218893Sdim return ExprError(); 2825218893Sdim } 2826218893Sdim 2827218893Sdim TypeResult RhsTy = ParseTypeName(); 2828218893Sdim if (RhsTy.isInvalid()) { 2829263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2830218893Sdim return ExprError(); 2831218893Sdim } 2832218893Sdim 2833226633Sdim T.consumeClose(); 2834218893Sdim 2835226633Sdim return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), 2836226633Sdim T.getCloseLocation()); 2837218893Sdim} 2838218893Sdim 2839234353Sdim/// \brief Parse the built-in type-trait pseudo-functions that allow 2840234353Sdim/// implementation of the TR1/C++11 type traits templates. 2841234353Sdim/// 2842234353Sdim/// primary-expression: 2843234353Sdim/// type-trait '(' type-id-seq ')' 2844234353Sdim/// 2845234353Sdim/// type-id-seq: 2846234353Sdim/// type-id ...[opt] type-id-seq[opt] 2847234353Sdim/// 2848234353SdimExprResult Parser::ParseTypeTrait() { 2849234353Sdim TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind()); 2850234353Sdim SourceLocation Loc = ConsumeToken(); 2851234353Sdim 2852234353Sdim BalancedDelimiterTracker Parens(*this, tok::l_paren); 2853234353Sdim if (Parens.expectAndConsume(diag::err_expected_lparen)) 2854234353Sdim return ExprError(); 2855234353Sdim 2856249423Sdim SmallVector<ParsedType, 2> Args; 2857234353Sdim do { 2858234353Sdim // Parse the next type. 2859234353Sdim TypeResult Ty = ParseTypeName(); 2860234353Sdim if (Ty.isInvalid()) { 2861234353Sdim Parens.skipToEnd(); 2862234353Sdim return ExprError(); 2863234353Sdim } 2864234353Sdim 2865234353Sdim // Parse the ellipsis, if present. 2866234353Sdim if (Tok.is(tok::ellipsis)) { 2867234353Sdim Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken()); 2868234353Sdim if (Ty.isInvalid()) { 2869234353Sdim Parens.skipToEnd(); 2870234353Sdim return ExprError(); 2871234353Sdim } 2872234353Sdim } 2873234353Sdim 2874234353Sdim // Add this type to the list of arguments. 2875234353Sdim Args.push_back(Ty.get()); 2876234353Sdim 2877234353Sdim if (Tok.is(tok::comma)) { 2878234353Sdim ConsumeToken(); 2879234353Sdim continue; 2880234353Sdim } 2881234353Sdim 2882234353Sdim break; 2883234353Sdim } while (true); 2884234353Sdim 2885234353Sdim if (Parens.consumeClose()) 2886234353Sdim return ExprError(); 2887234353Sdim 2888234353Sdim return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation()); 2889234353Sdim} 2890234353Sdim 2891221345Sdim/// ParseArrayTypeTrait - Parse the built-in array type-trait 2892221345Sdim/// pseudo-functions. 2893221345Sdim/// 2894221345Sdim/// primary-expression: 2895221345Sdim/// [Embarcadero] '__array_rank' '(' type-id ')' 2896221345Sdim/// [Embarcadero] '__array_extent' '(' type-id ',' expression ')' 2897221345Sdim/// 2898221345SdimExprResult Parser::ParseArrayTypeTrait() { 2899221345Sdim ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); 2900221345Sdim SourceLocation Loc = ConsumeToken(); 2901221345Sdim 2902226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2903226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2904221345Sdim return ExprError(); 2905221345Sdim 2906221345Sdim TypeResult Ty = ParseTypeName(); 2907221345Sdim if (Ty.isInvalid()) { 2908263508Sdim SkipUntil(tok::comma, StopAtSemi); 2909263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2910221345Sdim return ExprError(); 2911221345Sdim } 2912221345Sdim 2913221345Sdim switch (ATT) { 2914221345Sdim case ATT_ArrayRank: { 2915226633Sdim T.consumeClose(); 2916226633Sdim return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, 2917226633Sdim T.getCloseLocation()); 2918221345Sdim } 2919221345Sdim case ATT_ArrayExtent: { 2920221345Sdim if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 2921263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2922221345Sdim return ExprError(); 2923221345Sdim } 2924221345Sdim 2925221345Sdim ExprResult DimExpr = ParseExpression(); 2926226633Sdim T.consumeClose(); 2927221345Sdim 2928226633Sdim return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), 2929226633Sdim T.getCloseLocation()); 2930221345Sdim } 2931221345Sdim } 2932234353Sdim llvm_unreachable("Invalid ArrayTypeTrait!"); 2933221345Sdim} 2934221345Sdim 2935221345Sdim/// ParseExpressionTrait - Parse built-in expression-trait 2936221345Sdim/// pseudo-functions like __is_lvalue_expr( xxx ). 2937221345Sdim/// 2938221345Sdim/// primary-expression: 2939221345Sdim/// [Embarcadero] expression-trait '(' expression ')' 2940221345Sdim/// 2941221345SdimExprResult Parser::ParseExpressionTrait() { 2942221345Sdim ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); 2943221345Sdim SourceLocation Loc = ConsumeToken(); 2944221345Sdim 2945226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2946226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2947221345Sdim return ExprError(); 2948221345Sdim 2949221345Sdim ExprResult Expr = ParseExpression(); 2950221345Sdim 2951226633Sdim T.consumeClose(); 2952221345Sdim 2953226633Sdim return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), 2954226633Sdim T.getCloseLocation()); 2955221345Sdim} 2956221345Sdim 2957221345Sdim 2958193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 2959193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 2960193326Sed/// based on the context past the parens. 2961212904SdimExprResult 2962193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 2963212904Sdim ParsedType &CastTy, 2964226633Sdim BalancedDelimiterTracker &Tracker) { 2965234353Sdim assert(getLangOpts().CPlusPlus && "Should only be called for C++!"); 2966193326Sed assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 2967193326Sed assert(isTypeIdInParens() && "Not a type-id!"); 2968193326Sed 2969212904Sdim ExprResult Result(true); 2970212904Sdim CastTy = ParsedType(); 2971193326Sed 2972193326Sed // We need to disambiguate a very ugly part of the C++ syntax: 2973193326Sed // 2974193326Sed // (T())x; - type-id 2975193326Sed // (T())*x; - type-id 2976193326Sed // (T())/x; - expression 2977193326Sed // (T()); - expression 2978193326Sed // 2979193326Sed // The bad news is that we cannot use the specialized tentative parser, since 2980193326Sed // it can only verify that the thing inside the parens can be parsed as 2981193326Sed // type-id, it is not useful for determining the context past the parens. 2982193326Sed // 2983193326Sed // The good news is that the parser can disambiguate this part without 2984193326Sed // making any unnecessary Action calls. 2985193326Sed // 2986193326Sed // It uses a scheme similar to parsing inline methods. The parenthesized 2987193326Sed // tokens are cached, the context that follows is determined (possibly by 2988193326Sed // parsing a cast-expression), and then we re-introduce the cached tokens 2989193326Sed // into the token stream and parse them appropriately. 2990193326Sed 2991198092Srdivacky ParenParseOption ParseAs; 2992193326Sed CachedTokens Toks; 2993193326Sed 2994193326Sed // Store the tokens of the parentheses. We will parse them after we determine 2995193326Sed // the context that follows them. 2996207619Srdivacky if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { 2997193326Sed // We didn't find the ')' we expected. 2998226633Sdim Tracker.consumeClose(); 2999193326Sed return ExprError(); 3000193326Sed } 3001193326Sed 3002193326Sed if (Tok.is(tok::l_brace)) { 3003193326Sed ParseAs = CompoundLiteral; 3004193326Sed } else { 3005193326Sed bool NotCastExpr; 3006193326Sed // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 3007193326Sed if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 3008193326Sed NotCastExpr = true; 3009193326Sed } else { 3010193326Sed // Try parsing the cast-expression that may follow. 3011193326Sed // If it is not a cast-expression, NotCastExpr will be true and no token 3012193326Sed // will be consumed. 3013193326Sed Result = ParseCastExpression(false/*isUnaryExpression*/, 3014193326Sed false/*isAddressofOperand*/, 3015212904Sdim NotCastExpr, 3016224145Sdim // type-id has priority. 3017234353Sdim IsTypeCast); 3018193326Sed } 3019193326Sed 3020193326Sed // If we parsed a cast-expression, it's really a type-id, otherwise it's 3021193326Sed // an expression. 3022193326Sed ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 3023193326Sed } 3024193326Sed 3025198092Srdivacky // The current token should go after the cached tokens. 3026193326Sed Toks.push_back(Tok); 3027193326Sed // Re-enter the stored parenthesized tokens into the token stream, so we may 3028193326Sed // parse them now. 3029193326Sed PP.EnterTokenStream(Toks.data(), Toks.size(), 3030193326Sed true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 3031193326Sed // Drop the current token and bring the first cached one. It's the same token 3032193326Sed // as when we entered this function. 3033193326Sed ConsumeAnyToken(); 3034193326Sed 3035193326Sed if (ParseAs >= CompoundLiteral) { 3036224145Sdim // Parse the type declarator. 3037224145Sdim DeclSpec DS(AttrFactory); 3038224145Sdim ParseSpecifierQualifierList(DS); 3039224145Sdim Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 3040224145Sdim ParseDeclarator(DeclaratorInfo); 3041193326Sed 3042193326Sed // Match the ')'. 3043226633Sdim Tracker.consumeClose(); 3044193326Sed 3045193326Sed if (ParseAs == CompoundLiteral) { 3046193326Sed ExprType = CompoundLiteral; 3047224145Sdim TypeResult Ty = ParseTypeName(); 3048226633Sdim return ParseCompoundLiteralExpression(Ty.get(), 3049226633Sdim Tracker.getOpenLocation(), 3050226633Sdim Tracker.getCloseLocation()); 3051193326Sed } 3052198092Srdivacky 3053193326Sed // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 3054193326Sed assert(ParseAs == CastExpr); 3055193326Sed 3056224145Sdim if (DeclaratorInfo.isInvalidType()) 3057193326Sed return ExprError(); 3058193326Sed 3059193326Sed // Result is what ParseCastExpression returned earlier. 3060193326Sed if (!Result.isInvalid()) 3061226633Sdim Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), 3062226633Sdim DeclaratorInfo, CastTy, 3063226633Sdim Tracker.getCloseLocation(), Result.take()); 3064243830Sdim return Result; 3065193326Sed } 3066198092Srdivacky 3067193326Sed // Not a compound literal, and not followed by a cast-expression. 3068193326Sed assert(ParseAs == SimpleExpr); 3069193326Sed 3070193326Sed ExprType = SimpleExpr; 3071193326Sed Result = ParseExpression(); 3072193326Sed if (!Result.isInvalid() && Tok.is(tok::r_paren)) 3073226633Sdim Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 3074226633Sdim Tok.getLocation(), Result.take()); 3075193326Sed 3076193326Sed // Match the ')'. 3077193326Sed if (Result.isInvalid()) { 3078263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 3079193326Sed return ExprError(); 3080193326Sed } 3081198092Srdivacky 3082226633Sdim Tracker.consumeClose(); 3083243830Sdim return Result; 3084193326Sed} 3085