10b57cec5SDimitry Andric //===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the Expression parsing implementation for C++. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric #include "clang/Parse/Parser.h" 130b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 1455e4f9d5SDimitry Andric #include "clang/AST/Decl.h" 150b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 1655e4f9d5SDimitry Andric #include "clang/AST/ExprCXX.h" 170b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 180b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h" 190b57cec5SDimitry Andric #include "clang/Parse/ParseDiagnostic.h" 200b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 210b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 220b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 230b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 250b57cec5SDimitry Andric #include <numeric> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace clang; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric static int SelectDigraphErrorMessage(tok::TokenKind Kind) { 300b57cec5SDimitry Andric switch (Kind) { 310b57cec5SDimitry Andric // template name 320b57cec5SDimitry Andric case tok::unknown: return 0; 330b57cec5SDimitry Andric // casts 340b57cec5SDimitry Andric case tok::kw_const_cast: return 1; 350b57cec5SDimitry Andric case tok::kw_dynamic_cast: return 2; 360b57cec5SDimitry Andric case tok::kw_reinterpret_cast: return 3; 370b57cec5SDimitry Andric case tok::kw_static_cast: return 4; 380b57cec5SDimitry Andric default: 390b57cec5SDimitry Andric llvm_unreachable("Unknown type for digraph error message."); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Are the two tokens adjacent in the same source file? 440b57cec5SDimitry Andric bool Parser::areTokensAdjacent(const Token &First, const Token &Second) { 450b57cec5SDimitry Andric SourceManager &SM = PP.getSourceManager(); 460b57cec5SDimitry Andric SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation()); 470b57cec5SDimitry Andric SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength()); 480b57cec5SDimitry Andric return FirstEnd == SM.getSpellingLoc(Second.getLocation()); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric // Suggest fixit for "<::" after a cast. 520b57cec5SDimitry Andric static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, 530b57cec5SDimitry Andric Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) { 540b57cec5SDimitry Andric // Pull '<:' and ':' off token stream. 550b57cec5SDimitry Andric if (!AtDigraph) 560b57cec5SDimitry Andric PP.Lex(DigraphToken); 570b57cec5SDimitry Andric PP.Lex(ColonToken); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric SourceRange Range; 600b57cec5SDimitry Andric Range.setBegin(DigraphToken.getLocation()); 610b57cec5SDimitry Andric Range.setEnd(ColonToken.getLocation()); 620b57cec5SDimitry Andric P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph) 630b57cec5SDimitry Andric << SelectDigraphErrorMessage(Kind) 640b57cec5SDimitry Andric << FixItHint::CreateReplacement(Range, "< ::"); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric // Update token information to reflect their change in token type. 670b57cec5SDimitry Andric ColonToken.setKind(tok::coloncolon); 680b57cec5SDimitry Andric ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1)); 690b57cec5SDimitry Andric ColonToken.setLength(2); 700b57cec5SDimitry Andric DigraphToken.setKind(tok::less); 710b57cec5SDimitry Andric DigraphToken.setLength(1); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric // Push new tokens back to token stream. 740b57cec5SDimitry Andric PP.EnterToken(ColonToken, /*IsReinject*/ true); 750b57cec5SDimitry Andric if (!AtDigraph) 760b57cec5SDimitry Andric PP.EnterToken(DigraphToken, /*IsReinject*/ true); 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric // Check for '<::' which should be '< ::' instead of '[:' when following 800b57cec5SDimitry Andric // a template name. 810b57cec5SDimitry Andric void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, 820b57cec5SDimitry Andric bool EnteringContext, 830b57cec5SDimitry Andric IdentifierInfo &II, CXXScopeSpec &SS) { 840b57cec5SDimitry Andric if (!Next.is(tok::l_square) || Next.getLength() != 2) 850b57cec5SDimitry Andric return; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric Token SecondToken = GetLookAheadToken(2); 880b57cec5SDimitry Andric if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken)) 890b57cec5SDimitry Andric return; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric TemplateTy Template; 920b57cec5SDimitry Andric UnqualifiedId TemplateName; 930b57cec5SDimitry Andric TemplateName.setIdentifier(&II, Tok.getLocation()); 940b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 950b57cec5SDimitry Andric if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, 960b57cec5SDimitry Andric TemplateName, ObjectType, EnteringContext, 970b57cec5SDimitry Andric Template, MemberOfUnknownSpecialization)) 980b57cec5SDimitry Andric return; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric FixDigraph(*this, PP, Next, SecondToken, tok::unknown, 1010b57cec5SDimitry Andric /*AtDigraph*/false); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// Parse global scope or nested-name-specifier if present. 1050b57cec5SDimitry Andric /// 1060b57cec5SDimitry Andric /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 1070b57cec5SDimitry Andric /// may be preceded by '::'). Note that this routine will not parse ::new or 1080b57cec5SDimitry Andric /// ::delete; it will just leave them in the token stream. 1090b57cec5SDimitry Andric /// 1100b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 1110b57cec5SDimitry Andric /// '::' 1120b57cec5SDimitry Andric /// 1130b57cec5SDimitry Andric /// nested-name-specifier: 1140b57cec5SDimitry Andric /// type-name '::' 1150b57cec5SDimitry Andric /// namespace-name '::' 1160b57cec5SDimitry Andric /// nested-name-specifier identifier '::' 1170b57cec5SDimitry Andric /// nested-name-specifier 'template'[opt] simple-template-id '::' 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// 1200b57cec5SDimitry Andric /// \param SS the scope specifier that will be set to the parsed 1210b57cec5SDimitry Andric /// nested-name-specifier (or empty) 1220b57cec5SDimitry Andric /// 1230b57cec5SDimitry Andric /// \param ObjectType if this nested-name-specifier is being parsed following 1240b57cec5SDimitry Andric /// the "." or "->" of a member access expression, this parameter provides the 1250b57cec5SDimitry Andric /// type of the object whose members are being accessed. 1260b57cec5SDimitry Andric /// 1270b57cec5SDimitry Andric /// \param EnteringContext whether we will be entering into the context of 1280b57cec5SDimitry Andric /// the nested-name-specifier after parsing it. 1290b57cec5SDimitry Andric /// 1300b57cec5SDimitry Andric /// \param MayBePseudoDestructor When non-NULL, points to a flag that 1310b57cec5SDimitry Andric /// indicates whether this nested-name-specifier may be part of a 1320b57cec5SDimitry Andric /// pseudo-destructor name. In this case, the flag will be set false 1330b57cec5SDimitry Andric /// if we don't actually end up parsing a destructor name. Moreorover, 1340b57cec5SDimitry Andric /// if we do end up determining that we are parsing a destructor name, 1350b57cec5SDimitry Andric /// the last component of the nested-name-specifier is not parsed as 1360b57cec5SDimitry Andric /// part of the scope specifier. 1370b57cec5SDimitry Andric /// 1380b57cec5SDimitry Andric /// \param IsTypename If \c true, this nested-name-specifier is known to be 1390b57cec5SDimitry Andric /// part of a type name. This is used to improve error recovery. 1400b57cec5SDimitry Andric /// 1410b57cec5SDimitry Andric /// \param LastII When non-NULL, points to an IdentifierInfo* that will be 1420b57cec5SDimitry Andric /// filled in with the leading identifier in the last component of the 1430b57cec5SDimitry Andric /// nested-name-specifier, if any. 1440b57cec5SDimitry Andric /// 1450b57cec5SDimitry Andric /// \param OnlyNamespace If true, only considers namespaces in lookup. 1460b57cec5SDimitry Andric /// 147480093f4SDimitry Andric /// 1480b57cec5SDimitry Andric /// \returns true if there was an error parsing a scope specifier 1490b57cec5SDimitry Andric bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 1500b57cec5SDimitry Andric ParsedType ObjectType, 1510b57cec5SDimitry Andric bool EnteringContext, 1520b57cec5SDimitry Andric bool *MayBePseudoDestructor, 1530b57cec5SDimitry Andric bool IsTypename, 1540b57cec5SDimitry Andric IdentifierInfo **LastII, 155480093f4SDimitry Andric bool OnlyNamespace, 156480093f4SDimitry Andric bool InUsingDeclaration) { 1570b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus && 1580b57cec5SDimitry Andric "Call sites of this function should be guarded by checking for C++"); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 1610b57cec5SDimitry Andric assert(!LastII && "want last identifier but have already annotated scope"); 1620b57cec5SDimitry Andric assert(!MayBePseudoDestructor && "unexpected annot_cxxscope"); 1630b57cec5SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1640b57cec5SDimitry Andric Tok.getAnnotationRange(), 1650b57cec5SDimitry Andric SS); 1660b57cec5SDimitry Andric ConsumeAnnotationToken(); 1670b57cec5SDimitry Andric return false; 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric // Has to happen before any "return false"s in this function. 1710b57cec5SDimitry Andric bool CheckForDestructor = false; 1720b57cec5SDimitry Andric if (MayBePseudoDestructor && *MayBePseudoDestructor) { 1730b57cec5SDimitry Andric CheckForDestructor = true; 1740b57cec5SDimitry Andric *MayBePseudoDestructor = false; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric if (LastII) 1780b57cec5SDimitry Andric *LastII = nullptr; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric bool HasScopeSpecifier = false; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric if (Tok.is(tok::coloncolon)) { 1830b57cec5SDimitry Andric // ::new and ::delete aren't nested-name-specifiers. 1840b57cec5SDimitry Andric tok::TokenKind NextKind = NextToken().getKind(); 1850b57cec5SDimitry Andric if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 1860b57cec5SDimitry Andric return false; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric if (NextKind == tok::l_brace) { 1890b57cec5SDimitry Andric // It is invalid to have :: {, consume the scope qualifier and pretend 1900b57cec5SDimitry Andric // like we never saw it. 1910b57cec5SDimitry Andric Diag(ConsumeToken(), diag::err_expected) << tok::identifier; 1920b57cec5SDimitry Andric } else { 1930b57cec5SDimitry Andric // '::' - Global scope qualifier. 1940b57cec5SDimitry Andric if (Actions.ActOnCXXGlobalScopeSpecifier(ConsumeToken(), SS)) 1950b57cec5SDimitry Andric return true; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric HasScopeSpecifier = true; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric if (Tok.is(tok::kw___super)) { 2020b57cec5SDimitry Andric SourceLocation SuperLoc = ConsumeToken(); 2030b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) { 2040b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super); 2050b57cec5SDimitry Andric return true; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric if (!HasScopeSpecifier && 2120b57cec5SDimitry Andric Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) { 2130b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 2140b57cec5SDimitry Andric SourceLocation DeclLoc = Tok.getLocation(); 2150b57cec5SDimitry Andric SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric SourceLocation CCLoc; 2180b57cec5SDimitry Andric // Work around a standard defect: 'decltype(auto)::' is not a 2190b57cec5SDimitry Andric // nested-name-specifier. 2200b57cec5SDimitry Andric if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto || 2210b57cec5SDimitry Andric !TryConsumeToken(tok::coloncolon, CCLoc)) { 2220b57cec5SDimitry Andric AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc); 2230b57cec5SDimitry Andric return false; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc)) 2270b57cec5SDimitry Andric SS.SetInvalid(SourceRange(DeclLoc, CCLoc)); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric HasScopeSpecifier = true; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric // Preferred type might change when parsing qualifiers, we need the original. 2330b57cec5SDimitry Andric auto SavedType = PreferredType; 2340b57cec5SDimitry Andric while (true) { 2350b57cec5SDimitry Andric if (HasScopeSpecifier) { 2360b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 2370b57cec5SDimitry Andric // Code completion for a nested-name-specifier, where the code 2380b57cec5SDimitry Andric // completion token follows the '::'. 2390b57cec5SDimitry Andric Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext, 240480093f4SDimitry Andric InUsingDeclaration, ObjectType.get(), 2410b57cec5SDimitry Andric SavedType.get(SS.getBeginLoc())); 2420b57cec5SDimitry Andric // Include code completion token into the range of the scope otherwise 2430b57cec5SDimitry Andric // when we try to annotate the scope tokens the dangling code completion 2440b57cec5SDimitry Andric // token will cause assertion in 2450b57cec5SDimitry Andric // Preprocessor::AnnotatePreviousCachedTokens. 2460b57cec5SDimitry Andric SS.setEndLoc(Tok.getLocation()); 2470b57cec5SDimitry Andric cutOffParsing(); 2480b57cec5SDimitry Andric return true; 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric // C++ [basic.lookup.classref]p5: 2520b57cec5SDimitry Andric // If the qualified-id has the form 2530b57cec5SDimitry Andric // 2540b57cec5SDimitry Andric // ::class-name-or-namespace-name::... 2550b57cec5SDimitry Andric // 2560b57cec5SDimitry Andric // the class-name-or-namespace-name is looked up in global scope as a 2570b57cec5SDimitry Andric // class-name or namespace-name. 2580b57cec5SDimitry Andric // 2590b57cec5SDimitry Andric // To implement this, we clear out the object type as soon as we've 2600b57cec5SDimitry Andric // seen a leading '::' or part of a nested-name-specifier. 2610b57cec5SDimitry Andric ObjectType = nullptr; 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // nested-name-specifier: 2650b57cec5SDimitry Andric // nested-name-specifier 'template'[opt] simple-template-id '::' 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // Parse the optional 'template' keyword, then make sure we have 2680b57cec5SDimitry Andric // 'identifier <' after it. 2690b57cec5SDimitry Andric if (Tok.is(tok::kw_template)) { 2700b57cec5SDimitry Andric // If we don't have a scope specifier or an object type, this isn't a 2710b57cec5SDimitry Andric // nested-name-specifier, since they aren't allowed to start with 2720b57cec5SDimitry Andric // 'template'. 2730b57cec5SDimitry Andric if (!HasScopeSpecifier && !ObjectType) 2740b57cec5SDimitry Andric break; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 2770b57cec5SDimitry Andric SourceLocation TemplateKWLoc = ConsumeToken(); 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric UnqualifiedId TemplateName; 2800b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 2810b57cec5SDimitry Andric // Consume the identifier. 2820b57cec5SDimitry Andric TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 2830b57cec5SDimitry Andric ConsumeToken(); 2840b57cec5SDimitry Andric } else if (Tok.is(tok::kw_operator)) { 2850b57cec5SDimitry Andric // We don't need to actually parse the unqualified-id in this case, 2860b57cec5SDimitry Andric // because a simple-template-id cannot start with 'operator', but 2870b57cec5SDimitry Andric // go ahead and parse it anyway for consistency with the case where 2880b57cec5SDimitry Andric // we already annotated the template-id. 2890b57cec5SDimitry Andric if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 2900b57cec5SDimitry Andric TemplateName)) { 2910b57cec5SDimitry Andric TPA.Commit(); 2920b57cec5SDimitry Andric break; 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId && 2960b57cec5SDimitry Andric TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) { 2970b57cec5SDimitry Andric Diag(TemplateName.getSourceRange().getBegin(), 2980b57cec5SDimitry Andric diag::err_id_after_template_in_nested_name_spec) 2990b57cec5SDimitry Andric << TemplateName.getSourceRange(); 3000b57cec5SDimitry Andric TPA.Commit(); 3010b57cec5SDimitry Andric break; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric } else { 3040b57cec5SDimitry Andric TPA.Revert(); 3050b57cec5SDimitry Andric break; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // If the next token is not '<', we have a qualified-id that refers 3090b57cec5SDimitry Andric // to a template name, such as T::template apply, but is not a 3100b57cec5SDimitry Andric // template-id. 3110b57cec5SDimitry Andric if (Tok.isNot(tok::less)) { 3120b57cec5SDimitry Andric TPA.Revert(); 3130b57cec5SDimitry Andric break; 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric // Commit to parsing the template-id. 3170b57cec5SDimitry Andric TPA.Commit(); 3180b57cec5SDimitry Andric TemplateTy Template; 3190b57cec5SDimitry Andric if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName( 3200b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType, 3210b57cec5SDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true)) { 3220b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc, 3230b57cec5SDimitry Andric TemplateName, false)) 3240b57cec5SDimitry Andric return true; 3250b57cec5SDimitry Andric } else 3260b57cec5SDimitry Andric return true; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric continue; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 3320b57cec5SDimitry Andric // We have 3330b57cec5SDimitry Andric // 3340b57cec5SDimitry Andric // template-id '::' 3350b57cec5SDimitry Andric // 3360b57cec5SDimitry Andric // So we need to check whether the template-id is a simple-template-id of 3370b57cec5SDimitry Andric // the right kind (it should name a type or be dependent), and then 3380b57cec5SDimitry Andric // convert it into a type within the nested-name-specifier. 3390b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 3400b57cec5SDimitry Andric if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 3410b57cec5SDimitry Andric *MayBePseudoDestructor = true; 3420b57cec5SDimitry Andric return false; 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric if (LastII) 3460b57cec5SDimitry Andric *LastII = TemplateId->Name; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // Consume the template-id token. 3490b57cec5SDimitry Andric ConsumeAnnotationToken(); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 3520b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric HasScopeSpecifier = true; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 3570b57cec5SDimitry Andric TemplateId->NumArgs); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), 3600b57cec5SDimitry Andric SS, 3610b57cec5SDimitry Andric TemplateId->TemplateKWLoc, 3620b57cec5SDimitry Andric TemplateId->Template, 3630b57cec5SDimitry Andric TemplateId->TemplateNameLoc, 3640b57cec5SDimitry Andric TemplateId->LAngleLoc, 3650b57cec5SDimitry Andric TemplateArgsPtr, 3660b57cec5SDimitry Andric TemplateId->RAngleLoc, 3670b57cec5SDimitry Andric CCLoc, 3680b57cec5SDimitry Andric EnteringContext)) { 3690b57cec5SDimitry Andric SourceLocation StartLoc 3700b57cec5SDimitry Andric = SS.getBeginLoc().isValid()? SS.getBeginLoc() 3710b57cec5SDimitry Andric : TemplateId->TemplateNameLoc; 3720b57cec5SDimitry Andric SS.SetInvalid(SourceRange(StartLoc, CCLoc)); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric continue; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric // The rest of the nested-name-specifier possibilities start with 3790b57cec5SDimitry Andric // tok::identifier. 3800b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 3810b57cec5SDimitry Andric break; 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric // nested-name-specifier: 3860b57cec5SDimitry Andric // type-name '::' 3870b57cec5SDimitry Andric // namespace-name '::' 3880b57cec5SDimitry Andric // nested-name-specifier identifier '::' 3890b57cec5SDimitry Andric Token Next = NextToken(); 3900b57cec5SDimitry Andric Sema::NestedNameSpecInfo IdInfo(&II, Tok.getLocation(), Next.getLocation(), 3910b57cec5SDimitry Andric ObjectType); 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 3940b57cec5SDimitry Andric // and emit a fixit hint for it. 3950b57cec5SDimitry Andric if (Next.is(tok::colon) && !ColonIsSacred) { 3960b57cec5SDimitry Andric if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, IdInfo, 3970b57cec5SDimitry Andric EnteringContext) && 3980b57cec5SDimitry Andric // If the token after the colon isn't an identifier, it's still an 3990b57cec5SDimitry Andric // error, but they probably meant something else strange so don't 4000b57cec5SDimitry Andric // recover like this. 4010b57cec5SDimitry Andric PP.LookAhead(1).is(tok::identifier)) { 4020b57cec5SDimitry Andric Diag(Next, diag::err_unexpected_colon_in_nested_name_spec) 4030b57cec5SDimitry Andric << FixItHint::CreateReplacement(Next.getLocation(), "::"); 4040b57cec5SDimitry Andric // Recover as if the user wrote '::'. 4050b57cec5SDimitry Andric Next.setKind(tok::coloncolon); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) { 4100b57cec5SDimitry Andric // It is invalid to have :: {, consume the scope qualifier and pretend 4110b57cec5SDimitry Andric // like we never saw it. 4120b57cec5SDimitry Andric Token Identifier = Tok; // Stash away the identifier. 4130b57cec5SDimitry Andric ConsumeToken(); // Eat the identifier, current token is now '::'. 4140b57cec5SDimitry Andric Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected) 4150b57cec5SDimitry Andric << tok::identifier; 4160b57cec5SDimitry Andric UnconsumeToken(Identifier); // Stick the identifier back. 4170b57cec5SDimitry Andric Next = NextToken(); // Point Next at the '{' token. 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric if (Next.is(tok::coloncolon)) { 4210b57cec5SDimitry Andric if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && 4220b57cec5SDimitry Andric !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, IdInfo)) { 4230b57cec5SDimitry Andric *MayBePseudoDestructor = true; 4240b57cec5SDimitry Andric return false; 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric if (ColonIsSacred) { 4280b57cec5SDimitry Andric const Token &Next2 = GetLookAheadToken(2); 4290b57cec5SDimitry Andric if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) || 4300b57cec5SDimitry Andric Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) { 4310b57cec5SDimitry Andric Diag(Next2, diag::err_unexpected_token_in_nested_name_spec) 4320b57cec5SDimitry Andric << Next2.getName() 4330b57cec5SDimitry Andric << FixItHint::CreateReplacement(Next.getLocation(), ":"); 4340b57cec5SDimitry Andric Token ColonColon; 4350b57cec5SDimitry Andric PP.Lex(ColonColon); 4360b57cec5SDimitry Andric ColonColon.setKind(tok::colon); 4370b57cec5SDimitry Andric PP.EnterToken(ColonColon, /*IsReinject*/ true); 4380b57cec5SDimitry Andric break; 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric if (LastII) 4430b57cec5SDimitry Andric *LastII = &II; 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric // We have an identifier followed by a '::'. Lookup this name 4460b57cec5SDimitry Andric // as the name in a nested-name-specifier. 4470b57cec5SDimitry Andric Token Identifier = Tok; 4480b57cec5SDimitry Andric SourceLocation IdLoc = ConsumeToken(); 4490b57cec5SDimitry Andric assert(Tok.isOneOf(tok::coloncolon, tok::colon) && 4500b57cec5SDimitry Andric "NextToken() not working properly!"); 4510b57cec5SDimitry Andric Token ColonColon = Tok; 4520b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric bool IsCorrectedToColon = false; 4550b57cec5SDimitry Andric bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr; 4560b57cec5SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifier( 4570b57cec5SDimitry Andric getCurScope(), IdInfo, EnteringContext, SS, false, 4580b57cec5SDimitry Andric CorrectionFlagPtr, OnlyNamespace)) { 4590b57cec5SDimitry Andric // Identifier is not recognized as a nested name, but we can have 4600b57cec5SDimitry Andric // mistyped '::' instead of ':'. 4610b57cec5SDimitry Andric if (CorrectionFlagPtr && IsCorrectedToColon) { 4620b57cec5SDimitry Andric ColonColon.setKind(tok::colon); 4630b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/ true); 4640b57cec5SDimitry Andric PP.EnterToken(ColonColon, /*IsReinject*/ true); 4650b57cec5SDimitry Andric Tok = Identifier; 4660b57cec5SDimitry Andric break; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric SS.SetInvalid(SourceRange(IdLoc, CCLoc)); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric HasScopeSpecifier = true; 4710b57cec5SDimitry Andric continue; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // nested-name-specifier: 4770b57cec5SDimitry Andric // type-name '<' 4780b57cec5SDimitry Andric if (Next.is(tok::less)) { 479480093f4SDimitry Andric 4800b57cec5SDimitry Andric TemplateTy Template; 4810b57cec5SDimitry Andric UnqualifiedId TemplateName; 4820b57cec5SDimitry Andric TemplateName.setIdentifier(&II, Tok.getLocation()); 4830b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 4840b57cec5SDimitry Andric if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 4850b57cec5SDimitry Andric /*hasTemplateKeyword=*/false, 4860b57cec5SDimitry Andric TemplateName, 4870b57cec5SDimitry Andric ObjectType, 4880b57cec5SDimitry Andric EnteringContext, 4890b57cec5SDimitry Andric Template, 4900b57cec5SDimitry Andric MemberOfUnknownSpecialization)) { 4910b57cec5SDimitry Andric // If lookup didn't find anything, we treat the name as a template-name 4920b57cec5SDimitry Andric // anyway. C++20 requires this, and in prior language modes it improves 4930b57cec5SDimitry Andric // error recovery. But before we commit to this, check that we actually 4940b57cec5SDimitry Andric // have something that looks like a template-argument-list next. 4950b57cec5SDimitry Andric if (!IsTypename && TNK == TNK_Undeclared_template && 4960b57cec5SDimitry Andric isTemplateArgumentList(1) == TPResult::False) 4970b57cec5SDimitry Andric break; 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric // We have found a template name, so annotate this token 5000b57cec5SDimitry Andric // with a template-id annotation. We do not permit the 5010b57cec5SDimitry Andric // template-id to be translated into a type annotation, 5020b57cec5SDimitry Andric // because some clients (e.g., the parsing of class template 5030b57cec5SDimitry Andric // specializations) still want to see the original template-id 504480093f4SDimitry Andric // token, and it might not be a type at all (e.g. a concept name in a 505480093f4SDimitry Andric // type-constraint). 5060b57cec5SDimitry Andric ConsumeToken(); 5070b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 5080b57cec5SDimitry Andric TemplateName, false)) 5090b57cec5SDimitry Andric return true; 5100b57cec5SDimitry Andric continue; 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 5140b57cec5SDimitry Andric (IsTypename || isTemplateArgumentList(1) == TPResult::True)) { 5150b57cec5SDimitry Andric // We have something like t::getAs<T>, where getAs is a 5160b57cec5SDimitry Andric // member of an unknown specialization. However, this will only 5170b57cec5SDimitry Andric // parse correctly as a template, so suggest the keyword 'template' 5180b57cec5SDimitry Andric // before 'getAs' and treat this as a dependent template name. 5190b57cec5SDimitry Andric unsigned DiagID = diag::err_missing_dependent_template_keyword; 5200b57cec5SDimitry Andric if (getLangOpts().MicrosoftExt) 5210b57cec5SDimitry Andric DiagID = diag::warn_missing_dependent_template_keyword; 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric Diag(Tok.getLocation(), DiagID) 5240b57cec5SDimitry Andric << II.getName() 5250b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "template "); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName( 5280b57cec5SDimitry Andric getCurScope(), SS, Tok.getLocation(), TemplateName, ObjectType, 5290b57cec5SDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true)) { 5300b57cec5SDimitry Andric // Consume the identifier. 5310b57cec5SDimitry Andric ConsumeToken(); 5320b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 5330b57cec5SDimitry Andric TemplateName, false)) 5340b57cec5SDimitry Andric return true; 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric else 5370b57cec5SDimitry Andric return true; 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric continue; 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric // We don't have any tokens that form the beginning of a 5440b57cec5SDimitry Andric // nested-name-specifier, so we're done. 5450b57cec5SDimitry Andric break; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // Even if we didn't see any pieces of a nested-name-specifier, we 5490b57cec5SDimitry Andric // still check whether there is a tilde in this position, which 5500b57cec5SDimitry Andric // indicates a potential pseudo-destructor. 5510b57cec5SDimitry Andric if (CheckForDestructor && Tok.is(tok::tilde)) 5520b57cec5SDimitry Andric *MayBePseudoDestructor = true; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric return false; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 557a7dea167SDimitry Andric ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, 558a7dea167SDimitry Andric bool isAddressOfOperand, 5590b57cec5SDimitry Andric Token &Replacement) { 560a7dea167SDimitry Andric ExprResult E; 561a7dea167SDimitry Andric 562a7dea167SDimitry Andric // We may have already annotated this id-expression. 563a7dea167SDimitry Andric switch (Tok.getKind()) { 564a7dea167SDimitry Andric case tok::annot_non_type: { 565a7dea167SDimitry Andric NamedDecl *ND = getNonTypeAnnotation(Tok); 566a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 567a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsNonType(getCurScope(), SS, ND, Loc, Tok); 568a7dea167SDimitry Andric break; 569a7dea167SDimitry Andric } 570a7dea167SDimitry Andric 571a7dea167SDimitry Andric case tok::annot_non_type_dependent: { 572a7dea167SDimitry Andric IdentifierInfo *II = getIdentifierAnnotation(Tok); 573a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 574a7dea167SDimitry Andric 575a7dea167SDimitry Andric // This is only the direct operand of an & operator if it is not 576a7dea167SDimitry Andric // followed by a postfix-expression suffix. 577a7dea167SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 578a7dea167SDimitry Andric isAddressOfOperand = false; 579a7dea167SDimitry Andric 580a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsDependentNonType(SS, II, Loc, 581a7dea167SDimitry Andric isAddressOfOperand); 582a7dea167SDimitry Andric break; 583a7dea167SDimitry Andric } 584a7dea167SDimitry Andric 585a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 586a7dea167SDimitry Andric assert(SS.isEmpty() && 587a7dea167SDimitry Andric "undeclared non-type annotation should be unqualified"); 588a7dea167SDimitry Andric IdentifierInfo *II = getIdentifierAnnotation(Tok); 589a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 590a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsUndeclaredNonType(II, Loc); 591a7dea167SDimitry Andric break; 592a7dea167SDimitry Andric } 593a7dea167SDimitry Andric 594a7dea167SDimitry Andric default: 5950b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 5960b57cec5SDimitry Andric UnqualifiedId Name; 5970b57cec5SDimitry Andric if (ParseUnqualifiedId(SS, 5980b57cec5SDimitry Andric /*EnteringContext=*/false, 5990b57cec5SDimitry Andric /*AllowDestructorName=*/false, 6000b57cec5SDimitry Andric /*AllowConstructorName=*/false, 6010b57cec5SDimitry Andric /*AllowDeductionGuide=*/false, 6020b57cec5SDimitry Andric /*ObjectType=*/nullptr, &TemplateKWLoc, Name)) 6030b57cec5SDimitry Andric return ExprError(); 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric // This is only the direct operand of an & operator if it is not 6060b57cec5SDimitry Andric // followed by a postfix-expression suffix. 6070b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 6080b57cec5SDimitry Andric isAddressOfOperand = false; 6090b57cec5SDimitry Andric 610a7dea167SDimitry Andric E = Actions.ActOnIdExpression( 6110b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren), 6120b57cec5SDimitry Andric isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false, 6130b57cec5SDimitry Andric &Replacement); 614a7dea167SDimitry Andric break; 615a7dea167SDimitry Andric } 616a7dea167SDimitry Andric 6170b57cec5SDimitry Andric if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less)) 6180b57cec5SDimitry Andric checkPotentialAngleBracket(E); 6190b57cec5SDimitry Andric return E; 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric /// ParseCXXIdExpression - Handle id-expression. 6230b57cec5SDimitry Andric /// 6240b57cec5SDimitry Andric /// id-expression: 6250b57cec5SDimitry Andric /// unqualified-id 6260b57cec5SDimitry Andric /// qualified-id 6270b57cec5SDimitry Andric /// 6280b57cec5SDimitry Andric /// qualified-id: 6290b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 6300b57cec5SDimitry Andric /// '::' identifier 6310b57cec5SDimitry Andric /// '::' operator-function-id 6320b57cec5SDimitry Andric /// '::' template-id 6330b57cec5SDimitry Andric /// 6340b57cec5SDimitry Andric /// NOTE: The standard specifies that, for qualified-id, the parser does not 6350b57cec5SDimitry Andric /// expect: 6360b57cec5SDimitry Andric /// 6370b57cec5SDimitry Andric /// '::' conversion-function-id 6380b57cec5SDimitry Andric /// '::' '~' class-name 6390b57cec5SDimitry Andric /// 6400b57cec5SDimitry Andric /// This may cause a slight inconsistency on diagnostics: 6410b57cec5SDimitry Andric /// 6420b57cec5SDimitry Andric /// class C {}; 6430b57cec5SDimitry Andric /// namespace A {} 6440b57cec5SDimitry Andric /// void f() { 6450b57cec5SDimitry Andric /// :: A :: ~ C(); // Some Sema error about using destructor with a 6460b57cec5SDimitry Andric /// // namespace. 6470b57cec5SDimitry Andric /// :: ~ C(); // Some Parser error like 'unexpected ~'. 6480b57cec5SDimitry Andric /// } 6490b57cec5SDimitry Andric /// 6500b57cec5SDimitry Andric /// We simplify the parser a bit and make it work like: 6510b57cec5SDimitry Andric /// 6520b57cec5SDimitry Andric /// qualified-id: 6530b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 6540b57cec5SDimitry Andric /// '::' unqualified-id 6550b57cec5SDimitry Andric /// 6560b57cec5SDimitry Andric /// That way Sema can handle and report similar errors for namespaces and the 6570b57cec5SDimitry Andric /// global scope. 6580b57cec5SDimitry Andric /// 6590b57cec5SDimitry Andric /// The isAddressOfOperand parameter indicates that this id-expression is a 6600b57cec5SDimitry Andric /// direct operand of the address-of operator. This is, besides member contexts, 6610b57cec5SDimitry Andric /// the only place where a qualified-id naming a non-static class member may 6620b57cec5SDimitry Andric /// appear. 6630b57cec5SDimitry Andric /// 6640b57cec5SDimitry Andric ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 6650b57cec5SDimitry Andric // qualified-id: 6660b57cec5SDimitry Andric // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 6670b57cec5SDimitry Andric // '::' unqualified-id 6680b57cec5SDimitry Andric // 6690b57cec5SDimitry Andric CXXScopeSpec SS; 6700b57cec5SDimitry Andric ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric Token Replacement; 6730b57cec5SDimitry Andric ExprResult Result = 6740b57cec5SDimitry Andric tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 6750b57cec5SDimitry Andric if (Result.isUnset()) { 6760b57cec5SDimitry Andric // If the ExprResult is valid but null, then typo correction suggested a 6770b57cec5SDimitry Andric // keyword replacement that needs to be reparsed. 6780b57cec5SDimitry Andric UnconsumeToken(Replacement); 6790b57cec5SDimitry Andric Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric assert(!Result.isUnset() && "Typo correction suggested a keyword replacement " 6820b57cec5SDimitry Andric "for a previous keyword suggestion"); 6830b57cec5SDimitry Andric return Result; 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric /// ParseLambdaExpression - Parse a C++11 lambda expression. 6870b57cec5SDimitry Andric /// 6880b57cec5SDimitry Andric /// lambda-expression: 6890b57cec5SDimitry Andric /// lambda-introducer lambda-declarator[opt] compound-statement 6900b57cec5SDimitry Andric /// lambda-introducer '<' template-parameter-list '>' 6910b57cec5SDimitry Andric /// lambda-declarator[opt] compound-statement 6920b57cec5SDimitry Andric /// 6930b57cec5SDimitry Andric /// lambda-introducer: 6940b57cec5SDimitry Andric /// '[' lambda-capture[opt] ']' 6950b57cec5SDimitry Andric /// 6960b57cec5SDimitry Andric /// lambda-capture: 6970b57cec5SDimitry Andric /// capture-default 6980b57cec5SDimitry Andric /// capture-list 6990b57cec5SDimitry Andric /// capture-default ',' capture-list 7000b57cec5SDimitry Andric /// 7010b57cec5SDimitry Andric /// capture-default: 7020b57cec5SDimitry Andric /// '&' 7030b57cec5SDimitry Andric /// '=' 7040b57cec5SDimitry Andric /// 7050b57cec5SDimitry Andric /// capture-list: 7060b57cec5SDimitry Andric /// capture 7070b57cec5SDimitry Andric /// capture-list ',' capture 7080b57cec5SDimitry Andric /// 7090b57cec5SDimitry Andric /// capture: 7100b57cec5SDimitry Andric /// simple-capture 7110b57cec5SDimitry Andric /// init-capture [C++1y] 7120b57cec5SDimitry Andric /// 7130b57cec5SDimitry Andric /// simple-capture: 7140b57cec5SDimitry Andric /// identifier 7150b57cec5SDimitry Andric /// '&' identifier 7160b57cec5SDimitry Andric /// 'this' 7170b57cec5SDimitry Andric /// 7180b57cec5SDimitry Andric /// init-capture: [C++1y] 7190b57cec5SDimitry Andric /// identifier initializer 7200b57cec5SDimitry Andric /// '&' identifier initializer 7210b57cec5SDimitry Andric /// 7220b57cec5SDimitry Andric /// lambda-declarator: 7230b57cec5SDimitry Andric /// '(' parameter-declaration-clause ')' attribute-specifier[opt] 7240b57cec5SDimitry Andric /// 'mutable'[opt] exception-specification[opt] 7250b57cec5SDimitry Andric /// trailing-return-type[opt] 7260b57cec5SDimitry Andric /// 7270b57cec5SDimitry Andric ExprResult Parser::ParseLambdaExpression() { 7280b57cec5SDimitry Andric // Parse lambda-introducer. 7290b57cec5SDimitry Andric LambdaIntroducer Intro; 7300b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro)) { 7310b57cec5SDimitry Andric SkipUntil(tok::r_square, StopAtSemi); 7320b57cec5SDimitry Andric SkipUntil(tok::l_brace, StopAtSemi); 7330b57cec5SDimitry Andric SkipUntil(tok::r_brace, StopAtSemi); 7340b57cec5SDimitry Andric return ExprError(); 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric return ParseLambdaExpressionAfterIntroducer(Intro); 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric /// Use lookahead and potentially tentative parsing to determine if we are 7410b57cec5SDimitry Andric /// looking at a C++11 lambda expression, and parse it if we are. 7420b57cec5SDimitry Andric /// 7430b57cec5SDimitry Andric /// If we are not looking at a lambda expression, returns ExprError(). 7440b57cec5SDimitry Andric ExprResult Parser::TryParseLambdaExpression() { 7450b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus11 7460b57cec5SDimitry Andric && Tok.is(tok::l_square) 7470b57cec5SDimitry Andric && "Not at the start of a possible lambda expression."); 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric const Token Next = NextToken(); 7500b57cec5SDimitry Andric if (Next.is(tok::eof)) // Nothing else to lookup here... 7510b57cec5SDimitry Andric return ExprEmpty(); 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric const Token After = GetLookAheadToken(2); 7540b57cec5SDimitry Andric // If lookahead indicates this is a lambda... 7550b57cec5SDimitry Andric if (Next.is(tok::r_square) || // [] 7560b57cec5SDimitry Andric Next.is(tok::equal) || // [= 7570b57cec5SDimitry Andric (Next.is(tok::amp) && // [&] or [&, 7580b57cec5SDimitry Andric After.isOneOf(tok::r_square, tok::comma)) || 7590b57cec5SDimitry Andric (Next.is(tok::identifier) && // [identifier] 7600b57cec5SDimitry Andric After.is(tok::r_square)) || 7610b57cec5SDimitry Andric Next.is(tok::ellipsis)) { // [... 7620b57cec5SDimitry Andric return ParseLambdaExpression(); 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric // If lookahead indicates an ObjC message send... 7660b57cec5SDimitry Andric // [identifier identifier 7670b57cec5SDimitry Andric if (Next.is(tok::identifier) && After.is(tok::identifier)) 7680b57cec5SDimitry Andric return ExprEmpty(); 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric // Here, we're stuck: lambda introducers and Objective-C message sends are 7710b57cec5SDimitry Andric // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a 7720b57cec5SDimitry Andric // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of 7730b57cec5SDimitry Andric // writing two routines to parse a lambda introducer, just try to parse 7740b57cec5SDimitry Andric // a lambda introducer first, and fall back if that fails. 7750b57cec5SDimitry Andric LambdaIntroducer Intro; 7760b57cec5SDimitry Andric { 7770b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 7780b57cec5SDimitry Andric LambdaIntroducerTentativeParse Tentative; 7790b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro, &Tentative)) { 7800b57cec5SDimitry Andric TPA.Commit(); 7810b57cec5SDimitry Andric return ExprError(); 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric switch (Tentative) { 7850b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Success: 7860b57cec5SDimitry Andric TPA.Commit(); 7870b57cec5SDimitry Andric break; 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Incomplete: 7900b57cec5SDimitry Andric // Didn't fully parse the lambda-introducer, try again with a 7910b57cec5SDimitry Andric // non-tentative parse. 7920b57cec5SDimitry Andric TPA.Revert(); 7930b57cec5SDimitry Andric Intro = LambdaIntroducer(); 7940b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro)) 7950b57cec5SDimitry Andric return ExprError(); 7960b57cec5SDimitry Andric break; 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::MessageSend: 7990b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Invalid: 8000b57cec5SDimitry Andric // Not a lambda-introducer, might be a message send. 8010b57cec5SDimitry Andric TPA.Revert(); 8020b57cec5SDimitry Andric return ExprEmpty(); 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric return ParseLambdaExpressionAfterIntroducer(Intro); 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric /// Parse a lambda introducer. 8100b57cec5SDimitry Andric /// \param Intro A LambdaIntroducer filled in with information about the 8110b57cec5SDimitry Andric /// contents of the lambda-introducer. 8120b57cec5SDimitry Andric /// \param Tentative If non-null, we are disambiguating between a 8130b57cec5SDimitry Andric /// lambda-introducer and some other construct. In this mode, we do not 8140b57cec5SDimitry Andric /// produce any diagnostics or take any other irreversible action unless 8150b57cec5SDimitry Andric /// we're sure that this is a lambda-expression. 8160b57cec5SDimitry Andric /// \return \c true if parsing (or disambiguation) failed with a diagnostic and 8170b57cec5SDimitry Andric /// the caller should bail out / recover. 8180b57cec5SDimitry Andric bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, 8190b57cec5SDimitry Andric LambdaIntroducerTentativeParse *Tentative) { 8200b57cec5SDimitry Andric if (Tentative) 8210b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Success; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); 8240b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 8250b57cec5SDimitry Andric T.consumeOpen(); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric Intro.Range.setBegin(T.getOpenLocation()); 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric bool First = true; 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric // Produce a diagnostic if we're not tentatively parsing; otherwise track 8320b57cec5SDimitry Andric // that our parse has failed. 8330b57cec5SDimitry Andric auto Invalid = [&](llvm::function_ref<void()> Action) { 8340b57cec5SDimitry Andric if (Tentative) { 8350b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Invalid; 8360b57cec5SDimitry Andric return false; 8370b57cec5SDimitry Andric } 8380b57cec5SDimitry Andric Action(); 8390b57cec5SDimitry Andric return true; 8400b57cec5SDimitry Andric }; 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric // Perform some irreversible action if this is a non-tentative parse; 8430b57cec5SDimitry Andric // otherwise note that our actions were incomplete. 8440b57cec5SDimitry Andric auto NonTentativeAction = [&](llvm::function_ref<void()> Action) { 8450b57cec5SDimitry Andric if (Tentative) 8460b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 8470b57cec5SDimitry Andric else 8480b57cec5SDimitry Andric Action(); 8490b57cec5SDimitry Andric }; 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric // Parse capture-default. 8520b57cec5SDimitry Andric if (Tok.is(tok::amp) && 8530b57cec5SDimitry Andric (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) { 8540b57cec5SDimitry Andric Intro.Default = LCD_ByRef; 8550b57cec5SDimitry Andric Intro.DefaultLoc = ConsumeToken(); 8560b57cec5SDimitry Andric First = false; 8570b57cec5SDimitry Andric if (!Tok.getIdentifierInfo()) { 8580b57cec5SDimitry Andric // This can only be a lambda; no need for tentative parsing any more. 8590b57cec5SDimitry Andric // '[[and]]' can still be an attribute, though. 8600b57cec5SDimitry Andric Tentative = nullptr; 8610b57cec5SDimitry Andric } 8620b57cec5SDimitry Andric } else if (Tok.is(tok::equal)) { 8630b57cec5SDimitry Andric Intro.Default = LCD_ByCopy; 8640b57cec5SDimitry Andric Intro.DefaultLoc = ConsumeToken(); 8650b57cec5SDimitry Andric First = false; 8660b57cec5SDimitry Andric Tentative = nullptr; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric while (Tok.isNot(tok::r_square)) { 8700b57cec5SDimitry Andric if (!First) { 8710b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) { 8720b57cec5SDimitry Andric // Provide a completion for a lambda introducer here. Except 8730b57cec5SDimitry Andric // in Objective-C, where this is Almost Surely meant to be a message 8740b57cec5SDimitry Andric // send. In that case, fail here and let the ObjC message 8750b57cec5SDimitry Andric // expression parser perform the completion. 8760b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && 8770b57cec5SDimitry Andric !(getLangOpts().ObjC && Tentative)) { 8780b57cec5SDimitry Andric Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 8790b57cec5SDimitry Andric /*AfterAmpersand=*/false); 8800b57cec5SDimitry Andric cutOffParsing(); 8810b57cec5SDimitry Andric break; 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric return Invalid([&] { 8850b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare); 8860b57cec5SDimitry Andric }); 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric ConsumeToken(); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 8920b57cec5SDimitry Andric // If we're in Objective-C++ and we have a bare '[', then this is more 8930b57cec5SDimitry Andric // likely to be a message receiver. 8940b57cec5SDimitry Andric if (getLangOpts().ObjC && Tentative && First) 8950b57cec5SDimitry Andric Actions.CodeCompleteObjCMessageReceiver(getCurScope()); 8960b57cec5SDimitry Andric else 8970b57cec5SDimitry Andric Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 8980b57cec5SDimitry Andric /*AfterAmpersand=*/false); 8990b57cec5SDimitry Andric cutOffParsing(); 9000b57cec5SDimitry Andric break; 9010b57cec5SDimitry Andric } 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric First = false; 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric // Parse capture. 9060b57cec5SDimitry Andric LambdaCaptureKind Kind = LCK_ByCopy; 9070b57cec5SDimitry Andric LambdaCaptureInitKind InitKind = LambdaCaptureInitKind::NoInit; 9080b57cec5SDimitry Andric SourceLocation Loc; 9090b57cec5SDimitry Andric IdentifierInfo *Id = nullptr; 9100b57cec5SDimitry Andric SourceLocation EllipsisLocs[4]; 9110b57cec5SDimitry Andric ExprResult Init; 9120b57cec5SDimitry Andric SourceLocation LocStart = Tok.getLocation(); 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric if (Tok.is(tok::star)) { 9150b57cec5SDimitry Andric Loc = ConsumeToken(); 9160b57cec5SDimitry Andric if (Tok.is(tok::kw_this)) { 9170b57cec5SDimitry Andric ConsumeToken(); 9180b57cec5SDimitry Andric Kind = LCK_StarThis; 9190b57cec5SDimitry Andric } else { 9200b57cec5SDimitry Andric return Invalid([&] { 9210b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_star_this_capture); 9220b57cec5SDimitry Andric }); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric } else if (Tok.is(tok::kw_this)) { 9250b57cec5SDimitry Andric Kind = LCK_This; 9260b57cec5SDimitry Andric Loc = ConsumeToken(); 9270b57cec5SDimitry Andric } else { 9280b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[0]); 9290b57cec5SDimitry Andric 9300b57cec5SDimitry Andric if (Tok.is(tok::amp)) { 9310b57cec5SDimitry Andric Kind = LCK_ByRef; 9320b57cec5SDimitry Andric ConsumeToken(); 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 9350b57cec5SDimitry Andric Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 9360b57cec5SDimitry Andric /*AfterAmpersand=*/true); 9370b57cec5SDimitry Andric cutOffParsing(); 9380b57cec5SDimitry Andric break; 9390b57cec5SDimitry Andric } 9400b57cec5SDimitry Andric } 9410b57cec5SDimitry Andric 9420b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[1]); 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 9450b57cec5SDimitry Andric Id = Tok.getIdentifierInfo(); 9460b57cec5SDimitry Andric Loc = ConsumeToken(); 9470b57cec5SDimitry Andric } else if (Tok.is(tok::kw_this)) { 9480b57cec5SDimitry Andric return Invalid([&] { 9490b57cec5SDimitry Andric // FIXME: Suggest a fixit here. 9500b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_this_captured_by_reference); 9510b57cec5SDimitry Andric }); 9520b57cec5SDimitry Andric } else { 9530b57cec5SDimitry Andric return Invalid([&] { 9540b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_capture); 9550b57cec5SDimitry Andric }); 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[2]); 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 9610b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 9620b57cec5SDimitry Andric Parens.consumeOpen(); 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::DirectInit; 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric ExprVector Exprs; 9670b57cec5SDimitry Andric CommaLocsTy Commas; 9680b57cec5SDimitry Andric if (Tentative) { 9690b57cec5SDimitry Andric Parens.skipToEnd(); 9700b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 9710b57cec5SDimitry Andric } else if (ParseExpressionList(Exprs, Commas)) { 9720b57cec5SDimitry Andric Parens.skipToEnd(); 9730b57cec5SDimitry Andric Init = ExprError(); 9740b57cec5SDimitry Andric } else { 9750b57cec5SDimitry Andric Parens.consumeClose(); 9760b57cec5SDimitry Andric Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(), 9770b57cec5SDimitry Andric Parens.getCloseLocation(), 9780b57cec5SDimitry Andric Exprs); 9790b57cec5SDimitry Andric } 9800b57cec5SDimitry Andric } else if (Tok.isOneOf(tok::l_brace, tok::equal)) { 9810b57cec5SDimitry Andric // Each lambda init-capture forms its own full expression, which clears 9820b57cec5SDimitry Andric // Actions.MaybeODRUseExprs. So create an expression evaluation context 9830b57cec5SDimitry Andric // to save the necessary state, and restore it later. 9840b57cec5SDimitry Andric EnterExpressionEvaluationContext EC( 9850b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric if (TryConsumeToken(tok::equal)) 9880b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::CopyInit; 9890b57cec5SDimitry Andric else 9900b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::ListInit; 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric if (!Tentative) { 9930b57cec5SDimitry Andric Init = ParseInitializer(); 9940b57cec5SDimitry Andric } else if (Tok.is(tok::l_brace)) { 9950b57cec5SDimitry Andric BalancedDelimiterTracker Braces(*this, tok::l_brace); 9960b57cec5SDimitry Andric Braces.consumeOpen(); 9970b57cec5SDimitry Andric Braces.skipToEnd(); 9980b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 9990b57cec5SDimitry Andric } else { 10000b57cec5SDimitry Andric // We're disambiguating this: 10010b57cec5SDimitry Andric // 10020b57cec5SDimitry Andric // [..., x = expr 10030b57cec5SDimitry Andric // 10040b57cec5SDimitry Andric // We need to find the end of the following expression in order to 10050b57cec5SDimitry Andric // determine whether this is an Obj-C message send's receiver, a 10060b57cec5SDimitry Andric // C99 designator, or a lambda init-capture. 10070b57cec5SDimitry Andric // 10080b57cec5SDimitry Andric // Parse the expression to find where it ends, and annotate it back 10090b57cec5SDimitry Andric // onto the tokens. We would have parsed this expression the same way 10100b57cec5SDimitry Andric // in either case: both the RHS of an init-capture and the RHS of an 10110b57cec5SDimitry Andric // assignment expression are parsed as an initializer-clause, and in 10120b57cec5SDimitry Andric // neither case can anything be added to the scope between the '[' and 10130b57cec5SDimitry Andric // here. 10140b57cec5SDimitry Andric // 10150b57cec5SDimitry Andric // FIXME: This is horrible. Adding a mechanism to skip an expression 10160b57cec5SDimitry Andric // would be much cleaner. 10170b57cec5SDimitry Andric // FIXME: If there is a ',' before the next ']' or ':', we can skip to 10180b57cec5SDimitry Andric // that instead. (And if we see a ':' with no matching '?', we can 10190b57cec5SDimitry Andric // classify this as an Obj-C message send.) 10200b57cec5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 10210b57cec5SDimitry Andric InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true); 10220b57cec5SDimitry Andric Init = ParseInitializer(); 10230b57cec5SDimitry Andric if (!Init.isInvalid()) 10240b57cec5SDimitry Andric Init = Actions.CorrectDelayedTyposInExpr(Init.get()); 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric if (Tok.getLocation() != StartLoc) { 10270b57cec5SDimitry Andric // Back out the lexing of the token after the initializer. 10280b57cec5SDimitry Andric PP.RevertCachedTokens(1); 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric // Replace the consumed tokens with an appropriate annotation. 10310b57cec5SDimitry Andric Tok.setLocation(StartLoc); 10320b57cec5SDimitry Andric Tok.setKind(tok::annot_primary_expr); 10330b57cec5SDimitry Andric setExprAnnotation(Tok, Init); 10340b57cec5SDimitry Andric Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation()); 10350b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // Consume the annotated initializer. 10380b57cec5SDimitry Andric ConsumeAnnotationToken(); 10390b57cec5SDimitry Andric } 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[3]); 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric // Check if this is a message send before we act on a possible init-capture. 10470b57cec5SDimitry Andric if (Tentative && Tok.is(tok::identifier) && 10480b57cec5SDimitry Andric NextToken().isOneOf(tok::colon, tok::r_square)) { 10490b57cec5SDimitry Andric // This can only be a message send. We're done with disambiguation. 10500b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::MessageSend; 10510b57cec5SDimitry Andric return false; 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric // Ensure that any ellipsis was in the right place. 10550b57cec5SDimitry Andric SourceLocation EllipsisLoc; 10560b57cec5SDimitry Andric if (std::any_of(std::begin(EllipsisLocs), std::end(EllipsisLocs), 10570b57cec5SDimitry Andric [](SourceLocation Loc) { return Loc.isValid(); })) { 10580b57cec5SDimitry Andric // The '...' should appear before the identifier in an init-capture, and 10590b57cec5SDimitry Andric // after the identifier otherwise. 10600b57cec5SDimitry Andric bool InitCapture = InitKind != LambdaCaptureInitKind::NoInit; 10610b57cec5SDimitry Andric SourceLocation *ExpectedEllipsisLoc = 10620b57cec5SDimitry Andric !InitCapture ? &EllipsisLocs[2] : 10630b57cec5SDimitry Andric Kind == LCK_ByRef ? &EllipsisLocs[1] : 10640b57cec5SDimitry Andric &EllipsisLocs[0]; 10650b57cec5SDimitry Andric EllipsisLoc = *ExpectedEllipsisLoc; 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric unsigned DiagID = 0; 10680b57cec5SDimitry Andric if (EllipsisLoc.isInvalid()) { 10690b57cec5SDimitry Andric DiagID = diag::err_lambda_capture_misplaced_ellipsis; 10700b57cec5SDimitry Andric for (SourceLocation Loc : EllipsisLocs) { 10710b57cec5SDimitry Andric if (Loc.isValid()) 10720b57cec5SDimitry Andric EllipsisLoc = Loc; 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric } else { 10750b57cec5SDimitry Andric unsigned NumEllipses = std::accumulate( 10760b57cec5SDimitry Andric std::begin(EllipsisLocs), std::end(EllipsisLocs), 0, 10770b57cec5SDimitry Andric [](int N, SourceLocation Loc) { return N + Loc.isValid(); }); 10780b57cec5SDimitry Andric if (NumEllipses > 1) 10790b57cec5SDimitry Andric DiagID = diag::err_lambda_capture_multiple_ellipses; 10800b57cec5SDimitry Andric } 10810b57cec5SDimitry Andric if (DiagID) { 10820b57cec5SDimitry Andric NonTentativeAction([&] { 10830b57cec5SDimitry Andric // Point the diagnostic at the first misplaced ellipsis. 10840b57cec5SDimitry Andric SourceLocation DiagLoc; 10850b57cec5SDimitry Andric for (SourceLocation &Loc : EllipsisLocs) { 10860b57cec5SDimitry Andric if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) { 10870b57cec5SDimitry Andric DiagLoc = Loc; 10880b57cec5SDimitry Andric break; 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric } 10910b57cec5SDimitry Andric assert(DiagLoc.isValid() && "no location for diagnostic"); 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric // Issue the diagnostic and produce fixits showing where the ellipsis 10940b57cec5SDimitry Andric // should have been written. 10950b57cec5SDimitry Andric auto &&D = Diag(DiagLoc, DiagID); 10960b57cec5SDimitry Andric if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) { 10970b57cec5SDimitry Andric SourceLocation ExpectedLoc = 10980b57cec5SDimitry Andric InitCapture ? Loc 10990b57cec5SDimitry Andric : Lexer::getLocForEndOfToken( 11000b57cec5SDimitry Andric Loc, 0, PP.getSourceManager(), getLangOpts()); 11010b57cec5SDimitry Andric D << InitCapture << FixItHint::CreateInsertion(ExpectedLoc, "..."); 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric for (SourceLocation &Loc : EllipsisLocs) { 11040b57cec5SDimitry Andric if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) 11050b57cec5SDimitry Andric D << FixItHint::CreateRemoval(Loc); 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric }); 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric // Process the init-capture initializers now rather than delaying until we 11120b57cec5SDimitry Andric // form the lambda-expression so that they can be handled in the context 11130b57cec5SDimitry Andric // enclosing the lambda-expression, rather than in the context of the 11140b57cec5SDimitry Andric // lambda-expression itself. 11150b57cec5SDimitry Andric ParsedType InitCaptureType; 11160b57cec5SDimitry Andric if (Init.isUsable()) 11170b57cec5SDimitry Andric Init = Actions.CorrectDelayedTyposInExpr(Init.get()); 11180b57cec5SDimitry Andric if (Init.isUsable()) { 11190b57cec5SDimitry Andric NonTentativeAction([&] { 11200b57cec5SDimitry Andric // Get the pointer and store it in an lvalue, so we can use it as an 11210b57cec5SDimitry Andric // out argument. 11220b57cec5SDimitry Andric Expr *InitExpr = Init.get(); 11230b57cec5SDimitry Andric // This performs any lvalue-to-rvalue conversions if necessary, which 11240b57cec5SDimitry Andric // can affect what gets captured in the containing decl-context. 11250b57cec5SDimitry Andric InitCaptureType = Actions.actOnLambdaInitCaptureInitialization( 11260b57cec5SDimitry Andric Loc, Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, InitExpr); 11270b57cec5SDimitry Andric Init = InitExpr; 11280b57cec5SDimitry Andric }); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andric SourceLocation LocEnd = PrevTokLocation; 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, 11340b57cec5SDimitry Andric InitCaptureType, SourceRange(LocStart, LocEnd)); 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric T.consumeClose(); 11380b57cec5SDimitry Andric Intro.Range.setEnd(T.getCloseLocation()); 11390b57cec5SDimitry Andric return false; 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric static void tryConsumeLambdaSpecifierToken(Parser &P, 11430b57cec5SDimitry Andric SourceLocation &MutableLoc, 11440b57cec5SDimitry Andric SourceLocation &ConstexprLoc, 11450b57cec5SDimitry Andric SourceLocation &ConstevalLoc, 11460b57cec5SDimitry Andric SourceLocation &DeclEndLoc) { 11470b57cec5SDimitry Andric assert(MutableLoc.isInvalid()); 11480b57cec5SDimitry Andric assert(ConstexprLoc.isInvalid()); 11490b57cec5SDimitry Andric // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc 11500b57cec5SDimitry Andric // to the final of those locations. Emit an error if we have multiple 11510b57cec5SDimitry Andric // copies of those keywords and recover. 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric while (true) { 11540b57cec5SDimitry Andric switch (P.getCurToken().getKind()) { 11550b57cec5SDimitry Andric case tok::kw_mutable: { 11560b57cec5SDimitry Andric if (MutableLoc.isValid()) { 11570b57cec5SDimitry Andric P.Diag(P.getCurToken().getLocation(), 11580b57cec5SDimitry Andric diag::err_lambda_decl_specifier_repeated) 11590b57cec5SDimitry Andric << 0 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); 11600b57cec5SDimitry Andric } 11610b57cec5SDimitry Andric MutableLoc = P.ConsumeToken(); 11620b57cec5SDimitry Andric DeclEndLoc = MutableLoc; 11630b57cec5SDimitry Andric break /*switch*/; 11640b57cec5SDimitry Andric } 11650b57cec5SDimitry Andric case tok::kw_constexpr: 11660b57cec5SDimitry Andric if (ConstexprLoc.isValid()) { 11670b57cec5SDimitry Andric P.Diag(P.getCurToken().getLocation(), 11680b57cec5SDimitry Andric diag::err_lambda_decl_specifier_repeated) 11690b57cec5SDimitry Andric << 1 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric ConstexprLoc = P.ConsumeToken(); 11720b57cec5SDimitry Andric DeclEndLoc = ConstexprLoc; 11730b57cec5SDimitry Andric break /*switch*/; 11740b57cec5SDimitry Andric case tok::kw_consteval: 11750b57cec5SDimitry Andric if (ConstevalLoc.isValid()) { 11760b57cec5SDimitry Andric P.Diag(P.getCurToken().getLocation(), 11770b57cec5SDimitry Andric diag::err_lambda_decl_specifier_repeated) 11780b57cec5SDimitry Andric << 2 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); 11790b57cec5SDimitry Andric } 11800b57cec5SDimitry Andric ConstevalLoc = P.ConsumeToken(); 11810b57cec5SDimitry Andric DeclEndLoc = ConstevalLoc; 11820b57cec5SDimitry Andric break /*switch*/; 11830b57cec5SDimitry Andric default: 11840b57cec5SDimitry Andric return; 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric } 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric static void 11900b57cec5SDimitry Andric addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, 11910b57cec5SDimitry Andric DeclSpec &DS) { 11920b57cec5SDimitry Andric if (ConstexprLoc.isValid()) { 11930b57cec5SDimitry Andric P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus17 11940b57cec5SDimitry Andric ? diag::ext_constexpr_on_lambda_cxx17 11950b57cec5SDimitry Andric : diag::warn_cxx14_compat_constexpr_on_lambda); 11960b57cec5SDimitry Andric const char *PrevSpec = nullptr; 11970b57cec5SDimitry Andric unsigned DiagID = 0; 11980b57cec5SDimitry Andric DS.SetConstexprSpec(CSK_constexpr, ConstexprLoc, PrevSpec, DiagID); 11990b57cec5SDimitry Andric assert(PrevSpec == nullptr && DiagID == 0 && 12000b57cec5SDimitry Andric "Constexpr cannot have been set previously!"); 12010b57cec5SDimitry Andric } 12020b57cec5SDimitry Andric } 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric static void addConstevalToLambdaDeclSpecifier(Parser &P, 12050b57cec5SDimitry Andric SourceLocation ConstevalLoc, 12060b57cec5SDimitry Andric DeclSpec &DS) { 12070b57cec5SDimitry Andric if (ConstevalLoc.isValid()) { 12080b57cec5SDimitry Andric P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval); 12090b57cec5SDimitry Andric const char *PrevSpec = nullptr; 12100b57cec5SDimitry Andric unsigned DiagID = 0; 12110b57cec5SDimitry Andric DS.SetConstexprSpec(CSK_consteval, ConstevalLoc, PrevSpec, DiagID); 12120b57cec5SDimitry Andric if (DiagID != 0) 12130b57cec5SDimitry Andric P.Diag(ConstevalLoc, DiagID) << PrevSpec; 12140b57cec5SDimitry Andric } 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda 12180b57cec5SDimitry Andric /// expression. 12190b57cec5SDimitry Andric ExprResult Parser::ParseLambdaExpressionAfterIntroducer( 12200b57cec5SDimitry Andric LambdaIntroducer &Intro) { 12210b57cec5SDimitry Andric SourceLocation LambdaBeginLoc = Intro.Range.getBegin(); 12220b57cec5SDimitry Andric Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda); 12230b57cec5SDimitry Andric 12240b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, 12250b57cec5SDimitry Andric "lambda expression parsing"); 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric // FIXME: Call into Actions to add any init-capture declarations to the 12300b57cec5SDimitry Andric // scope while parsing the lambda-declarator and compound-statement. 12310b57cec5SDimitry Andric 12320b57cec5SDimitry Andric // Parse lambda-declarator[opt]. 12330b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 12340b57cec5SDimitry Andric Declarator D(DS, DeclaratorContext::LambdaExprContext); 12350b57cec5SDimitry Andric TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); 12360b57cec5SDimitry Andric Actions.PushLambdaScope(); 12370b57cec5SDimitry Andric 12380b57cec5SDimitry Andric ParsedAttributes Attr(AttrFactory); 12390b57cec5SDimitry Andric SourceLocation DeclLoc = Tok.getLocation(); 12400b57cec5SDimitry Andric if (getLangOpts().CUDA) { 12410b57cec5SDimitry Andric // In CUDA code, GNU attributes are allowed to appear immediately after the 12420b57cec5SDimitry Andric // "[...]", even if there is no "(...)" before the lambda body. 12430b57cec5SDimitry Andric MaybeParseGNUAttributes(D); 12440b57cec5SDimitry Andric } 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric // Helper to emit a warning if we see a CUDA host/device/global attribute 12470b57cec5SDimitry Andric // after '(...)'. nvcc doesn't accept this. 12480b57cec5SDimitry Andric auto WarnIfHasCUDATargetAttr = [&] { 12490b57cec5SDimitry Andric if (getLangOpts().CUDA) 12500b57cec5SDimitry Andric for (const ParsedAttr &A : Attr) 12510b57cec5SDimitry Andric if (A.getKind() == ParsedAttr::AT_CUDADevice || 12520b57cec5SDimitry Andric A.getKind() == ParsedAttr::AT_CUDAHost || 12530b57cec5SDimitry Andric A.getKind() == ParsedAttr::AT_CUDAGlobal) 12540b57cec5SDimitry Andric Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) 1255a7dea167SDimitry Andric << A.getAttrName()->getName(); 12560b57cec5SDimitry Andric }; 12570b57cec5SDimitry Andric 12580b57cec5SDimitry Andric // FIXME: Consider allowing this as an extension for GCC compatibiblity. 12590b57cec5SDimitry Andric const bool HasExplicitTemplateParams = Tok.is(tok::less); 12600b57cec5SDimitry Andric ParseScope TemplateParamScope(this, Scope::TemplateParamScope, 12610b57cec5SDimitry Andric /*EnteredScope=*/HasExplicitTemplateParams); 12620b57cec5SDimitry Andric if (HasExplicitTemplateParams) { 12630b57cec5SDimitry Andric Diag(Tok, getLangOpts().CPlusPlus2a 12640b57cec5SDimitry Andric ? diag::warn_cxx17_compat_lambda_template_parameter_list 12650b57cec5SDimitry Andric : diag::ext_lambda_template_parameter_list); 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric SmallVector<NamedDecl*, 4> TemplateParams; 12680b57cec5SDimitry Andric SourceLocation LAngleLoc, RAngleLoc; 12690b57cec5SDimitry Andric if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), 12700b57cec5SDimitry Andric TemplateParams, LAngleLoc, RAngleLoc)) { 12710b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 12720b57cec5SDimitry Andric return ExprError(); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric if (TemplateParams.empty()) { 12760b57cec5SDimitry Andric Diag(RAngleLoc, 12770b57cec5SDimitry Andric diag::err_lambda_template_parameter_list_empty); 12780b57cec5SDimitry Andric } else { 12790b57cec5SDimitry Andric Actions.ActOnLambdaExplicitTemplateParameterList( 12800b57cec5SDimitry Andric LAngleLoc, TemplateParams, RAngleLoc); 12810b57cec5SDimitry Andric ++CurTemplateDepthTracker; 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric } 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric TypeResult TrailingReturnType; 12860b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 12870b57cec5SDimitry Andric ParseScope PrototypeScope(this, 12880b57cec5SDimitry Andric Scope::FunctionPrototypeScope | 12890b57cec5SDimitry Andric Scope::FunctionDeclarationScope | 12900b57cec5SDimitry Andric Scope::DeclScope); 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 12930b57cec5SDimitry Andric T.consumeOpen(); 12940b57cec5SDimitry Andric SourceLocation LParenLoc = T.getOpenLocation(); 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric // Parse parameter-declaration-clause. 12970b57cec5SDimitry Andric SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 12980b57cec5SDimitry Andric SourceLocation EllipsisLoc; 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 13010b57cec5SDimitry Andric Actions.RecordParsingTemplateParameterDepth( 13020b57cec5SDimitry Andric CurTemplateDepthTracker.getOriginalDepth()); 13030b57cec5SDimitry Andric 130455e4f9d5SDimitry Andric ParseParameterDeclarationClause(D.getContext(), Attr, ParamInfo, 130555e4f9d5SDimitry Andric EllipsisLoc); 13060b57cec5SDimitry Andric // For a generic lambda, each 'auto' within the parameter declaration 13070b57cec5SDimitry Andric // clause creates a template type parameter, so increment the depth. 13080b57cec5SDimitry Andric // If we've parsed any explicit template parameters, then the depth will 13090b57cec5SDimitry Andric // have already been incremented. So we make sure that at most a single 13100b57cec5SDimitry Andric // depth level is added. 13110b57cec5SDimitry Andric if (Actions.getCurGenericLambda()) 13120b57cec5SDimitry Andric CurTemplateDepthTracker.setAddedDepth(1); 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andric T.consumeClose(); 13160b57cec5SDimitry Andric SourceLocation RParenLoc = T.getCloseLocation(); 13170b57cec5SDimitry Andric SourceLocation DeclEndLoc = RParenLoc; 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric // GNU-style attributes must be parsed before the mutable specifier to be 13200b57cec5SDimitry Andric // compatible with GCC. 13210b57cec5SDimitry Andric MaybeParseGNUAttributes(Attr, &DeclEndLoc); 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric // MSVC-style attributes must be parsed before the mutable specifier to be 13240b57cec5SDimitry Andric // compatible with MSVC. 13250b57cec5SDimitry Andric MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc); 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andric // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update the 13280b57cec5SDimitry Andric // DeclEndLoc. 13290b57cec5SDimitry Andric SourceLocation MutableLoc; 13300b57cec5SDimitry Andric SourceLocation ConstexprLoc; 13310b57cec5SDimitry Andric SourceLocation ConstevalLoc; 13320b57cec5SDimitry Andric tryConsumeLambdaSpecifierToken(*this, MutableLoc, ConstexprLoc, 13330b57cec5SDimitry Andric ConstevalLoc, DeclEndLoc); 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); 13360b57cec5SDimitry Andric addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); 13370b57cec5SDimitry Andric // Parse exception-specification[opt]. 13380b57cec5SDimitry Andric ExceptionSpecificationType ESpecType = EST_None; 13390b57cec5SDimitry Andric SourceRange ESpecRange; 13400b57cec5SDimitry Andric SmallVector<ParsedType, 2> DynamicExceptions; 13410b57cec5SDimitry Andric SmallVector<SourceRange, 2> DynamicExceptionRanges; 13420b57cec5SDimitry Andric ExprResult NoexceptExpr; 13430b57cec5SDimitry Andric CachedTokens *ExceptionSpecTokens; 13440b57cec5SDimitry Andric ESpecType = tryParseExceptionSpecification(/*Delayed=*/false, 13450b57cec5SDimitry Andric ESpecRange, 13460b57cec5SDimitry Andric DynamicExceptions, 13470b57cec5SDimitry Andric DynamicExceptionRanges, 13480b57cec5SDimitry Andric NoexceptExpr, 13490b57cec5SDimitry Andric ExceptionSpecTokens); 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric if (ESpecType != EST_None) 13520b57cec5SDimitry Andric DeclEndLoc = ESpecRange.getEnd(); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric // Parse attribute-specifier[opt]. 13550b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attr, &DeclEndLoc); 13560b57cec5SDimitry Andric 1357480093f4SDimitry Andric // Parse OpenCL addr space attribute. 1358480093f4SDimitry Andric if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, 1359480093f4SDimitry Andric tok::kw___constant, tok::kw___generic)) { 1360480093f4SDimitry Andric ParseOpenCLQualifiers(DS.getAttributes()); 1361480093f4SDimitry Andric ConsumeToken(); 1362480093f4SDimitry Andric } 1363480093f4SDimitry Andric 13640b57cec5SDimitry Andric SourceLocation FunLocalRangeEnd = DeclEndLoc; 13650b57cec5SDimitry Andric 13660b57cec5SDimitry Andric // Parse trailing-return-type[opt]. 13670b57cec5SDimitry Andric if (Tok.is(tok::arrow)) { 13680b57cec5SDimitry Andric FunLocalRangeEnd = Tok.getLocation(); 13690b57cec5SDimitry Andric SourceRange Range; 13700b57cec5SDimitry Andric TrailingReturnType = 13710b57cec5SDimitry Andric ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); 13720b57cec5SDimitry Andric if (Range.getEnd().isValid()) 13730b57cec5SDimitry Andric DeclEndLoc = Range.getEnd(); 13740b57cec5SDimitry Andric } 13750b57cec5SDimitry Andric 13760b57cec5SDimitry Andric SourceLocation NoLoc; 13770b57cec5SDimitry Andric D.AddTypeInfo(DeclaratorChunk::getFunction( 13780b57cec5SDimitry Andric /*HasProto=*/true, 13790b57cec5SDimitry Andric /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), 13800b57cec5SDimitry Andric ParamInfo.size(), EllipsisLoc, RParenLoc, 13810b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 13820b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, 13830b57cec5SDimitry Andric ESpecRange, DynamicExceptions.data(), 13840b57cec5SDimitry Andric DynamicExceptionRanges.data(), DynamicExceptions.size(), 13850b57cec5SDimitry Andric NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, 13860b57cec5SDimitry Andric /*ExceptionSpecTokens*/ nullptr, 13870b57cec5SDimitry Andric /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, 1388480093f4SDimitry Andric TrailingReturnType, &DS), 13890b57cec5SDimitry Andric std::move(Attr), DeclEndLoc); 1390480093f4SDimitry Andric 1391480093f4SDimitry Andric // Parse requires-clause[opt]. 1392480093f4SDimitry Andric if (Tok.is(tok::kw_requires)) 1393480093f4SDimitry Andric ParseTrailingRequiresClause(D); 1394480093f4SDimitry Andric 1395480093f4SDimitry Andric PrototypeScope.Exit(); 1396480093f4SDimitry Andric 1397480093f4SDimitry Andric WarnIfHasCUDATargetAttr(); 13980b57cec5SDimitry Andric } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, 1399480093f4SDimitry Andric tok::kw_constexpr, tok::kw_consteval, 1400480093f4SDimitry Andric tok::kw___private, tok::kw___global, tok::kw___local, 1401480093f4SDimitry Andric tok::kw___constant, tok::kw___generic, 1402480093f4SDimitry Andric tok::kw_requires) || 14030b57cec5SDimitry Andric (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { 14040b57cec5SDimitry Andric // It's common to forget that one needs '()' before 'mutable', an attribute 1405480093f4SDimitry Andric // specifier, the result type, or the requires clause. Deal with this. 14060b57cec5SDimitry Andric unsigned TokKind = 0; 14070b57cec5SDimitry Andric switch (Tok.getKind()) { 14080b57cec5SDimitry Andric case tok::kw_mutable: TokKind = 0; break; 14090b57cec5SDimitry Andric case tok::arrow: TokKind = 1; break; 14100b57cec5SDimitry Andric case tok::kw___attribute: 1411480093f4SDimitry Andric case tok::kw___private: 1412480093f4SDimitry Andric case tok::kw___global: 1413480093f4SDimitry Andric case tok::kw___local: 1414480093f4SDimitry Andric case tok::kw___constant: 1415480093f4SDimitry Andric case tok::kw___generic: 14160b57cec5SDimitry Andric case tok::l_square: TokKind = 2; break; 14170b57cec5SDimitry Andric case tok::kw_constexpr: TokKind = 3; break; 14180b57cec5SDimitry Andric case tok::kw_consteval: TokKind = 4; break; 1419480093f4SDimitry Andric case tok::kw_requires: TokKind = 5; break; 14200b57cec5SDimitry Andric default: llvm_unreachable("Unknown token kind"); 14210b57cec5SDimitry Andric } 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric Diag(Tok, diag::err_lambda_missing_parens) 14240b57cec5SDimitry Andric << TokKind 14250b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "() "); 14260b57cec5SDimitry Andric SourceLocation DeclEndLoc = DeclLoc; 14270b57cec5SDimitry Andric 14280b57cec5SDimitry Andric // GNU-style attributes must be parsed before the mutable specifier to be 14290b57cec5SDimitry Andric // compatible with GCC. 14300b57cec5SDimitry Andric MaybeParseGNUAttributes(Attr, &DeclEndLoc); 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric // Parse 'mutable', if it's there. 14330b57cec5SDimitry Andric SourceLocation MutableLoc; 14340b57cec5SDimitry Andric if (Tok.is(tok::kw_mutable)) { 14350b57cec5SDimitry Andric MutableLoc = ConsumeToken(); 14360b57cec5SDimitry Andric DeclEndLoc = MutableLoc; 14370b57cec5SDimitry Andric } 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric // Parse attribute-specifier[opt]. 14400b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attr, &DeclEndLoc); 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric // Parse the return type, if there is one. 14430b57cec5SDimitry Andric if (Tok.is(tok::arrow)) { 14440b57cec5SDimitry Andric SourceRange Range; 14450b57cec5SDimitry Andric TrailingReturnType = 14460b57cec5SDimitry Andric ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); 14470b57cec5SDimitry Andric if (Range.getEnd().isValid()) 14480b57cec5SDimitry Andric DeclEndLoc = Range.getEnd(); 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric 14510b57cec5SDimitry Andric SourceLocation NoLoc; 14520b57cec5SDimitry Andric D.AddTypeInfo(DeclaratorChunk::getFunction( 14530b57cec5SDimitry Andric /*HasProto=*/true, 14540b57cec5SDimitry Andric /*IsAmbiguous=*/false, 14550b57cec5SDimitry Andric /*LParenLoc=*/NoLoc, 14560b57cec5SDimitry Andric /*Params=*/nullptr, 14570b57cec5SDimitry Andric /*NumParams=*/0, 14580b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 14590b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 14600b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 14610b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, MutableLoc, EST_None, 14620b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 14630b57cec5SDimitry Andric /*Exceptions=*/nullptr, 14640b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 14650b57cec5SDimitry Andric /*NumExceptions=*/0, 14660b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 14670b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 14680b57cec5SDimitry Andric /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, 14690b57cec5SDimitry Andric TrailingReturnType), 14700b57cec5SDimitry Andric std::move(Attr), DeclEndLoc); 1471480093f4SDimitry Andric 1472480093f4SDimitry Andric // Parse the requires-clause, if present. 1473480093f4SDimitry Andric if (Tok.is(tok::kw_requires)) 1474480093f4SDimitry Andric ParseTrailingRequiresClause(D); 1475480093f4SDimitry Andric 1476480093f4SDimitry Andric WarnIfHasCUDATargetAttr(); 14770b57cec5SDimitry Andric } 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using 14800b57cec5SDimitry Andric // it. 14810b57cec5SDimitry Andric unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope | 14820b57cec5SDimitry Andric Scope::CompoundStmtScope; 14830b57cec5SDimitry Andric ParseScope BodyScope(this, ScopeFlags); 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope()); 14860b57cec5SDimitry Andric 14870b57cec5SDimitry Andric // Parse compound-statement. 14880b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 14890b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lambda_body); 14900b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 14910b57cec5SDimitry Andric return ExprError(); 14920b57cec5SDimitry Andric } 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 14950b57cec5SDimitry Andric BodyScope.Exit(); 14960b57cec5SDimitry Andric TemplateParamScope.Exit(); 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid()) 14990b57cec5SDimitry Andric return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope()); 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 15020b57cec5SDimitry Andric return ExprError(); 15030b57cec5SDimitry Andric } 15040b57cec5SDimitry Andric 15050b57cec5SDimitry Andric /// ParseCXXCasts - This handles the various ways to cast expressions to another 15060b57cec5SDimitry Andric /// type. 15070b57cec5SDimitry Andric /// 15080b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 15090b57cec5SDimitry Andric /// 'dynamic_cast' '<' type-name '>' '(' expression ')' 15100b57cec5SDimitry Andric /// 'static_cast' '<' type-name '>' '(' expression ')' 15110b57cec5SDimitry Andric /// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 15120b57cec5SDimitry Andric /// 'const_cast' '<' type-name '>' '(' expression ')' 15130b57cec5SDimitry Andric /// 15140b57cec5SDimitry Andric ExprResult Parser::ParseCXXCasts() { 15150b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 15160b57cec5SDimitry Andric const char *CastName = nullptr; // For error messages 15170b57cec5SDimitry Andric 15180b57cec5SDimitry Andric switch (Kind) { 15190b57cec5SDimitry Andric default: llvm_unreachable("Unknown C++ cast!"); 15200b57cec5SDimitry Andric case tok::kw_const_cast: CastName = "const_cast"; break; 15210b57cec5SDimitry Andric case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 15220b57cec5SDimitry Andric case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 15230b57cec5SDimitry Andric case tok::kw_static_cast: CastName = "static_cast"; break; 15240b57cec5SDimitry Andric } 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 15270b57cec5SDimitry Andric SourceLocation LAngleBracketLoc = Tok.getLocation(); 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andric // Check for "<::" which is parsed as "[:". If found, fix token stream, 15300b57cec5SDimitry Andric // diagnose error, suggest fix, and recover parsing. 15310b57cec5SDimitry Andric if (Tok.is(tok::l_square) && Tok.getLength() == 2) { 15320b57cec5SDimitry Andric Token Next = NextToken(); 15330b57cec5SDimitry Andric if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next)) 15340b57cec5SDimitry Andric FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric 15370b57cec5SDimitry Andric if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 15380b57cec5SDimitry Andric return ExprError(); 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 15410b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15420b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric // Parse the abstract-declarator, if present. 15450b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 15460b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 15470b57cec5SDimitry Andric 15480b57cec5SDimitry Andric SourceLocation RAngleBracketLoc = Tok.getLocation(); 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric if (ExpectAndConsume(tok::greater)) 15510b57cec5SDimitry Andric return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less); 15520b57cec5SDimitry Andric 15530b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 15540b57cec5SDimitry Andric 15550b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) 15560b57cec5SDimitry Andric return ExprError(); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric ExprResult Result = ParseExpression(); 15590b57cec5SDimitry Andric 15600b57cec5SDimitry Andric // Match the ')'. 15610b57cec5SDimitry Andric T.consumeClose(); 15620b57cec5SDimitry Andric 15630b57cec5SDimitry Andric if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) 15640b57cec5SDimitry Andric Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 15650b57cec5SDimitry Andric LAngleBracketLoc, DeclaratorInfo, 15660b57cec5SDimitry Andric RAngleBracketLoc, 15670b57cec5SDimitry Andric T.getOpenLocation(), Result.get(), 15680b57cec5SDimitry Andric T.getCloseLocation()); 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric return Result; 15710b57cec5SDimitry Andric } 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric /// ParseCXXTypeid - This handles the C++ typeid expression. 15740b57cec5SDimitry Andric /// 15750b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 15760b57cec5SDimitry Andric /// 'typeid' '(' expression ')' 15770b57cec5SDimitry Andric /// 'typeid' '(' type-id ')' 15780b57cec5SDimitry Andric /// 15790b57cec5SDimitry Andric ExprResult Parser::ParseCXXTypeid() { 15800b57cec5SDimitry Andric assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 15810b57cec5SDimitry Andric 15820b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 15830b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 15840b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 15850b57cec5SDimitry Andric 15860b57cec5SDimitry Andric // typeid expressions are always parenthesized. 15870b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) 15880b57cec5SDimitry Andric return ExprError(); 15890b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 15900b57cec5SDimitry Andric 15910b57cec5SDimitry Andric ExprResult Result; 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric // C++0x [expr.typeid]p3: 15940b57cec5SDimitry Andric // When typeid is applied to an expression other than an lvalue of a 15950b57cec5SDimitry Andric // polymorphic class type [...] The expression is an unevaluated 15960b57cec5SDimitry Andric // operand (Clause 5). 15970b57cec5SDimitry Andric // 15980b57cec5SDimitry Andric // Note that we can't tell whether the expression is an lvalue of a 15990b57cec5SDimitry Andric // polymorphic class type until after we've parsed the expression; we 16000b57cec5SDimitry Andric // speculatively assume the subexpression is unevaluated, and fix it up 16010b57cec5SDimitry Andric // later. 16020b57cec5SDimitry Andric // 16030b57cec5SDimitry Andric // We enter the unevaluated context before trying to determine whether we 16040b57cec5SDimitry Andric // have a type-id, because the tentative parse logic will try to resolve 16050b57cec5SDimitry Andric // names, and must treat them as unevaluated. 16060b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 16070b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 16080b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andric if (isTypeIdInParens()) { 16110b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 16120b57cec5SDimitry Andric 16130b57cec5SDimitry Andric // Match the ')'. 16140b57cec5SDimitry Andric T.consumeClose(); 16150b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 16160b57cec5SDimitry Andric if (Ty.isInvalid() || RParenLoc.isInvalid()) 16170b57cec5SDimitry Andric return ExprError(); 16180b57cec5SDimitry Andric 16190b57cec5SDimitry Andric Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 16200b57cec5SDimitry Andric Ty.get().getAsOpaquePtr(), RParenLoc); 16210b57cec5SDimitry Andric } else { 16220b57cec5SDimitry Andric Result = ParseExpression(); 16230b57cec5SDimitry Andric 16240b57cec5SDimitry Andric // Match the ')'. 16250b57cec5SDimitry Andric if (Result.isInvalid()) 16260b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 16270b57cec5SDimitry Andric else { 16280b57cec5SDimitry Andric T.consumeClose(); 16290b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 16300b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 16310b57cec5SDimitry Andric return ExprError(); 16320b57cec5SDimitry Andric 16330b57cec5SDimitry Andric Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 16340b57cec5SDimitry Andric Result.get(), RParenLoc); 16350b57cec5SDimitry Andric } 16360b57cec5SDimitry Andric } 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric return Result; 16390b57cec5SDimitry Andric } 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andric /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. 16420b57cec5SDimitry Andric /// 16430b57cec5SDimitry Andric /// '__uuidof' '(' expression ')' 16440b57cec5SDimitry Andric /// '__uuidof' '(' type-id ')' 16450b57cec5SDimitry Andric /// 16460b57cec5SDimitry Andric ExprResult Parser::ParseCXXUuidof() { 16470b57cec5SDimitry Andric assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); 16480b57cec5SDimitry Andric 16490b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 16500b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric // __uuidof expressions are always parenthesized. 16530b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) 16540b57cec5SDimitry Andric return ExprError(); 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andric ExprResult Result; 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andric if (isTypeIdInParens()) { 16590b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 16600b57cec5SDimitry Andric 16610b57cec5SDimitry Andric // Match the ')'. 16620b57cec5SDimitry Andric T.consumeClose(); 16630b57cec5SDimitry Andric 16640b57cec5SDimitry Andric if (Ty.isInvalid()) 16650b57cec5SDimitry Andric return ExprError(); 16660b57cec5SDimitry Andric 16670b57cec5SDimitry Andric Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, 16680b57cec5SDimitry Andric Ty.get().getAsOpaquePtr(), 16690b57cec5SDimitry Andric T.getCloseLocation()); 16700b57cec5SDimitry Andric } else { 16710b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 16720b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 16730b57cec5SDimitry Andric Result = ParseExpression(); 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric // Match the ')'. 16760b57cec5SDimitry Andric if (Result.isInvalid()) 16770b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 16780b57cec5SDimitry Andric else { 16790b57cec5SDimitry Andric T.consumeClose(); 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andric Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), 16820b57cec5SDimitry Andric /*isType=*/false, 16830b57cec5SDimitry Andric Result.get(), T.getCloseLocation()); 16840b57cec5SDimitry Andric } 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric return Result; 16880b57cec5SDimitry Andric } 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric /// Parse a C++ pseudo-destructor expression after the base, 16910b57cec5SDimitry Andric /// . or -> operator, and nested-name-specifier have already been 16920b57cec5SDimitry Andric /// parsed. 16930b57cec5SDimitry Andric /// 16940b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2] 16950b57cec5SDimitry Andric /// postfix-expression . pseudo-destructor-name 16960b57cec5SDimitry Andric /// postfix-expression -> pseudo-destructor-name 16970b57cec5SDimitry Andric /// 16980b57cec5SDimitry Andric /// pseudo-destructor-name: 16990b57cec5SDimitry Andric /// ::[opt] nested-name-specifier[opt] type-name :: ~type-name 17000b57cec5SDimitry Andric /// ::[opt] nested-name-specifier template simple-template-id :: 17010b57cec5SDimitry Andric /// ~type-name 17020b57cec5SDimitry Andric /// ::[opt] nested-name-specifier[opt] ~type-name 17030b57cec5SDimitry Andric /// 17040b57cec5SDimitry Andric ExprResult 17050b57cec5SDimitry Andric Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, 17060b57cec5SDimitry Andric tok::TokenKind OpKind, 17070b57cec5SDimitry Andric CXXScopeSpec &SS, 17080b57cec5SDimitry Andric ParsedType ObjectType) { 17090b57cec5SDimitry Andric // We're parsing either a pseudo-destructor-name or a dependent 17100b57cec5SDimitry Andric // member access that has the same form as a 17110b57cec5SDimitry Andric // pseudo-destructor-name. We parse both in the same way and let 17120b57cec5SDimitry Andric // the action model sort them out. 17130b57cec5SDimitry Andric // 17140b57cec5SDimitry Andric // Note that the ::[opt] nested-name-specifier[opt] has already 17150b57cec5SDimitry Andric // been parsed, and if there was a simple-template-id, it has 17160b57cec5SDimitry Andric // been coalesced into a template-id annotation token. 17170b57cec5SDimitry Andric UnqualifiedId FirstTypeName; 17180b57cec5SDimitry Andric SourceLocation CCLoc; 17190b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 17200b57cec5SDimitry Andric FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 17210b57cec5SDimitry Andric ConsumeToken(); 17220b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 17230b57cec5SDimitry Andric CCLoc = ConsumeToken(); 17240b57cec5SDimitry Andric } else if (Tok.is(tok::annot_template_id)) { 17250b57cec5SDimitry Andric // FIXME: retrieve TemplateKWLoc from template-id annotation and 17260b57cec5SDimitry Andric // store it in the pseudo-dtor node (to be used when instantiating it). 17270b57cec5SDimitry Andric FirstTypeName.setTemplateId( 17280b57cec5SDimitry Andric (TemplateIdAnnotation *)Tok.getAnnotationValue()); 17290b57cec5SDimitry Andric ConsumeAnnotationToken(); 17300b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 17310b57cec5SDimitry Andric CCLoc = ConsumeToken(); 17320b57cec5SDimitry Andric } else { 17330b57cec5SDimitry Andric FirstTypeName.setIdentifier(nullptr, SourceLocation()); 17340b57cec5SDimitry Andric } 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andric // Parse the tilde. 17370b57cec5SDimitry Andric assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 17380b57cec5SDimitry Andric SourceLocation TildeLoc = ConsumeToken(); 17390b57cec5SDimitry Andric 17400b57cec5SDimitry Andric if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) { 17410b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 17420b57cec5SDimitry Andric ParseDecltypeSpecifier(DS); 17430b57cec5SDimitry Andric if (DS.getTypeSpecType() == TST_error) 17440b57cec5SDimitry Andric return ExprError(); 17450b57cec5SDimitry Andric return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, 17460b57cec5SDimitry Andric TildeLoc, DS); 17470b57cec5SDimitry Andric } 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) { 17500b57cec5SDimitry Andric Diag(Tok, diag::err_destructor_tilde_identifier); 17510b57cec5SDimitry Andric return ExprError(); 17520b57cec5SDimitry Andric } 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric // Parse the second type. 17550b57cec5SDimitry Andric UnqualifiedId SecondTypeName; 17560b57cec5SDimitry Andric IdentifierInfo *Name = Tok.getIdentifierInfo(); 17570b57cec5SDimitry Andric SourceLocation NameLoc = ConsumeToken(); 17580b57cec5SDimitry Andric SecondTypeName.setIdentifier(Name, NameLoc); 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric // If there is a '<', the second type name is a template-id. Parse 17610b57cec5SDimitry Andric // it as such. 17620b57cec5SDimitry Andric if (Tok.is(tok::less) && 17630b57cec5SDimitry Andric ParseUnqualifiedIdTemplateId(SS, SourceLocation(), 17640b57cec5SDimitry Andric Name, NameLoc, 17650b57cec5SDimitry Andric false, ObjectType, SecondTypeName, 17660b57cec5SDimitry Andric /*AssumeTemplateId=*/true)) 17670b57cec5SDimitry Andric return ExprError(); 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, 17700b57cec5SDimitry Andric SS, FirstTypeName, CCLoc, TildeLoc, 17710b57cec5SDimitry Andric SecondTypeName); 17720b57cec5SDimitry Andric } 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric /// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 17750b57cec5SDimitry Andric /// 17760b57cec5SDimitry Andric /// boolean-literal: [C++ 2.13.5] 17770b57cec5SDimitry Andric /// 'true' 17780b57cec5SDimitry Andric /// 'false' 17790b57cec5SDimitry Andric ExprResult Parser::ParseCXXBoolLiteral() { 17800b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 17810b57cec5SDimitry Andric return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric /// ParseThrowExpression - This handles the C++ throw expression. 17850b57cec5SDimitry Andric /// 17860b57cec5SDimitry Andric /// throw-expression: [C++ 15] 17870b57cec5SDimitry Andric /// 'throw' assignment-expression[opt] 17880b57cec5SDimitry Andric ExprResult Parser::ParseThrowExpression() { 17890b57cec5SDimitry Andric assert(Tok.is(tok::kw_throw) && "Not throw!"); 17900b57cec5SDimitry Andric SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 17910b57cec5SDimitry Andric 17920b57cec5SDimitry Andric // If the current token isn't the start of an assignment-expression, 17930b57cec5SDimitry Andric // then the expression is not present. This handles things like: 17940b57cec5SDimitry Andric // "C ? throw : (void)42", which is crazy but legal. 17950b57cec5SDimitry Andric switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 17960b57cec5SDimitry Andric case tok::semi: 17970b57cec5SDimitry Andric case tok::r_paren: 17980b57cec5SDimitry Andric case tok::r_square: 17990b57cec5SDimitry Andric case tok::r_brace: 18000b57cec5SDimitry Andric case tok::colon: 18010b57cec5SDimitry Andric case tok::comma: 18020b57cec5SDimitry Andric return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, nullptr); 18030b57cec5SDimitry Andric 18040b57cec5SDimitry Andric default: 18050b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 18060b57cec5SDimitry Andric if (Expr.isInvalid()) return Expr; 18070b57cec5SDimitry Andric return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get()); 18080b57cec5SDimitry Andric } 18090b57cec5SDimitry Andric } 18100b57cec5SDimitry Andric 18110b57cec5SDimitry Andric /// Parse the C++ Coroutines co_yield expression. 18120b57cec5SDimitry Andric /// 18130b57cec5SDimitry Andric /// co_yield-expression: 18140b57cec5SDimitry Andric /// 'co_yield' assignment-expression[opt] 18150b57cec5SDimitry Andric ExprResult Parser::ParseCoyieldExpression() { 18160b57cec5SDimitry Andric assert(Tok.is(tok::kw_co_yield) && "Not co_yield!"); 18170b57cec5SDimitry Andric 18180b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 18190b57cec5SDimitry Andric ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer() 18200b57cec5SDimitry Andric : ParseAssignmentExpression(); 18210b57cec5SDimitry Andric if (!Expr.isInvalid()) 18220b57cec5SDimitry Andric Expr = Actions.ActOnCoyieldExpr(getCurScope(), Loc, Expr.get()); 18230b57cec5SDimitry Andric return Expr; 18240b57cec5SDimitry Andric } 18250b57cec5SDimitry Andric 18260b57cec5SDimitry Andric /// ParseCXXThis - This handles the C++ 'this' pointer. 18270b57cec5SDimitry Andric /// 18280b57cec5SDimitry Andric /// C++ 9.3.2: In the body of a non-static member function, the keyword this is 18290b57cec5SDimitry Andric /// a non-lvalue expression whose value is the address of the object for which 18300b57cec5SDimitry Andric /// the function is called. 18310b57cec5SDimitry Andric ExprResult Parser::ParseCXXThis() { 18320b57cec5SDimitry Andric assert(Tok.is(tok::kw_this) && "Not 'this'!"); 18330b57cec5SDimitry Andric SourceLocation ThisLoc = ConsumeToken(); 18340b57cec5SDimitry Andric return Actions.ActOnCXXThis(ThisLoc); 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric /// ParseCXXTypeConstructExpression - Parse construction of a specified type. 18380b57cec5SDimitry Andric /// Can be interpreted either as function-style casting ("int(x)") 18390b57cec5SDimitry Andric /// or class type construction ("ClassType(x,y,z)") 18400b57cec5SDimitry Andric /// or creation of a value-initialized type ("int()"). 18410b57cec5SDimitry Andric /// See [C++ 5.2.3]. 18420b57cec5SDimitry Andric /// 18430b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 18440b57cec5SDimitry Andric /// simple-type-specifier '(' expression-list[opt] ')' 18450b57cec5SDimitry Andric /// [C++0x] simple-type-specifier braced-init-list 18460b57cec5SDimitry Andric /// typename-specifier '(' expression-list[opt] ')' 18470b57cec5SDimitry Andric /// [C++0x] typename-specifier braced-init-list 18480b57cec5SDimitry Andric /// 18490b57cec5SDimitry Andric /// In C++1z onwards, the type specifier can also be a template-name. 18500b57cec5SDimitry Andric ExprResult 18510b57cec5SDimitry Andric Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 18520b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::FunctionalCastContext); 18530b57cec5SDimitry Andric ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); 18540b57cec5SDimitry Andric 18550b57cec5SDimitry Andric assert((Tok.is(tok::l_paren) || 18560b57cec5SDimitry Andric (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) 18570b57cec5SDimitry Andric && "Expected '(' or '{'!"); 18580b57cec5SDimitry Andric 18590b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 18600b57cec5SDimitry Andric ExprResult Init = ParseBraceInitializer(); 18610b57cec5SDimitry Andric if (Init.isInvalid()) 18620b57cec5SDimitry Andric return Init; 18630b57cec5SDimitry Andric Expr *InitList = Init.get(); 18640b57cec5SDimitry Andric return Actions.ActOnCXXTypeConstructExpr( 18650b57cec5SDimitry Andric TypeRep, InitList->getBeginLoc(), MultiExprArg(&InitList, 1), 18660b57cec5SDimitry Andric InitList->getEndLoc(), /*ListInitialization=*/true); 18670b57cec5SDimitry Andric } else { 18680b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 18690b57cec5SDimitry Andric T.consumeOpen(); 18700b57cec5SDimitry Andric 18710b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get()); 18720b57cec5SDimitry Andric 18730b57cec5SDimitry Andric ExprVector Exprs; 18740b57cec5SDimitry Andric CommaLocsTy CommaLocs; 18750b57cec5SDimitry Andric 18760b57cec5SDimitry Andric auto RunSignatureHelp = [&]() { 1877480093f4SDimitry Andric QualType PreferredType; 1878480093f4SDimitry Andric if (TypeRep) 1879480093f4SDimitry Andric PreferredType = Actions.ProduceConstructorSignatureHelp( 18800b57cec5SDimitry Andric getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), 18810b57cec5SDimitry Andric DS.getEndLoc(), Exprs, T.getOpenLocation()); 18820b57cec5SDimitry Andric CalledSignatureHelp = true; 18830b57cec5SDimitry Andric return PreferredType; 18840b57cec5SDimitry Andric }; 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 18870b57cec5SDimitry Andric if (ParseExpressionList(Exprs, CommaLocs, [&] { 18880b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 18890b57cec5SDimitry Andric RunSignatureHelp); 18900b57cec5SDimitry Andric })) { 18910b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 18920b57cec5SDimitry Andric RunSignatureHelp(); 18930b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 18940b57cec5SDimitry Andric return ExprError(); 18950b57cec5SDimitry Andric } 18960b57cec5SDimitry Andric } 18970b57cec5SDimitry Andric 18980b57cec5SDimitry Andric // Match the ')'. 18990b57cec5SDimitry Andric T.consumeClose(); 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric // TypeRep could be null, if it references an invalid typedef. 19020b57cec5SDimitry Andric if (!TypeRep) 19030b57cec5SDimitry Andric return ExprError(); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 19060b57cec5SDimitry Andric "Unexpected number of commas!"); 19070b57cec5SDimitry Andric return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), 19080b57cec5SDimitry Andric Exprs, T.getCloseLocation(), 19090b57cec5SDimitry Andric /*ListInitialization=*/false); 19100b57cec5SDimitry Andric } 19110b57cec5SDimitry Andric } 19120b57cec5SDimitry Andric 19130b57cec5SDimitry Andric /// ParseCXXCondition - if/switch/while condition expression. 19140b57cec5SDimitry Andric /// 19150b57cec5SDimitry Andric /// condition: 19160b57cec5SDimitry Andric /// expression 19170b57cec5SDimitry Andric /// type-specifier-seq declarator '=' assignment-expression 19180b57cec5SDimitry Andric /// [C++11] type-specifier-seq declarator '=' initializer-clause 19190b57cec5SDimitry Andric /// [C++11] type-specifier-seq declarator braced-init-list 19200b57cec5SDimitry Andric /// [Clang] type-specifier-seq ref-qualifier[opt] '[' identifier-list ']' 19210b57cec5SDimitry Andric /// brace-or-equal-initializer 19220b57cec5SDimitry Andric /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 19230b57cec5SDimitry Andric /// '=' assignment-expression 19240b57cec5SDimitry Andric /// 19250b57cec5SDimitry Andric /// In C++1z, a condition may in some contexts be preceded by an 19260b57cec5SDimitry Andric /// optional init-statement. This function will parse that too. 19270b57cec5SDimitry Andric /// 19280b57cec5SDimitry Andric /// \param InitStmt If non-null, an init-statement is permitted, and if present 19290b57cec5SDimitry Andric /// will be parsed and stored here. 19300b57cec5SDimitry Andric /// 19310b57cec5SDimitry Andric /// \param Loc The location of the start of the statement that requires this 19320b57cec5SDimitry Andric /// condition, e.g., the "for" in a for loop. 19330b57cec5SDimitry Andric /// 19340b57cec5SDimitry Andric /// \param FRI If non-null, a for range declaration is permitted, and if 19350b57cec5SDimitry Andric /// present will be parsed and stored here, and a null result will be returned. 19360b57cec5SDimitry Andric /// 19370b57cec5SDimitry Andric /// \returns The parsed condition. 19380b57cec5SDimitry Andric Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, 19390b57cec5SDimitry Andric SourceLocation Loc, 19400b57cec5SDimitry Andric Sema::ConditionKind CK, 19410b57cec5SDimitry Andric ForRangeInfo *FRI) { 19420b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 19430b57cec5SDimitry Andric PreferredType.enterCondition(Actions, Tok.getLocation()); 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 19460b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); 19470b57cec5SDimitry Andric cutOffParsing(); 19480b57cec5SDimitry Andric return Sema::ConditionError(); 19490b57cec5SDimitry Andric } 19500b57cec5SDimitry Andric 19510b57cec5SDimitry Andric ParsedAttributesWithRange attrs(AttrFactory); 19520b57cec5SDimitry Andric MaybeParseCXX11Attributes(attrs); 19530b57cec5SDimitry Andric 19540b57cec5SDimitry Andric const auto WarnOnInit = [this, &CK] { 19550b57cec5SDimitry Andric Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 19560b57cec5SDimitry Andric ? diag::warn_cxx14_compat_init_statement 19570b57cec5SDimitry Andric : diag::ext_init_statement) 19580b57cec5SDimitry Andric << (CK == Sema::ConditionKind::Switch); 19590b57cec5SDimitry Andric }; 19600b57cec5SDimitry Andric 19610b57cec5SDimitry Andric // Determine what kind of thing we have. 19620b57cec5SDimitry Andric switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) { 19630b57cec5SDimitry Andric case ConditionOrInitStatement::Expression: { 19640b57cec5SDimitry Andric ProhibitAttributes(attrs); 19650b57cec5SDimitry Andric 19660b57cec5SDimitry Andric // We can have an empty expression here. 19670b57cec5SDimitry Andric // if (; true); 19680b57cec5SDimitry Andric if (InitStmt && Tok.is(tok::semi)) { 19690b57cec5SDimitry Andric WarnOnInit(); 19700b57cec5SDimitry Andric SourceLocation SemiLoc = Tok.getLocation(); 19710b57cec5SDimitry Andric if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID()) { 19720b57cec5SDimitry Andric Diag(SemiLoc, diag::warn_empty_init_statement) 19730b57cec5SDimitry Andric << (CK == Sema::ConditionKind::Switch) 19740b57cec5SDimitry Andric << FixItHint::CreateRemoval(SemiLoc); 19750b57cec5SDimitry Andric } 19760b57cec5SDimitry Andric ConsumeToken(); 19770b57cec5SDimitry Andric *InitStmt = Actions.ActOnNullStmt(SemiLoc); 19780b57cec5SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK); 19790b57cec5SDimitry Andric } 19800b57cec5SDimitry Andric 19810b57cec5SDimitry Andric // Parse the expression. 19820b57cec5SDimitry Andric ExprResult Expr = ParseExpression(); // expression 19830b57cec5SDimitry Andric if (Expr.isInvalid()) 19840b57cec5SDimitry Andric return Sema::ConditionError(); 19850b57cec5SDimitry Andric 19860b57cec5SDimitry Andric if (InitStmt && Tok.is(tok::semi)) { 19870b57cec5SDimitry Andric WarnOnInit(); 19880b57cec5SDimitry Andric *InitStmt = Actions.ActOnExprStmt(Expr.get()); 19890b57cec5SDimitry Andric ConsumeToken(); 19900b57cec5SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK); 19910b57cec5SDimitry Andric } 19920b57cec5SDimitry Andric 19930b57cec5SDimitry Andric return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK); 19940b57cec5SDimitry Andric } 19950b57cec5SDimitry Andric 19960b57cec5SDimitry Andric case ConditionOrInitStatement::InitStmtDecl: { 19970b57cec5SDimitry Andric WarnOnInit(); 19980b57cec5SDimitry Andric SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 19990b57cec5SDimitry Andric DeclGroupPtrTy DG = 20000b57cec5SDimitry Andric ParseSimpleDeclaration(DeclaratorContext::InitStmtContext, DeclEnd, 20010b57cec5SDimitry Andric attrs, /*RequireSemi=*/true); 20020b57cec5SDimitry Andric *InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd); 20030b57cec5SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK); 20040b57cec5SDimitry Andric } 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric case ConditionOrInitStatement::ForRangeDecl: { 20070b57cec5SDimitry Andric assert(FRI && "should not parse a for range declaration here"); 20080b57cec5SDimitry Andric SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 20090b57cec5SDimitry Andric DeclGroupPtrTy DG = ParseSimpleDeclaration( 20100b57cec5SDimitry Andric DeclaratorContext::ForContext, DeclEnd, attrs, false, FRI); 20110b57cec5SDimitry Andric FRI->LoopVar = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); 20120b57cec5SDimitry Andric return Sema::ConditionResult(); 20130b57cec5SDimitry Andric } 20140b57cec5SDimitry Andric 20150b57cec5SDimitry Andric case ConditionOrInitStatement::ConditionDecl: 20160b57cec5SDimitry Andric case ConditionOrInitStatement::Error: 20170b57cec5SDimitry Andric break; 20180b57cec5SDimitry Andric } 20190b57cec5SDimitry Andric 20200b57cec5SDimitry Andric // type-specifier-seq 20210b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 20220b57cec5SDimitry Andric DS.takeAttributesFrom(attrs); 20230b57cec5SDimitry Andric ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition); 20240b57cec5SDimitry Andric 20250b57cec5SDimitry Andric // declarator 20260b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::ConditionContext); 20270b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 20280b57cec5SDimitry Andric 20290b57cec5SDimitry Andric // simple-asm-expr[opt] 20300b57cec5SDimitry Andric if (Tok.is(tok::kw_asm)) { 20310b57cec5SDimitry Andric SourceLocation Loc; 2032480093f4SDimitry Andric ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc)); 20330b57cec5SDimitry Andric if (AsmLabel.isInvalid()) { 20340b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi); 20350b57cec5SDimitry Andric return Sema::ConditionError(); 20360b57cec5SDimitry Andric } 20370b57cec5SDimitry Andric DeclaratorInfo.setAsmLabel(AsmLabel.get()); 20380b57cec5SDimitry Andric DeclaratorInfo.SetRangeEnd(Loc); 20390b57cec5SDimitry Andric } 20400b57cec5SDimitry Andric 20410b57cec5SDimitry Andric // If attributes are present, parse them. 20420b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 20430b57cec5SDimitry Andric 20440b57cec5SDimitry Andric // Type-check the declaration itself. 20450b57cec5SDimitry Andric DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 20460b57cec5SDimitry Andric DeclaratorInfo); 20470b57cec5SDimitry Andric if (Dcl.isInvalid()) 20480b57cec5SDimitry Andric return Sema::ConditionError(); 20490b57cec5SDimitry Andric Decl *DeclOut = Dcl.get(); 20500b57cec5SDimitry Andric 20510b57cec5SDimitry Andric // '=' assignment-expression 20520b57cec5SDimitry Andric // If a '==' or '+=' is found, suggest a fixit to '='. 20530b57cec5SDimitry Andric bool CopyInitialization = isTokenEqualOrEqualTypo(); 20540b57cec5SDimitry Andric if (CopyInitialization) 20550b57cec5SDimitry Andric ConsumeToken(); 20560b57cec5SDimitry Andric 20570b57cec5SDimitry Andric ExprResult InitExpr = ExprError(); 20580b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 20590b57cec5SDimitry Andric Diag(Tok.getLocation(), 20600b57cec5SDimitry Andric diag::warn_cxx98_compat_generalized_initializer_lists); 20610b57cec5SDimitry Andric InitExpr = ParseBraceInitializer(); 20620b57cec5SDimitry Andric } else if (CopyInitialization) { 20630b57cec5SDimitry Andric PreferredType.enterVariableInit(Tok.getLocation(), DeclOut); 20640b57cec5SDimitry Andric InitExpr = ParseAssignmentExpression(); 20650b57cec5SDimitry Andric } else if (Tok.is(tok::l_paren)) { 20660b57cec5SDimitry Andric // This was probably an attempt to initialize the variable. 20670b57cec5SDimitry Andric SourceLocation LParen = ConsumeParen(), RParen = LParen; 20680b57cec5SDimitry Andric if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) 20690b57cec5SDimitry Andric RParen = ConsumeParen(); 20700b57cec5SDimitry Andric Diag(DeclOut->getLocation(), 20710b57cec5SDimitry Andric diag::err_expected_init_in_condition_lparen) 20720b57cec5SDimitry Andric << SourceRange(LParen, RParen); 20730b57cec5SDimitry Andric } else { 20740b57cec5SDimitry Andric Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition); 20750b57cec5SDimitry Andric } 20760b57cec5SDimitry Andric 20770b57cec5SDimitry Andric if (!InitExpr.isInvalid()) 20780b57cec5SDimitry Andric Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization); 20790b57cec5SDimitry Andric else 20800b57cec5SDimitry Andric Actions.ActOnInitializerError(DeclOut); 20810b57cec5SDimitry Andric 20820b57cec5SDimitry Andric Actions.FinalizeDeclaration(DeclOut); 20830b57cec5SDimitry Andric return Actions.ActOnConditionVariable(DeclOut, Loc, CK); 20840b57cec5SDimitry Andric } 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andric /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 20870b57cec5SDimitry Andric /// This should only be called when the current token is known to be part of 20880b57cec5SDimitry Andric /// simple-type-specifier. 20890b57cec5SDimitry Andric /// 20900b57cec5SDimitry Andric /// simple-type-specifier: 20910b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier[opt] type-name 20920b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 20930b57cec5SDimitry Andric /// char 20940b57cec5SDimitry Andric /// wchar_t 20950b57cec5SDimitry Andric /// bool 20960b57cec5SDimitry Andric /// short 20970b57cec5SDimitry Andric /// int 20980b57cec5SDimitry Andric /// long 20990b57cec5SDimitry Andric /// signed 21000b57cec5SDimitry Andric /// unsigned 21010b57cec5SDimitry Andric /// float 21020b57cec5SDimitry Andric /// double 21030b57cec5SDimitry Andric /// void 21040b57cec5SDimitry Andric /// [GNU] typeof-specifier 21050b57cec5SDimitry Andric /// [C++0x] auto [TODO] 21060b57cec5SDimitry Andric /// 21070b57cec5SDimitry Andric /// type-name: 21080b57cec5SDimitry Andric /// class-name 21090b57cec5SDimitry Andric /// enum-name 21100b57cec5SDimitry Andric /// typedef-name 21110b57cec5SDimitry Andric /// 21120b57cec5SDimitry Andric void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 21130b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 21140b57cec5SDimitry Andric const char *PrevSpec; 21150b57cec5SDimitry Andric unsigned DiagID; 21160b57cec5SDimitry Andric SourceLocation Loc = Tok.getLocation(); 21170b57cec5SDimitry Andric const clang::PrintingPolicy &Policy = 21180b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy(); 21190b57cec5SDimitry Andric 21200b57cec5SDimitry Andric switch (Tok.getKind()) { 21210b57cec5SDimitry Andric case tok::identifier: // foo::bar 21220b57cec5SDimitry Andric case tok::coloncolon: // ::foo::bar 21230b57cec5SDimitry Andric llvm_unreachable("Annotation token should already be formed!"); 21240b57cec5SDimitry Andric default: 21250b57cec5SDimitry Andric llvm_unreachable("Not a simple-type-specifier token!"); 21260b57cec5SDimitry Andric 21270b57cec5SDimitry Andric // type-name 21280b57cec5SDimitry Andric case tok::annot_typename: { 21290b57cec5SDimitry Andric if (getTypeAnnotation(Tok)) 21300b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 21310b57cec5SDimitry Andric getTypeAnnotation(Tok), Policy); 21320b57cec5SDimitry Andric else 21330b57cec5SDimitry Andric DS.SetTypeSpecError(); 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 21360b57cec5SDimitry Andric ConsumeAnnotationToken(); 21370b57cec5SDimitry Andric 21380b57cec5SDimitry Andric DS.Finish(Actions, Policy); 21390b57cec5SDimitry Andric return; 21400b57cec5SDimitry Andric } 21410b57cec5SDimitry Andric 21420b57cec5SDimitry Andric // builtin types 21430b57cec5SDimitry Andric case tok::kw_short: 21440b57cec5SDimitry Andric DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID, Policy); 21450b57cec5SDimitry Andric break; 21460b57cec5SDimitry Andric case tok::kw_long: 21470b57cec5SDimitry Andric DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID, Policy); 21480b57cec5SDimitry Andric break; 21490b57cec5SDimitry Andric case tok::kw___int64: 21500b57cec5SDimitry Andric DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID, Policy); 21510b57cec5SDimitry Andric break; 21520b57cec5SDimitry Andric case tok::kw_signed: 21530b57cec5SDimitry Andric DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 21540b57cec5SDimitry Andric break; 21550b57cec5SDimitry Andric case tok::kw_unsigned: 21560b57cec5SDimitry Andric DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 21570b57cec5SDimitry Andric break; 21580b57cec5SDimitry Andric case tok::kw_void: 21590b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy); 21600b57cec5SDimitry Andric break; 21610b57cec5SDimitry Andric case tok::kw_char: 21620b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy); 21630b57cec5SDimitry Andric break; 21640b57cec5SDimitry Andric case tok::kw_int: 21650b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy); 21660b57cec5SDimitry Andric break; 21670b57cec5SDimitry Andric case tok::kw___int128: 21680b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy); 21690b57cec5SDimitry Andric break; 21700b57cec5SDimitry Andric case tok::kw_half: 21710b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy); 21720b57cec5SDimitry Andric break; 21730b57cec5SDimitry Andric case tok::kw_float: 21740b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy); 21750b57cec5SDimitry Andric break; 21760b57cec5SDimitry Andric case tok::kw_double: 21770b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy); 21780b57cec5SDimitry Andric break; 21790b57cec5SDimitry Andric case tok::kw__Float16: 21800b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy); 21810b57cec5SDimitry Andric break; 21820b57cec5SDimitry Andric case tok::kw___float128: 21830b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); 21840b57cec5SDimitry Andric break; 21850b57cec5SDimitry Andric case tok::kw_wchar_t: 21860b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy); 21870b57cec5SDimitry Andric break; 21880b57cec5SDimitry Andric case tok::kw_char8_t: 21890b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy); 21900b57cec5SDimitry Andric break; 21910b57cec5SDimitry Andric case tok::kw_char16_t: 21920b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy); 21930b57cec5SDimitry Andric break; 21940b57cec5SDimitry Andric case tok::kw_char32_t: 21950b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy); 21960b57cec5SDimitry Andric break; 21970b57cec5SDimitry Andric case tok::kw_bool: 21980b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy); 21990b57cec5SDimitry Andric break; 22000b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) \ 22010b57cec5SDimitry Andric case tok::kw_##ImgType##_t: \ 22020b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \ 22030b57cec5SDimitry Andric Policy); \ 22040b57cec5SDimitry Andric break; 22050b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andric case tok::annot_decltype: 22080b57cec5SDimitry Andric case tok::kw_decltype: 22090b57cec5SDimitry Andric DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); 22100b57cec5SDimitry Andric return DS.Finish(Actions, Policy); 22110b57cec5SDimitry Andric 22120b57cec5SDimitry Andric // GNU typeof support. 22130b57cec5SDimitry Andric case tok::kw_typeof: 22140b57cec5SDimitry Andric ParseTypeofSpecifier(DS); 22150b57cec5SDimitry Andric DS.Finish(Actions, Policy); 22160b57cec5SDimitry Andric return; 22170b57cec5SDimitry Andric } 22180b57cec5SDimitry Andric ConsumeAnyToken(); 22190b57cec5SDimitry Andric DS.SetRangeEnd(PrevTokLocation); 22200b57cec5SDimitry Andric DS.Finish(Actions, Policy); 22210b57cec5SDimitry Andric } 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric /// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 22240b57cec5SDimitry Andric /// [dcl.name]), which is a non-empty sequence of type-specifiers, 22250b57cec5SDimitry Andric /// e.g., "const short int". Note that the DeclSpec is *not* finished 22260b57cec5SDimitry Andric /// by parsing the type-specifier-seq, because these sequences are 22270b57cec5SDimitry Andric /// typically followed by some form of declarator. Returns true and 22280b57cec5SDimitry Andric /// emits diagnostics if this is not a type-specifier-seq, false 22290b57cec5SDimitry Andric /// otherwise. 22300b57cec5SDimitry Andric /// 22310b57cec5SDimitry Andric /// type-specifier-seq: [C++ 8.1] 22320b57cec5SDimitry Andric /// type-specifier type-specifier-seq[opt] 22330b57cec5SDimitry Andric /// 22340b57cec5SDimitry Andric bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 22350b57cec5SDimitry Andric ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_type_specifier); 22360b57cec5SDimitry Andric DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy()); 22370b57cec5SDimitry Andric return false; 22380b57cec5SDimitry Andric } 22390b57cec5SDimitry Andric 22400b57cec5SDimitry Andric /// Finish parsing a C++ unqualified-id that is a template-id of 22410b57cec5SDimitry Andric /// some form. 22420b57cec5SDimitry Andric /// 22430b57cec5SDimitry Andric /// This routine is invoked when a '<' is encountered after an identifier or 22440b57cec5SDimitry Andric /// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 22450b57cec5SDimitry Andric /// whether the unqualified-id is actually a template-id. This routine will 22460b57cec5SDimitry Andric /// then parse the template arguments and form the appropriate template-id to 22470b57cec5SDimitry Andric /// return to the caller. 22480b57cec5SDimitry Andric /// 22490b57cec5SDimitry Andric /// \param SS the nested-name-specifier that precedes this template-id, if 22500b57cec5SDimitry Andric /// we're actually parsing a qualified-id. 22510b57cec5SDimitry Andric /// 22520b57cec5SDimitry Andric /// \param Name for constructor and destructor names, this is the actual 22530b57cec5SDimitry Andric /// identifier that may be a template-name. 22540b57cec5SDimitry Andric /// 22550b57cec5SDimitry Andric /// \param NameLoc the location of the class-name in a constructor or 22560b57cec5SDimitry Andric /// destructor. 22570b57cec5SDimitry Andric /// 22580b57cec5SDimitry Andric /// \param EnteringContext whether we're entering the scope of the 22590b57cec5SDimitry Andric /// nested-name-specifier. 22600b57cec5SDimitry Andric /// 22610b57cec5SDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 22620b57cec5SDimitry Andric /// expression, the type of the base object whose member is being accessed. 22630b57cec5SDimitry Andric /// 22640b57cec5SDimitry Andric /// \param Id as input, describes the template-name or operator-function-id 22650b57cec5SDimitry Andric /// that precedes the '<'. If template arguments were parsed successfully, 22660b57cec5SDimitry Andric /// will be updated with the template-id. 22670b57cec5SDimitry Andric /// 22680b57cec5SDimitry Andric /// \param AssumeTemplateId When true, this routine will assume that the name 22690b57cec5SDimitry Andric /// refers to a template without performing name lookup to verify. 22700b57cec5SDimitry Andric /// 22710b57cec5SDimitry Andric /// \returns true if a parse error occurred, false otherwise. 22720b57cec5SDimitry Andric bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 22730b57cec5SDimitry Andric SourceLocation TemplateKWLoc, 22740b57cec5SDimitry Andric IdentifierInfo *Name, 22750b57cec5SDimitry Andric SourceLocation NameLoc, 22760b57cec5SDimitry Andric bool EnteringContext, 22770b57cec5SDimitry Andric ParsedType ObjectType, 22780b57cec5SDimitry Andric UnqualifiedId &Id, 22790b57cec5SDimitry Andric bool AssumeTemplateId) { 22800b57cec5SDimitry Andric assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id"); 22810b57cec5SDimitry Andric 22820b57cec5SDimitry Andric TemplateTy Template; 22830b57cec5SDimitry Andric TemplateNameKind TNK = TNK_Non_template; 22840b57cec5SDimitry Andric switch (Id.getKind()) { 22850b57cec5SDimitry Andric case UnqualifiedIdKind::IK_Identifier: 22860b57cec5SDimitry Andric case UnqualifiedIdKind::IK_OperatorFunctionId: 22870b57cec5SDimitry Andric case UnqualifiedIdKind::IK_LiteralOperatorId: 22880b57cec5SDimitry Andric if (AssumeTemplateId) { 22890b57cec5SDimitry Andric // We defer the injected-class-name checks until we've found whether 22900b57cec5SDimitry Andric // this template-id is used to form a nested-name-specifier or not. 22910b57cec5SDimitry Andric TNK = Actions.ActOnDependentTemplateName( 22920b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext, 22930b57cec5SDimitry Andric Template, /*AllowInjectedClassName*/ true); 22940b57cec5SDimitry Andric if (TNK == TNK_Non_template) 22950b57cec5SDimitry Andric return true; 22960b57cec5SDimitry Andric } else { 22970b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 22980b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, 22990b57cec5SDimitry Andric TemplateKWLoc.isValid(), Id, 23000b57cec5SDimitry Andric ObjectType, EnteringContext, Template, 23010b57cec5SDimitry Andric MemberOfUnknownSpecialization); 23020b57cec5SDimitry Andric // If lookup found nothing but we're assuming that this is a template 23030b57cec5SDimitry Andric // name, double-check that makes sense syntactically before committing 23040b57cec5SDimitry Andric // to it. 23050b57cec5SDimitry Andric if (TNK == TNK_Undeclared_template && 23060b57cec5SDimitry Andric isTemplateArgumentList(0) == TPResult::False) 23070b57cec5SDimitry Andric return false; 23080b57cec5SDimitry Andric 23090b57cec5SDimitry Andric if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && 23100b57cec5SDimitry Andric ObjectType && isTemplateArgumentList(0) == TPResult::True) { 23110b57cec5SDimitry Andric // We have something like t->getAs<T>(), where getAs is a 23120b57cec5SDimitry Andric // member of an unknown specialization. However, this will only 23130b57cec5SDimitry Andric // parse correctly as a template, so suggest the keyword 'template' 23140b57cec5SDimitry Andric // before 'getAs' and treat this as a dependent template name. 23150b57cec5SDimitry Andric std::string Name; 23160b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_Identifier) 23170b57cec5SDimitry Andric Name = Id.Identifier->getName(); 23180b57cec5SDimitry Andric else { 23190b57cec5SDimitry Andric Name = "operator "; 23200b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) 23210b57cec5SDimitry Andric Name += getOperatorSpelling(Id.OperatorFunctionId.Operator); 23220b57cec5SDimitry Andric else 23230b57cec5SDimitry Andric Name += Id.Identifier->getName(); 23240b57cec5SDimitry Andric } 23250b57cec5SDimitry Andric Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) 23260b57cec5SDimitry Andric << Name 23270b57cec5SDimitry Andric << FixItHint::CreateInsertion(Id.StartLocation, "template "); 23280b57cec5SDimitry Andric TNK = Actions.ActOnDependentTemplateName( 23290b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext, 23300b57cec5SDimitry Andric Template, /*AllowInjectedClassName*/ true); 23310b57cec5SDimitry Andric if (TNK == TNK_Non_template) 23320b57cec5SDimitry Andric return true; 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric } 23350b57cec5SDimitry Andric break; 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric case UnqualifiedIdKind::IK_ConstructorName: { 23380b57cec5SDimitry Andric UnqualifiedId TemplateName; 23390b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 23400b57cec5SDimitry Andric TemplateName.setIdentifier(Name, NameLoc); 23410b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 23420b57cec5SDimitry Andric TemplateName, ObjectType, 23430b57cec5SDimitry Andric EnteringContext, Template, 23440b57cec5SDimitry Andric MemberOfUnknownSpecialization); 23450b57cec5SDimitry Andric break; 23460b57cec5SDimitry Andric } 23470b57cec5SDimitry Andric 23480b57cec5SDimitry Andric case UnqualifiedIdKind::IK_DestructorName: { 23490b57cec5SDimitry Andric UnqualifiedId TemplateName; 23500b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 23510b57cec5SDimitry Andric TemplateName.setIdentifier(Name, NameLoc); 23520b57cec5SDimitry Andric if (ObjectType) { 23530b57cec5SDimitry Andric TNK = Actions.ActOnDependentTemplateName( 23540b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType, 23550b57cec5SDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true); 23560b57cec5SDimitry Andric if (TNK == TNK_Non_template) 23570b57cec5SDimitry Andric return true; 23580b57cec5SDimitry Andric } else { 23590b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 23600b57cec5SDimitry Andric TemplateName, ObjectType, 23610b57cec5SDimitry Andric EnteringContext, Template, 23620b57cec5SDimitry Andric MemberOfUnknownSpecialization); 23630b57cec5SDimitry Andric 23640b57cec5SDimitry Andric if (TNK == TNK_Non_template && !Id.DestructorName.get()) { 23650b57cec5SDimitry Andric Diag(NameLoc, diag::err_destructor_template_id) 23660b57cec5SDimitry Andric << Name << SS.getRange(); 23670b57cec5SDimitry Andric return true; 23680b57cec5SDimitry Andric } 23690b57cec5SDimitry Andric } 23700b57cec5SDimitry Andric break; 23710b57cec5SDimitry Andric } 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric default: 23740b57cec5SDimitry Andric return false; 23750b57cec5SDimitry Andric } 23760b57cec5SDimitry Andric 23770b57cec5SDimitry Andric if (TNK == TNK_Non_template) 23780b57cec5SDimitry Andric return false; 23790b57cec5SDimitry Andric 23800b57cec5SDimitry Andric // Parse the enclosed template argument list. 23810b57cec5SDimitry Andric SourceLocation LAngleLoc, RAngleLoc; 23820b57cec5SDimitry Andric TemplateArgList TemplateArgs; 23830b57cec5SDimitry Andric if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, 23840b57cec5SDimitry Andric RAngleLoc)) 23850b57cec5SDimitry Andric return true; 23860b57cec5SDimitry Andric 23870b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_Identifier || 23880b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId || 23890b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) { 23900b57cec5SDimitry Andric // Form a parsed representation of the template-id to be stored in the 23910b57cec5SDimitry Andric // UnqualifiedId. 23920b57cec5SDimitry Andric 23930b57cec5SDimitry Andric // FIXME: Store name for literal operator too. 23940b57cec5SDimitry Andric IdentifierInfo *TemplateII = 23950b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier 23960b57cec5SDimitry Andric : nullptr; 23970b57cec5SDimitry Andric OverloadedOperatorKind OpKind = 23980b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_Identifier 23990b57cec5SDimitry Andric ? OO_None 24000b57cec5SDimitry Andric : Id.OperatorFunctionId.Operator; 24010b57cec5SDimitry Andric 24020b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( 240355e4f9d5SDimitry Andric TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK, 24040b57cec5SDimitry Andric LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds); 24050b57cec5SDimitry Andric 24060b57cec5SDimitry Andric Id.setTemplateId(TemplateId); 24070b57cec5SDimitry Andric return false; 24080b57cec5SDimitry Andric } 24090b57cec5SDimitry Andric 24100b57cec5SDimitry Andric // Bundle the template arguments together. 24110b57cec5SDimitry Andric ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); 24120b57cec5SDimitry Andric 24130b57cec5SDimitry Andric // Constructor and destructor names. 24140b57cec5SDimitry Andric TypeResult Type = Actions.ActOnTemplateIdType( 24150b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc, 24160b57cec5SDimitry Andric TemplateArgsPtr, RAngleLoc, /*IsCtorOrDtorName=*/true); 24170b57cec5SDimitry Andric if (Type.isInvalid()) 24180b57cec5SDimitry Andric return true; 24190b57cec5SDimitry Andric 24200b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName) 24210b57cec5SDimitry Andric Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 24220b57cec5SDimitry Andric else 24230b57cec5SDimitry Andric Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric return false; 24260b57cec5SDimitry Andric } 24270b57cec5SDimitry Andric 24280b57cec5SDimitry Andric /// Parse an operator-function-id or conversion-function-id as part 24290b57cec5SDimitry Andric /// of a C++ unqualified-id. 24300b57cec5SDimitry Andric /// 24310b57cec5SDimitry Andric /// This routine is responsible only for parsing the operator-function-id or 24320b57cec5SDimitry Andric /// conversion-function-id; it does not handle template arguments in any way. 24330b57cec5SDimitry Andric /// 24340b57cec5SDimitry Andric /// \code 24350b57cec5SDimitry Andric /// operator-function-id: [C++ 13.5] 24360b57cec5SDimitry Andric /// 'operator' operator 24370b57cec5SDimitry Andric /// 24380b57cec5SDimitry Andric /// operator: one of 24390b57cec5SDimitry Andric /// new delete new[] delete[] 24400b57cec5SDimitry Andric /// + - * / % ^ & | ~ 24410b57cec5SDimitry Andric /// ! = < > += -= *= /= %= 24420b57cec5SDimitry Andric /// ^= &= |= << >> >>= <<= == != 24430b57cec5SDimitry Andric /// <= >= && || ++ -- , ->* -> 24440b57cec5SDimitry Andric /// () [] <=> 24450b57cec5SDimitry Andric /// 24460b57cec5SDimitry Andric /// conversion-function-id: [C++ 12.3.2] 24470b57cec5SDimitry Andric /// operator conversion-type-id 24480b57cec5SDimitry Andric /// 24490b57cec5SDimitry Andric /// conversion-type-id: 24500b57cec5SDimitry Andric /// type-specifier-seq conversion-declarator[opt] 24510b57cec5SDimitry Andric /// 24520b57cec5SDimitry Andric /// conversion-declarator: 24530b57cec5SDimitry Andric /// ptr-operator conversion-declarator[opt] 24540b57cec5SDimitry Andric /// \endcode 24550b57cec5SDimitry Andric /// 24560b57cec5SDimitry Andric /// \param SS The nested-name-specifier that preceded this unqualified-id. If 24570b57cec5SDimitry Andric /// non-empty, then we are parsing the unqualified-id of a qualified-id. 24580b57cec5SDimitry Andric /// 24590b57cec5SDimitry Andric /// \param EnteringContext whether we are entering the scope of the 24600b57cec5SDimitry Andric /// nested-name-specifier. 24610b57cec5SDimitry Andric /// 24620b57cec5SDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 24630b57cec5SDimitry Andric /// expression, the type of the base object whose member is being accessed. 24640b57cec5SDimitry Andric /// 24650b57cec5SDimitry Andric /// \param Result on a successful parse, contains the parsed unqualified-id. 24660b57cec5SDimitry Andric /// 24670b57cec5SDimitry Andric /// \returns true if parsing fails, false otherwise. 24680b57cec5SDimitry Andric bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 24690b57cec5SDimitry Andric ParsedType ObjectType, 24700b57cec5SDimitry Andric UnqualifiedId &Result) { 24710b57cec5SDimitry Andric assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 24720b57cec5SDimitry Andric 24730b57cec5SDimitry Andric // Consume the 'operator' keyword. 24740b57cec5SDimitry Andric SourceLocation KeywordLoc = ConsumeToken(); 24750b57cec5SDimitry Andric 24760b57cec5SDimitry Andric // Determine what kind of operator name we have. 24770b57cec5SDimitry Andric unsigned SymbolIdx = 0; 24780b57cec5SDimitry Andric SourceLocation SymbolLocations[3]; 24790b57cec5SDimitry Andric OverloadedOperatorKind Op = OO_None; 24800b57cec5SDimitry Andric switch (Tok.getKind()) { 24810b57cec5SDimitry Andric case tok::kw_new: 24820b57cec5SDimitry Andric case tok::kw_delete: { 24830b57cec5SDimitry Andric bool isNew = Tok.getKind() == tok::kw_new; 24840b57cec5SDimitry Andric // Consume the 'new' or 'delete'. 24850b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = ConsumeToken(); 24860b57cec5SDimitry Andric // Check for array new/delete. 24870b57cec5SDimitry Andric if (Tok.is(tok::l_square) && 24880b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) { 24890b57cec5SDimitry Andric // Consume the '[' and ']'. 24900b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 24910b57cec5SDimitry Andric T.consumeOpen(); 24920b57cec5SDimitry Andric T.consumeClose(); 24930b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 24940b57cec5SDimitry Andric return true; 24950b57cec5SDimitry Andric 24960b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 24970b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 24980b57cec5SDimitry Andric Op = isNew? OO_Array_New : OO_Array_Delete; 24990b57cec5SDimitry Andric } else { 25000b57cec5SDimitry Andric Op = isNew? OO_New : OO_Delete; 25010b57cec5SDimitry Andric } 25020b57cec5SDimitry Andric break; 25030b57cec5SDimitry Andric } 25040b57cec5SDimitry Andric 25050b57cec5SDimitry Andric #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 25060b57cec5SDimitry Andric case tok::Token: \ 25070b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 25080b57cec5SDimitry Andric Op = OO_##Name; \ 25090b57cec5SDimitry Andric break; 25100b57cec5SDimitry Andric #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 25110b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.def" 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andric case tok::l_paren: { 25140b57cec5SDimitry Andric // Consume the '(' and ')'. 25150b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 25160b57cec5SDimitry Andric T.consumeOpen(); 25170b57cec5SDimitry Andric T.consumeClose(); 25180b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 25190b57cec5SDimitry Andric return true; 25200b57cec5SDimitry Andric 25210b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 25220b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 25230b57cec5SDimitry Andric Op = OO_Call; 25240b57cec5SDimitry Andric break; 25250b57cec5SDimitry Andric } 25260b57cec5SDimitry Andric 25270b57cec5SDimitry Andric case tok::l_square: { 25280b57cec5SDimitry Andric // Consume the '[' and ']'. 25290b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 25300b57cec5SDimitry Andric T.consumeOpen(); 25310b57cec5SDimitry Andric T.consumeClose(); 25320b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 25330b57cec5SDimitry Andric return true; 25340b57cec5SDimitry Andric 25350b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 25360b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 25370b57cec5SDimitry Andric Op = OO_Subscript; 25380b57cec5SDimitry Andric break; 25390b57cec5SDimitry Andric } 25400b57cec5SDimitry Andric 25410b57cec5SDimitry Andric case tok::code_completion: { 25420b57cec5SDimitry Andric // Code completion for the operator name. 25430b57cec5SDimitry Andric Actions.CodeCompleteOperatorName(getCurScope()); 25440b57cec5SDimitry Andric cutOffParsing(); 25450b57cec5SDimitry Andric // Don't try to parse any further. 25460b57cec5SDimitry Andric return true; 25470b57cec5SDimitry Andric } 25480b57cec5SDimitry Andric 25490b57cec5SDimitry Andric default: 25500b57cec5SDimitry Andric break; 25510b57cec5SDimitry Andric } 25520b57cec5SDimitry Andric 25530b57cec5SDimitry Andric if (Op != OO_None) { 25540b57cec5SDimitry Andric // We have parsed an operator-function-id. 25550b57cec5SDimitry Andric Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 25560b57cec5SDimitry Andric return false; 25570b57cec5SDimitry Andric } 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric // Parse a literal-operator-id. 25600b57cec5SDimitry Andric // 25610b57cec5SDimitry Andric // literal-operator-id: C++11 [over.literal] 25620b57cec5SDimitry Andric // operator string-literal identifier 25630b57cec5SDimitry Andric // operator user-defined-string-literal 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) { 25660b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); 25670b57cec5SDimitry Andric 25680b57cec5SDimitry Andric SourceLocation DiagLoc; 25690b57cec5SDimitry Andric unsigned DiagId = 0; 25700b57cec5SDimitry Andric 25710b57cec5SDimitry Andric // We're past translation phase 6, so perform string literal concatenation 25720b57cec5SDimitry Andric // before checking for "". 25730b57cec5SDimitry Andric SmallVector<Token, 4> Toks; 25740b57cec5SDimitry Andric SmallVector<SourceLocation, 4> TokLocs; 25750b57cec5SDimitry Andric while (isTokenStringLiteral()) { 25760b57cec5SDimitry Andric if (!Tok.is(tok::string_literal) && !DiagId) { 25770b57cec5SDimitry Andric // C++11 [over.literal]p1: 25780b57cec5SDimitry Andric // The string-literal or user-defined-string-literal in a 25790b57cec5SDimitry Andric // literal-operator-id shall have no encoding-prefix [...]. 25800b57cec5SDimitry Andric DiagLoc = Tok.getLocation(); 25810b57cec5SDimitry Andric DiagId = diag::err_literal_operator_string_prefix; 25820b57cec5SDimitry Andric } 25830b57cec5SDimitry Andric Toks.push_back(Tok); 25840b57cec5SDimitry Andric TokLocs.push_back(ConsumeStringToken()); 25850b57cec5SDimitry Andric } 25860b57cec5SDimitry Andric 25870b57cec5SDimitry Andric StringLiteralParser Literal(Toks, PP); 25880b57cec5SDimitry Andric if (Literal.hadError) 25890b57cec5SDimitry Andric return true; 25900b57cec5SDimitry Andric 25910b57cec5SDimitry Andric // Grab the literal operator's suffix, which will be either the next token 25920b57cec5SDimitry Andric // or a ud-suffix from the string literal. 25930b57cec5SDimitry Andric IdentifierInfo *II = nullptr; 25940b57cec5SDimitry Andric SourceLocation SuffixLoc; 25950b57cec5SDimitry Andric if (!Literal.getUDSuffix().empty()) { 25960b57cec5SDimitry Andric II = &PP.getIdentifierTable().get(Literal.getUDSuffix()); 25970b57cec5SDimitry Andric SuffixLoc = 25980b57cec5SDimitry Andric Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()], 25990b57cec5SDimitry Andric Literal.getUDSuffixOffset(), 26000b57cec5SDimitry Andric PP.getSourceManager(), getLangOpts()); 26010b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 26020b57cec5SDimitry Andric II = Tok.getIdentifierInfo(); 26030b57cec5SDimitry Andric SuffixLoc = ConsumeToken(); 26040b57cec5SDimitry Andric TokLocs.push_back(SuffixLoc); 26050b57cec5SDimitry Andric } else { 26060b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::identifier; 26070b57cec5SDimitry Andric return true; 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric 26100b57cec5SDimitry Andric // The string literal must be empty. 26110b57cec5SDimitry Andric if (!Literal.GetString().empty() || Literal.Pascal) { 26120b57cec5SDimitry Andric // C++11 [over.literal]p1: 26130b57cec5SDimitry Andric // The string-literal or user-defined-string-literal in a 26140b57cec5SDimitry Andric // literal-operator-id shall [...] contain no characters 26150b57cec5SDimitry Andric // other than the implicit terminating '\0'. 26160b57cec5SDimitry Andric DiagLoc = TokLocs.front(); 26170b57cec5SDimitry Andric DiagId = diag::err_literal_operator_string_not_empty; 26180b57cec5SDimitry Andric } 26190b57cec5SDimitry Andric 26200b57cec5SDimitry Andric if (DiagId) { 26210b57cec5SDimitry Andric // This isn't a valid literal-operator-id, but we think we know 26220b57cec5SDimitry Andric // what the user meant. Tell them what they should have written. 26230b57cec5SDimitry Andric SmallString<32> Str; 26240b57cec5SDimitry Andric Str += "\"\""; 26250b57cec5SDimitry Andric Str += II->getName(); 26260b57cec5SDimitry Andric Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement( 26270b57cec5SDimitry Andric SourceRange(TokLocs.front(), TokLocs.back()), Str); 26280b57cec5SDimitry Andric } 26290b57cec5SDimitry Andric 26300b57cec5SDimitry Andric Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc); 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric return Actions.checkLiteralOperatorId(SS, Result); 26330b57cec5SDimitry Andric } 26340b57cec5SDimitry Andric 26350b57cec5SDimitry Andric // Parse a conversion-function-id. 26360b57cec5SDimitry Andric // 26370b57cec5SDimitry Andric // conversion-function-id: [C++ 12.3.2] 26380b57cec5SDimitry Andric // operator conversion-type-id 26390b57cec5SDimitry Andric // 26400b57cec5SDimitry Andric // conversion-type-id: 26410b57cec5SDimitry Andric // type-specifier-seq conversion-declarator[opt] 26420b57cec5SDimitry Andric // 26430b57cec5SDimitry Andric // conversion-declarator: 26440b57cec5SDimitry Andric // ptr-operator conversion-declarator[opt] 26450b57cec5SDimitry Andric 26460b57cec5SDimitry Andric // Parse the type-specifier-seq. 26470b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 26480b57cec5SDimitry Andric if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? 26490b57cec5SDimitry Andric return true; 26500b57cec5SDimitry Andric 26510b57cec5SDimitry Andric // Parse the conversion-declarator, which is merely a sequence of 26520b57cec5SDimitry Andric // ptr-operators. 26530b57cec5SDimitry Andric Declarator D(DS, DeclaratorContext::ConversionIdContext); 26540b57cec5SDimitry Andric ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr); 26550b57cec5SDimitry Andric 26560b57cec5SDimitry Andric // Finish up the type. 26570b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); 26580b57cec5SDimitry Andric if (Ty.isInvalid()) 26590b57cec5SDimitry Andric return true; 26600b57cec5SDimitry Andric 26610b57cec5SDimitry Andric // Note that this is a conversion-function-id. 26620b57cec5SDimitry Andric Result.setConversionFunctionId(KeywordLoc, Ty.get(), 26630b57cec5SDimitry Andric D.getSourceRange().getEnd()); 26640b57cec5SDimitry Andric return false; 26650b57cec5SDimitry Andric } 26660b57cec5SDimitry Andric 26670b57cec5SDimitry Andric /// Parse a C++ unqualified-id (or a C identifier), which describes the 26680b57cec5SDimitry Andric /// name of an entity. 26690b57cec5SDimitry Andric /// 26700b57cec5SDimitry Andric /// \code 26710b57cec5SDimitry Andric /// unqualified-id: [C++ expr.prim.general] 26720b57cec5SDimitry Andric /// identifier 26730b57cec5SDimitry Andric /// operator-function-id 26740b57cec5SDimitry Andric /// conversion-function-id 26750b57cec5SDimitry Andric /// [C++0x] literal-operator-id [TODO] 26760b57cec5SDimitry Andric /// ~ class-name 26770b57cec5SDimitry Andric /// template-id 26780b57cec5SDimitry Andric /// 26790b57cec5SDimitry Andric /// \endcode 26800b57cec5SDimitry Andric /// 26810b57cec5SDimitry Andric /// \param SS The nested-name-specifier that preceded this unqualified-id. If 26820b57cec5SDimitry Andric /// non-empty, then we are parsing the unqualified-id of a qualified-id. 26830b57cec5SDimitry Andric /// 26840b57cec5SDimitry Andric /// \param EnteringContext whether we are entering the scope of the 26850b57cec5SDimitry Andric /// nested-name-specifier. 26860b57cec5SDimitry Andric /// 26870b57cec5SDimitry Andric /// \param AllowDestructorName whether we allow parsing of a destructor name. 26880b57cec5SDimitry Andric /// 26890b57cec5SDimitry Andric /// \param AllowConstructorName whether we allow parsing a constructor name. 26900b57cec5SDimitry Andric /// 26910b57cec5SDimitry Andric /// \param AllowDeductionGuide whether we allow parsing a deduction guide name. 26920b57cec5SDimitry Andric /// 26930b57cec5SDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 26940b57cec5SDimitry Andric /// expression, the type of the base object whose member is being accessed. 26950b57cec5SDimitry Andric /// 26960b57cec5SDimitry Andric /// \param Result on a successful parse, contains the parsed unqualified-id. 26970b57cec5SDimitry Andric /// 26980b57cec5SDimitry Andric /// \returns true if parsing fails, false otherwise. 26990b57cec5SDimitry Andric bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 27000b57cec5SDimitry Andric bool AllowDestructorName, 27010b57cec5SDimitry Andric bool AllowConstructorName, 27020b57cec5SDimitry Andric bool AllowDeductionGuide, 27030b57cec5SDimitry Andric ParsedType ObjectType, 27040b57cec5SDimitry Andric SourceLocation *TemplateKWLoc, 27050b57cec5SDimitry Andric UnqualifiedId &Result) { 27060b57cec5SDimitry Andric if (TemplateKWLoc) 27070b57cec5SDimitry Andric *TemplateKWLoc = SourceLocation(); 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andric // Handle 'A::template B'. This is for template-ids which have not 27100b57cec5SDimitry Andric // already been annotated by ParseOptionalCXXScopeSpecifier(). 27110b57cec5SDimitry Andric bool TemplateSpecified = false; 27120b57cec5SDimitry Andric if (Tok.is(tok::kw_template)) { 27130b57cec5SDimitry Andric if (TemplateKWLoc && (ObjectType || SS.isSet())) { 27140b57cec5SDimitry Andric TemplateSpecified = true; 27150b57cec5SDimitry Andric *TemplateKWLoc = ConsumeToken(); 27160b57cec5SDimitry Andric } else { 27170b57cec5SDimitry Andric SourceLocation TemplateLoc = ConsumeToken(); 27180b57cec5SDimitry Andric Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) 27190b57cec5SDimitry Andric << FixItHint::CreateRemoval(TemplateLoc); 27200b57cec5SDimitry Andric } 27210b57cec5SDimitry Andric } 27220b57cec5SDimitry Andric 27230b57cec5SDimitry Andric // unqualified-id: 27240b57cec5SDimitry Andric // identifier 27250b57cec5SDimitry Andric // template-id (when it hasn't already been annotated) 27260b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 27270b57cec5SDimitry Andric // Consume the identifier. 27280b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 27290b57cec5SDimitry Andric SourceLocation IdLoc = ConsumeToken(); 27300b57cec5SDimitry Andric 27310b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 27320b57cec5SDimitry Andric // If we're not in C++, only identifiers matter. Record the 27330b57cec5SDimitry Andric // identifier and return. 27340b57cec5SDimitry Andric Result.setIdentifier(Id, IdLoc); 27350b57cec5SDimitry Andric return false; 27360b57cec5SDimitry Andric } 27370b57cec5SDimitry Andric 27380b57cec5SDimitry Andric ParsedTemplateTy TemplateName; 27390b57cec5SDimitry Andric if (AllowConstructorName && 27400b57cec5SDimitry Andric Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { 27410b57cec5SDimitry Andric // We have parsed a constructor name. 27420b57cec5SDimitry Andric ParsedType Ty = Actions.getConstructorName(*Id, IdLoc, getCurScope(), SS, 27430b57cec5SDimitry Andric EnteringContext); 27440b57cec5SDimitry Andric if (!Ty) 27450b57cec5SDimitry Andric return true; 27460b57cec5SDimitry Andric Result.setConstructorName(Ty, IdLoc, IdLoc); 27470b57cec5SDimitry Andric } else if (getLangOpts().CPlusPlus17 && 27480b57cec5SDimitry Andric AllowDeductionGuide && SS.isEmpty() && 27490b57cec5SDimitry Andric Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc, 27500b57cec5SDimitry Andric &TemplateName)) { 27510b57cec5SDimitry Andric // We have parsed a template-name naming a deduction guide. 27520b57cec5SDimitry Andric Result.setDeductionGuideName(TemplateName, IdLoc); 27530b57cec5SDimitry Andric } else { 27540b57cec5SDimitry Andric // We have parsed an identifier. 27550b57cec5SDimitry Andric Result.setIdentifier(Id, IdLoc); 27560b57cec5SDimitry Andric } 27570b57cec5SDimitry Andric 27580b57cec5SDimitry Andric // If the next token is a '<', we may have a template. 27590b57cec5SDimitry Andric TemplateTy Template; 27600b57cec5SDimitry Andric if (Tok.is(tok::less)) 27610b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 27620b57cec5SDimitry Andric SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, 27630b57cec5SDimitry Andric EnteringContext, ObjectType, Result, TemplateSpecified); 27640b57cec5SDimitry Andric else if (TemplateSpecified && 27650b57cec5SDimitry Andric Actions.ActOnDependentTemplateName( 27660b57cec5SDimitry Andric getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, 27670b57cec5SDimitry Andric EnteringContext, Template, 27680b57cec5SDimitry Andric /*AllowInjectedClassName*/ true) == TNK_Non_template) 27690b57cec5SDimitry Andric return true; 27700b57cec5SDimitry Andric 27710b57cec5SDimitry Andric return false; 27720b57cec5SDimitry Andric } 27730b57cec5SDimitry Andric 27740b57cec5SDimitry Andric // unqualified-id: 27750b57cec5SDimitry Andric // template-id (already parsed and annotated) 27760b57cec5SDimitry Andric if (Tok.is(tok::annot_template_id)) { 27770b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric // If the template-name names the current class, then this is a constructor 27800b57cec5SDimitry Andric if (AllowConstructorName && TemplateId->Name && 27810b57cec5SDimitry Andric Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 27820b57cec5SDimitry Andric if (SS.isSet()) { 27830b57cec5SDimitry Andric // C++ [class.qual]p2 specifies that a qualified template-name 27840b57cec5SDimitry Andric // is taken as the constructor name where a constructor can be 27850b57cec5SDimitry Andric // declared. Thus, the template arguments are extraneous, so 27860b57cec5SDimitry Andric // complain about them and remove them entirely. 27870b57cec5SDimitry Andric Diag(TemplateId->TemplateNameLoc, 27880b57cec5SDimitry Andric diag::err_out_of_line_constructor_template_id) 27890b57cec5SDimitry Andric << TemplateId->Name 27900b57cec5SDimitry Andric << FixItHint::CreateRemoval( 27910b57cec5SDimitry Andric SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 27920b57cec5SDimitry Andric ParsedType Ty = Actions.getConstructorName( 27930b57cec5SDimitry Andric *TemplateId->Name, TemplateId->TemplateNameLoc, getCurScope(), SS, 27940b57cec5SDimitry Andric EnteringContext); 27950b57cec5SDimitry Andric if (!Ty) 27960b57cec5SDimitry Andric return true; 27970b57cec5SDimitry Andric Result.setConstructorName(Ty, TemplateId->TemplateNameLoc, 27980b57cec5SDimitry Andric TemplateId->RAngleLoc); 27990b57cec5SDimitry Andric ConsumeAnnotationToken(); 28000b57cec5SDimitry Andric return false; 28010b57cec5SDimitry Andric } 28020b57cec5SDimitry Andric 28030b57cec5SDimitry Andric Result.setConstructorTemplateId(TemplateId); 28040b57cec5SDimitry Andric ConsumeAnnotationToken(); 28050b57cec5SDimitry Andric return false; 28060b57cec5SDimitry Andric } 28070b57cec5SDimitry Andric 28080b57cec5SDimitry Andric // We have already parsed a template-id; consume the annotation token as 28090b57cec5SDimitry Andric // our unqualified-id. 28100b57cec5SDimitry Andric Result.setTemplateId(TemplateId); 28110b57cec5SDimitry Andric SourceLocation TemplateLoc = TemplateId->TemplateKWLoc; 28120b57cec5SDimitry Andric if (TemplateLoc.isValid()) { 28130b57cec5SDimitry Andric if (TemplateKWLoc && (ObjectType || SS.isSet())) 28140b57cec5SDimitry Andric *TemplateKWLoc = TemplateLoc; 28150b57cec5SDimitry Andric else 28160b57cec5SDimitry Andric Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) 28170b57cec5SDimitry Andric << FixItHint::CreateRemoval(TemplateLoc); 28180b57cec5SDimitry Andric } 28190b57cec5SDimitry Andric ConsumeAnnotationToken(); 28200b57cec5SDimitry Andric return false; 28210b57cec5SDimitry Andric } 28220b57cec5SDimitry Andric 28230b57cec5SDimitry Andric // unqualified-id: 28240b57cec5SDimitry Andric // operator-function-id 28250b57cec5SDimitry Andric // conversion-function-id 28260b57cec5SDimitry Andric if (Tok.is(tok::kw_operator)) { 28270b57cec5SDimitry Andric if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 28280b57cec5SDimitry Andric return true; 28290b57cec5SDimitry Andric 28300b57cec5SDimitry Andric // If we have an operator-function-id or a literal-operator-id and the next 28310b57cec5SDimitry Andric // token is a '<', we may have a 28320b57cec5SDimitry Andric // 28330b57cec5SDimitry Andric // template-id: 28340b57cec5SDimitry Andric // operator-function-id < template-argument-list[opt] > 28350b57cec5SDimitry Andric TemplateTy Template; 28360b57cec5SDimitry Andric if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId || 28370b57cec5SDimitry Andric Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) && 28380b57cec5SDimitry Andric Tok.is(tok::less)) 28390b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 28400b57cec5SDimitry Andric SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr, 28410b57cec5SDimitry Andric SourceLocation(), EnteringContext, ObjectType, Result, 28420b57cec5SDimitry Andric TemplateSpecified); 28430b57cec5SDimitry Andric else if (TemplateSpecified && 28440b57cec5SDimitry Andric Actions.ActOnDependentTemplateName( 28450b57cec5SDimitry Andric getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, 28460b57cec5SDimitry Andric EnteringContext, Template, 28470b57cec5SDimitry Andric /*AllowInjectedClassName*/ true) == TNK_Non_template) 28480b57cec5SDimitry Andric return true; 28490b57cec5SDimitry Andric 28500b57cec5SDimitry Andric return false; 28510b57cec5SDimitry Andric } 28520b57cec5SDimitry Andric 28530b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && 28540b57cec5SDimitry Andric (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 28550b57cec5SDimitry Andric // C++ [expr.unary.op]p10: 28560b57cec5SDimitry Andric // There is an ambiguity in the unary-expression ~X(), where X is a 28570b57cec5SDimitry Andric // class-name. The ambiguity is resolved in favor of treating ~ as a 28580b57cec5SDimitry Andric // unary complement rather than treating ~X as referring to a destructor. 28590b57cec5SDimitry Andric 28600b57cec5SDimitry Andric // Parse the '~'. 28610b57cec5SDimitry Andric SourceLocation TildeLoc = ConsumeToken(); 28620b57cec5SDimitry Andric 28630b57cec5SDimitry Andric if (SS.isEmpty() && Tok.is(tok::kw_decltype)) { 28640b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 28650b57cec5SDimitry Andric SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 28660b57cec5SDimitry Andric if (ParsedType Type = 28670b57cec5SDimitry Andric Actions.getDestructorTypeForDecltype(DS, ObjectType)) { 28680b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, Type, EndLoc); 28690b57cec5SDimitry Andric return false; 28700b57cec5SDimitry Andric } 28710b57cec5SDimitry Andric return true; 28720b57cec5SDimitry Andric } 28730b57cec5SDimitry Andric 28740b57cec5SDimitry Andric // Parse the class-name. 28750b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 28760b57cec5SDimitry Andric Diag(Tok, diag::err_destructor_tilde_identifier); 28770b57cec5SDimitry Andric return true; 28780b57cec5SDimitry Andric } 28790b57cec5SDimitry Andric 28800b57cec5SDimitry Andric // If the user wrote ~T::T, correct it to T::~T. 28810b57cec5SDimitry Andric DeclaratorScopeObj DeclScopeObj(*this, SS); 28820b57cec5SDimitry Andric if (!TemplateSpecified && NextToken().is(tok::coloncolon)) { 28830b57cec5SDimitry Andric // Don't let ParseOptionalCXXScopeSpecifier() "correct" 28840b57cec5SDimitry Andric // `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`, 28850b57cec5SDimitry Andric // it will confuse this recovery logic. 28860b57cec5SDimitry Andric ColonProtectionRAIIObject ColonRAII(*this, false); 28870b57cec5SDimitry Andric 28880b57cec5SDimitry Andric if (SS.isSet()) { 28890b57cec5SDimitry Andric AnnotateScopeToken(SS, /*NewAnnotation*/true); 28900b57cec5SDimitry Andric SS.clear(); 28910b57cec5SDimitry Andric } 28920b57cec5SDimitry Andric if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, EnteringContext)) 28930b57cec5SDimitry Andric return true; 28940b57cec5SDimitry Andric if (SS.isNotEmpty()) 28950b57cec5SDimitry Andric ObjectType = nullptr; 28960b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) || 28970b57cec5SDimitry Andric !SS.isSet()) { 28980b57cec5SDimitry Andric Diag(TildeLoc, diag::err_destructor_tilde_scope); 28990b57cec5SDimitry Andric return true; 29000b57cec5SDimitry Andric } 29010b57cec5SDimitry Andric 29020b57cec5SDimitry Andric // Recover as if the tilde had been written before the identifier. 29030b57cec5SDimitry Andric Diag(TildeLoc, diag::err_destructor_tilde_scope) 29040b57cec5SDimitry Andric << FixItHint::CreateRemoval(TildeLoc) 29050b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "~"); 29060b57cec5SDimitry Andric 29070b57cec5SDimitry Andric // Temporarily enter the scope for the rest of this function. 29080b57cec5SDimitry Andric if (Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 29090b57cec5SDimitry Andric DeclScopeObj.EnterDeclaratorScope(); 29100b57cec5SDimitry Andric } 29110b57cec5SDimitry Andric 29120b57cec5SDimitry Andric // Parse the class-name (or template-name in a simple-template-id). 29130b57cec5SDimitry Andric IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 29140b57cec5SDimitry Andric SourceLocation ClassNameLoc = ConsumeToken(); 29150b57cec5SDimitry Andric 29160b57cec5SDimitry Andric if (Tok.is(tok::less)) { 29170b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc); 29180b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 29190b57cec5SDimitry Andric SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName, 29200b57cec5SDimitry Andric ClassNameLoc, EnteringContext, ObjectType, Result, TemplateSpecified); 29210b57cec5SDimitry Andric } 29220b57cec5SDimitry Andric 29230b57cec5SDimitry Andric // Note that this is a destructor name. 29240b57cec5SDimitry Andric ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 29250b57cec5SDimitry Andric ClassNameLoc, getCurScope(), 29260b57cec5SDimitry Andric SS, ObjectType, 29270b57cec5SDimitry Andric EnteringContext); 29280b57cec5SDimitry Andric if (!Ty) 29290b57cec5SDimitry Andric return true; 29300b57cec5SDimitry Andric 29310b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 29320b57cec5SDimitry Andric return false; 29330b57cec5SDimitry Andric } 29340b57cec5SDimitry Andric 29350b57cec5SDimitry Andric Diag(Tok, diag::err_expected_unqualified_id) 29360b57cec5SDimitry Andric << getLangOpts().CPlusPlus; 29370b57cec5SDimitry Andric return true; 29380b57cec5SDimitry Andric } 29390b57cec5SDimitry Andric 29400b57cec5SDimitry Andric /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 29410b57cec5SDimitry Andric /// memory in a typesafe manner and call constructors. 29420b57cec5SDimitry Andric /// 29430b57cec5SDimitry Andric /// This method is called to parse the new expression after the optional :: has 29440b57cec5SDimitry Andric /// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 29450b57cec5SDimitry Andric /// is its location. Otherwise, "Start" is the location of the 'new' token. 29460b57cec5SDimitry Andric /// 29470b57cec5SDimitry Andric /// new-expression: 29480b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 29490b57cec5SDimitry Andric /// new-initializer[opt] 29500b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 29510b57cec5SDimitry Andric /// new-initializer[opt] 29520b57cec5SDimitry Andric /// 29530b57cec5SDimitry Andric /// new-placement: 29540b57cec5SDimitry Andric /// '(' expression-list ')' 29550b57cec5SDimitry Andric /// 29560b57cec5SDimitry Andric /// new-type-id: 29570b57cec5SDimitry Andric /// type-specifier-seq new-declarator[opt] 29580b57cec5SDimitry Andric /// [GNU] attributes type-specifier-seq new-declarator[opt] 29590b57cec5SDimitry Andric /// 29600b57cec5SDimitry Andric /// new-declarator: 29610b57cec5SDimitry Andric /// ptr-operator new-declarator[opt] 29620b57cec5SDimitry Andric /// direct-new-declarator 29630b57cec5SDimitry Andric /// 29640b57cec5SDimitry Andric /// new-initializer: 29650b57cec5SDimitry Andric /// '(' expression-list[opt] ')' 29660b57cec5SDimitry Andric /// [C++0x] braced-init-list 29670b57cec5SDimitry Andric /// 29680b57cec5SDimitry Andric ExprResult 29690b57cec5SDimitry Andric Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 29700b57cec5SDimitry Andric assert(Tok.is(tok::kw_new) && "expected 'new' token"); 29710b57cec5SDimitry Andric ConsumeToken(); // Consume 'new' 29720b57cec5SDimitry Andric 29730b57cec5SDimitry Andric // A '(' now can be a new-placement or the '(' wrapping the type-id in the 29740b57cec5SDimitry Andric // second form of new-expression. It can't be a new-type-id. 29750b57cec5SDimitry Andric 29760b57cec5SDimitry Andric ExprVector PlacementArgs; 29770b57cec5SDimitry Andric SourceLocation PlacementLParen, PlacementRParen; 29780b57cec5SDimitry Andric 29790b57cec5SDimitry Andric SourceRange TypeIdParens; 29800b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 29810b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::CXXNewContext); 29820b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 29830b57cec5SDimitry Andric // If it turns out to be a placement, we change the type location. 29840b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 29850b57cec5SDimitry Andric T.consumeOpen(); 29860b57cec5SDimitry Andric PlacementLParen = T.getOpenLocation(); 29870b57cec5SDimitry Andric if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 29880b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 29890b57cec5SDimitry Andric return ExprError(); 29900b57cec5SDimitry Andric } 29910b57cec5SDimitry Andric 29920b57cec5SDimitry Andric T.consumeClose(); 29930b57cec5SDimitry Andric PlacementRParen = T.getCloseLocation(); 29940b57cec5SDimitry Andric if (PlacementRParen.isInvalid()) { 29950b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 29960b57cec5SDimitry Andric return ExprError(); 29970b57cec5SDimitry Andric } 29980b57cec5SDimitry Andric 29990b57cec5SDimitry Andric if (PlacementArgs.empty()) { 30000b57cec5SDimitry Andric // Reset the placement locations. There was no placement. 30010b57cec5SDimitry Andric TypeIdParens = T.getRange(); 30020b57cec5SDimitry Andric PlacementLParen = PlacementRParen = SourceLocation(); 30030b57cec5SDimitry Andric } else { 30040b57cec5SDimitry Andric // We still need the type. 30050b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 30060b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 30070b57cec5SDimitry Andric T.consumeOpen(); 30080b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 30090b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 30100b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 30110b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 30120b57cec5SDimitry Andric T.consumeClose(); 30130b57cec5SDimitry Andric TypeIdParens = T.getRange(); 30140b57cec5SDimitry Andric } else { 30150b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 30160b57cec5SDimitry Andric if (ParseCXXTypeSpecifierSeq(DS)) 30170b57cec5SDimitry Andric DeclaratorInfo.setInvalidType(true); 30180b57cec5SDimitry Andric else { 30190b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 30200b57cec5SDimitry Andric ParseDeclaratorInternal(DeclaratorInfo, 30210b57cec5SDimitry Andric &Parser::ParseDirectNewDeclarator); 30220b57cec5SDimitry Andric } 30230b57cec5SDimitry Andric } 30240b57cec5SDimitry Andric } 30250b57cec5SDimitry Andric } else { 30260b57cec5SDimitry Andric // A new-type-id is a simplified type-id, where essentially the 30270b57cec5SDimitry Andric // direct-declarator is replaced by a direct-new-declarator. 30280b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 30290b57cec5SDimitry Andric if (ParseCXXTypeSpecifierSeq(DS)) 30300b57cec5SDimitry Andric DeclaratorInfo.setInvalidType(true); 30310b57cec5SDimitry Andric else { 30320b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 30330b57cec5SDimitry Andric ParseDeclaratorInternal(DeclaratorInfo, 30340b57cec5SDimitry Andric &Parser::ParseDirectNewDeclarator); 30350b57cec5SDimitry Andric } 30360b57cec5SDimitry Andric } 30370b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) { 30380b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 30390b57cec5SDimitry Andric return ExprError(); 30400b57cec5SDimitry Andric } 30410b57cec5SDimitry Andric 30420b57cec5SDimitry Andric ExprResult Initializer; 30430b57cec5SDimitry Andric 30440b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 30450b57cec5SDimitry Andric SourceLocation ConstructorLParen, ConstructorRParen; 30460b57cec5SDimitry Andric ExprVector ConstructorArgs; 30470b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 30480b57cec5SDimitry Andric T.consumeOpen(); 30490b57cec5SDimitry Andric ConstructorLParen = T.getOpenLocation(); 30500b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 30510b57cec5SDimitry Andric CommaLocsTy CommaLocs; 30520b57cec5SDimitry Andric auto RunSignatureHelp = [&]() { 30530b57cec5SDimitry Andric ParsedType TypeRep = 30540b57cec5SDimitry Andric Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); 3055480093f4SDimitry Andric assert(TypeRep && "invalid types should be handled before"); 30560b57cec5SDimitry Andric QualType PreferredType = Actions.ProduceConstructorSignatureHelp( 30570b57cec5SDimitry Andric getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), 30580b57cec5SDimitry Andric DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); 30590b57cec5SDimitry Andric CalledSignatureHelp = true; 30600b57cec5SDimitry Andric return PreferredType; 30610b57cec5SDimitry Andric }; 30620b57cec5SDimitry Andric if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] { 30630b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 30640b57cec5SDimitry Andric RunSignatureHelp); 30650b57cec5SDimitry Andric })) { 30660b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 30670b57cec5SDimitry Andric RunSignatureHelp(); 30680b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 30690b57cec5SDimitry Andric return ExprError(); 30700b57cec5SDimitry Andric } 30710b57cec5SDimitry Andric } 30720b57cec5SDimitry Andric T.consumeClose(); 30730b57cec5SDimitry Andric ConstructorRParen = T.getCloseLocation(); 30740b57cec5SDimitry Andric if (ConstructorRParen.isInvalid()) { 30750b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 30760b57cec5SDimitry Andric return ExprError(); 30770b57cec5SDimitry Andric } 30780b57cec5SDimitry Andric Initializer = Actions.ActOnParenListExpr(ConstructorLParen, 30790b57cec5SDimitry Andric ConstructorRParen, 30800b57cec5SDimitry Andric ConstructorArgs); 30810b57cec5SDimitry Andric } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) { 30820b57cec5SDimitry Andric Diag(Tok.getLocation(), 30830b57cec5SDimitry Andric diag::warn_cxx98_compat_generalized_initializer_lists); 30840b57cec5SDimitry Andric Initializer = ParseBraceInitializer(); 30850b57cec5SDimitry Andric } 30860b57cec5SDimitry Andric if (Initializer.isInvalid()) 30870b57cec5SDimitry Andric return Initializer; 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 30900b57cec5SDimitry Andric PlacementArgs, PlacementRParen, 30910b57cec5SDimitry Andric TypeIdParens, DeclaratorInfo, Initializer.get()); 30920b57cec5SDimitry Andric } 30930b57cec5SDimitry Andric 30940b57cec5SDimitry Andric /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 30950b57cec5SDimitry Andric /// passed to ParseDeclaratorInternal. 30960b57cec5SDimitry Andric /// 30970b57cec5SDimitry Andric /// direct-new-declarator: 30980b57cec5SDimitry Andric /// '[' expression[opt] ']' 30990b57cec5SDimitry Andric /// direct-new-declarator '[' constant-expression ']' 31000b57cec5SDimitry Andric /// 31010b57cec5SDimitry Andric void Parser::ParseDirectNewDeclarator(Declarator &D) { 31020b57cec5SDimitry Andric // Parse the array dimensions. 31030b57cec5SDimitry Andric bool First = true; 31040b57cec5SDimitry Andric while (Tok.is(tok::l_square)) { 31050b57cec5SDimitry Andric // An array-size expression can't start with a lambda. 31060b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 31070b57cec5SDimitry Andric continue; 31080b57cec5SDimitry Andric 31090b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 31100b57cec5SDimitry Andric T.consumeOpen(); 31110b57cec5SDimitry Andric 31120b57cec5SDimitry Andric ExprResult Size = 31130b57cec5SDimitry Andric First ? (Tok.is(tok::r_square) ? ExprResult() : ParseExpression()) 31140b57cec5SDimitry Andric : ParseConstantExpression(); 31150b57cec5SDimitry Andric if (Size.isInvalid()) { 31160b57cec5SDimitry Andric // Recover 31170b57cec5SDimitry Andric SkipUntil(tok::r_square, StopAtSemi); 31180b57cec5SDimitry Andric return; 31190b57cec5SDimitry Andric } 31200b57cec5SDimitry Andric First = false; 31210b57cec5SDimitry Andric 31220b57cec5SDimitry Andric T.consumeClose(); 31230b57cec5SDimitry Andric 31240b57cec5SDimitry Andric // Attributes here appertain to the array type. C++11 [expr.new]p5. 31250b57cec5SDimitry Andric ParsedAttributes Attrs(AttrFactory); 31260b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attrs); 31270b57cec5SDimitry Andric 31280b57cec5SDimitry Andric D.AddTypeInfo(DeclaratorChunk::getArray(0, 31290b57cec5SDimitry Andric /*isStatic=*/false, /*isStar=*/false, 31300b57cec5SDimitry Andric Size.get(), T.getOpenLocation(), 31310b57cec5SDimitry Andric T.getCloseLocation()), 31320b57cec5SDimitry Andric std::move(Attrs), T.getCloseLocation()); 31330b57cec5SDimitry Andric 31340b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 31350b57cec5SDimitry Andric return; 31360b57cec5SDimitry Andric } 31370b57cec5SDimitry Andric } 31380b57cec5SDimitry Andric 31390b57cec5SDimitry Andric /// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 31400b57cec5SDimitry Andric /// This ambiguity appears in the syntax of the C++ new operator. 31410b57cec5SDimitry Andric /// 31420b57cec5SDimitry Andric /// new-expression: 31430b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 31440b57cec5SDimitry Andric /// new-initializer[opt] 31450b57cec5SDimitry Andric /// 31460b57cec5SDimitry Andric /// new-placement: 31470b57cec5SDimitry Andric /// '(' expression-list ')' 31480b57cec5SDimitry Andric /// 31490b57cec5SDimitry Andric bool Parser::ParseExpressionListOrTypeId( 31500b57cec5SDimitry Andric SmallVectorImpl<Expr*> &PlacementArgs, 31510b57cec5SDimitry Andric Declarator &D) { 31520b57cec5SDimitry Andric // The '(' was already consumed. 31530b57cec5SDimitry Andric if (isTypeIdInParens()) { 31540b57cec5SDimitry Andric ParseSpecifierQualifierList(D.getMutableDeclSpec()); 31550b57cec5SDimitry Andric D.SetSourceRange(D.getDeclSpec().getSourceRange()); 31560b57cec5SDimitry Andric ParseDeclarator(D); 31570b57cec5SDimitry Andric return D.isInvalidType(); 31580b57cec5SDimitry Andric } 31590b57cec5SDimitry Andric 31600b57cec5SDimitry Andric // It's not a type, it has to be an expression list. 31610b57cec5SDimitry Andric // Discard the comma locations - ActOnCXXNew has enough parameters. 31620b57cec5SDimitry Andric CommaLocsTy CommaLocs; 31630b57cec5SDimitry Andric return ParseExpressionList(PlacementArgs, CommaLocs); 31640b57cec5SDimitry Andric } 31650b57cec5SDimitry Andric 31660b57cec5SDimitry Andric /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 31670b57cec5SDimitry Andric /// to free memory allocated by new. 31680b57cec5SDimitry Andric /// 31690b57cec5SDimitry Andric /// This method is called to parse the 'delete' expression after the optional 31700b57cec5SDimitry Andric /// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 31710b57cec5SDimitry Andric /// and "Start" is its location. Otherwise, "Start" is the location of the 31720b57cec5SDimitry Andric /// 'delete' token. 31730b57cec5SDimitry Andric /// 31740b57cec5SDimitry Andric /// delete-expression: 31750b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 31760b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 31770b57cec5SDimitry Andric ExprResult 31780b57cec5SDimitry Andric Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 31790b57cec5SDimitry Andric assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 31800b57cec5SDimitry Andric ConsumeToken(); // Consume 'delete' 31810b57cec5SDimitry Andric 31820b57cec5SDimitry Andric // Array delete? 31830b57cec5SDimitry Andric bool ArrayDelete = false; 31840b57cec5SDimitry Andric if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) { 31850b57cec5SDimitry Andric // C++11 [expr.delete]p1: 31860b57cec5SDimitry Andric // Whenever the delete keyword is followed by empty square brackets, it 31870b57cec5SDimitry Andric // shall be interpreted as [array delete]. 31880b57cec5SDimitry Andric // [Footnote: A lambda expression with a lambda-introducer that consists 31890b57cec5SDimitry Andric // of empty square brackets can follow the delete keyword if 31900b57cec5SDimitry Andric // the lambda expression is enclosed in parentheses.] 31910b57cec5SDimitry Andric 31920b57cec5SDimitry Andric const Token Next = GetLookAheadToken(2); 31930b57cec5SDimitry Andric 31940b57cec5SDimitry Andric // Basic lookahead to check if we have a lambda expression. 31950b57cec5SDimitry Andric if (Next.isOneOf(tok::l_brace, tok::less) || 31960b57cec5SDimitry Andric (Next.is(tok::l_paren) && 31970b57cec5SDimitry Andric (GetLookAheadToken(3).is(tok::r_paren) || 31980b57cec5SDimitry Andric (GetLookAheadToken(3).is(tok::identifier) && 31990b57cec5SDimitry Andric GetLookAheadToken(4).is(tok::identifier))))) { 32000b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 32010b57cec5SDimitry Andric SourceLocation LSquareLoc = Tok.getLocation(); 32020b57cec5SDimitry Andric SourceLocation RSquareLoc = NextToken().getLocation(); 32030b57cec5SDimitry Andric 32040b57cec5SDimitry Andric // SkipUntil can't skip pairs of </*...*/>; don't emit a FixIt in this 32050b57cec5SDimitry Andric // case. 32060b57cec5SDimitry Andric SkipUntil({tok::l_brace, tok::less}, StopBeforeMatch); 32070b57cec5SDimitry Andric SourceLocation RBraceLoc; 32080b57cec5SDimitry Andric bool EmitFixIt = false; 32090b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 32100b57cec5SDimitry Andric ConsumeBrace(); 32110b57cec5SDimitry Andric SkipUntil(tok::r_brace, StopBeforeMatch); 32120b57cec5SDimitry Andric RBraceLoc = Tok.getLocation(); 32130b57cec5SDimitry Andric EmitFixIt = true; 32140b57cec5SDimitry Andric } 32150b57cec5SDimitry Andric 32160b57cec5SDimitry Andric TPA.Revert(); 32170b57cec5SDimitry Andric 32180b57cec5SDimitry Andric if (EmitFixIt) 32190b57cec5SDimitry Andric Diag(Start, diag::err_lambda_after_delete) 32200b57cec5SDimitry Andric << SourceRange(Start, RSquareLoc) 32210b57cec5SDimitry Andric << FixItHint::CreateInsertion(LSquareLoc, "(") 32220b57cec5SDimitry Andric << FixItHint::CreateInsertion( 32230b57cec5SDimitry Andric Lexer::getLocForEndOfToken( 32240b57cec5SDimitry Andric RBraceLoc, 0, Actions.getSourceManager(), getLangOpts()), 32250b57cec5SDimitry Andric ")"); 32260b57cec5SDimitry Andric else 32270b57cec5SDimitry Andric Diag(Start, diag::err_lambda_after_delete) 32280b57cec5SDimitry Andric << SourceRange(Start, RSquareLoc); 32290b57cec5SDimitry Andric 32300b57cec5SDimitry Andric // Warn that the non-capturing lambda isn't surrounded by parentheses 32310b57cec5SDimitry Andric // to disambiguate it from 'delete[]'. 32320b57cec5SDimitry Andric ExprResult Lambda = ParseLambdaExpression(); 32330b57cec5SDimitry Andric if (Lambda.isInvalid()) 32340b57cec5SDimitry Andric return ExprError(); 32350b57cec5SDimitry Andric 32360b57cec5SDimitry Andric // Evaluate any postfix expressions used on the lambda. 32370b57cec5SDimitry Andric Lambda = ParsePostfixExpressionSuffix(Lambda); 32380b57cec5SDimitry Andric if (Lambda.isInvalid()) 32390b57cec5SDimitry Andric return ExprError(); 32400b57cec5SDimitry Andric return Actions.ActOnCXXDelete(Start, UseGlobal, /*ArrayForm=*/false, 32410b57cec5SDimitry Andric Lambda.get()); 32420b57cec5SDimitry Andric } 32430b57cec5SDimitry Andric 32440b57cec5SDimitry Andric ArrayDelete = true; 32450b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 32460b57cec5SDimitry Andric 32470b57cec5SDimitry Andric T.consumeOpen(); 32480b57cec5SDimitry Andric T.consumeClose(); 32490b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 32500b57cec5SDimitry Andric return ExprError(); 32510b57cec5SDimitry Andric } 32520b57cec5SDimitry Andric 3253480093f4SDimitry Andric ExprResult Operand(ParseCastExpression(AnyCastExpr)); 32540b57cec5SDimitry Andric if (Operand.isInvalid()) 32550b57cec5SDimitry Andric return Operand; 32560b57cec5SDimitry Andric 32570b57cec5SDimitry Andric return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get()); 32580b57cec5SDimitry Andric } 32590b57cec5SDimitry Andric 326055e4f9d5SDimitry Andric /// ParseRequiresExpression - Parse a C++2a requires-expression. 326155e4f9d5SDimitry Andric /// C++2a [expr.prim.req]p1 326255e4f9d5SDimitry Andric /// A requires-expression provides a concise way to express requirements on 326355e4f9d5SDimitry Andric /// template arguments. A requirement is one that can be checked by name 326455e4f9d5SDimitry Andric /// lookup (6.4) or by checking properties of types and expressions. 326555e4f9d5SDimitry Andric /// 326655e4f9d5SDimitry Andric /// requires-expression: 326755e4f9d5SDimitry Andric /// 'requires' requirement-parameter-list[opt] requirement-body 326855e4f9d5SDimitry Andric /// 326955e4f9d5SDimitry Andric /// requirement-parameter-list: 327055e4f9d5SDimitry Andric /// '(' parameter-declaration-clause[opt] ')' 327155e4f9d5SDimitry Andric /// 327255e4f9d5SDimitry Andric /// requirement-body: 327355e4f9d5SDimitry Andric /// '{' requirement-seq '}' 327455e4f9d5SDimitry Andric /// 327555e4f9d5SDimitry Andric /// requirement-seq: 327655e4f9d5SDimitry Andric /// requirement 327755e4f9d5SDimitry Andric /// requirement-seq requirement 327855e4f9d5SDimitry Andric /// 327955e4f9d5SDimitry Andric /// requirement: 328055e4f9d5SDimitry Andric /// simple-requirement 328155e4f9d5SDimitry Andric /// type-requirement 328255e4f9d5SDimitry Andric /// compound-requirement 328355e4f9d5SDimitry Andric /// nested-requirement 328455e4f9d5SDimitry Andric ExprResult Parser::ParseRequiresExpression() { 328555e4f9d5SDimitry Andric assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword"); 328655e4f9d5SDimitry Andric SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires' 328755e4f9d5SDimitry Andric 328855e4f9d5SDimitry Andric llvm::SmallVector<ParmVarDecl *, 2> LocalParameterDecls; 328955e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) { 329055e4f9d5SDimitry Andric // requirement parameter list is present. 329155e4f9d5SDimitry Andric ParseScope LocalParametersScope(this, Scope::FunctionPrototypeScope | 329255e4f9d5SDimitry Andric Scope::DeclScope); 329355e4f9d5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 329455e4f9d5SDimitry Andric Parens.consumeOpen(); 329555e4f9d5SDimitry Andric if (!Tok.is(tok::r_paren)) { 329655e4f9d5SDimitry Andric ParsedAttributes FirstArgAttrs(getAttrFactory()); 329755e4f9d5SDimitry Andric SourceLocation EllipsisLoc; 329855e4f9d5SDimitry Andric llvm::SmallVector<DeclaratorChunk::ParamInfo, 2> LocalParameters; 329955e4f9d5SDimitry Andric DiagnosticErrorTrap Trap(Diags); 330055e4f9d5SDimitry Andric ParseParameterDeclarationClause(DeclaratorContext::RequiresExprContext, 330155e4f9d5SDimitry Andric FirstArgAttrs, LocalParameters, 330255e4f9d5SDimitry Andric EllipsisLoc); 330355e4f9d5SDimitry Andric if (EllipsisLoc.isValid()) 330455e4f9d5SDimitry Andric Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis); 330555e4f9d5SDimitry Andric for (auto &ParamInfo : LocalParameters) 330655e4f9d5SDimitry Andric LocalParameterDecls.push_back(cast<ParmVarDecl>(ParamInfo.Param)); 330755e4f9d5SDimitry Andric if (Trap.hasErrorOccurred()) 330855e4f9d5SDimitry Andric SkipUntil(tok::r_paren, StopBeforeMatch); 330955e4f9d5SDimitry Andric } 331055e4f9d5SDimitry Andric Parens.consumeClose(); 331155e4f9d5SDimitry Andric } 331255e4f9d5SDimitry Andric 331355e4f9d5SDimitry Andric BalancedDelimiterTracker Braces(*this, tok::l_brace); 331455e4f9d5SDimitry Andric if (Braces.expectAndConsume()) 331555e4f9d5SDimitry Andric return ExprError(); 331655e4f9d5SDimitry Andric 331755e4f9d5SDimitry Andric // Start of requirement list 331855e4f9d5SDimitry Andric llvm::SmallVector<concepts::Requirement *, 2> Requirements; 331955e4f9d5SDimitry Andric 332055e4f9d5SDimitry Andric // C++2a [expr.prim.req]p2 332155e4f9d5SDimitry Andric // Expressions appearing within a requirement-body are unevaluated operands. 332255e4f9d5SDimitry Andric EnterExpressionEvaluationContext Ctx( 332355e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 332455e4f9d5SDimitry Andric 332555e4f9d5SDimitry Andric ParseScope BodyScope(this, Scope::DeclScope); 332655e4f9d5SDimitry Andric RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr( 332755e4f9d5SDimitry Andric RequiresKWLoc, LocalParameterDecls, getCurScope()); 332855e4f9d5SDimitry Andric 332955e4f9d5SDimitry Andric if (Tok.is(tok::r_brace)) { 333055e4f9d5SDimitry Andric // Grammar does not allow an empty body. 333155e4f9d5SDimitry Andric // requirement-body: 333255e4f9d5SDimitry Andric // { requirement-seq } 333355e4f9d5SDimitry Andric // requirement-seq: 333455e4f9d5SDimitry Andric // requirement 333555e4f9d5SDimitry Andric // requirement-seq requirement 333655e4f9d5SDimitry Andric Diag(Tok, diag::err_empty_requires_expr); 333755e4f9d5SDimitry Andric // Continue anyway and produce a requires expr with no requirements. 333855e4f9d5SDimitry Andric } else { 333955e4f9d5SDimitry Andric while (!Tok.is(tok::r_brace)) { 334055e4f9d5SDimitry Andric switch (Tok.getKind()) { 334155e4f9d5SDimitry Andric case tok::l_brace: { 334255e4f9d5SDimitry Andric // Compound requirement 334355e4f9d5SDimitry Andric // C++ [expr.prim.req.compound] 334455e4f9d5SDimitry Andric // compound-requirement: 334555e4f9d5SDimitry Andric // '{' expression '}' 'noexcept'[opt] 334655e4f9d5SDimitry Andric // return-type-requirement[opt] ';' 334755e4f9d5SDimitry Andric // return-type-requirement: 334855e4f9d5SDimitry Andric // trailing-return-type 334955e4f9d5SDimitry Andric // '->' cv-qualifier-seq[opt] constrained-parameter 335055e4f9d5SDimitry Andric // cv-qualifier-seq[opt] abstract-declarator[opt] 335155e4f9d5SDimitry Andric BalancedDelimiterTracker ExprBraces(*this, tok::l_brace); 335255e4f9d5SDimitry Andric ExprBraces.consumeOpen(); 335355e4f9d5SDimitry Andric ExprResult Expression = 335455e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 335555e4f9d5SDimitry Andric if (!Expression.isUsable()) { 335655e4f9d5SDimitry Andric ExprBraces.skipToEnd(); 335755e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 335855e4f9d5SDimitry Andric break; 335955e4f9d5SDimitry Andric } 336055e4f9d5SDimitry Andric if (ExprBraces.consumeClose()) 336155e4f9d5SDimitry Andric ExprBraces.skipToEnd(); 336255e4f9d5SDimitry Andric 336355e4f9d5SDimitry Andric concepts::Requirement *Req = nullptr; 336455e4f9d5SDimitry Andric SourceLocation NoexceptLoc; 336555e4f9d5SDimitry Andric TryConsumeToken(tok::kw_noexcept, NoexceptLoc); 336655e4f9d5SDimitry Andric if (Tok.is(tok::semi)) { 336755e4f9d5SDimitry Andric Req = Actions.ActOnCompoundRequirement(Expression.get(), NoexceptLoc); 336855e4f9d5SDimitry Andric if (Req) 336955e4f9d5SDimitry Andric Requirements.push_back(Req); 337055e4f9d5SDimitry Andric break; 337155e4f9d5SDimitry Andric } 337255e4f9d5SDimitry Andric if (!TryConsumeToken(tok::arrow)) 337355e4f9d5SDimitry Andric // User probably forgot the arrow, remind them and try to continue. 337455e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_missing_arrow) 337555e4f9d5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "->"); 337655e4f9d5SDimitry Andric // Try to parse a 'type-constraint' 337755e4f9d5SDimitry Andric if (TryAnnotateTypeConstraint()) { 337855e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 337955e4f9d5SDimitry Andric break; 338055e4f9d5SDimitry Andric } 338155e4f9d5SDimitry Andric if (!isTypeConstraintAnnotation()) { 338255e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_expected_type_constraint); 338355e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 338455e4f9d5SDimitry Andric break; 338555e4f9d5SDimitry Andric } 3386*13138422SDimitry Andric CXXScopeSpec SS; 3387*13138422SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 3388*13138422SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 3389*13138422SDimitry Andric Tok.getAnnotationRange(), 3390*13138422SDimitry Andric SS); 339155e4f9d5SDimitry Andric ConsumeAnnotationToken(); 3392*13138422SDimitry Andric } 339355e4f9d5SDimitry Andric 339455e4f9d5SDimitry Andric Req = Actions.ActOnCompoundRequirement( 339555e4f9d5SDimitry Andric Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok), 339655e4f9d5SDimitry Andric TemplateParameterDepth); 339755e4f9d5SDimitry Andric ConsumeAnnotationToken(); 339855e4f9d5SDimitry Andric if (Req) 339955e4f9d5SDimitry Andric Requirements.push_back(Req); 340055e4f9d5SDimitry Andric break; 340155e4f9d5SDimitry Andric } 340255e4f9d5SDimitry Andric default: { 340355e4f9d5SDimitry Andric bool PossibleRequiresExprInSimpleRequirement = false; 340455e4f9d5SDimitry Andric if (Tok.is(tok::kw_requires)) { 340555e4f9d5SDimitry Andric auto IsNestedRequirement = [&] { 340655e4f9d5SDimitry Andric RevertingTentativeParsingAction TPA(*this); 340755e4f9d5SDimitry Andric ConsumeToken(); // 'requires' 340855e4f9d5SDimitry Andric if (Tok.is(tok::l_brace)) 340955e4f9d5SDimitry Andric // This is a requires expression 341055e4f9d5SDimitry Andric // requires (T t) { 341155e4f9d5SDimitry Andric // requires { t++; }; 341255e4f9d5SDimitry Andric // ... ^ 341355e4f9d5SDimitry Andric // } 341455e4f9d5SDimitry Andric return false; 341555e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) { 341655e4f9d5SDimitry Andric // This might be the parameter list of a requires expression 341755e4f9d5SDimitry Andric ConsumeParen(); 341855e4f9d5SDimitry Andric auto Res = TryParseParameterDeclarationClause(); 341955e4f9d5SDimitry Andric if (Res != TPResult::False) { 342055e4f9d5SDimitry Andric // Skip to the closing parenthesis 342155e4f9d5SDimitry Andric // FIXME: Don't traverse these tokens twice (here and in 342255e4f9d5SDimitry Andric // TryParseParameterDeclarationClause). 342355e4f9d5SDimitry Andric unsigned Depth = 1; 342455e4f9d5SDimitry Andric while (Depth != 0) { 342555e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) 342655e4f9d5SDimitry Andric Depth++; 342755e4f9d5SDimitry Andric else if (Tok.is(tok::r_paren)) 342855e4f9d5SDimitry Andric Depth--; 342955e4f9d5SDimitry Andric ConsumeAnyToken(); 343055e4f9d5SDimitry Andric } 343155e4f9d5SDimitry Andric // requires (T t) { 343255e4f9d5SDimitry Andric // requires () ? 343355e4f9d5SDimitry Andric // ... ^ 343455e4f9d5SDimitry Andric // - OR - 343555e4f9d5SDimitry Andric // requires (int x) ? 343655e4f9d5SDimitry Andric // ... ^ 343755e4f9d5SDimitry Andric // } 343855e4f9d5SDimitry Andric if (Tok.is(tok::l_brace)) 343955e4f9d5SDimitry Andric // requires (...) { 344055e4f9d5SDimitry Andric // ^ - a requires expression as a 344155e4f9d5SDimitry Andric // simple-requirement. 344255e4f9d5SDimitry Andric return false; 344355e4f9d5SDimitry Andric } 344455e4f9d5SDimitry Andric } 344555e4f9d5SDimitry Andric return true; 344655e4f9d5SDimitry Andric }; 344755e4f9d5SDimitry Andric if (IsNestedRequirement()) { 344855e4f9d5SDimitry Andric ConsumeToken(); 344955e4f9d5SDimitry Andric // Nested requirement 345055e4f9d5SDimitry Andric // C++ [expr.prim.req.nested] 345155e4f9d5SDimitry Andric // nested-requirement: 345255e4f9d5SDimitry Andric // 'requires' constraint-expression ';' 345355e4f9d5SDimitry Andric ExprResult ConstraintExpr = 345455e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); 345555e4f9d5SDimitry Andric if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) { 345655e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, 345755e4f9d5SDimitry Andric SkipUntilFlags::StopBeforeMatch); 345855e4f9d5SDimitry Andric break; 345955e4f9d5SDimitry Andric } 346055e4f9d5SDimitry Andric if (auto *Req = 346155e4f9d5SDimitry Andric Actions.ActOnNestedRequirement(ConstraintExpr.get())) 346255e4f9d5SDimitry Andric Requirements.push_back(Req); 346355e4f9d5SDimitry Andric else { 346455e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, 346555e4f9d5SDimitry Andric SkipUntilFlags::StopBeforeMatch); 346655e4f9d5SDimitry Andric break; 346755e4f9d5SDimitry Andric } 346855e4f9d5SDimitry Andric break; 346955e4f9d5SDimitry Andric } else 347055e4f9d5SDimitry Andric PossibleRequiresExprInSimpleRequirement = true; 347155e4f9d5SDimitry Andric } else if (Tok.is(tok::kw_typename)) { 347255e4f9d5SDimitry Andric // This might be 'typename T::value_type;' (a type requirement) or 347355e4f9d5SDimitry Andric // 'typename T::value_type{};' (a simple requirement). 347455e4f9d5SDimitry Andric TentativeParsingAction TPA(*this); 347555e4f9d5SDimitry Andric 347655e4f9d5SDimitry Andric // We need to consume the typename to allow 'requires { typename a; }' 347755e4f9d5SDimitry Andric SourceLocation TypenameKWLoc = ConsumeToken(); 347855e4f9d5SDimitry Andric if (TryAnnotateCXXScopeToken()) { 3479*13138422SDimitry Andric TPA.Commit(); 348055e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 348155e4f9d5SDimitry Andric break; 348255e4f9d5SDimitry Andric } 348355e4f9d5SDimitry Andric CXXScopeSpec SS; 348455e4f9d5SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 348555e4f9d5SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation( 348655e4f9d5SDimitry Andric Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS); 348755e4f9d5SDimitry Andric ConsumeAnnotationToken(); 348855e4f9d5SDimitry Andric } 348955e4f9d5SDimitry Andric 349055e4f9d5SDimitry Andric if (Tok.isOneOf(tok::identifier, tok::annot_template_id) && 349155e4f9d5SDimitry Andric !NextToken().isOneOf(tok::l_brace, tok::l_paren)) { 349255e4f9d5SDimitry Andric TPA.Commit(); 349355e4f9d5SDimitry Andric SourceLocation NameLoc = Tok.getLocation(); 349455e4f9d5SDimitry Andric IdentifierInfo *II = nullptr; 349555e4f9d5SDimitry Andric TemplateIdAnnotation *TemplateId = nullptr; 349655e4f9d5SDimitry Andric if (Tok.is(tok::identifier)) { 349755e4f9d5SDimitry Andric II = Tok.getIdentifierInfo(); 349855e4f9d5SDimitry Andric ConsumeToken(); 349955e4f9d5SDimitry Andric } else { 350055e4f9d5SDimitry Andric TemplateId = takeTemplateIdAnnotation(Tok); 350155e4f9d5SDimitry Andric ConsumeAnnotationToken(); 350255e4f9d5SDimitry Andric } 350355e4f9d5SDimitry Andric 350455e4f9d5SDimitry Andric if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS, 350555e4f9d5SDimitry Andric NameLoc, II, 350655e4f9d5SDimitry Andric TemplateId)) { 350755e4f9d5SDimitry Andric Requirements.push_back(Req); 350855e4f9d5SDimitry Andric } 350955e4f9d5SDimitry Andric break; 351055e4f9d5SDimitry Andric } 351155e4f9d5SDimitry Andric TPA.Revert(); 351255e4f9d5SDimitry Andric } 351355e4f9d5SDimitry Andric // Simple requirement 351455e4f9d5SDimitry Andric // C++ [expr.prim.req.simple] 351555e4f9d5SDimitry Andric // simple-requirement: 351655e4f9d5SDimitry Andric // expression ';' 351755e4f9d5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 351855e4f9d5SDimitry Andric ExprResult Expression = 351955e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 352055e4f9d5SDimitry Andric if (!Expression.isUsable()) { 352155e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 352255e4f9d5SDimitry Andric break; 352355e4f9d5SDimitry Andric } 352455e4f9d5SDimitry Andric if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement) 352555e4f9d5SDimitry Andric Diag(StartLoc, diag::warn_requires_expr_in_simple_requirement) 352655e4f9d5SDimitry Andric << FixItHint::CreateInsertion(StartLoc, "requires"); 352755e4f9d5SDimitry Andric if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get())) 352855e4f9d5SDimitry Andric Requirements.push_back(Req); 352955e4f9d5SDimitry Andric else { 353055e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 353155e4f9d5SDimitry Andric break; 353255e4f9d5SDimitry Andric } 353355e4f9d5SDimitry Andric // User may have tried to put some compound requirement stuff here 353455e4f9d5SDimitry Andric if (Tok.is(tok::kw_noexcept)) { 353555e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept) 353655e4f9d5SDimitry Andric << FixItHint::CreateInsertion(StartLoc, "{") 353755e4f9d5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "}"); 353855e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 353955e4f9d5SDimitry Andric break; 354055e4f9d5SDimitry Andric } 354155e4f9d5SDimitry Andric break; 354255e4f9d5SDimitry Andric } 354355e4f9d5SDimitry Andric } 354455e4f9d5SDimitry Andric if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) { 354555e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 354655e4f9d5SDimitry Andric TryConsumeToken(tok::semi); 354755e4f9d5SDimitry Andric break; 354855e4f9d5SDimitry Andric } 354955e4f9d5SDimitry Andric } 355055e4f9d5SDimitry Andric if (Requirements.empty()) { 355155e4f9d5SDimitry Andric // Don't emit an empty requires expr here to avoid confusing the user with 355255e4f9d5SDimitry Andric // other diagnostics quoting an empty requires expression they never 355355e4f9d5SDimitry Andric // wrote. 355455e4f9d5SDimitry Andric Braces.consumeClose(); 355555e4f9d5SDimitry Andric Actions.ActOnFinishRequiresExpr(); 355655e4f9d5SDimitry Andric return ExprError(); 355755e4f9d5SDimitry Andric } 355855e4f9d5SDimitry Andric } 355955e4f9d5SDimitry Andric Braces.consumeClose(); 356055e4f9d5SDimitry Andric Actions.ActOnFinishRequiresExpr(); 356155e4f9d5SDimitry Andric return Actions.ActOnRequiresExpr(RequiresKWLoc, Body, LocalParameterDecls, 356255e4f9d5SDimitry Andric Requirements, Braces.getCloseLocation()); 356355e4f9d5SDimitry Andric } 356455e4f9d5SDimitry Andric 35650b57cec5SDimitry Andric static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) { 35660b57cec5SDimitry Andric switch (kind) { 35670b57cec5SDimitry Andric default: llvm_unreachable("Not a known type trait"); 35680b57cec5SDimitry Andric #define TYPE_TRAIT_1(Spelling, Name, Key) \ 35690b57cec5SDimitry Andric case tok::kw_ ## Spelling: return UTT_ ## Name; 35700b57cec5SDimitry Andric #define TYPE_TRAIT_2(Spelling, Name, Key) \ 35710b57cec5SDimitry Andric case tok::kw_ ## Spelling: return BTT_ ## Name; 35720b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 35730b57cec5SDimitry Andric #define TYPE_TRAIT_N(Spelling, Name, Key) \ 35740b57cec5SDimitry Andric case tok::kw_ ## Spelling: return TT_ ## Name; 35750b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 35760b57cec5SDimitry Andric } 35770b57cec5SDimitry Andric } 35780b57cec5SDimitry Andric 35790b57cec5SDimitry Andric static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { 35800b57cec5SDimitry Andric switch(kind) { 35810b57cec5SDimitry Andric default: llvm_unreachable("Not a known binary type trait"); 35820b57cec5SDimitry Andric case tok::kw___array_rank: return ATT_ArrayRank; 35830b57cec5SDimitry Andric case tok::kw___array_extent: return ATT_ArrayExtent; 35840b57cec5SDimitry Andric } 35850b57cec5SDimitry Andric } 35860b57cec5SDimitry Andric 35870b57cec5SDimitry Andric static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { 35880b57cec5SDimitry Andric switch(kind) { 35890b57cec5SDimitry Andric default: llvm_unreachable("Not a known unary expression trait."); 35900b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: return ET_IsLValueExpr; 35910b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: return ET_IsRValueExpr; 35920b57cec5SDimitry Andric } 35930b57cec5SDimitry Andric } 35940b57cec5SDimitry Andric 35950b57cec5SDimitry Andric static unsigned TypeTraitArity(tok::TokenKind kind) { 35960b57cec5SDimitry Andric switch (kind) { 35970b57cec5SDimitry Andric default: llvm_unreachable("Not a known type trait"); 35980b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) case tok::kw_##Spelling: return N; 35990b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 36000b57cec5SDimitry Andric } 36010b57cec5SDimitry Andric } 36020b57cec5SDimitry Andric 36030b57cec5SDimitry Andric /// Parse the built-in type-trait pseudo-functions that allow 36040b57cec5SDimitry Andric /// implementation of the TR1/C++11 type traits templates. 36050b57cec5SDimitry Andric /// 36060b57cec5SDimitry Andric /// primary-expression: 36070b57cec5SDimitry Andric /// unary-type-trait '(' type-id ')' 36080b57cec5SDimitry Andric /// binary-type-trait '(' type-id ',' type-id ')' 36090b57cec5SDimitry Andric /// type-trait '(' type-id-seq ')' 36100b57cec5SDimitry Andric /// 36110b57cec5SDimitry Andric /// type-id-seq: 36120b57cec5SDimitry Andric /// type-id ...[opt] type-id-seq[opt] 36130b57cec5SDimitry Andric /// 36140b57cec5SDimitry Andric ExprResult Parser::ParseTypeTrait() { 36150b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 36160b57cec5SDimitry Andric unsigned Arity = TypeTraitArity(Kind); 36170b57cec5SDimitry Andric 36180b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 36190b57cec5SDimitry Andric 36200b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 36210b57cec5SDimitry Andric if (Parens.expectAndConsume()) 36220b57cec5SDimitry Andric return ExprError(); 36230b57cec5SDimitry Andric 36240b57cec5SDimitry Andric SmallVector<ParsedType, 2> Args; 36250b57cec5SDimitry Andric do { 36260b57cec5SDimitry Andric // Parse the next type. 36270b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 36280b57cec5SDimitry Andric if (Ty.isInvalid()) { 36290b57cec5SDimitry Andric Parens.skipToEnd(); 36300b57cec5SDimitry Andric return ExprError(); 36310b57cec5SDimitry Andric } 36320b57cec5SDimitry Andric 36330b57cec5SDimitry Andric // Parse the ellipsis, if present. 36340b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) { 36350b57cec5SDimitry Andric Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken()); 36360b57cec5SDimitry Andric if (Ty.isInvalid()) { 36370b57cec5SDimitry Andric Parens.skipToEnd(); 36380b57cec5SDimitry Andric return ExprError(); 36390b57cec5SDimitry Andric } 36400b57cec5SDimitry Andric } 36410b57cec5SDimitry Andric 36420b57cec5SDimitry Andric // Add this type to the list of arguments. 36430b57cec5SDimitry Andric Args.push_back(Ty.get()); 36440b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 36450b57cec5SDimitry Andric 36460b57cec5SDimitry Andric if (Parens.consumeClose()) 36470b57cec5SDimitry Andric return ExprError(); 36480b57cec5SDimitry Andric 36490b57cec5SDimitry Andric SourceLocation EndLoc = Parens.getCloseLocation(); 36500b57cec5SDimitry Andric 36510b57cec5SDimitry Andric if (Arity && Args.size() != Arity) { 36520b57cec5SDimitry Andric Diag(EndLoc, diag::err_type_trait_arity) 36530b57cec5SDimitry Andric << Arity << 0 << (Arity > 1) << (int)Args.size() << SourceRange(Loc); 36540b57cec5SDimitry Andric return ExprError(); 36550b57cec5SDimitry Andric } 36560b57cec5SDimitry Andric 36570b57cec5SDimitry Andric if (!Arity && Args.empty()) { 36580b57cec5SDimitry Andric Diag(EndLoc, diag::err_type_trait_arity) 36590b57cec5SDimitry Andric << 1 << 1 << 1 << (int)Args.size() << SourceRange(Loc); 36600b57cec5SDimitry Andric return ExprError(); 36610b57cec5SDimitry Andric } 36620b57cec5SDimitry Andric 36630b57cec5SDimitry Andric return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc); 36640b57cec5SDimitry Andric } 36650b57cec5SDimitry Andric 36660b57cec5SDimitry Andric /// ParseArrayTypeTrait - Parse the built-in array type-trait 36670b57cec5SDimitry Andric /// pseudo-functions. 36680b57cec5SDimitry Andric /// 36690b57cec5SDimitry Andric /// primary-expression: 36700b57cec5SDimitry Andric /// [Embarcadero] '__array_rank' '(' type-id ')' 36710b57cec5SDimitry Andric /// [Embarcadero] '__array_extent' '(' type-id ',' expression ')' 36720b57cec5SDimitry Andric /// 36730b57cec5SDimitry Andric ExprResult Parser::ParseArrayTypeTrait() { 36740b57cec5SDimitry Andric ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); 36750b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 36760b57cec5SDimitry Andric 36770b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 36780b57cec5SDimitry Andric if (T.expectAndConsume()) 36790b57cec5SDimitry Andric return ExprError(); 36800b57cec5SDimitry Andric 36810b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 36820b57cec5SDimitry Andric if (Ty.isInvalid()) { 36830b57cec5SDimitry Andric SkipUntil(tok::comma, StopAtSemi); 36840b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 36850b57cec5SDimitry Andric return ExprError(); 36860b57cec5SDimitry Andric } 36870b57cec5SDimitry Andric 36880b57cec5SDimitry Andric switch (ATT) { 36890b57cec5SDimitry Andric case ATT_ArrayRank: { 36900b57cec5SDimitry Andric T.consumeClose(); 36910b57cec5SDimitry Andric return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), nullptr, 36920b57cec5SDimitry Andric T.getCloseLocation()); 36930b57cec5SDimitry Andric } 36940b57cec5SDimitry Andric case ATT_ArrayExtent: { 36950b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 36960b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 36970b57cec5SDimitry Andric return ExprError(); 36980b57cec5SDimitry Andric } 36990b57cec5SDimitry Andric 37000b57cec5SDimitry Andric ExprResult DimExpr = ParseExpression(); 37010b57cec5SDimitry Andric T.consumeClose(); 37020b57cec5SDimitry Andric 37030b57cec5SDimitry Andric return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), 37040b57cec5SDimitry Andric T.getCloseLocation()); 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric } 37070b57cec5SDimitry Andric llvm_unreachable("Invalid ArrayTypeTrait!"); 37080b57cec5SDimitry Andric } 37090b57cec5SDimitry Andric 37100b57cec5SDimitry Andric /// ParseExpressionTrait - Parse built-in expression-trait 37110b57cec5SDimitry Andric /// pseudo-functions like __is_lvalue_expr( xxx ). 37120b57cec5SDimitry Andric /// 37130b57cec5SDimitry Andric /// primary-expression: 37140b57cec5SDimitry Andric /// [Embarcadero] expression-trait '(' expression ')' 37150b57cec5SDimitry Andric /// 37160b57cec5SDimitry Andric ExprResult Parser::ParseExpressionTrait() { 37170b57cec5SDimitry Andric ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); 37180b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 37190b57cec5SDimitry Andric 37200b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 37210b57cec5SDimitry Andric if (T.expectAndConsume()) 37220b57cec5SDimitry Andric return ExprError(); 37230b57cec5SDimitry Andric 37240b57cec5SDimitry Andric ExprResult Expr = ParseExpression(); 37250b57cec5SDimitry Andric 37260b57cec5SDimitry Andric T.consumeClose(); 37270b57cec5SDimitry Andric 37280b57cec5SDimitry Andric return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), 37290b57cec5SDimitry Andric T.getCloseLocation()); 37300b57cec5SDimitry Andric } 37310b57cec5SDimitry Andric 37320b57cec5SDimitry Andric 37330b57cec5SDimitry Andric /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 37340b57cec5SDimitry Andric /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 37350b57cec5SDimitry Andric /// based on the context past the parens. 37360b57cec5SDimitry Andric ExprResult 37370b57cec5SDimitry Andric Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 37380b57cec5SDimitry Andric ParsedType &CastTy, 37390b57cec5SDimitry Andric BalancedDelimiterTracker &Tracker, 37400b57cec5SDimitry Andric ColonProtectionRAIIObject &ColonProt) { 37410b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus && "Should only be called for C++!"); 37420b57cec5SDimitry Andric assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 37430b57cec5SDimitry Andric assert(isTypeIdInParens() && "Not a type-id!"); 37440b57cec5SDimitry Andric 37450b57cec5SDimitry Andric ExprResult Result(true); 37460b57cec5SDimitry Andric CastTy = nullptr; 37470b57cec5SDimitry Andric 37480b57cec5SDimitry Andric // We need to disambiguate a very ugly part of the C++ syntax: 37490b57cec5SDimitry Andric // 37500b57cec5SDimitry Andric // (T())x; - type-id 37510b57cec5SDimitry Andric // (T())*x; - type-id 37520b57cec5SDimitry Andric // (T())/x; - expression 37530b57cec5SDimitry Andric // (T()); - expression 37540b57cec5SDimitry Andric // 37550b57cec5SDimitry Andric // The bad news is that we cannot use the specialized tentative parser, since 37560b57cec5SDimitry Andric // it can only verify that the thing inside the parens can be parsed as 37570b57cec5SDimitry Andric // type-id, it is not useful for determining the context past the parens. 37580b57cec5SDimitry Andric // 37590b57cec5SDimitry Andric // The good news is that the parser can disambiguate this part without 37600b57cec5SDimitry Andric // making any unnecessary Action calls. 37610b57cec5SDimitry Andric // 37620b57cec5SDimitry Andric // It uses a scheme similar to parsing inline methods. The parenthesized 37630b57cec5SDimitry Andric // tokens are cached, the context that follows is determined (possibly by 37640b57cec5SDimitry Andric // parsing a cast-expression), and then we re-introduce the cached tokens 37650b57cec5SDimitry Andric // into the token stream and parse them appropriately. 37660b57cec5SDimitry Andric 37670b57cec5SDimitry Andric ParenParseOption ParseAs; 37680b57cec5SDimitry Andric CachedTokens Toks; 37690b57cec5SDimitry Andric 37700b57cec5SDimitry Andric // Store the tokens of the parentheses. We will parse them after we determine 37710b57cec5SDimitry Andric // the context that follows them. 37720b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { 37730b57cec5SDimitry Andric // We didn't find the ')' we expected. 37740b57cec5SDimitry Andric Tracker.consumeClose(); 37750b57cec5SDimitry Andric return ExprError(); 37760b57cec5SDimitry Andric } 37770b57cec5SDimitry Andric 37780b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 37790b57cec5SDimitry Andric ParseAs = CompoundLiteral; 37800b57cec5SDimitry Andric } else { 37810b57cec5SDimitry Andric bool NotCastExpr; 37820b57cec5SDimitry Andric if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 37830b57cec5SDimitry Andric NotCastExpr = true; 37840b57cec5SDimitry Andric } else { 37850b57cec5SDimitry Andric // Try parsing the cast-expression that may follow. 37860b57cec5SDimitry Andric // If it is not a cast-expression, NotCastExpr will be true and no token 37870b57cec5SDimitry Andric // will be consumed. 37880b57cec5SDimitry Andric ColonProt.restore(); 3789480093f4SDimitry Andric Result = ParseCastExpression(AnyCastExpr, 37900b57cec5SDimitry Andric false/*isAddressofOperand*/, 37910b57cec5SDimitry Andric NotCastExpr, 37920b57cec5SDimitry Andric // type-id has priority. 37930b57cec5SDimitry Andric IsTypeCast); 37940b57cec5SDimitry Andric } 37950b57cec5SDimitry Andric 37960b57cec5SDimitry Andric // If we parsed a cast-expression, it's really a type-id, otherwise it's 37970b57cec5SDimitry Andric // an expression. 37980b57cec5SDimitry Andric ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 37990b57cec5SDimitry Andric } 38000b57cec5SDimitry Andric 38010b57cec5SDimitry Andric // Create a fake EOF to mark end of Toks buffer. 38020b57cec5SDimitry Andric Token AttrEnd; 38030b57cec5SDimitry Andric AttrEnd.startToken(); 38040b57cec5SDimitry Andric AttrEnd.setKind(tok::eof); 38050b57cec5SDimitry Andric AttrEnd.setLocation(Tok.getLocation()); 38060b57cec5SDimitry Andric AttrEnd.setEofData(Toks.data()); 38070b57cec5SDimitry Andric Toks.push_back(AttrEnd); 38080b57cec5SDimitry Andric 38090b57cec5SDimitry Andric // The current token should go after the cached tokens. 38100b57cec5SDimitry Andric Toks.push_back(Tok); 38110b57cec5SDimitry Andric // Re-enter the stored parenthesized tokens into the token stream, so we may 38120b57cec5SDimitry Andric // parse them now. 38130b57cec5SDimitry Andric PP.EnterTokenStream(Toks, /*DisableMacroExpansion*/ true, 38140b57cec5SDimitry Andric /*IsReinject*/ true); 38150b57cec5SDimitry Andric // Drop the current token and bring the first cached one. It's the same token 38160b57cec5SDimitry Andric // as when we entered this function. 38170b57cec5SDimitry Andric ConsumeAnyToken(); 38180b57cec5SDimitry Andric 38190b57cec5SDimitry Andric if (ParseAs >= CompoundLiteral) { 38200b57cec5SDimitry Andric // Parse the type declarator. 38210b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 38220b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 38230b57cec5SDimitry Andric { 38240b57cec5SDimitry Andric ColonProtectionRAIIObject InnerColonProtection(*this); 38250b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 38260b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 38270b57cec5SDimitry Andric } 38280b57cec5SDimitry Andric 38290b57cec5SDimitry Andric // Match the ')'. 38300b57cec5SDimitry Andric Tracker.consumeClose(); 38310b57cec5SDimitry Andric ColonProt.restore(); 38320b57cec5SDimitry Andric 38330b57cec5SDimitry Andric // Consume EOF marker for Toks buffer. 38340b57cec5SDimitry Andric assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); 38350b57cec5SDimitry Andric ConsumeAnyToken(); 38360b57cec5SDimitry Andric 38370b57cec5SDimitry Andric if (ParseAs == CompoundLiteral) { 38380b57cec5SDimitry Andric ExprType = CompoundLiteral; 38390b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 38400b57cec5SDimitry Andric return ExprError(); 38410b57cec5SDimitry Andric 38420b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 38430b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), 38440b57cec5SDimitry Andric Tracker.getOpenLocation(), 38450b57cec5SDimitry Andric Tracker.getCloseLocation()); 38460b57cec5SDimitry Andric } 38470b57cec5SDimitry Andric 38480b57cec5SDimitry Andric // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 38490b57cec5SDimitry Andric assert(ParseAs == CastExpr); 38500b57cec5SDimitry Andric 38510b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 38520b57cec5SDimitry Andric return ExprError(); 38530b57cec5SDimitry Andric 38540b57cec5SDimitry Andric // Result is what ParseCastExpression returned earlier. 38550b57cec5SDimitry Andric if (!Result.isInvalid()) 38560b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), 38570b57cec5SDimitry Andric DeclaratorInfo, CastTy, 38580b57cec5SDimitry Andric Tracker.getCloseLocation(), Result.get()); 38590b57cec5SDimitry Andric return Result; 38600b57cec5SDimitry Andric } 38610b57cec5SDimitry Andric 38620b57cec5SDimitry Andric // Not a compound literal, and not followed by a cast-expression. 38630b57cec5SDimitry Andric assert(ParseAs == SimpleExpr); 38640b57cec5SDimitry Andric 38650b57cec5SDimitry Andric ExprType = SimpleExpr; 38660b57cec5SDimitry Andric Result = ParseExpression(); 38670b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 38680b57cec5SDimitry Andric Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 38690b57cec5SDimitry Andric Tok.getLocation(), Result.get()); 38700b57cec5SDimitry Andric 38710b57cec5SDimitry Andric // Match the ')'. 38720b57cec5SDimitry Andric if (Result.isInvalid()) { 38730b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 38740b57cec5SDimitry Andric ConsumeAnyToken(); 38750b57cec5SDimitry Andric assert(Tok.getEofData() == AttrEnd.getEofData()); 38760b57cec5SDimitry Andric ConsumeAnyToken(); 38770b57cec5SDimitry Andric return ExprError(); 38780b57cec5SDimitry Andric } 38790b57cec5SDimitry Andric 38800b57cec5SDimitry Andric Tracker.consumeClose(); 38810b57cec5SDimitry Andric // Consume EOF marker for Toks buffer. 38820b57cec5SDimitry Andric assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); 38830b57cec5SDimitry Andric ConsumeAnyToken(); 38840b57cec5SDimitry Andric return Result; 38850b57cec5SDimitry Andric } 38860b57cec5SDimitry Andric 38870b57cec5SDimitry Andric /// Parse a __builtin_bit_cast(T, E). 38880b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinBitCast() { 38890b57cec5SDimitry Andric SourceLocation KWLoc = ConsumeToken(); 38900b57cec5SDimitry Andric 38910b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 38920b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast")) 38930b57cec5SDimitry Andric return ExprError(); 38940b57cec5SDimitry Andric 38950b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 38960b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 38970b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 38980b57cec5SDimitry Andric 38990b57cec5SDimitry Andric // Parse the abstract-declarator, if present. 39000b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 39010b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 39020b57cec5SDimitry Andric 39030b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 39040b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::comma; 39050b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 39060b57cec5SDimitry Andric return ExprError(); 39070b57cec5SDimitry Andric } 39080b57cec5SDimitry Andric 39090b57cec5SDimitry Andric ExprResult Operand = ParseExpression(); 39100b57cec5SDimitry Andric 39110b57cec5SDimitry Andric if (T.consumeClose()) 39120b57cec5SDimitry Andric return ExprError(); 39130b57cec5SDimitry Andric 39140b57cec5SDimitry Andric if (Operand.isInvalid() || DeclaratorInfo.isInvalidType()) 39150b57cec5SDimitry Andric return ExprError(); 39160b57cec5SDimitry Andric 39170b57cec5SDimitry Andric return Actions.ActOnBuiltinBitCastExpr(KWLoc, DeclaratorInfo, Operand, 39180b57cec5SDimitry Andric T.getCloseLocation()); 39190b57cec5SDimitry Andric } 3920