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/AST/ASTContext.h" 1355e4f9d5SDimitry Andric #include "clang/AST/Decl.h" 140b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 1555e4f9d5SDimitry Andric #include "clang/AST/ExprCXX.h" 160b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 17*0fca6ea1SDimitry Andric #include "clang/Basic/TemplateKinds.h" 18bdd1243dSDimitry Andric #include "clang/Basic/TokenKinds.h" 190b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h" 200b57cec5SDimitry Andric #include "clang/Parse/ParseDiagnostic.h" 21fe6060f1SDimitry Andric #include "clang/Parse/Parser.h" 220b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 230b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 2406c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h" 250b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 260b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 27*0fca6ea1SDimitry Andric #include "clang/Sema/SemaCodeCompletion.h" 28bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h" 290b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 300b57cec5SDimitry Andric #include <numeric> 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric using namespace clang; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric static int SelectDigraphErrorMessage(tok::TokenKind Kind) { 350b57cec5SDimitry Andric switch (Kind) { 360b57cec5SDimitry Andric // template name 370b57cec5SDimitry Andric case tok::unknown: return 0; 380b57cec5SDimitry Andric // casts 395ffd83dbSDimitry Andric case tok::kw_addrspace_cast: return 1; 405ffd83dbSDimitry Andric case tok::kw_const_cast: return 2; 415ffd83dbSDimitry Andric case tok::kw_dynamic_cast: return 3; 425ffd83dbSDimitry Andric case tok::kw_reinterpret_cast: return 4; 435ffd83dbSDimitry Andric case tok::kw_static_cast: return 5; 440b57cec5SDimitry Andric default: 450b57cec5SDimitry Andric llvm_unreachable("Unknown type for digraph error message."); 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // Are the two tokens adjacent in the same source file? 500b57cec5SDimitry Andric bool Parser::areTokensAdjacent(const Token &First, const Token &Second) { 510b57cec5SDimitry Andric SourceManager &SM = PP.getSourceManager(); 520b57cec5SDimitry Andric SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation()); 530b57cec5SDimitry Andric SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength()); 540b57cec5SDimitry Andric return FirstEnd == SM.getSpellingLoc(Second.getLocation()); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // Suggest fixit for "<::" after a cast. 580b57cec5SDimitry Andric static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, 590b57cec5SDimitry Andric Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) { 600b57cec5SDimitry Andric // Pull '<:' and ':' off token stream. 610b57cec5SDimitry Andric if (!AtDigraph) 620b57cec5SDimitry Andric PP.Lex(DigraphToken); 630b57cec5SDimitry Andric PP.Lex(ColonToken); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric SourceRange Range; 660b57cec5SDimitry Andric Range.setBegin(DigraphToken.getLocation()); 670b57cec5SDimitry Andric Range.setEnd(ColonToken.getLocation()); 680b57cec5SDimitry Andric P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph) 690b57cec5SDimitry Andric << SelectDigraphErrorMessage(Kind) 700b57cec5SDimitry Andric << FixItHint::CreateReplacement(Range, "< ::"); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Update token information to reflect their change in token type. 730b57cec5SDimitry Andric ColonToken.setKind(tok::coloncolon); 740b57cec5SDimitry Andric ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1)); 750b57cec5SDimitry Andric ColonToken.setLength(2); 760b57cec5SDimitry Andric DigraphToken.setKind(tok::less); 770b57cec5SDimitry Andric DigraphToken.setLength(1); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric // Push new tokens back to token stream. 800b57cec5SDimitry Andric PP.EnterToken(ColonToken, /*IsReinject*/ true); 810b57cec5SDimitry Andric if (!AtDigraph) 820b57cec5SDimitry Andric PP.EnterToken(DigraphToken, /*IsReinject*/ true); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // Check for '<::' which should be '< ::' instead of '[:' when following 860b57cec5SDimitry Andric // a template name. 870b57cec5SDimitry Andric void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, 880b57cec5SDimitry Andric bool EnteringContext, 890b57cec5SDimitry Andric IdentifierInfo &II, CXXScopeSpec &SS) { 900b57cec5SDimitry Andric if (!Next.is(tok::l_square) || Next.getLength() != 2) 910b57cec5SDimitry Andric return; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric Token SecondToken = GetLookAheadToken(2); 940b57cec5SDimitry Andric if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken)) 950b57cec5SDimitry Andric return; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric TemplateTy Template; 980b57cec5SDimitry Andric UnqualifiedId TemplateName; 990b57cec5SDimitry Andric TemplateName.setIdentifier(&II, Tok.getLocation()); 1000b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 1010b57cec5SDimitry Andric if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, 1020b57cec5SDimitry Andric TemplateName, ObjectType, EnteringContext, 1030b57cec5SDimitry Andric Template, MemberOfUnknownSpecialization)) 1040b57cec5SDimitry Andric return; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric FixDigraph(*this, PP, Next, SecondToken, tok::unknown, 1070b57cec5SDimitry Andric /*AtDigraph*/false); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// Parse global scope or nested-name-specifier if present. 1110b57cec5SDimitry Andric /// 1120b57cec5SDimitry Andric /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 1130b57cec5SDimitry Andric /// may be preceded by '::'). Note that this routine will not parse ::new or 1140b57cec5SDimitry Andric /// ::delete; it will just leave them in the token stream. 1150b57cec5SDimitry Andric /// 1160b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 1170b57cec5SDimitry Andric /// '::' 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// nested-name-specifier: 1200b57cec5SDimitry Andric /// type-name '::' 1210b57cec5SDimitry Andric /// namespace-name '::' 1220b57cec5SDimitry Andric /// nested-name-specifier identifier '::' 1230b57cec5SDimitry Andric /// nested-name-specifier 'template'[opt] simple-template-id '::' 1240b57cec5SDimitry Andric /// 1250b57cec5SDimitry Andric /// 1260b57cec5SDimitry Andric /// \param SS the scope specifier that will be set to the parsed 1270b57cec5SDimitry Andric /// nested-name-specifier (or empty) 1280b57cec5SDimitry Andric /// 1290b57cec5SDimitry Andric /// \param ObjectType if this nested-name-specifier is being parsed following 1300b57cec5SDimitry Andric /// the "." or "->" of a member access expression, this parameter provides the 1310b57cec5SDimitry Andric /// type of the object whose members are being accessed. 1320b57cec5SDimitry Andric /// 1335ffd83dbSDimitry Andric /// \param ObjectHadErrors if this unqualified-id occurs within a member access 1345ffd83dbSDimitry Andric /// expression, indicates whether the original subexpressions had any errors. 1355ffd83dbSDimitry Andric /// When true, diagnostics for missing 'template' keyword will be supressed. 1365ffd83dbSDimitry Andric /// 1370b57cec5SDimitry Andric /// \param EnteringContext whether we will be entering into the context of 1380b57cec5SDimitry Andric /// the nested-name-specifier after parsing it. 1390b57cec5SDimitry Andric /// 1400b57cec5SDimitry Andric /// \param MayBePseudoDestructor When non-NULL, points to a flag that 1410b57cec5SDimitry Andric /// indicates whether this nested-name-specifier may be part of a 1420b57cec5SDimitry Andric /// pseudo-destructor name. In this case, the flag will be set false 1435ffd83dbSDimitry Andric /// if we don't actually end up parsing a destructor name. Moreover, 1440b57cec5SDimitry Andric /// if we do end up determining that we are parsing a destructor name, 1450b57cec5SDimitry Andric /// the last component of the nested-name-specifier is not parsed as 1460b57cec5SDimitry Andric /// part of the scope specifier. 1470b57cec5SDimitry Andric /// 1480b57cec5SDimitry Andric /// \param IsTypename If \c true, this nested-name-specifier is known to be 1490b57cec5SDimitry Andric /// part of a type name. This is used to improve error recovery. 1500b57cec5SDimitry Andric /// 1510b57cec5SDimitry Andric /// \param LastII When non-NULL, points to an IdentifierInfo* that will be 1520b57cec5SDimitry Andric /// filled in with the leading identifier in the last component of the 1530b57cec5SDimitry Andric /// nested-name-specifier, if any. 1540b57cec5SDimitry Andric /// 1550b57cec5SDimitry Andric /// \param OnlyNamespace If true, only considers namespaces in lookup. 1560b57cec5SDimitry Andric /// 157480093f4SDimitry Andric /// 1580b57cec5SDimitry Andric /// \returns true if there was an error parsing a scope specifier 1595ffd83dbSDimitry Andric bool Parser::ParseOptionalCXXScopeSpecifier( 1605ffd83dbSDimitry Andric CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, 1615ffd83dbSDimitry Andric bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename, 162*0fca6ea1SDimitry Andric const IdentifierInfo **LastII, bool OnlyNamespace, 163*0fca6ea1SDimitry Andric bool InUsingDeclaration) { 1640b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus && 1650b57cec5SDimitry Andric "Call sites of this function should be guarded by checking for C++"); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 1680b57cec5SDimitry Andric assert(!LastII && "want last identifier but have already annotated scope"); 1690b57cec5SDimitry Andric assert(!MayBePseudoDestructor && "unexpected annot_cxxscope"); 1700b57cec5SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1710b57cec5SDimitry Andric Tok.getAnnotationRange(), 1720b57cec5SDimitry Andric SS); 1730b57cec5SDimitry Andric ConsumeAnnotationToken(); 1740b57cec5SDimitry Andric return false; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric // Has to happen before any "return false"s in this function. 1780b57cec5SDimitry Andric bool CheckForDestructor = false; 1790b57cec5SDimitry Andric if (MayBePseudoDestructor && *MayBePseudoDestructor) { 1800b57cec5SDimitry Andric CheckForDestructor = true; 1810b57cec5SDimitry Andric *MayBePseudoDestructor = false; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric if (LastII) 1850b57cec5SDimitry Andric *LastII = nullptr; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric bool HasScopeSpecifier = false; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric if (Tok.is(tok::coloncolon)) { 1900b57cec5SDimitry Andric // ::new and ::delete aren't nested-name-specifiers. 1910b57cec5SDimitry Andric tok::TokenKind NextKind = NextToken().getKind(); 1920b57cec5SDimitry Andric if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 1930b57cec5SDimitry Andric return false; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric if (NextKind == tok::l_brace) { 1960b57cec5SDimitry Andric // It is invalid to have :: {, consume the scope qualifier and pretend 1970b57cec5SDimitry Andric // like we never saw it. 1980b57cec5SDimitry Andric Diag(ConsumeToken(), diag::err_expected) << tok::identifier; 1990b57cec5SDimitry Andric } else { 2000b57cec5SDimitry Andric // '::' - Global scope qualifier. 2010b57cec5SDimitry Andric if (Actions.ActOnCXXGlobalScopeSpecifier(ConsumeToken(), SS)) 2020b57cec5SDimitry Andric return true; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric HasScopeSpecifier = true; 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric if (Tok.is(tok::kw___super)) { 2090b57cec5SDimitry Andric SourceLocation SuperLoc = ConsumeToken(); 2100b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) { 2110b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super); 2120b57cec5SDimitry Andric return true; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric if (!HasScopeSpecifier && 2190b57cec5SDimitry Andric Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) { 2200b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 2210b57cec5SDimitry Andric SourceLocation DeclLoc = Tok.getLocation(); 2220b57cec5SDimitry Andric SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric SourceLocation CCLoc; 2250b57cec5SDimitry Andric // Work around a standard defect: 'decltype(auto)::' is not a 2260b57cec5SDimitry Andric // nested-name-specifier. 2270b57cec5SDimitry Andric if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto || 2280b57cec5SDimitry Andric !TryConsumeToken(tok::coloncolon, CCLoc)) { 2290b57cec5SDimitry Andric AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc); 2300b57cec5SDimitry Andric return false; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc)) 2340b57cec5SDimitry Andric SS.SetInvalid(SourceRange(DeclLoc, CCLoc)); 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric HasScopeSpecifier = true; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 239*0fca6ea1SDimitry Andric else if (!HasScopeSpecifier && Tok.is(tok::identifier) && 240*0fca6ea1SDimitry Andric GetLookAheadToken(1).is(tok::ellipsis) && 241*0fca6ea1SDimitry Andric GetLookAheadToken(2).is(tok::l_square)) { 242*0fca6ea1SDimitry Andric SourceLocation Start = Tok.getLocation(); 243*0fca6ea1SDimitry Andric DeclSpec DS(AttrFactory); 244*0fca6ea1SDimitry Andric SourceLocation CCLoc; 245*0fca6ea1SDimitry Andric SourceLocation EndLoc = ParsePackIndexingType(DS); 246*0fca6ea1SDimitry Andric if (DS.getTypeSpecType() == DeclSpec::TST_error) 247*0fca6ea1SDimitry Andric return false; 248*0fca6ea1SDimitry Andric 249*0fca6ea1SDimitry Andric QualType Type = Actions.ActOnPackIndexingType( 250*0fca6ea1SDimitry Andric DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(), 251*0fca6ea1SDimitry Andric DS.getEllipsisLoc()); 252*0fca6ea1SDimitry Andric 253*0fca6ea1SDimitry Andric if (Type.isNull()) 254*0fca6ea1SDimitry Andric return false; 255*0fca6ea1SDimitry Andric 256*0fca6ea1SDimitry Andric if (!TryConsumeToken(tok::coloncolon, CCLoc)) { 257*0fca6ea1SDimitry Andric AnnotateExistingIndexedTypeNamePack(ParsedType::make(Type), Start, 258*0fca6ea1SDimitry Andric EndLoc); 259*0fca6ea1SDimitry Andric return false; 260*0fca6ea1SDimitry Andric } 261*0fca6ea1SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifierIndexedPack(SS, DS, CCLoc, 262*0fca6ea1SDimitry Andric std::move(Type))) 263*0fca6ea1SDimitry Andric SS.SetInvalid(SourceRange(Start, CCLoc)); 264*0fca6ea1SDimitry Andric HasScopeSpecifier = true; 265*0fca6ea1SDimitry Andric } 266*0fca6ea1SDimitry Andric 2670b57cec5SDimitry Andric // Preferred type might change when parsing qualifiers, we need the original. 2680b57cec5SDimitry Andric auto SavedType = PreferredType; 2690b57cec5SDimitry Andric while (true) { 2700b57cec5SDimitry Andric if (HasScopeSpecifier) { 2710b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 272fe6060f1SDimitry Andric cutOffParsing(); 2730b57cec5SDimitry Andric // Code completion for a nested-name-specifier, where the code 2740b57cec5SDimitry Andric // completion token follows the '::'. 275*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteQualifiedId( 276*0fca6ea1SDimitry Andric getCurScope(), SS, EnteringContext, InUsingDeclaration, 277*0fca6ea1SDimitry Andric ObjectType.get(), SavedType.get(SS.getBeginLoc())); 2780b57cec5SDimitry Andric // Include code completion token into the range of the scope otherwise 2790b57cec5SDimitry Andric // when we try to annotate the scope tokens the dangling code completion 2800b57cec5SDimitry Andric // token will cause assertion in 2810b57cec5SDimitry Andric // Preprocessor::AnnotatePreviousCachedTokens. 2820b57cec5SDimitry Andric SS.setEndLoc(Tok.getLocation()); 2830b57cec5SDimitry Andric return true; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // C++ [basic.lookup.classref]p5: 2870b57cec5SDimitry Andric // If the qualified-id has the form 2880b57cec5SDimitry Andric // 2890b57cec5SDimitry Andric // ::class-name-or-namespace-name::... 2900b57cec5SDimitry Andric // 2910b57cec5SDimitry Andric // the class-name-or-namespace-name is looked up in global scope as a 2920b57cec5SDimitry Andric // class-name or namespace-name. 2930b57cec5SDimitry Andric // 2940b57cec5SDimitry Andric // To implement this, we clear out the object type as soon as we've 2950b57cec5SDimitry Andric // seen a leading '::' or part of a nested-name-specifier. 2960b57cec5SDimitry Andric ObjectType = nullptr; 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric // nested-name-specifier: 3000b57cec5SDimitry Andric // nested-name-specifier 'template'[opt] simple-template-id '::' 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric // Parse the optional 'template' keyword, then make sure we have 3030b57cec5SDimitry Andric // 'identifier <' after it. 3040b57cec5SDimitry Andric if (Tok.is(tok::kw_template)) { 3050b57cec5SDimitry Andric // If we don't have a scope specifier or an object type, this isn't a 3060b57cec5SDimitry Andric // nested-name-specifier, since they aren't allowed to start with 3070b57cec5SDimitry Andric // 'template'. 3080b57cec5SDimitry Andric if (!HasScopeSpecifier && !ObjectType) 3090b57cec5SDimitry Andric break; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 3120b57cec5SDimitry Andric SourceLocation TemplateKWLoc = ConsumeToken(); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric UnqualifiedId TemplateName; 3150b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 3160b57cec5SDimitry Andric // Consume the identifier. 3170b57cec5SDimitry Andric TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 3180b57cec5SDimitry Andric ConsumeToken(); 3190b57cec5SDimitry Andric } else if (Tok.is(tok::kw_operator)) { 3200b57cec5SDimitry Andric // We don't need to actually parse the unqualified-id in this case, 3210b57cec5SDimitry Andric // because a simple-template-id cannot start with 'operator', but 3220b57cec5SDimitry Andric // go ahead and parse it anyway for consistency with the case where 3230b57cec5SDimitry Andric // we already annotated the template-id. 3240b57cec5SDimitry Andric if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 3250b57cec5SDimitry Andric TemplateName)) { 3260b57cec5SDimitry Andric TPA.Commit(); 3270b57cec5SDimitry Andric break; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId && 3310b57cec5SDimitry Andric TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) { 3320b57cec5SDimitry Andric Diag(TemplateName.getSourceRange().getBegin(), 3330b57cec5SDimitry Andric diag::err_id_after_template_in_nested_name_spec) 3340b57cec5SDimitry Andric << TemplateName.getSourceRange(); 3350b57cec5SDimitry Andric TPA.Commit(); 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric } else { 3390b57cec5SDimitry Andric TPA.Revert(); 3400b57cec5SDimitry Andric break; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // If the next token is not '<', we have a qualified-id that refers 3440b57cec5SDimitry Andric // to a template name, such as T::template apply, but is not a 3450b57cec5SDimitry Andric // template-id. 3460b57cec5SDimitry Andric if (Tok.isNot(tok::less)) { 3470b57cec5SDimitry Andric TPA.Revert(); 3480b57cec5SDimitry Andric break; 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // Commit to parsing the template-id. 3520b57cec5SDimitry Andric TPA.Commit(); 3530b57cec5SDimitry Andric TemplateTy Template; 3545ffd83dbSDimitry Andric TemplateNameKind TNK = Actions.ActOnTemplateName( 3550b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType, 3565ffd83dbSDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true); 3570b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc, 3580b57cec5SDimitry Andric TemplateName, false)) 3590b57cec5SDimitry Andric return true; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric continue; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 3650b57cec5SDimitry Andric // We have 3660b57cec5SDimitry Andric // 3670b57cec5SDimitry Andric // template-id '::' 3680b57cec5SDimitry Andric // 3690b57cec5SDimitry Andric // So we need to check whether the template-id is a simple-template-id of 3700b57cec5SDimitry Andric // the right kind (it should name a type or be dependent), and then 3710b57cec5SDimitry Andric // convert it into a type within the nested-name-specifier. 3720b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 3730b57cec5SDimitry Andric if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 3740b57cec5SDimitry Andric *MayBePseudoDestructor = true; 3750b57cec5SDimitry Andric return false; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric if (LastII) 3790b57cec5SDimitry Andric *LastII = TemplateId->Name; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric // Consume the template-id token. 3820b57cec5SDimitry Andric ConsumeAnnotationToken(); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 3850b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric HasScopeSpecifier = true; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 3900b57cec5SDimitry Andric TemplateId->NumArgs); 3910b57cec5SDimitry Andric 3925ffd83dbSDimitry Andric if (TemplateId->isInvalid() || 3935ffd83dbSDimitry Andric Actions.ActOnCXXNestedNameSpecifier(getCurScope(), 3940b57cec5SDimitry Andric SS, 3950b57cec5SDimitry Andric TemplateId->TemplateKWLoc, 3960b57cec5SDimitry Andric TemplateId->Template, 3970b57cec5SDimitry Andric TemplateId->TemplateNameLoc, 3980b57cec5SDimitry Andric TemplateId->LAngleLoc, 3990b57cec5SDimitry Andric TemplateArgsPtr, 4000b57cec5SDimitry Andric TemplateId->RAngleLoc, 4010b57cec5SDimitry Andric CCLoc, 4020b57cec5SDimitry Andric EnteringContext)) { 4030b57cec5SDimitry Andric SourceLocation StartLoc 4040b57cec5SDimitry Andric = SS.getBeginLoc().isValid()? SS.getBeginLoc() 4050b57cec5SDimitry Andric : TemplateId->TemplateNameLoc; 4060b57cec5SDimitry Andric SS.SetInvalid(SourceRange(StartLoc, CCLoc)); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric continue; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 412*0fca6ea1SDimitry Andric switch (Tok.getKind()) { 413*0fca6ea1SDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: 414*0fca6ea1SDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 415*0fca6ea1SDimitry Andric if (!NextToken().is(tok::l_paren)) { 416*0fca6ea1SDimitry Andric Tok.setKind(tok::identifier); 417*0fca6ea1SDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 418*0fca6ea1SDimitry Andric << Tok.getIdentifierInfo()->getName() << 0; 419*0fca6ea1SDimitry Andric continue; 420*0fca6ea1SDimitry Andric } 421*0fca6ea1SDimitry Andric [[fallthrough]]; 422*0fca6ea1SDimitry Andric default: 423*0fca6ea1SDimitry Andric break; 424*0fca6ea1SDimitry Andric } 425*0fca6ea1SDimitry Andric 4260b57cec5SDimitry Andric // The rest of the nested-name-specifier possibilities start with 4270b57cec5SDimitry Andric // tok::identifier. 4280b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 4290b57cec5SDimitry Andric break; 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric // nested-name-specifier: 4340b57cec5SDimitry Andric // type-name '::' 4350b57cec5SDimitry Andric // namespace-name '::' 4360b57cec5SDimitry Andric // nested-name-specifier identifier '::' 4370b57cec5SDimitry Andric Token Next = NextToken(); 4380b57cec5SDimitry Andric Sema::NestedNameSpecInfo IdInfo(&II, Tok.getLocation(), Next.getLocation(), 4390b57cec5SDimitry Andric ObjectType); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 4420b57cec5SDimitry Andric // and emit a fixit hint for it. 4430b57cec5SDimitry Andric if (Next.is(tok::colon) && !ColonIsSacred) { 4440b57cec5SDimitry Andric if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, IdInfo, 4450b57cec5SDimitry Andric EnteringContext) && 4460b57cec5SDimitry Andric // If the token after the colon isn't an identifier, it's still an 4470b57cec5SDimitry Andric // error, but they probably meant something else strange so don't 4480b57cec5SDimitry Andric // recover like this. 4490b57cec5SDimitry Andric PP.LookAhead(1).is(tok::identifier)) { 4500b57cec5SDimitry Andric Diag(Next, diag::err_unexpected_colon_in_nested_name_spec) 4510b57cec5SDimitry Andric << FixItHint::CreateReplacement(Next.getLocation(), "::"); 4520b57cec5SDimitry Andric // Recover as if the user wrote '::'. 4530b57cec5SDimitry Andric Next.setKind(tok::coloncolon); 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) { 4580b57cec5SDimitry Andric // It is invalid to have :: {, consume the scope qualifier and pretend 4590b57cec5SDimitry Andric // like we never saw it. 4600b57cec5SDimitry Andric Token Identifier = Tok; // Stash away the identifier. 4610b57cec5SDimitry Andric ConsumeToken(); // Eat the identifier, current token is now '::'. 4620b57cec5SDimitry Andric Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected) 4630b57cec5SDimitry Andric << tok::identifier; 4640b57cec5SDimitry Andric UnconsumeToken(Identifier); // Stick the identifier back. 4650b57cec5SDimitry Andric Next = NextToken(); // Point Next at the '{' token. 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric if (Next.is(tok::coloncolon)) { 4695ffd83dbSDimitry Andric if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 4700b57cec5SDimitry Andric *MayBePseudoDestructor = true; 4710b57cec5SDimitry Andric return false; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric if (ColonIsSacred) { 4750b57cec5SDimitry Andric const Token &Next2 = GetLookAheadToken(2); 4760b57cec5SDimitry Andric if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) || 4770b57cec5SDimitry Andric Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) { 4780b57cec5SDimitry Andric Diag(Next2, diag::err_unexpected_token_in_nested_name_spec) 4790b57cec5SDimitry Andric << Next2.getName() 4800b57cec5SDimitry Andric << FixItHint::CreateReplacement(Next.getLocation(), ":"); 4810b57cec5SDimitry Andric Token ColonColon; 4820b57cec5SDimitry Andric PP.Lex(ColonColon); 4830b57cec5SDimitry Andric ColonColon.setKind(tok::colon); 4840b57cec5SDimitry Andric PP.EnterToken(ColonColon, /*IsReinject*/ true); 4850b57cec5SDimitry Andric break; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric if (LastII) 4900b57cec5SDimitry Andric *LastII = &II; 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric // We have an identifier followed by a '::'. Lookup this name 4930b57cec5SDimitry Andric // as the name in a nested-name-specifier. 4940b57cec5SDimitry Andric Token Identifier = Tok; 4950b57cec5SDimitry Andric SourceLocation IdLoc = ConsumeToken(); 4960b57cec5SDimitry Andric assert(Tok.isOneOf(tok::coloncolon, tok::colon) && 4970b57cec5SDimitry Andric "NextToken() not working properly!"); 4980b57cec5SDimitry Andric Token ColonColon = Tok; 4990b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric bool IsCorrectedToColon = false; 5020b57cec5SDimitry Andric bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr; 5030b57cec5SDimitry Andric if (Actions.ActOnCXXNestedNameSpecifier( 50481ad6265SDimitry Andric getCurScope(), IdInfo, EnteringContext, SS, CorrectionFlagPtr, 50581ad6265SDimitry Andric OnlyNamespace)) { 5060b57cec5SDimitry Andric // Identifier is not recognized as a nested name, but we can have 5070b57cec5SDimitry Andric // mistyped '::' instead of ':'. 5080b57cec5SDimitry Andric if (CorrectionFlagPtr && IsCorrectedToColon) { 5090b57cec5SDimitry Andric ColonColon.setKind(tok::colon); 5100b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/ true); 5110b57cec5SDimitry Andric PP.EnterToken(ColonColon, /*IsReinject*/ true); 5120b57cec5SDimitry Andric Tok = Identifier; 5130b57cec5SDimitry Andric break; 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric SS.SetInvalid(SourceRange(IdLoc, CCLoc)); 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric HasScopeSpecifier = true; 5180b57cec5SDimitry Andric continue; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric // nested-name-specifier: 5240b57cec5SDimitry Andric // type-name '<' 5250b57cec5SDimitry Andric if (Next.is(tok::less)) { 526480093f4SDimitry Andric 5270b57cec5SDimitry Andric TemplateTy Template; 5280b57cec5SDimitry Andric UnqualifiedId TemplateName; 5290b57cec5SDimitry Andric TemplateName.setIdentifier(&II, Tok.getLocation()); 5300b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 5310b57cec5SDimitry Andric if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 5320b57cec5SDimitry Andric /*hasTemplateKeyword=*/false, 5330b57cec5SDimitry Andric TemplateName, 5340b57cec5SDimitry Andric ObjectType, 5350b57cec5SDimitry Andric EnteringContext, 5360b57cec5SDimitry Andric Template, 5370b57cec5SDimitry Andric MemberOfUnknownSpecialization)) { 5380b57cec5SDimitry Andric // If lookup didn't find anything, we treat the name as a template-name 5390b57cec5SDimitry Andric // anyway. C++20 requires this, and in prior language modes it improves 5400b57cec5SDimitry Andric // error recovery. But before we commit to this, check that we actually 5410b57cec5SDimitry Andric // have something that looks like a template-argument-list next. 5420b57cec5SDimitry Andric if (!IsTypename && TNK == TNK_Undeclared_template && 5430b57cec5SDimitry Andric isTemplateArgumentList(1) == TPResult::False) 5440b57cec5SDimitry Andric break; 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric // We have found a template name, so annotate this token 5470b57cec5SDimitry Andric // with a template-id annotation. We do not permit the 5480b57cec5SDimitry Andric // template-id to be translated into a type annotation, 5490b57cec5SDimitry Andric // because some clients (e.g., the parsing of class template 5500b57cec5SDimitry Andric // specializations) still want to see the original template-id 551480093f4SDimitry Andric // token, and it might not be a type at all (e.g. a concept name in a 552480093f4SDimitry Andric // type-constraint). 5530b57cec5SDimitry Andric ConsumeToken(); 5540b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 5550b57cec5SDimitry Andric TemplateName, false)) 5560b57cec5SDimitry Andric return true; 5570b57cec5SDimitry Andric continue; 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 5610b57cec5SDimitry Andric (IsTypename || isTemplateArgumentList(1) == TPResult::True)) { 5625ffd83dbSDimitry Andric // If we had errors before, ObjectType can be dependent even without any 5635ffd83dbSDimitry Andric // templates. Do not report missing template keyword in that case. 5645ffd83dbSDimitry Andric if (!ObjectHadErrors) { 5650b57cec5SDimitry Andric // We have something like t::getAs<T>, where getAs is a 5660b57cec5SDimitry Andric // member of an unknown specialization. However, this will only 5670b57cec5SDimitry Andric // parse correctly as a template, so suggest the keyword 'template' 5680b57cec5SDimitry Andric // before 'getAs' and treat this as a dependent template name. 5690b57cec5SDimitry Andric unsigned DiagID = diag::err_missing_dependent_template_keyword; 5700b57cec5SDimitry Andric if (getLangOpts().MicrosoftExt) 5710b57cec5SDimitry Andric DiagID = diag::warn_missing_dependent_template_keyword; 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric Diag(Tok.getLocation(), DiagID) 5740b57cec5SDimitry Andric << II.getName() 5750b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "template "); 5765ffd83dbSDimitry Andric } 5770b57cec5SDimitry Andric 5785ffd83dbSDimitry Andric SourceLocation TemplateNameLoc = ConsumeToken(); 5795ffd83dbSDimitry Andric 5805ffd83dbSDimitry Andric TemplateNameKind TNK = Actions.ActOnTemplateName( 5815ffd83dbSDimitry Andric getCurScope(), SS, TemplateNameLoc, TemplateName, ObjectType, 5825ffd83dbSDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true); 5830b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 5840b57cec5SDimitry Andric TemplateName, false)) 5850b57cec5SDimitry Andric return true; 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric continue; 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // We don't have any tokens that form the beginning of a 5920b57cec5SDimitry Andric // nested-name-specifier, so we're done. 5930b57cec5SDimitry Andric break; 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric // Even if we didn't see any pieces of a nested-name-specifier, we 5970b57cec5SDimitry Andric // still check whether there is a tilde in this position, which 5980b57cec5SDimitry Andric // indicates a potential pseudo-destructor. 5995ffd83dbSDimitry Andric if (CheckForDestructor && !HasScopeSpecifier && Tok.is(tok::tilde)) 6000b57cec5SDimitry Andric *MayBePseudoDestructor = true; 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric return false; 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 605a7dea167SDimitry Andric ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, 606a7dea167SDimitry Andric bool isAddressOfOperand, 6070b57cec5SDimitry Andric Token &Replacement) { 608a7dea167SDimitry Andric ExprResult E; 609a7dea167SDimitry Andric 610a7dea167SDimitry Andric // We may have already annotated this id-expression. 611a7dea167SDimitry Andric switch (Tok.getKind()) { 612a7dea167SDimitry Andric case tok::annot_non_type: { 613a7dea167SDimitry Andric NamedDecl *ND = getNonTypeAnnotation(Tok); 614a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 615a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsNonType(getCurScope(), SS, ND, Loc, Tok); 616a7dea167SDimitry Andric break; 617a7dea167SDimitry Andric } 618a7dea167SDimitry Andric 619a7dea167SDimitry Andric case tok::annot_non_type_dependent: { 620a7dea167SDimitry Andric IdentifierInfo *II = getIdentifierAnnotation(Tok); 621a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 622a7dea167SDimitry Andric 623a7dea167SDimitry Andric // This is only the direct operand of an & operator if it is not 624a7dea167SDimitry Andric // followed by a postfix-expression suffix. 625a7dea167SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 626a7dea167SDimitry Andric isAddressOfOperand = false; 627a7dea167SDimitry Andric 628a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsDependentNonType(SS, II, Loc, 629a7dea167SDimitry Andric isAddressOfOperand); 630a7dea167SDimitry Andric break; 631a7dea167SDimitry Andric } 632a7dea167SDimitry Andric 633a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 634a7dea167SDimitry Andric assert(SS.isEmpty() && 635a7dea167SDimitry Andric "undeclared non-type annotation should be unqualified"); 636a7dea167SDimitry Andric IdentifierInfo *II = getIdentifierAnnotation(Tok); 637a7dea167SDimitry Andric SourceLocation Loc = ConsumeAnnotationToken(); 638a7dea167SDimitry Andric E = Actions.ActOnNameClassifiedAsUndeclaredNonType(II, Loc); 639a7dea167SDimitry Andric break; 640a7dea167SDimitry Andric } 641a7dea167SDimitry Andric 642a7dea167SDimitry Andric default: 6430b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 6440b57cec5SDimitry Andric UnqualifiedId Name; 6455ffd83dbSDimitry Andric if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr, 6465ffd83dbSDimitry Andric /*ObjectHadErrors=*/false, 6470b57cec5SDimitry Andric /*EnteringContext=*/false, 6480b57cec5SDimitry Andric /*AllowDestructorName=*/false, 6490b57cec5SDimitry Andric /*AllowConstructorName=*/false, 6505ffd83dbSDimitry Andric /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) 6510b57cec5SDimitry Andric return ExprError(); 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric // This is only the direct operand of an & operator if it is not 6540b57cec5SDimitry Andric // followed by a postfix-expression suffix. 6550b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 6560b57cec5SDimitry Andric isAddressOfOperand = false; 6570b57cec5SDimitry Andric 658a7dea167SDimitry Andric E = Actions.ActOnIdExpression( 6590b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren), 6600b57cec5SDimitry Andric isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false, 6610b57cec5SDimitry Andric &Replacement); 662a7dea167SDimitry Andric break; 663a7dea167SDimitry Andric } 664a7dea167SDimitry Andric 665*0fca6ea1SDimitry Andric // Might be a pack index expression! 666*0fca6ea1SDimitry Andric E = tryParseCXXPackIndexingExpression(E); 667*0fca6ea1SDimitry Andric 6680b57cec5SDimitry Andric if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less)) 6690b57cec5SDimitry Andric checkPotentialAngleBracket(E); 6700b57cec5SDimitry Andric return E; 6710b57cec5SDimitry Andric } 6720b57cec5SDimitry Andric 673*0fca6ea1SDimitry Andric ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) { 674*0fca6ea1SDimitry Andric assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) && 675*0fca6ea1SDimitry Andric "expected ...["); 676*0fca6ea1SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 677*0fca6ea1SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 678*0fca6ea1SDimitry Andric T.consumeOpen(); 679*0fca6ea1SDimitry Andric ExprResult IndexExpr = ParseConstantExpression(); 680*0fca6ea1SDimitry Andric if (T.consumeClose() || IndexExpr.isInvalid()) 681*0fca6ea1SDimitry Andric return ExprError(); 682*0fca6ea1SDimitry Andric return Actions.ActOnPackIndexingExpr(getCurScope(), PackIdExpression.get(), 683*0fca6ea1SDimitry Andric EllipsisLoc, T.getOpenLocation(), 684*0fca6ea1SDimitry Andric IndexExpr.get(), T.getCloseLocation()); 685*0fca6ea1SDimitry Andric } 686*0fca6ea1SDimitry Andric 687*0fca6ea1SDimitry Andric ExprResult 688*0fca6ea1SDimitry Andric Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) { 689*0fca6ea1SDimitry Andric ExprResult E = PackIdExpression; 690*0fca6ea1SDimitry Andric if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() && 691*0fca6ea1SDimitry Andric Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) { 692*0fca6ea1SDimitry Andric E = ParseCXXPackIndexingExpression(E); 693*0fca6ea1SDimitry Andric } 694*0fca6ea1SDimitry Andric return E; 695*0fca6ea1SDimitry Andric } 696*0fca6ea1SDimitry Andric 6970b57cec5SDimitry Andric /// ParseCXXIdExpression - Handle id-expression. 6980b57cec5SDimitry Andric /// 6990b57cec5SDimitry Andric /// id-expression: 7000b57cec5SDimitry Andric /// unqualified-id 7010b57cec5SDimitry Andric /// qualified-id 7020b57cec5SDimitry Andric /// 7030b57cec5SDimitry Andric /// qualified-id: 7040b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 7050b57cec5SDimitry Andric /// '::' identifier 7060b57cec5SDimitry Andric /// '::' operator-function-id 7070b57cec5SDimitry Andric /// '::' template-id 7080b57cec5SDimitry Andric /// 7090b57cec5SDimitry Andric /// NOTE: The standard specifies that, for qualified-id, the parser does not 7100b57cec5SDimitry Andric /// expect: 7110b57cec5SDimitry Andric /// 7120b57cec5SDimitry Andric /// '::' conversion-function-id 7130b57cec5SDimitry Andric /// '::' '~' class-name 7140b57cec5SDimitry Andric /// 7150b57cec5SDimitry Andric /// This may cause a slight inconsistency on diagnostics: 7160b57cec5SDimitry Andric /// 7170b57cec5SDimitry Andric /// class C {}; 7180b57cec5SDimitry Andric /// namespace A {} 7190b57cec5SDimitry Andric /// void f() { 7200b57cec5SDimitry Andric /// :: A :: ~ C(); // Some Sema error about using destructor with a 7210b57cec5SDimitry Andric /// // namespace. 7220b57cec5SDimitry Andric /// :: ~ C(); // Some Parser error like 'unexpected ~'. 7230b57cec5SDimitry Andric /// } 7240b57cec5SDimitry Andric /// 7250b57cec5SDimitry Andric /// We simplify the parser a bit and make it work like: 7260b57cec5SDimitry Andric /// 7270b57cec5SDimitry Andric /// qualified-id: 7280b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 7290b57cec5SDimitry Andric /// '::' unqualified-id 7300b57cec5SDimitry Andric /// 7310b57cec5SDimitry Andric /// That way Sema can handle and report similar errors for namespaces and the 7320b57cec5SDimitry Andric /// global scope. 7330b57cec5SDimitry Andric /// 7340b57cec5SDimitry Andric /// The isAddressOfOperand parameter indicates that this id-expression is a 7350b57cec5SDimitry Andric /// direct operand of the address-of operator. This is, besides member contexts, 7360b57cec5SDimitry Andric /// the only place where a qualified-id naming a non-static class member may 7370b57cec5SDimitry Andric /// appear. 7380b57cec5SDimitry Andric /// 7390b57cec5SDimitry Andric ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 7400b57cec5SDimitry Andric // qualified-id: 7410b57cec5SDimitry Andric // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 7420b57cec5SDimitry Andric // '::' unqualified-id 7430b57cec5SDimitry Andric // 7440b57cec5SDimitry Andric CXXScopeSpec SS; 7455ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 74604eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 7475ffd83dbSDimitry Andric /*EnteringContext=*/false); 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric Token Replacement; 7500b57cec5SDimitry Andric ExprResult Result = 7510b57cec5SDimitry Andric tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 7520b57cec5SDimitry Andric if (Result.isUnset()) { 7530b57cec5SDimitry Andric // If the ExprResult is valid but null, then typo correction suggested a 7540b57cec5SDimitry Andric // keyword replacement that needs to be reparsed. 7550b57cec5SDimitry Andric UnconsumeToken(Replacement); 7560b57cec5SDimitry Andric Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 7570b57cec5SDimitry Andric } 7580b57cec5SDimitry Andric assert(!Result.isUnset() && "Typo correction suggested a keyword replacement " 7590b57cec5SDimitry Andric "for a previous keyword suggestion"); 7600b57cec5SDimitry Andric return Result; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric /// ParseLambdaExpression - Parse a C++11 lambda expression. 7640b57cec5SDimitry Andric /// 7650b57cec5SDimitry Andric /// lambda-expression: 766fe6060f1SDimitry Andric /// lambda-introducer lambda-declarator compound-statement 7670b57cec5SDimitry Andric /// lambda-introducer '<' template-parameter-list '>' 768fe6060f1SDimitry Andric /// requires-clause[opt] lambda-declarator compound-statement 7690b57cec5SDimitry Andric /// 7700b57cec5SDimitry Andric /// lambda-introducer: 7710b57cec5SDimitry Andric /// '[' lambda-capture[opt] ']' 7720b57cec5SDimitry Andric /// 7730b57cec5SDimitry Andric /// lambda-capture: 7740b57cec5SDimitry Andric /// capture-default 7750b57cec5SDimitry Andric /// capture-list 7760b57cec5SDimitry Andric /// capture-default ',' capture-list 7770b57cec5SDimitry Andric /// 7780b57cec5SDimitry Andric /// capture-default: 7790b57cec5SDimitry Andric /// '&' 7800b57cec5SDimitry Andric /// '=' 7810b57cec5SDimitry Andric /// 7820b57cec5SDimitry Andric /// capture-list: 7830b57cec5SDimitry Andric /// capture 7840b57cec5SDimitry Andric /// capture-list ',' capture 7850b57cec5SDimitry Andric /// 7860b57cec5SDimitry Andric /// capture: 7870b57cec5SDimitry Andric /// simple-capture 7880b57cec5SDimitry Andric /// init-capture [C++1y] 7890b57cec5SDimitry Andric /// 7900b57cec5SDimitry Andric /// simple-capture: 7910b57cec5SDimitry Andric /// identifier 7920b57cec5SDimitry Andric /// '&' identifier 7930b57cec5SDimitry Andric /// 'this' 7940b57cec5SDimitry Andric /// 7950b57cec5SDimitry Andric /// init-capture: [C++1y] 7960b57cec5SDimitry Andric /// identifier initializer 7970b57cec5SDimitry Andric /// '&' identifier initializer 7980b57cec5SDimitry Andric /// 7990b57cec5SDimitry Andric /// lambda-declarator: 80006c3fb27SDimitry Andric /// lambda-specifiers [C++23] 801fe6060f1SDimitry Andric /// '(' parameter-declaration-clause ')' lambda-specifiers 802fe6060f1SDimitry Andric /// requires-clause[opt] 803fe6060f1SDimitry Andric /// 804fe6060f1SDimitry Andric /// lambda-specifiers: 805fe6060f1SDimitry Andric /// decl-specifier-seq[opt] noexcept-specifier[opt] 806fe6060f1SDimitry Andric /// attribute-specifier-seq[opt] trailing-return-type[opt] 8070b57cec5SDimitry Andric /// 8080b57cec5SDimitry Andric ExprResult Parser::ParseLambdaExpression() { 8090b57cec5SDimitry Andric // Parse lambda-introducer. 8100b57cec5SDimitry Andric LambdaIntroducer Intro; 8110b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro)) { 8120b57cec5SDimitry Andric SkipUntil(tok::r_square, StopAtSemi); 8130b57cec5SDimitry Andric SkipUntil(tok::l_brace, StopAtSemi); 8140b57cec5SDimitry Andric SkipUntil(tok::r_brace, StopAtSemi); 8150b57cec5SDimitry Andric return ExprError(); 8160b57cec5SDimitry Andric } 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric return ParseLambdaExpressionAfterIntroducer(Intro); 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric /// Use lookahead and potentially tentative parsing to determine if we are 8220b57cec5SDimitry Andric /// looking at a C++11 lambda expression, and parse it if we are. 8230b57cec5SDimitry Andric /// 8240b57cec5SDimitry Andric /// If we are not looking at a lambda expression, returns ExprError(). 8250b57cec5SDimitry Andric ExprResult Parser::TryParseLambdaExpression() { 826*0fca6ea1SDimitry Andric assert(getLangOpts().CPlusPlus && Tok.is(tok::l_square) && 827*0fca6ea1SDimitry Andric "Not at the start of a possible lambda expression."); 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric const Token Next = NextToken(); 8300b57cec5SDimitry Andric if (Next.is(tok::eof)) // Nothing else to lookup here... 8310b57cec5SDimitry Andric return ExprEmpty(); 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric const Token After = GetLookAheadToken(2); 8340b57cec5SDimitry Andric // If lookahead indicates this is a lambda... 8350b57cec5SDimitry Andric if (Next.is(tok::r_square) || // [] 8360b57cec5SDimitry Andric Next.is(tok::equal) || // [= 8370b57cec5SDimitry Andric (Next.is(tok::amp) && // [&] or [&, 8380b57cec5SDimitry Andric After.isOneOf(tok::r_square, tok::comma)) || 8390b57cec5SDimitry Andric (Next.is(tok::identifier) && // [identifier] 8400b57cec5SDimitry Andric After.is(tok::r_square)) || 8410b57cec5SDimitry Andric Next.is(tok::ellipsis)) { // [... 8420b57cec5SDimitry Andric return ParseLambdaExpression(); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric // If lookahead indicates an ObjC message send... 8460b57cec5SDimitry Andric // [identifier identifier 8470b57cec5SDimitry Andric if (Next.is(tok::identifier) && After.is(tok::identifier)) 8480b57cec5SDimitry Andric return ExprEmpty(); 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric // Here, we're stuck: lambda introducers and Objective-C message sends are 8510b57cec5SDimitry Andric // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a 8520b57cec5SDimitry Andric // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of 8530b57cec5SDimitry Andric // writing two routines to parse a lambda introducer, just try to parse 8540b57cec5SDimitry Andric // a lambda introducer first, and fall back if that fails. 8550b57cec5SDimitry Andric LambdaIntroducer Intro; 8560b57cec5SDimitry Andric { 8570b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 8580b57cec5SDimitry Andric LambdaIntroducerTentativeParse Tentative; 8590b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro, &Tentative)) { 8600b57cec5SDimitry Andric TPA.Commit(); 8610b57cec5SDimitry Andric return ExprError(); 8620b57cec5SDimitry Andric } 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric switch (Tentative) { 8650b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Success: 8660b57cec5SDimitry Andric TPA.Commit(); 8670b57cec5SDimitry Andric break; 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Incomplete: 8700b57cec5SDimitry Andric // Didn't fully parse the lambda-introducer, try again with a 8710b57cec5SDimitry Andric // non-tentative parse. 8720b57cec5SDimitry Andric TPA.Revert(); 8730b57cec5SDimitry Andric Intro = LambdaIntroducer(); 8740b57cec5SDimitry Andric if (ParseLambdaIntroducer(Intro)) 8750b57cec5SDimitry Andric return ExprError(); 8760b57cec5SDimitry Andric break; 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::MessageSend: 8790b57cec5SDimitry Andric case LambdaIntroducerTentativeParse::Invalid: 8800b57cec5SDimitry Andric // Not a lambda-introducer, might be a message send. 8810b57cec5SDimitry Andric TPA.Revert(); 8820b57cec5SDimitry Andric return ExprEmpty(); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric return ParseLambdaExpressionAfterIntroducer(Intro); 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric /// Parse a lambda introducer. 8900b57cec5SDimitry Andric /// \param Intro A LambdaIntroducer filled in with information about the 8910b57cec5SDimitry Andric /// contents of the lambda-introducer. 8920b57cec5SDimitry Andric /// \param Tentative If non-null, we are disambiguating between a 8930b57cec5SDimitry Andric /// lambda-introducer and some other construct. In this mode, we do not 8940b57cec5SDimitry Andric /// produce any diagnostics or take any other irreversible action unless 8950b57cec5SDimitry Andric /// we're sure that this is a lambda-expression. 8960b57cec5SDimitry Andric /// \return \c true if parsing (or disambiguation) failed with a diagnostic and 8970b57cec5SDimitry Andric /// the caller should bail out / recover. 8980b57cec5SDimitry Andric bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, 8990b57cec5SDimitry Andric LambdaIntroducerTentativeParse *Tentative) { 9000b57cec5SDimitry Andric if (Tentative) 9010b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Success; 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); 9040b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 9050b57cec5SDimitry Andric T.consumeOpen(); 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric Intro.Range.setBegin(T.getOpenLocation()); 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric bool First = true; 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric // Produce a diagnostic if we're not tentatively parsing; otherwise track 9120b57cec5SDimitry Andric // that our parse has failed. 9130b57cec5SDimitry Andric auto Invalid = [&](llvm::function_ref<void()> Action) { 9140b57cec5SDimitry Andric if (Tentative) { 9150b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Invalid; 9160b57cec5SDimitry Andric return false; 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric Action(); 9190b57cec5SDimitry Andric return true; 9200b57cec5SDimitry Andric }; 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andric // Perform some irreversible action if this is a non-tentative parse; 9230b57cec5SDimitry Andric // otherwise note that our actions were incomplete. 9240b57cec5SDimitry Andric auto NonTentativeAction = [&](llvm::function_ref<void()> Action) { 9250b57cec5SDimitry Andric if (Tentative) 9260b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 9270b57cec5SDimitry Andric else 9280b57cec5SDimitry Andric Action(); 9290b57cec5SDimitry Andric }; 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric // Parse capture-default. 9320b57cec5SDimitry Andric if (Tok.is(tok::amp) && 9330b57cec5SDimitry Andric (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) { 9340b57cec5SDimitry Andric Intro.Default = LCD_ByRef; 9350b57cec5SDimitry Andric Intro.DefaultLoc = ConsumeToken(); 9360b57cec5SDimitry Andric First = false; 9370b57cec5SDimitry Andric if (!Tok.getIdentifierInfo()) { 9380b57cec5SDimitry Andric // This can only be a lambda; no need for tentative parsing any more. 9390b57cec5SDimitry Andric // '[[and]]' can still be an attribute, though. 9400b57cec5SDimitry Andric Tentative = nullptr; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric } else if (Tok.is(tok::equal)) { 9430b57cec5SDimitry Andric Intro.Default = LCD_ByCopy; 9440b57cec5SDimitry Andric Intro.DefaultLoc = ConsumeToken(); 9450b57cec5SDimitry Andric First = false; 9460b57cec5SDimitry Andric Tentative = nullptr; 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric while (Tok.isNot(tok::r_square)) { 9500b57cec5SDimitry Andric if (!First) { 9510b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) { 9520b57cec5SDimitry Andric // Provide a completion for a lambda introducer here. Except 9530b57cec5SDimitry Andric // in Objective-C, where this is Almost Surely meant to be a message 9540b57cec5SDimitry Andric // send. In that case, fail here and let the ObjC message 9550b57cec5SDimitry Andric // expression parser perform the completion. 9560b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && 9570b57cec5SDimitry Andric !(getLangOpts().ObjC && Tentative)) { 958fe6060f1SDimitry Andric cutOffParsing(); 959*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteLambdaIntroducer( 960*0fca6ea1SDimitry Andric getCurScope(), Intro, 9610b57cec5SDimitry Andric /*AfterAmpersand=*/false); 9620b57cec5SDimitry Andric break; 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric return Invalid([&] { 9660b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare); 9670b57cec5SDimitry Andric }); 9680b57cec5SDimitry Andric } 9690b57cec5SDimitry Andric ConsumeToken(); 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 973fe6060f1SDimitry Andric cutOffParsing(); 9740b57cec5SDimitry Andric // If we're in Objective-C++ and we have a bare '[', then this is more 9750b57cec5SDimitry Andric // likely to be a message receiver. 9760b57cec5SDimitry Andric if (getLangOpts().ObjC && Tentative && First) 977*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(getCurScope()); 9780b57cec5SDimitry Andric else 979*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteLambdaIntroducer( 980*0fca6ea1SDimitry Andric getCurScope(), Intro, 9810b57cec5SDimitry Andric /*AfterAmpersand=*/false); 9820b57cec5SDimitry Andric break; 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andric First = false; 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric // Parse capture. 9880b57cec5SDimitry Andric LambdaCaptureKind Kind = LCK_ByCopy; 9890b57cec5SDimitry Andric LambdaCaptureInitKind InitKind = LambdaCaptureInitKind::NoInit; 9900b57cec5SDimitry Andric SourceLocation Loc; 9910b57cec5SDimitry Andric IdentifierInfo *Id = nullptr; 9920b57cec5SDimitry Andric SourceLocation EllipsisLocs[4]; 9930b57cec5SDimitry Andric ExprResult Init; 9940b57cec5SDimitry Andric SourceLocation LocStart = Tok.getLocation(); 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric if (Tok.is(tok::star)) { 9970b57cec5SDimitry Andric Loc = ConsumeToken(); 9980b57cec5SDimitry Andric if (Tok.is(tok::kw_this)) { 9990b57cec5SDimitry Andric ConsumeToken(); 10000b57cec5SDimitry Andric Kind = LCK_StarThis; 10010b57cec5SDimitry Andric } else { 10020b57cec5SDimitry Andric return Invalid([&] { 10030b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_star_this_capture); 10040b57cec5SDimitry Andric }); 10050b57cec5SDimitry Andric } 10060b57cec5SDimitry Andric } else if (Tok.is(tok::kw_this)) { 10070b57cec5SDimitry Andric Kind = LCK_This; 10080b57cec5SDimitry Andric Loc = ConsumeToken(); 1009e8d8bef9SDimitry Andric } else if (Tok.isOneOf(tok::amp, tok::equal) && 1010e8d8bef9SDimitry Andric NextToken().isOneOf(tok::comma, tok::r_square) && 1011e8d8bef9SDimitry Andric Intro.Default == LCD_None) { 1012e8d8bef9SDimitry Andric // We have a lone "&" or "=" which is either a misplaced capture-default 1013e8d8bef9SDimitry Andric // or the start of a capture (in the "&" case) with the rest of the 1014e8d8bef9SDimitry Andric // capture missing. Both are an error but a misplaced capture-default 1015e8d8bef9SDimitry Andric // is more likely if we don't already have a capture default. 1016e8d8bef9SDimitry Andric return Invalid( 1017e8d8bef9SDimitry Andric [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); }); 10180b57cec5SDimitry Andric } else { 10190b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[0]); 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric if (Tok.is(tok::amp)) { 10220b57cec5SDimitry Andric Kind = LCK_ByRef; 10230b57cec5SDimitry Andric ConsumeToken(); 10240b57cec5SDimitry Andric 10250b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 1026fe6060f1SDimitry Andric cutOffParsing(); 1027*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteLambdaIntroducer( 1028*0fca6ea1SDimitry Andric getCurScope(), Intro, 10290b57cec5SDimitry Andric /*AfterAmpersand=*/true); 10300b57cec5SDimitry Andric break; 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric } 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[1]); 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 10370b57cec5SDimitry Andric Id = Tok.getIdentifierInfo(); 10380b57cec5SDimitry Andric Loc = ConsumeToken(); 10390b57cec5SDimitry Andric } else if (Tok.is(tok::kw_this)) { 10400b57cec5SDimitry Andric return Invalid([&] { 10410b57cec5SDimitry Andric // FIXME: Suggest a fixit here. 10420b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_this_captured_by_reference); 10430b57cec5SDimitry Andric }); 10440b57cec5SDimitry Andric } else { 10450b57cec5SDimitry Andric return Invalid([&] { 10460b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_capture); 10470b57cec5SDimitry Andric }); 10480b57cec5SDimitry Andric } 10490b57cec5SDimitry Andric 10500b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[2]); 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 10530b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 10540b57cec5SDimitry Andric Parens.consumeOpen(); 10550b57cec5SDimitry Andric 10560b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::DirectInit; 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric ExprVector Exprs; 10590b57cec5SDimitry Andric if (Tentative) { 10600b57cec5SDimitry Andric Parens.skipToEnd(); 10610b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 1062bdd1243dSDimitry Andric } else if (ParseExpressionList(Exprs)) { 10630b57cec5SDimitry Andric Parens.skipToEnd(); 10640b57cec5SDimitry Andric Init = ExprError(); 10650b57cec5SDimitry Andric } else { 10660b57cec5SDimitry Andric Parens.consumeClose(); 10670b57cec5SDimitry Andric Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(), 10680b57cec5SDimitry Andric Parens.getCloseLocation(), 10690b57cec5SDimitry Andric Exprs); 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric } else if (Tok.isOneOf(tok::l_brace, tok::equal)) { 10720b57cec5SDimitry Andric // Each lambda init-capture forms its own full expression, which clears 10730b57cec5SDimitry Andric // Actions.MaybeODRUseExprs. So create an expression evaluation context 10740b57cec5SDimitry Andric // to save the necessary state, and restore it later. 10750b57cec5SDimitry Andric EnterExpressionEvaluationContext EC( 10760b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric if (TryConsumeToken(tok::equal)) 10790b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::CopyInit; 10800b57cec5SDimitry Andric else 10810b57cec5SDimitry Andric InitKind = LambdaCaptureInitKind::ListInit; 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric if (!Tentative) { 10840b57cec5SDimitry Andric Init = ParseInitializer(); 10850b57cec5SDimitry Andric } else if (Tok.is(tok::l_brace)) { 10860b57cec5SDimitry Andric BalancedDelimiterTracker Braces(*this, tok::l_brace); 10870b57cec5SDimitry Andric Braces.consumeOpen(); 10880b57cec5SDimitry Andric Braces.skipToEnd(); 10890b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::Incomplete; 10900b57cec5SDimitry Andric } else { 10910b57cec5SDimitry Andric // We're disambiguating this: 10920b57cec5SDimitry Andric // 10930b57cec5SDimitry Andric // [..., x = expr 10940b57cec5SDimitry Andric // 10950b57cec5SDimitry Andric // We need to find the end of the following expression in order to 10960b57cec5SDimitry Andric // determine whether this is an Obj-C message send's receiver, a 10970b57cec5SDimitry Andric // C99 designator, or a lambda init-capture. 10980b57cec5SDimitry Andric // 10990b57cec5SDimitry Andric // Parse the expression to find where it ends, and annotate it back 11000b57cec5SDimitry Andric // onto the tokens. We would have parsed this expression the same way 11010b57cec5SDimitry Andric // in either case: both the RHS of an init-capture and the RHS of an 11020b57cec5SDimitry Andric // assignment expression are parsed as an initializer-clause, and in 11030b57cec5SDimitry Andric // neither case can anything be added to the scope between the '[' and 11040b57cec5SDimitry Andric // here. 11050b57cec5SDimitry Andric // 11060b57cec5SDimitry Andric // FIXME: This is horrible. Adding a mechanism to skip an expression 11070b57cec5SDimitry Andric // would be much cleaner. 11080b57cec5SDimitry Andric // FIXME: If there is a ',' before the next ']' or ':', we can skip to 11090b57cec5SDimitry Andric // that instead. (And if we see a ':' with no matching '?', we can 11100b57cec5SDimitry Andric // classify this as an Obj-C message send.) 11110b57cec5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 11120b57cec5SDimitry Andric InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true); 11130b57cec5SDimitry Andric Init = ParseInitializer(); 11140b57cec5SDimitry Andric if (!Init.isInvalid()) 11150b57cec5SDimitry Andric Init = Actions.CorrectDelayedTyposInExpr(Init.get()); 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric if (Tok.getLocation() != StartLoc) { 11180b57cec5SDimitry Andric // Back out the lexing of the token after the initializer. 11190b57cec5SDimitry Andric PP.RevertCachedTokens(1); 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric // Replace the consumed tokens with an appropriate annotation. 11220b57cec5SDimitry Andric Tok.setLocation(StartLoc); 11230b57cec5SDimitry Andric Tok.setKind(tok::annot_primary_expr); 11240b57cec5SDimitry Andric setExprAnnotation(Tok, Init); 11250b57cec5SDimitry Andric Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation()); 11260b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric // Consume the annotated initializer. 11290b57cec5SDimitry Andric ConsumeAnnotationToken(); 11300b57cec5SDimitry Andric } 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric TryConsumeToken(tok::ellipsis, EllipsisLocs[3]); 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric // Check if this is a message send before we act on a possible init-capture. 11380b57cec5SDimitry Andric if (Tentative && Tok.is(tok::identifier) && 11390b57cec5SDimitry Andric NextToken().isOneOf(tok::colon, tok::r_square)) { 11400b57cec5SDimitry Andric // This can only be a message send. We're done with disambiguation. 11410b57cec5SDimitry Andric *Tentative = LambdaIntroducerTentativeParse::MessageSend; 11420b57cec5SDimitry Andric return false; 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric 11450b57cec5SDimitry Andric // Ensure that any ellipsis was in the right place. 11460b57cec5SDimitry Andric SourceLocation EllipsisLoc; 1147349cc55cSDimitry Andric if (llvm::any_of(EllipsisLocs, 11480b57cec5SDimitry Andric [](SourceLocation Loc) { return Loc.isValid(); })) { 11490b57cec5SDimitry Andric // The '...' should appear before the identifier in an init-capture, and 11500b57cec5SDimitry Andric // after the identifier otherwise. 11510b57cec5SDimitry Andric bool InitCapture = InitKind != LambdaCaptureInitKind::NoInit; 11520b57cec5SDimitry Andric SourceLocation *ExpectedEllipsisLoc = 11530b57cec5SDimitry Andric !InitCapture ? &EllipsisLocs[2] : 11540b57cec5SDimitry Andric Kind == LCK_ByRef ? &EllipsisLocs[1] : 11550b57cec5SDimitry Andric &EllipsisLocs[0]; 11560b57cec5SDimitry Andric EllipsisLoc = *ExpectedEllipsisLoc; 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric unsigned DiagID = 0; 11590b57cec5SDimitry Andric if (EllipsisLoc.isInvalid()) { 11600b57cec5SDimitry Andric DiagID = diag::err_lambda_capture_misplaced_ellipsis; 11610b57cec5SDimitry Andric for (SourceLocation Loc : EllipsisLocs) { 11620b57cec5SDimitry Andric if (Loc.isValid()) 11630b57cec5SDimitry Andric EllipsisLoc = Loc; 11640b57cec5SDimitry Andric } 11650b57cec5SDimitry Andric } else { 11660b57cec5SDimitry Andric unsigned NumEllipses = std::accumulate( 11670b57cec5SDimitry Andric std::begin(EllipsisLocs), std::end(EllipsisLocs), 0, 11680b57cec5SDimitry Andric [](int N, SourceLocation Loc) { return N + Loc.isValid(); }); 11690b57cec5SDimitry Andric if (NumEllipses > 1) 11700b57cec5SDimitry Andric DiagID = diag::err_lambda_capture_multiple_ellipses; 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric if (DiagID) { 11730b57cec5SDimitry Andric NonTentativeAction([&] { 11740b57cec5SDimitry Andric // Point the diagnostic at the first misplaced ellipsis. 11750b57cec5SDimitry Andric SourceLocation DiagLoc; 11760b57cec5SDimitry Andric for (SourceLocation &Loc : EllipsisLocs) { 11770b57cec5SDimitry Andric if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) { 11780b57cec5SDimitry Andric DiagLoc = Loc; 11790b57cec5SDimitry Andric break; 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric assert(DiagLoc.isValid() && "no location for diagnostic"); 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric // Issue the diagnostic and produce fixits showing where the ellipsis 11850b57cec5SDimitry Andric // should have been written. 11860b57cec5SDimitry Andric auto &&D = Diag(DiagLoc, DiagID); 11870b57cec5SDimitry Andric if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) { 11880b57cec5SDimitry Andric SourceLocation ExpectedLoc = 11890b57cec5SDimitry Andric InitCapture ? Loc 11900b57cec5SDimitry Andric : Lexer::getLocForEndOfToken( 11910b57cec5SDimitry Andric Loc, 0, PP.getSourceManager(), getLangOpts()); 11920b57cec5SDimitry Andric D << InitCapture << FixItHint::CreateInsertion(ExpectedLoc, "..."); 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric for (SourceLocation &Loc : EllipsisLocs) { 11950b57cec5SDimitry Andric if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) 11960b57cec5SDimitry Andric D << FixItHint::CreateRemoval(Loc); 11970b57cec5SDimitry Andric } 11980b57cec5SDimitry Andric }); 11990b57cec5SDimitry Andric } 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric // Process the init-capture initializers now rather than delaying until we 12030b57cec5SDimitry Andric // form the lambda-expression so that they can be handled in the context 12040b57cec5SDimitry Andric // enclosing the lambda-expression, rather than in the context of the 12050b57cec5SDimitry Andric // lambda-expression itself. 12060b57cec5SDimitry Andric ParsedType InitCaptureType; 12070b57cec5SDimitry Andric if (Init.isUsable()) 12080b57cec5SDimitry Andric Init = Actions.CorrectDelayedTyposInExpr(Init.get()); 12090b57cec5SDimitry Andric if (Init.isUsable()) { 12100b57cec5SDimitry Andric NonTentativeAction([&] { 12110b57cec5SDimitry Andric // Get the pointer and store it in an lvalue, so we can use it as an 12120b57cec5SDimitry Andric // out argument. 12130b57cec5SDimitry Andric Expr *InitExpr = Init.get(); 12140b57cec5SDimitry Andric // This performs any lvalue-to-rvalue conversions if necessary, which 12150b57cec5SDimitry Andric // can affect what gets captured in the containing decl-context. 12160b57cec5SDimitry Andric InitCaptureType = Actions.actOnLambdaInitCaptureInitialization( 12170b57cec5SDimitry Andric Loc, Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, InitExpr); 12180b57cec5SDimitry Andric Init = InitExpr; 12190b57cec5SDimitry Andric }); 12200b57cec5SDimitry Andric } 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric SourceLocation LocEnd = PrevTokLocation; 12230b57cec5SDimitry Andric 12240b57cec5SDimitry Andric Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, 12250b57cec5SDimitry Andric InitCaptureType, SourceRange(LocStart, LocEnd)); 12260b57cec5SDimitry Andric } 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric T.consumeClose(); 12290b57cec5SDimitry Andric Intro.Range.setEnd(T.getCloseLocation()); 12300b57cec5SDimitry Andric return false; 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric 12330b57cec5SDimitry Andric static void tryConsumeLambdaSpecifierToken(Parser &P, 12340b57cec5SDimitry Andric SourceLocation &MutableLoc, 1235bdd1243dSDimitry Andric SourceLocation &StaticLoc, 12360b57cec5SDimitry Andric SourceLocation &ConstexprLoc, 12370b57cec5SDimitry Andric SourceLocation &ConstevalLoc, 12380b57cec5SDimitry Andric SourceLocation &DeclEndLoc) { 12390b57cec5SDimitry Andric assert(MutableLoc.isInvalid()); 1240bdd1243dSDimitry Andric assert(StaticLoc.isInvalid()); 12410b57cec5SDimitry Andric assert(ConstexprLoc.isInvalid()); 1242bdd1243dSDimitry Andric assert(ConstevalLoc.isInvalid()); 12430b57cec5SDimitry Andric // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc 12440b57cec5SDimitry Andric // to the final of those locations. Emit an error if we have multiple 12450b57cec5SDimitry Andric // copies of those keywords and recover. 12460b57cec5SDimitry Andric 1247bdd1243dSDimitry Andric auto ConsumeLocation = [&P, &DeclEndLoc](SourceLocation &SpecifierLoc, 1248bdd1243dSDimitry Andric int DiagIndex) { 1249bdd1243dSDimitry Andric if (SpecifierLoc.isValid()) { 1250bdd1243dSDimitry Andric P.Diag(P.getCurToken().getLocation(), 1251bdd1243dSDimitry Andric diag::err_lambda_decl_specifier_repeated) 1252bdd1243dSDimitry Andric << DiagIndex 1253bdd1243dSDimitry Andric << FixItHint::CreateRemoval(P.getCurToken().getLocation()); 1254bdd1243dSDimitry Andric } 1255bdd1243dSDimitry Andric SpecifierLoc = P.ConsumeToken(); 1256bdd1243dSDimitry Andric DeclEndLoc = SpecifierLoc; 1257bdd1243dSDimitry Andric }; 1258bdd1243dSDimitry Andric 12590b57cec5SDimitry Andric while (true) { 12600b57cec5SDimitry Andric switch (P.getCurToken().getKind()) { 1261bdd1243dSDimitry Andric case tok::kw_mutable: 1262bdd1243dSDimitry Andric ConsumeLocation(MutableLoc, 0); 1263bdd1243dSDimitry Andric break; 1264bdd1243dSDimitry Andric case tok::kw_static: 1265bdd1243dSDimitry Andric ConsumeLocation(StaticLoc, 1); 1266bdd1243dSDimitry Andric break; 12670b57cec5SDimitry Andric case tok::kw_constexpr: 1268bdd1243dSDimitry Andric ConsumeLocation(ConstexprLoc, 2); 1269bdd1243dSDimitry Andric break; 12700b57cec5SDimitry Andric case tok::kw_consteval: 1271bdd1243dSDimitry Andric ConsumeLocation(ConstevalLoc, 3); 1272bdd1243dSDimitry Andric break; 12730b57cec5SDimitry Andric default: 12740b57cec5SDimitry Andric return; 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric 1279bdd1243dSDimitry Andric static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc, 1280bdd1243dSDimitry Andric DeclSpec &DS) { 1281bdd1243dSDimitry Andric if (StaticLoc.isValid()) { 128206c3fb27SDimitry Andric P.Diag(StaticLoc, !P.getLangOpts().CPlusPlus23 1283bdd1243dSDimitry Andric ? diag::err_static_lambda 1284bdd1243dSDimitry Andric : diag::warn_cxx20_compat_static_lambda); 1285bdd1243dSDimitry Andric const char *PrevSpec = nullptr; 1286bdd1243dSDimitry Andric unsigned DiagID = 0; 1287bdd1243dSDimitry Andric DS.SetStorageClassSpec(P.getActions(), DeclSpec::SCS_static, StaticLoc, 1288bdd1243dSDimitry Andric PrevSpec, DiagID, 1289bdd1243dSDimitry Andric P.getActions().getASTContext().getPrintingPolicy()); 1290bdd1243dSDimitry Andric assert(PrevSpec == nullptr && DiagID == 0 && 1291bdd1243dSDimitry Andric "Static cannot have been set previously!"); 1292bdd1243dSDimitry Andric } 1293bdd1243dSDimitry Andric } 1294bdd1243dSDimitry Andric 12950b57cec5SDimitry Andric static void 12960b57cec5SDimitry Andric addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, 12970b57cec5SDimitry Andric DeclSpec &DS) { 12980b57cec5SDimitry Andric if (ConstexprLoc.isValid()) { 12990b57cec5SDimitry Andric P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus17 13000b57cec5SDimitry Andric ? diag::ext_constexpr_on_lambda_cxx17 13010b57cec5SDimitry Andric : diag::warn_cxx14_compat_constexpr_on_lambda); 13020b57cec5SDimitry Andric const char *PrevSpec = nullptr; 13030b57cec5SDimitry Andric unsigned DiagID = 0; 1304e8d8bef9SDimitry Andric DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, ConstexprLoc, PrevSpec, 1305e8d8bef9SDimitry Andric DiagID); 13060b57cec5SDimitry Andric assert(PrevSpec == nullptr && DiagID == 0 && 13070b57cec5SDimitry Andric "Constexpr cannot have been set previously!"); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric } 13100b57cec5SDimitry Andric 13110b57cec5SDimitry Andric static void addConstevalToLambdaDeclSpecifier(Parser &P, 13120b57cec5SDimitry Andric SourceLocation ConstevalLoc, 13130b57cec5SDimitry Andric DeclSpec &DS) { 13140b57cec5SDimitry Andric if (ConstevalLoc.isValid()) { 13150b57cec5SDimitry Andric P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval); 13160b57cec5SDimitry Andric const char *PrevSpec = nullptr; 13170b57cec5SDimitry Andric unsigned DiagID = 0; 1318e8d8bef9SDimitry Andric DS.SetConstexprSpec(ConstexprSpecKind::Consteval, ConstevalLoc, PrevSpec, 1319e8d8bef9SDimitry Andric DiagID); 13200b57cec5SDimitry Andric if (DiagID != 0) 13210b57cec5SDimitry Andric P.Diag(ConstevalLoc, DiagID) << PrevSpec; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric } 13240b57cec5SDimitry Andric 1325bdd1243dSDimitry Andric static void DiagnoseStaticSpecifierRestrictions(Parser &P, 1326bdd1243dSDimitry Andric SourceLocation StaticLoc, 1327bdd1243dSDimitry Andric SourceLocation MutableLoc, 1328bdd1243dSDimitry Andric const LambdaIntroducer &Intro) { 1329bdd1243dSDimitry Andric if (StaticLoc.isInvalid()) 1330bdd1243dSDimitry Andric return; 1331bdd1243dSDimitry Andric 1332bdd1243dSDimitry Andric // [expr.prim.lambda.general] p4 1333bdd1243dSDimitry Andric // The lambda-specifier-seq shall not contain both mutable and static. 1334bdd1243dSDimitry Andric // If the lambda-specifier-seq contains static, there shall be no 1335bdd1243dSDimitry Andric // lambda-capture. 1336bdd1243dSDimitry Andric if (MutableLoc.isValid()) 1337bdd1243dSDimitry Andric P.Diag(StaticLoc, diag::err_static_mutable_lambda); 1338bdd1243dSDimitry Andric if (Intro.hasLambdaCapture()) { 1339bdd1243dSDimitry Andric P.Diag(StaticLoc, diag::err_static_lambda_captures); 1340bdd1243dSDimitry Andric } 1341bdd1243dSDimitry Andric } 1342bdd1243dSDimitry Andric 13430b57cec5SDimitry Andric /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda 13440b57cec5SDimitry Andric /// expression. 13450b57cec5SDimitry Andric ExprResult Parser::ParseLambdaExpressionAfterIntroducer( 13460b57cec5SDimitry Andric LambdaIntroducer &Intro) { 13470b57cec5SDimitry Andric SourceLocation LambdaBeginLoc = Intro.Range.getBegin(); 1348*0fca6ea1SDimitry Andric Diag(LambdaBeginLoc, getLangOpts().CPlusPlus11 1349*0fca6ea1SDimitry Andric ? diag::warn_cxx98_compat_lambda 1350*0fca6ea1SDimitry Andric : diag::ext_lambda); 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, 13530b57cec5SDimitry Andric "lambda expression parsing"); 13540b57cec5SDimitry Andric 13550b57cec5SDimitry Andric // Parse lambda-declarator[opt]. 13560b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 135781ad6265SDimitry Andric Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::LambdaExpr); 13580b57cec5SDimitry Andric TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); 13590b57cec5SDimitry Andric 136006c3fb27SDimitry Andric ParseScope LambdaScope(this, Scope::LambdaScope | Scope::DeclScope | 136106c3fb27SDimitry Andric Scope::FunctionDeclarationScope | 136206c3fb27SDimitry Andric Scope::FunctionPrototypeScope); 136306c3fb27SDimitry Andric 136406c3fb27SDimitry Andric Actions.PushLambdaScope(); 136506c3fb27SDimitry Andric Actions.ActOnLambdaExpressionAfterIntroducer(Intro, getCurScope()); 136606c3fb27SDimitry Andric 136706c3fb27SDimitry Andric ParsedAttributes Attributes(AttrFactory); 13680b57cec5SDimitry Andric if (getLangOpts().CUDA) { 13690b57cec5SDimitry Andric // In CUDA code, GNU attributes are allowed to appear immediately after the 13700b57cec5SDimitry Andric // "[...]", even if there is no "(...)" before the lambda body. 1371bdd1243dSDimitry Andric // 1372bdd1243dSDimitry Andric // Note that we support __noinline__ as a keyword in this mode and thus 1373bdd1243dSDimitry Andric // it has to be separately handled. 1374bdd1243dSDimitry Andric while (true) { 1375bdd1243dSDimitry Andric if (Tok.is(tok::kw___noinline__)) { 1376bdd1243dSDimitry Andric IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 1377bdd1243dSDimitry Andric SourceLocation AttrNameLoc = ConsumeToken(); 137806c3fb27SDimitry Andric Attributes.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr, 137906c3fb27SDimitry Andric AttrNameLoc, /*ArgsUnion=*/nullptr, 138006c3fb27SDimitry Andric /*numArgs=*/0, tok::kw___noinline__); 1381bdd1243dSDimitry Andric } else if (Tok.is(tok::kw___attribute)) 138206c3fb27SDimitry Andric ParseGNUAttributes(Attributes, /*LatePArsedAttrList=*/nullptr, &D); 1383bdd1243dSDimitry Andric else 1384bdd1243dSDimitry Andric break; 1385bdd1243dSDimitry Andric } 1386bdd1243dSDimitry Andric 138706c3fb27SDimitry Andric D.takeAttributes(Attributes); 13880b57cec5SDimitry Andric } 13890b57cec5SDimitry Andric 13905ffd83dbSDimitry Andric MultiParseScope TemplateParamScope(*this); 13915ffd83dbSDimitry Andric if (Tok.is(tok::less)) { 13925ffd83dbSDimitry Andric Diag(Tok, getLangOpts().CPlusPlus20 13930b57cec5SDimitry Andric ? diag::warn_cxx17_compat_lambda_template_parameter_list 13940b57cec5SDimitry Andric : diag::ext_lambda_template_parameter_list); 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric SmallVector<NamedDecl*, 4> TemplateParams; 13970b57cec5SDimitry Andric SourceLocation LAngleLoc, RAngleLoc; 13985ffd83dbSDimitry Andric if (ParseTemplateParameters(TemplateParamScope, 13995ffd83dbSDimitry Andric CurTemplateDepthTracker.getDepth(), 14000b57cec5SDimitry Andric TemplateParams, LAngleLoc, RAngleLoc)) { 14010b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 14020b57cec5SDimitry Andric return ExprError(); 14030b57cec5SDimitry Andric } 14040b57cec5SDimitry Andric 14050b57cec5SDimitry Andric if (TemplateParams.empty()) { 14060b57cec5SDimitry Andric Diag(RAngleLoc, 14070b57cec5SDimitry Andric diag::err_lambda_template_parameter_list_empty); 14080b57cec5SDimitry Andric } else { 1409*0fca6ea1SDimitry Andric // We increase the template depth before recursing into a requires-clause. 1410*0fca6ea1SDimitry Andric // 1411*0fca6ea1SDimitry Andric // This depth is used for setting up a LambdaScopeInfo (in 1412*0fca6ea1SDimitry Andric // Sema::RecordParsingTemplateParameterDepth), which is used later when 1413*0fca6ea1SDimitry Andric // inventing template parameters in InventTemplateParameter. 1414*0fca6ea1SDimitry Andric // 1415*0fca6ea1SDimitry Andric // This way, abbreviated generic lambdas could have different template 1416*0fca6ea1SDimitry Andric // depths, avoiding substitution into the wrong template parameters during 1417*0fca6ea1SDimitry Andric // constraint satisfaction check. 1418*0fca6ea1SDimitry Andric ++CurTemplateDepthTracker; 1419e8d8bef9SDimitry Andric ExprResult RequiresClause; 1420e8d8bef9SDimitry Andric if (TryConsumeToken(tok::kw_requires)) { 1421e8d8bef9SDimitry Andric RequiresClause = 1422e8d8bef9SDimitry Andric Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression( 1423e8d8bef9SDimitry Andric /*IsTrailingRequiresClause=*/false)); 1424e8d8bef9SDimitry Andric if (RequiresClause.isInvalid()) 1425e8d8bef9SDimitry Andric SkipUntil({tok::l_brace, tok::l_paren}, StopAtSemi | StopBeforeMatch); 1426e8d8bef9SDimitry Andric } 1427e8d8bef9SDimitry Andric 14280b57cec5SDimitry Andric Actions.ActOnLambdaExplicitTemplateParameterList( 142906c3fb27SDimitry Andric Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause); 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric 1433fe6060f1SDimitry Andric // Implement WG21 P2173, which allows attributes immediately before the 1434fe6060f1SDimitry Andric // lambda declarator and applies them to the corresponding function operator 1435fe6060f1SDimitry Andric // or operator template declaration. We accept this as a conforming extension 1436fe6060f1SDimitry Andric // in all language modes that support lambdas. 1437fe6060f1SDimitry Andric if (isCXX11AttributeSpecifier()) { 143806c3fb27SDimitry Andric Diag(Tok, getLangOpts().CPlusPlus23 1439fe6060f1SDimitry Andric ? diag::warn_cxx20_compat_decl_attrs_on_lambda 144006c3fb27SDimitry Andric : diag::ext_decl_attrs_on_lambda) 144106c3fb27SDimitry Andric << Tok.getIdentifierInfo() << Tok.isRegularKeywordAttribute(); 1442fe6060f1SDimitry Andric MaybeParseCXX11Attributes(D); 1443fe6060f1SDimitry Andric } 1444fe6060f1SDimitry Andric 14450b57cec5SDimitry Andric TypeResult TrailingReturnType; 1446e8d8bef9SDimitry Andric SourceLocation TrailingReturnTypeLoc; 144706c3fb27SDimitry Andric SourceLocation LParenLoc, RParenLoc; 144806c3fb27SDimitry Andric SourceLocation DeclEndLoc; 144906c3fb27SDimitry Andric bool HasParentheses = false; 145006c3fb27SDimitry Andric bool HasSpecifiers = false; 145106c3fb27SDimitry Andric SourceLocation MutableLoc; 1452fe6060f1SDimitry Andric 145306c3fb27SDimitry Andric ParseScope Prototype(this, Scope::FunctionPrototypeScope | 14540b57cec5SDimitry Andric Scope::FunctionDeclarationScope | 14550b57cec5SDimitry Andric Scope::DeclScope); 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric // Parse parameter-declaration-clause. 14580b57cec5SDimitry Andric SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 14590b57cec5SDimitry Andric SourceLocation EllipsisLoc; 14600b57cec5SDimitry Andric 146106c3fb27SDimitry Andric if (Tok.is(tok::l_paren)) { 146206c3fb27SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 146306c3fb27SDimitry Andric T.consumeOpen(); 146406c3fb27SDimitry Andric LParenLoc = T.getOpenLocation(); 146506c3fb27SDimitry Andric 14660b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 14670b57cec5SDimitry Andric Actions.RecordParsingTemplateParameterDepth( 14680b57cec5SDimitry Andric CurTemplateDepthTracker.getOriginalDepth()); 14690b57cec5SDimitry Andric 147006c3fb27SDimitry Andric ParseParameterDeclarationClause(D, Attributes, ParamInfo, EllipsisLoc); 14710b57cec5SDimitry Andric // For a generic lambda, each 'auto' within the parameter declaration 14720b57cec5SDimitry Andric // clause creates a template type parameter, so increment the depth. 14730b57cec5SDimitry Andric // If we've parsed any explicit template parameters, then the depth will 14740b57cec5SDimitry Andric // have already been incremented. So we make sure that at most a single 14750b57cec5SDimitry Andric // depth level is added. 14760b57cec5SDimitry Andric if (Actions.getCurGenericLambda()) 14770b57cec5SDimitry Andric CurTemplateDepthTracker.setAddedDepth(1); 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric T.consumeClose(); 148106c3fb27SDimitry Andric DeclEndLoc = RParenLoc = T.getCloseLocation(); 148206c3fb27SDimitry Andric HasParentheses = true; 148306c3fb27SDimitry Andric } 14840b57cec5SDimitry Andric 148506c3fb27SDimitry Andric HasSpecifiers = 148606c3fb27SDimitry Andric Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, 1487bdd1243dSDimitry Andric tok::kw_constexpr, tok::kw_consteval, tok::kw_static, 1488480093f4SDimitry Andric tok::kw___private, tok::kw___global, tok::kw___local, 148906c3fb27SDimitry Andric tok::kw___constant, tok::kw___generic, tok::kw_groupshared, 149006c3fb27SDimitry Andric tok::kw_requires, tok::kw_noexcept) || 149106c3fb27SDimitry Andric Tok.isRegularKeywordAttribute() || 149206c3fb27SDimitry Andric (Tok.is(tok::l_square) && NextToken().is(tok::l_square)); 149306c3fb27SDimitry Andric 149406c3fb27SDimitry Andric if (HasSpecifiers && !HasParentheses && !getLangOpts().CPlusPlus23) { 1495fe6060f1SDimitry Andric // It's common to forget that one needs '()' before 'mutable', an 1496fe6060f1SDimitry Andric // attribute specifier, the result type, or the requires clause. Deal with 1497fe6060f1SDimitry Andric // this. 1498fe6060f1SDimitry Andric Diag(Tok, diag::ext_lambda_missing_parens) 14990b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "() "); 1500fe6060f1SDimitry Andric } 1501480093f4SDimitry Andric 15025f757f3fSDimitry Andric if (HasParentheses || HasSpecifiers) { 15035f757f3fSDimitry Andric // GNU-style attributes must be parsed before the mutable specifier to 15045f757f3fSDimitry Andric // be compatible with GCC. MSVC-style attributes must be parsed before 15055f757f3fSDimitry Andric // the mutable specifier to be compatible with MSVC. 15065f757f3fSDimitry Andric MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes); 15075f757f3fSDimitry Andric // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update 15085f757f3fSDimitry Andric // the DeclEndLoc. 15095f757f3fSDimitry Andric SourceLocation ConstexprLoc; 15105f757f3fSDimitry Andric SourceLocation ConstevalLoc; 15115f757f3fSDimitry Andric SourceLocation StaticLoc; 15125f757f3fSDimitry Andric 15135f757f3fSDimitry Andric tryConsumeLambdaSpecifierToken(*this, MutableLoc, StaticLoc, ConstexprLoc, 15145f757f3fSDimitry Andric ConstevalLoc, DeclEndLoc); 15155f757f3fSDimitry Andric 15165f757f3fSDimitry Andric DiagnoseStaticSpecifierRestrictions(*this, StaticLoc, MutableLoc, Intro); 15175f757f3fSDimitry Andric 15185f757f3fSDimitry Andric addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS); 15195f757f3fSDimitry Andric addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); 15205f757f3fSDimitry Andric addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); 15215f757f3fSDimitry Andric } 152206c3fb27SDimitry Andric 152306c3fb27SDimitry Andric Actions.ActOnLambdaClosureParameters(getCurScope(), ParamInfo); 152406c3fb27SDimitry Andric 152506c3fb27SDimitry Andric if (!HasParentheses) 152606c3fb27SDimitry Andric Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); 152706c3fb27SDimitry Andric 15285f757f3fSDimitry Andric if (HasSpecifiers || HasParentheses) { 15295f757f3fSDimitry Andric // Parse exception-specification[opt]. 15305f757f3fSDimitry Andric ExceptionSpecificationType ESpecType = EST_None; 15315f757f3fSDimitry Andric SourceRange ESpecRange; 15325f757f3fSDimitry Andric SmallVector<ParsedType, 2> DynamicExceptions; 15335f757f3fSDimitry Andric SmallVector<SourceRange, 2> DynamicExceptionRanges; 15345f757f3fSDimitry Andric ExprResult NoexceptExpr; 15355f757f3fSDimitry Andric CachedTokens *ExceptionSpecTokens; 153606c3fb27SDimitry Andric 15375f757f3fSDimitry Andric ESpecType = tryParseExceptionSpecification( 15385f757f3fSDimitry Andric /*Delayed=*/false, ESpecRange, DynamicExceptions, 15395f757f3fSDimitry Andric DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens); 15405f757f3fSDimitry Andric 15415f757f3fSDimitry Andric if (ESpecType != EST_None) 15425f757f3fSDimitry Andric DeclEndLoc = ESpecRange.getEnd(); 15435f757f3fSDimitry Andric 15445f757f3fSDimitry Andric // Parse attribute-specifier[opt]. 15455f757f3fSDimitry Andric if (MaybeParseCXX11Attributes(Attributes)) 15465f757f3fSDimitry Andric DeclEndLoc = Attributes.Range.getEnd(); 15475f757f3fSDimitry Andric 15485f757f3fSDimitry Andric // Parse OpenCL addr space attribute. 15495f757f3fSDimitry Andric if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, 15505f757f3fSDimitry Andric tok::kw___constant, tok::kw___generic)) { 15515f757f3fSDimitry Andric ParseOpenCLQualifiers(DS.getAttributes()); 15525f757f3fSDimitry Andric ConsumeToken(); 15535f757f3fSDimitry Andric } 15545f757f3fSDimitry Andric 15555f757f3fSDimitry Andric SourceLocation FunLocalRangeEnd = DeclEndLoc; 15565f757f3fSDimitry Andric 15575f757f3fSDimitry Andric // Parse trailing-return-type[opt]. 15585f757f3fSDimitry Andric if (Tok.is(tok::arrow)) { 15595f757f3fSDimitry Andric FunLocalRangeEnd = Tok.getLocation(); 15605f757f3fSDimitry Andric SourceRange Range; 15615f757f3fSDimitry Andric TrailingReturnType = 15625f757f3fSDimitry Andric ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false); 15635f757f3fSDimitry Andric TrailingReturnTypeLoc = Range.getBegin(); 15645f757f3fSDimitry Andric if (Range.getEnd().isValid()) 15655f757f3fSDimitry Andric DeclEndLoc = Range.getEnd(); 15665f757f3fSDimitry Andric } 15675f757f3fSDimitry Andric 15685f757f3fSDimitry Andric SourceLocation NoLoc; 15695f757f3fSDimitry Andric D.AddTypeInfo(DeclaratorChunk::getFunction( 15705f757f3fSDimitry Andric /*HasProto=*/true, 15715f757f3fSDimitry Andric /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), 15725f757f3fSDimitry Andric ParamInfo.size(), EllipsisLoc, RParenLoc, 15735f757f3fSDimitry Andric /*RefQualifierIsLvalueRef=*/true, 15745f757f3fSDimitry Andric /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, 15755f757f3fSDimitry Andric ESpecRange, DynamicExceptions.data(), 15765f757f3fSDimitry Andric DynamicExceptionRanges.data(), DynamicExceptions.size(), 15775f757f3fSDimitry Andric NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, 15785f757f3fSDimitry Andric /*ExceptionSpecTokens*/ nullptr, 15795f757f3fSDimitry Andric /*DeclsInPrototype=*/std::nullopt, LParenLoc, 15805f757f3fSDimitry Andric FunLocalRangeEnd, D, TrailingReturnType, 15815f757f3fSDimitry Andric TrailingReturnTypeLoc, &DS), 15825f757f3fSDimitry Andric std::move(Attributes), DeclEndLoc); 15835f757f3fSDimitry Andric 1584*0fca6ea1SDimitry Andric // We have called ActOnLambdaClosureQualifiers for parentheses-less cases 1585*0fca6ea1SDimitry Andric // above. 1586*0fca6ea1SDimitry Andric if (HasParentheses) 15875f757f3fSDimitry Andric Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); 15885f757f3fSDimitry Andric 15895f757f3fSDimitry Andric if (HasParentheses && Tok.is(tok::kw_requires)) 15905f757f3fSDimitry Andric ParseTrailingRequiresClause(D); 15915f757f3fSDimitry Andric } 15925f757f3fSDimitry Andric 15935f757f3fSDimitry Andric // Emit a warning if we see a CUDA host/device/global attribute 15945f757f3fSDimitry Andric // after '(...)'. nvcc doesn't accept this. 15955f757f3fSDimitry Andric if (getLangOpts().CUDA) { 15965f757f3fSDimitry Andric for (const ParsedAttr &A : Attributes) 15975f757f3fSDimitry Andric if (A.getKind() == ParsedAttr::AT_CUDADevice || 15985f757f3fSDimitry Andric A.getKind() == ParsedAttr::AT_CUDAHost || 15995f757f3fSDimitry Andric A.getKind() == ParsedAttr::AT_CUDAGlobal) 16005f757f3fSDimitry Andric Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) 16015f757f3fSDimitry Andric << A.getAttrName()->getName(); 16025f757f3fSDimitry Andric } 16030b57cec5SDimitry Andric 160406c3fb27SDimitry Andric Prototype.Exit(); 160506c3fb27SDimitry Andric 16060b57cec5SDimitry Andric // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using 16070b57cec5SDimitry Andric // it. 16080b57cec5SDimitry Andric unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope | 16090b57cec5SDimitry Andric Scope::CompoundStmtScope; 16100b57cec5SDimitry Andric ParseScope BodyScope(this, ScopeFlags); 16110b57cec5SDimitry Andric 161206c3fb27SDimitry Andric Actions.ActOnStartOfLambdaDefinition(Intro, D, DS); 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andric // Parse compound-statement. 16150b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 16160b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lambda_body); 16170b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 16180b57cec5SDimitry Andric return ExprError(); 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 16220b57cec5SDimitry Andric BodyScope.Exit(); 16230b57cec5SDimitry Andric TemplateParamScope.Exit(); 162406c3fb27SDimitry Andric LambdaScope.Exit(); 16250b57cec5SDimitry Andric 16265f757f3fSDimitry Andric if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid() && 16275f757f3fSDimitry Andric !D.isInvalidType()) 16285f757f3fSDimitry Andric return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get()); 16290b57cec5SDimitry Andric 16300b57cec5SDimitry Andric Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 16310b57cec5SDimitry Andric return ExprError(); 16320b57cec5SDimitry Andric } 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric /// ParseCXXCasts - This handles the various ways to cast expressions to another 16350b57cec5SDimitry Andric /// type. 16360b57cec5SDimitry Andric /// 16370b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 16380b57cec5SDimitry Andric /// 'dynamic_cast' '<' type-name '>' '(' expression ')' 16390b57cec5SDimitry Andric /// 'static_cast' '<' type-name '>' '(' expression ')' 16400b57cec5SDimitry Andric /// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 16410b57cec5SDimitry Andric /// 'const_cast' '<' type-name '>' '(' expression ')' 16420b57cec5SDimitry Andric /// 16435ffd83dbSDimitry Andric /// C++ for OpenCL s2.3.1 adds: 16445ffd83dbSDimitry Andric /// 'addrspace_cast' '<' type-name '>' '(' expression ')' 16450b57cec5SDimitry Andric ExprResult Parser::ParseCXXCasts() { 16460b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 16470b57cec5SDimitry Andric const char *CastName = nullptr; // For error messages 16480b57cec5SDimitry Andric 16490b57cec5SDimitry Andric switch (Kind) { 16500b57cec5SDimitry Andric default: llvm_unreachable("Unknown C++ cast!"); 16515ffd83dbSDimitry Andric case tok::kw_addrspace_cast: CastName = "addrspace_cast"; break; 16520b57cec5SDimitry Andric case tok::kw_const_cast: CastName = "const_cast"; break; 16530b57cec5SDimitry Andric case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 16540b57cec5SDimitry Andric case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 16550b57cec5SDimitry Andric case tok::kw_static_cast: CastName = "static_cast"; break; 16560b57cec5SDimitry Andric } 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 16590b57cec5SDimitry Andric SourceLocation LAngleBracketLoc = Tok.getLocation(); 16600b57cec5SDimitry Andric 16610b57cec5SDimitry Andric // Check for "<::" which is parsed as "[:". If found, fix token stream, 16620b57cec5SDimitry Andric // diagnose error, suggest fix, and recover parsing. 16630b57cec5SDimitry Andric if (Tok.is(tok::l_square) && Tok.getLength() == 2) { 16640b57cec5SDimitry Andric Token Next = NextToken(); 16650b57cec5SDimitry Andric if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next)) 16660b57cec5SDimitry Andric FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); 16670b57cec5SDimitry Andric } 16680b57cec5SDimitry Andric 16690b57cec5SDimitry Andric if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 16700b57cec5SDimitry Andric return ExprError(); 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 16730b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 1674bdd1243dSDimitry Andric ParseSpecifierQualifierList(DS, /*AccessSpecifier=*/AS_none, 1675bdd1243dSDimitry Andric DeclSpecContext::DSC_type_specifier); 16760b57cec5SDimitry Andric 16770b57cec5SDimitry Andric // Parse the abstract-declarator, if present. 167881ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 167981ad6265SDimitry Andric DeclaratorContext::TypeName); 16800b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric SourceLocation RAngleBracketLoc = Tok.getLocation(); 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric if (ExpectAndConsume(tok::greater)) 16850b57cec5SDimitry Andric return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less); 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 16880b57cec5SDimitry Andric 16890b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) 16900b57cec5SDimitry Andric return ExprError(); 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric ExprResult Result = ParseExpression(); 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andric // Match the ')'. 16950b57cec5SDimitry Andric T.consumeClose(); 16960b57cec5SDimitry Andric 16970b57cec5SDimitry Andric if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) 16980b57cec5SDimitry Andric Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 16990b57cec5SDimitry Andric LAngleBracketLoc, DeclaratorInfo, 17000b57cec5SDimitry Andric RAngleBracketLoc, 17010b57cec5SDimitry Andric T.getOpenLocation(), Result.get(), 17020b57cec5SDimitry Andric T.getCloseLocation()); 17030b57cec5SDimitry Andric 17040b57cec5SDimitry Andric return Result; 17050b57cec5SDimitry Andric } 17060b57cec5SDimitry Andric 17070b57cec5SDimitry Andric /// ParseCXXTypeid - This handles the C++ typeid expression. 17080b57cec5SDimitry Andric /// 17090b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 17100b57cec5SDimitry Andric /// 'typeid' '(' expression ')' 17110b57cec5SDimitry Andric /// 'typeid' '(' type-id ')' 17120b57cec5SDimitry Andric /// 17130b57cec5SDimitry Andric ExprResult Parser::ParseCXXTypeid() { 17140b57cec5SDimitry Andric assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 17170b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 17180b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 17190b57cec5SDimitry Andric 17200b57cec5SDimitry Andric // typeid expressions are always parenthesized. 17210b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) 17220b57cec5SDimitry Andric return ExprError(); 17230b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 17240b57cec5SDimitry Andric 17250b57cec5SDimitry Andric ExprResult Result; 17260b57cec5SDimitry Andric 17270b57cec5SDimitry Andric // C++0x [expr.typeid]p3: 17280b57cec5SDimitry Andric // When typeid is applied to an expression other than an lvalue of a 17290b57cec5SDimitry Andric // polymorphic class type [...] The expression is an unevaluated 17300b57cec5SDimitry Andric // operand (Clause 5). 17310b57cec5SDimitry Andric // 17320b57cec5SDimitry Andric // Note that we can't tell whether the expression is an lvalue of a 17330b57cec5SDimitry Andric // polymorphic class type until after we've parsed the expression; we 17340b57cec5SDimitry Andric // speculatively assume the subexpression is unevaluated, and fix it up 17350b57cec5SDimitry Andric // later. 17360b57cec5SDimitry Andric // 17370b57cec5SDimitry Andric // We enter the unevaluated context before trying to determine whether we 17380b57cec5SDimitry Andric // have a type-id, because the tentative parse logic will try to resolve 17390b57cec5SDimitry Andric // names, and must treat them as unevaluated. 17400b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 17410b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 17420b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 17430b57cec5SDimitry Andric 17440b57cec5SDimitry Andric if (isTypeIdInParens()) { 17450b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 17460b57cec5SDimitry Andric 17470b57cec5SDimitry Andric // Match the ')'. 17480b57cec5SDimitry Andric T.consumeClose(); 17490b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 17500b57cec5SDimitry Andric if (Ty.isInvalid() || RParenLoc.isInvalid()) 17510b57cec5SDimitry Andric return ExprError(); 17520b57cec5SDimitry Andric 17530b57cec5SDimitry Andric Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 17540b57cec5SDimitry Andric Ty.get().getAsOpaquePtr(), RParenLoc); 17550b57cec5SDimitry Andric } else { 17560b57cec5SDimitry Andric Result = ParseExpression(); 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric // Match the ')'. 17590b57cec5SDimitry Andric if (Result.isInvalid()) 17600b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 17610b57cec5SDimitry Andric else { 17620b57cec5SDimitry Andric T.consumeClose(); 17630b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 17640b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 17650b57cec5SDimitry Andric return ExprError(); 17660b57cec5SDimitry Andric 17670b57cec5SDimitry Andric Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 17680b57cec5SDimitry Andric Result.get(), RParenLoc); 17690b57cec5SDimitry Andric } 17700b57cec5SDimitry Andric } 17710b57cec5SDimitry Andric 17720b57cec5SDimitry Andric return Result; 17730b57cec5SDimitry Andric } 17740b57cec5SDimitry Andric 17750b57cec5SDimitry Andric /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. 17760b57cec5SDimitry Andric /// 17770b57cec5SDimitry Andric /// '__uuidof' '(' expression ')' 17780b57cec5SDimitry Andric /// '__uuidof' '(' type-id ')' 17790b57cec5SDimitry Andric /// 17800b57cec5SDimitry Andric ExprResult Parser::ParseCXXUuidof() { 17810b57cec5SDimitry Andric assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); 17820b57cec5SDimitry Andric 17830b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 17840b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 17850b57cec5SDimitry Andric 17860b57cec5SDimitry Andric // __uuidof expressions are always parenthesized. 17870b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) 17880b57cec5SDimitry Andric return ExprError(); 17890b57cec5SDimitry Andric 17900b57cec5SDimitry Andric ExprResult Result; 17910b57cec5SDimitry Andric 17920b57cec5SDimitry Andric if (isTypeIdInParens()) { 17930b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 17940b57cec5SDimitry Andric 17950b57cec5SDimitry Andric // Match the ')'. 17960b57cec5SDimitry Andric T.consumeClose(); 17970b57cec5SDimitry Andric 17980b57cec5SDimitry Andric if (Ty.isInvalid()) 17990b57cec5SDimitry Andric return ExprError(); 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andric Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, 18020b57cec5SDimitry Andric Ty.get().getAsOpaquePtr(), 18030b57cec5SDimitry Andric T.getCloseLocation()); 18040b57cec5SDimitry Andric } else { 18050b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 18060b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 18070b57cec5SDimitry Andric Result = ParseExpression(); 18080b57cec5SDimitry Andric 18090b57cec5SDimitry Andric // Match the ')'. 18100b57cec5SDimitry Andric if (Result.isInvalid()) 18110b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 18120b57cec5SDimitry Andric else { 18130b57cec5SDimitry Andric T.consumeClose(); 18140b57cec5SDimitry Andric 18150b57cec5SDimitry Andric Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), 18160b57cec5SDimitry Andric /*isType=*/false, 18170b57cec5SDimitry Andric Result.get(), T.getCloseLocation()); 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric } 18200b57cec5SDimitry Andric 18210b57cec5SDimitry Andric return Result; 18220b57cec5SDimitry Andric } 18230b57cec5SDimitry Andric 18240b57cec5SDimitry Andric /// Parse a C++ pseudo-destructor expression after the base, 18250b57cec5SDimitry Andric /// . or -> operator, and nested-name-specifier have already been 18265ffd83dbSDimitry Andric /// parsed. We're handling this fragment of the grammar: 18270b57cec5SDimitry Andric /// 18285ffd83dbSDimitry Andric /// postfix-expression: [C++2a expr.post] 18295ffd83dbSDimitry Andric /// postfix-expression . template[opt] id-expression 18305ffd83dbSDimitry Andric /// postfix-expression -> template[opt] id-expression 18310b57cec5SDimitry Andric /// 18325ffd83dbSDimitry Andric /// id-expression: 18335ffd83dbSDimitry Andric /// qualified-id 18345ffd83dbSDimitry Andric /// unqualified-id 18355ffd83dbSDimitry Andric /// 18365ffd83dbSDimitry Andric /// qualified-id: 18375ffd83dbSDimitry Andric /// nested-name-specifier template[opt] unqualified-id 18385ffd83dbSDimitry Andric /// 18395ffd83dbSDimitry Andric /// nested-name-specifier: 18405ffd83dbSDimitry Andric /// type-name :: 18415ffd83dbSDimitry Andric /// decltype-specifier :: FIXME: not implemented, but probably only 18425ffd83dbSDimitry Andric /// allowed in C++ grammar by accident 18435ffd83dbSDimitry Andric /// nested-name-specifier identifier :: 18445ffd83dbSDimitry Andric /// nested-name-specifier template[opt] simple-template-id :: 18455ffd83dbSDimitry Andric /// [...] 18465ffd83dbSDimitry Andric /// 18475ffd83dbSDimitry Andric /// unqualified-id: 18480b57cec5SDimitry Andric /// ~ type-name 18495ffd83dbSDimitry Andric /// ~ decltype-specifier 18505ffd83dbSDimitry Andric /// [...] 18510b57cec5SDimitry Andric /// 18525ffd83dbSDimitry Andric /// ... where the all but the last component of the nested-name-specifier 18535ffd83dbSDimitry Andric /// has already been parsed, and the base expression is not of a non-dependent 18545ffd83dbSDimitry Andric /// class type. 18550b57cec5SDimitry Andric ExprResult 18560b57cec5SDimitry Andric Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, 18570b57cec5SDimitry Andric tok::TokenKind OpKind, 18580b57cec5SDimitry Andric CXXScopeSpec &SS, 18590b57cec5SDimitry Andric ParsedType ObjectType) { 18605ffd83dbSDimitry Andric // If the last component of the (optional) nested-name-specifier is 18615ffd83dbSDimitry Andric // template[opt] simple-template-id, it has already been annotated. 18620b57cec5SDimitry Andric UnqualifiedId FirstTypeName; 18630b57cec5SDimitry Andric SourceLocation CCLoc; 18640b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 18650b57cec5SDimitry Andric FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 18660b57cec5SDimitry Andric ConsumeToken(); 18670b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 18680b57cec5SDimitry Andric CCLoc = ConsumeToken(); 18690b57cec5SDimitry Andric } else if (Tok.is(tok::annot_template_id)) { 18705ffd83dbSDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 18715ffd83dbSDimitry Andric // FIXME: Carry on and build an AST representation for tooling. 18725ffd83dbSDimitry Andric if (TemplateId->isInvalid()) 18735ffd83dbSDimitry Andric return ExprError(); 18745ffd83dbSDimitry Andric FirstTypeName.setTemplateId(TemplateId); 18750b57cec5SDimitry Andric ConsumeAnnotationToken(); 18760b57cec5SDimitry Andric assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 18770b57cec5SDimitry Andric CCLoc = ConsumeToken(); 18780b57cec5SDimitry Andric } else { 18795ffd83dbSDimitry Andric assert(SS.isEmpty() && "missing last component of nested name specifier"); 18800b57cec5SDimitry Andric FirstTypeName.setIdentifier(nullptr, SourceLocation()); 18810b57cec5SDimitry Andric } 18820b57cec5SDimitry Andric 18830b57cec5SDimitry Andric // Parse the tilde. 18840b57cec5SDimitry Andric assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 18850b57cec5SDimitry Andric SourceLocation TildeLoc = ConsumeToken(); 18860b57cec5SDimitry Andric 18875ffd83dbSDimitry Andric if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid()) { 18880b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 18890b57cec5SDimitry Andric ParseDecltypeSpecifier(DS); 18900b57cec5SDimitry Andric if (DS.getTypeSpecType() == TST_error) 18910b57cec5SDimitry Andric return ExprError(); 18920b57cec5SDimitry Andric return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, 18930b57cec5SDimitry Andric TildeLoc, DS); 18940b57cec5SDimitry Andric } 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) { 18970b57cec5SDimitry Andric Diag(Tok, diag::err_destructor_tilde_identifier); 18980b57cec5SDimitry Andric return ExprError(); 18990b57cec5SDimitry Andric } 19000b57cec5SDimitry Andric 1901*0fca6ea1SDimitry Andric // pack-index-specifier 1902*0fca6ea1SDimitry Andric if (GetLookAheadToken(1).is(tok::ellipsis) && 1903*0fca6ea1SDimitry Andric GetLookAheadToken(2).is(tok::l_square)) { 1904*0fca6ea1SDimitry Andric DeclSpec DS(AttrFactory); 1905*0fca6ea1SDimitry Andric ParsePackIndexingType(DS); 1906*0fca6ea1SDimitry Andric return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, 1907*0fca6ea1SDimitry Andric TildeLoc, DS); 1908*0fca6ea1SDimitry Andric } 1909*0fca6ea1SDimitry Andric 19100b57cec5SDimitry Andric // Parse the second type. 19110b57cec5SDimitry Andric UnqualifiedId SecondTypeName; 19120b57cec5SDimitry Andric IdentifierInfo *Name = Tok.getIdentifierInfo(); 19130b57cec5SDimitry Andric SourceLocation NameLoc = ConsumeToken(); 19140b57cec5SDimitry Andric SecondTypeName.setIdentifier(Name, NameLoc); 19150b57cec5SDimitry Andric 19160b57cec5SDimitry Andric // If there is a '<', the second type name is a template-id. Parse 19170b57cec5SDimitry Andric // it as such. 19185ffd83dbSDimitry Andric // 19195ffd83dbSDimitry Andric // FIXME: This is not a context in which a '<' is assumed to start a template 19205ffd83dbSDimitry Andric // argument list. This affects examples such as 19215ffd83dbSDimitry Andric // void f(auto *p) { p->~X<int>(); } 19225ffd83dbSDimitry Andric // ... but there's no ambiguity, and nowhere to write 'template' in such an 19235ffd83dbSDimitry Andric // example, so we accept it anyway. 19240b57cec5SDimitry Andric if (Tok.is(tok::less) && 19255ffd83dbSDimitry Andric ParseUnqualifiedIdTemplateId( 19265ffd83dbSDimitry Andric SS, ObjectType, Base && Base->containsErrors(), SourceLocation(), 19275ffd83dbSDimitry Andric Name, NameLoc, false, SecondTypeName, 19280b57cec5SDimitry Andric /*AssumeTemplateId=*/true)) 19290b57cec5SDimitry Andric return ExprError(); 19300b57cec5SDimitry Andric 19310b57cec5SDimitry Andric return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, 19320b57cec5SDimitry Andric SS, FirstTypeName, CCLoc, TildeLoc, 19330b57cec5SDimitry Andric SecondTypeName); 19340b57cec5SDimitry Andric } 19350b57cec5SDimitry Andric 19360b57cec5SDimitry Andric /// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 19370b57cec5SDimitry Andric /// 19380b57cec5SDimitry Andric /// boolean-literal: [C++ 2.13.5] 19390b57cec5SDimitry Andric /// 'true' 19400b57cec5SDimitry Andric /// 'false' 19410b57cec5SDimitry Andric ExprResult Parser::ParseCXXBoolLiteral() { 19420b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 19430b57cec5SDimitry Andric return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 19440b57cec5SDimitry Andric } 19450b57cec5SDimitry Andric 19460b57cec5SDimitry Andric /// ParseThrowExpression - This handles the C++ throw expression. 19470b57cec5SDimitry Andric /// 19480b57cec5SDimitry Andric /// throw-expression: [C++ 15] 19490b57cec5SDimitry Andric /// 'throw' assignment-expression[opt] 19500b57cec5SDimitry Andric ExprResult Parser::ParseThrowExpression() { 19510b57cec5SDimitry Andric assert(Tok.is(tok::kw_throw) && "Not throw!"); 19520b57cec5SDimitry Andric SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 19530b57cec5SDimitry Andric 19540b57cec5SDimitry Andric // If the current token isn't the start of an assignment-expression, 19550b57cec5SDimitry Andric // then the expression is not present. This handles things like: 19560b57cec5SDimitry Andric // "C ? throw : (void)42", which is crazy but legal. 19570b57cec5SDimitry Andric switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 19580b57cec5SDimitry Andric case tok::semi: 19590b57cec5SDimitry Andric case tok::r_paren: 19600b57cec5SDimitry Andric case tok::r_square: 19610b57cec5SDimitry Andric case tok::r_brace: 19620b57cec5SDimitry Andric case tok::colon: 19630b57cec5SDimitry Andric case tok::comma: 19640b57cec5SDimitry Andric return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, nullptr); 19650b57cec5SDimitry Andric 19660b57cec5SDimitry Andric default: 19670b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 19680b57cec5SDimitry Andric if (Expr.isInvalid()) return Expr; 19690b57cec5SDimitry Andric return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get()); 19700b57cec5SDimitry Andric } 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric 19730b57cec5SDimitry Andric /// Parse the C++ Coroutines co_yield expression. 19740b57cec5SDimitry Andric /// 19750b57cec5SDimitry Andric /// co_yield-expression: 19760b57cec5SDimitry Andric /// 'co_yield' assignment-expression[opt] 19770b57cec5SDimitry Andric ExprResult Parser::ParseCoyieldExpression() { 19780b57cec5SDimitry Andric assert(Tok.is(tok::kw_co_yield) && "Not co_yield!"); 19790b57cec5SDimitry Andric 19800b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 19810b57cec5SDimitry Andric ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer() 19820b57cec5SDimitry Andric : ParseAssignmentExpression(); 19830b57cec5SDimitry Andric if (!Expr.isInvalid()) 19840b57cec5SDimitry Andric Expr = Actions.ActOnCoyieldExpr(getCurScope(), Loc, Expr.get()); 19850b57cec5SDimitry Andric return Expr; 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric 19880b57cec5SDimitry Andric /// ParseCXXThis - This handles the C++ 'this' pointer. 19890b57cec5SDimitry Andric /// 19900b57cec5SDimitry Andric /// C++ 9.3.2: In the body of a non-static member function, the keyword this is 19910b57cec5SDimitry Andric /// a non-lvalue expression whose value is the address of the object for which 19920b57cec5SDimitry Andric /// the function is called. 19930b57cec5SDimitry Andric ExprResult Parser::ParseCXXThis() { 19940b57cec5SDimitry Andric assert(Tok.is(tok::kw_this) && "Not 'this'!"); 19950b57cec5SDimitry Andric SourceLocation ThisLoc = ConsumeToken(); 19960b57cec5SDimitry Andric return Actions.ActOnCXXThis(ThisLoc); 19970b57cec5SDimitry Andric } 19980b57cec5SDimitry Andric 19990b57cec5SDimitry Andric /// ParseCXXTypeConstructExpression - Parse construction of a specified type. 20000b57cec5SDimitry Andric /// Can be interpreted either as function-style casting ("int(x)") 20010b57cec5SDimitry Andric /// or class type construction ("ClassType(x,y,z)") 20020b57cec5SDimitry Andric /// or creation of a value-initialized type ("int()"). 20030b57cec5SDimitry Andric /// See [C++ 5.2.3]. 20040b57cec5SDimitry Andric /// 20050b57cec5SDimitry Andric /// postfix-expression: [C++ 5.2p1] 20060b57cec5SDimitry Andric /// simple-type-specifier '(' expression-list[opt] ')' 20070b57cec5SDimitry Andric /// [C++0x] simple-type-specifier braced-init-list 20080b57cec5SDimitry Andric /// typename-specifier '(' expression-list[opt] ')' 20090b57cec5SDimitry Andric /// [C++0x] typename-specifier braced-init-list 20100b57cec5SDimitry Andric /// 20110b57cec5SDimitry Andric /// In C++1z onwards, the type specifier can also be a template-name. 20120b57cec5SDimitry Andric ExprResult 20130b57cec5SDimitry Andric Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 201481ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 201581ad6265SDimitry Andric DeclaratorContext::FunctionalCast); 20167a6dacacSDimitry Andric ParsedType TypeRep = Actions.ActOnTypeName(DeclaratorInfo).get(); 20170b57cec5SDimitry Andric 20180b57cec5SDimitry Andric assert((Tok.is(tok::l_paren) || 20190b57cec5SDimitry Andric (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) 20200b57cec5SDimitry Andric && "Expected '(' or '{'!"); 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 20235ffd83dbSDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get()); 20240b57cec5SDimitry Andric ExprResult Init = ParseBraceInitializer(); 20250b57cec5SDimitry Andric if (Init.isInvalid()) 20260b57cec5SDimitry Andric return Init; 20270b57cec5SDimitry Andric Expr *InitList = Init.get(); 20280b57cec5SDimitry Andric return Actions.ActOnCXXTypeConstructExpr( 20290b57cec5SDimitry Andric TypeRep, InitList->getBeginLoc(), MultiExprArg(&InitList, 1), 20300b57cec5SDimitry Andric InitList->getEndLoc(), /*ListInitialization=*/true); 20310b57cec5SDimitry Andric } else { 20320b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 20330b57cec5SDimitry Andric T.consumeOpen(); 20340b57cec5SDimitry Andric 20350b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get()); 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andric ExprVector Exprs; 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric auto RunSignatureHelp = [&]() { 2040480093f4SDimitry Andric QualType PreferredType; 2041480093f4SDimitry Andric if (TypeRep) 2042*0fca6ea1SDimitry Andric PreferredType = 2043*0fca6ea1SDimitry Andric Actions.CodeCompletion().ProduceConstructorSignatureHelp( 2044*0fca6ea1SDimitry Andric TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(), 2045*0fca6ea1SDimitry Andric Exprs, T.getOpenLocation(), /*Braced=*/false); 20460b57cec5SDimitry Andric CalledSignatureHelp = true; 20470b57cec5SDimitry Andric return PreferredType; 20480b57cec5SDimitry Andric }; 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 2051bdd1243dSDimitry Andric if (ParseExpressionList(Exprs, [&] { 20520b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 20530b57cec5SDimitry Andric RunSignatureHelp); 20540b57cec5SDimitry Andric })) { 20550b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 20560b57cec5SDimitry Andric RunSignatureHelp(); 20570b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 20580b57cec5SDimitry Andric return ExprError(); 20590b57cec5SDimitry Andric } 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric // Match the ')'. 20630b57cec5SDimitry Andric T.consumeClose(); 20640b57cec5SDimitry Andric 20650b57cec5SDimitry Andric // TypeRep could be null, if it references an invalid typedef. 20660b57cec5SDimitry Andric if (!TypeRep) 20670b57cec5SDimitry Andric return ExprError(); 20680b57cec5SDimitry Andric 20690b57cec5SDimitry Andric return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), 20700b57cec5SDimitry Andric Exprs, T.getCloseLocation(), 20710b57cec5SDimitry Andric /*ListInitialization=*/false); 20720b57cec5SDimitry Andric } 20730b57cec5SDimitry Andric } 20740b57cec5SDimitry Andric 2075349cc55cSDimitry Andric Parser::DeclGroupPtrTy 2076349cc55cSDimitry Andric Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context, 207781ad6265SDimitry Andric ParsedAttributes &Attrs) { 2078349cc55cSDimitry Andric assert(Tok.is(tok::kw_using) && "Expected using"); 2079349cc55cSDimitry Andric assert((Context == DeclaratorContext::ForInit || 2080349cc55cSDimitry Andric Context == DeclaratorContext::SelectionInit) && 2081349cc55cSDimitry Andric "Unexpected Declarator Context"); 2082349cc55cSDimitry Andric DeclGroupPtrTy DG; 2083349cc55cSDimitry Andric SourceLocation DeclStart = ConsumeToken(), DeclEnd; 2084349cc55cSDimitry Andric 2085349cc55cSDimitry Andric DG = ParseUsingDeclaration(Context, {}, DeclStart, DeclEnd, Attrs, AS_none); 2086349cc55cSDimitry Andric if (!DG) 2087349cc55cSDimitry Andric return DG; 2088349cc55cSDimitry Andric 208906c3fb27SDimitry Andric Diag(DeclStart, !getLangOpts().CPlusPlus23 2090349cc55cSDimitry Andric ? diag::ext_alias_in_init_statement 2091349cc55cSDimitry Andric : diag::warn_cxx20_alias_in_init_statement) 2092349cc55cSDimitry Andric << SourceRange(DeclStart, DeclEnd); 2093349cc55cSDimitry Andric 2094349cc55cSDimitry Andric return DG; 2095349cc55cSDimitry Andric } 2096349cc55cSDimitry Andric 20970b57cec5SDimitry Andric /// ParseCXXCondition - if/switch/while condition expression. 20980b57cec5SDimitry Andric /// 20990b57cec5SDimitry Andric /// condition: 21000b57cec5SDimitry Andric /// expression 21010b57cec5SDimitry Andric /// type-specifier-seq declarator '=' assignment-expression 21020b57cec5SDimitry Andric /// [C++11] type-specifier-seq declarator '=' initializer-clause 21030b57cec5SDimitry Andric /// [C++11] type-specifier-seq declarator braced-init-list 21040b57cec5SDimitry Andric /// [Clang] type-specifier-seq ref-qualifier[opt] '[' identifier-list ']' 21050b57cec5SDimitry Andric /// brace-or-equal-initializer 21060b57cec5SDimitry Andric /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 21070b57cec5SDimitry Andric /// '=' assignment-expression 21080b57cec5SDimitry Andric /// 21090b57cec5SDimitry Andric /// In C++1z, a condition may in some contexts be preceded by an 21100b57cec5SDimitry Andric /// optional init-statement. This function will parse that too. 21110b57cec5SDimitry Andric /// 21120b57cec5SDimitry Andric /// \param InitStmt If non-null, an init-statement is permitted, and if present 21130b57cec5SDimitry Andric /// will be parsed and stored here. 21140b57cec5SDimitry Andric /// 21150b57cec5SDimitry Andric /// \param Loc The location of the start of the statement that requires this 21160b57cec5SDimitry Andric /// condition, e.g., the "for" in a for loop. 21170b57cec5SDimitry Andric /// 211804eeddc0SDimitry Andric /// \param MissingOK Whether an empty condition is acceptable here. Otherwise 211904eeddc0SDimitry Andric /// it is considered an error to be recovered from. 212004eeddc0SDimitry Andric /// 21210b57cec5SDimitry Andric /// \param FRI If non-null, a for range declaration is permitted, and if 21220b57cec5SDimitry Andric /// present will be parsed and stored here, and a null result will be returned. 21230b57cec5SDimitry Andric /// 2124fe6060f1SDimitry Andric /// \param EnterForConditionScope If true, enter a continue/break scope at the 2125fe6060f1SDimitry Andric /// appropriate moment for a 'for' loop. 2126fe6060f1SDimitry Andric /// 21270b57cec5SDimitry Andric /// \returns The parsed condition. 212804eeddc0SDimitry Andric Sema::ConditionResult 212904eeddc0SDimitry Andric Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, 213004eeddc0SDimitry Andric Sema::ConditionKind CK, bool MissingOK, 213104eeddc0SDimitry Andric ForRangeInfo *FRI, bool EnterForConditionScope) { 2132fe6060f1SDimitry Andric // Helper to ensure we always enter a continue/break scope if requested. 2133fe6060f1SDimitry Andric struct ForConditionScopeRAII { 2134fe6060f1SDimitry Andric Scope *S; 2135fe6060f1SDimitry Andric void enter(bool IsConditionVariable) { 2136fe6060f1SDimitry Andric if (S) { 2137fe6060f1SDimitry Andric S->AddFlags(Scope::BreakScope | Scope::ContinueScope); 2138fe6060f1SDimitry Andric S->setIsConditionVarScope(IsConditionVariable); 2139fe6060f1SDimitry Andric } 2140fe6060f1SDimitry Andric } 2141fe6060f1SDimitry Andric ~ForConditionScopeRAII() { 2142fe6060f1SDimitry Andric if (S) 2143fe6060f1SDimitry Andric S->setIsConditionVarScope(false); 2144fe6060f1SDimitry Andric } 2145fe6060f1SDimitry Andric } ForConditionScope{EnterForConditionScope ? getCurScope() : nullptr}; 2146fe6060f1SDimitry Andric 21470b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 21480b57cec5SDimitry Andric PreferredType.enterCondition(Actions, Tok.getLocation()); 21490b57cec5SDimitry Andric 21500b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 21510b57cec5SDimitry Andric cutOffParsing(); 2152*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteOrdinaryName( 2153*0fca6ea1SDimitry Andric getCurScope(), SemaCodeCompletion::PCC_Condition); 21540b57cec5SDimitry Andric return Sema::ConditionError(); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric 215781ad6265SDimitry Andric ParsedAttributes attrs(AttrFactory); 21580b57cec5SDimitry Andric MaybeParseCXX11Attributes(attrs); 21590b57cec5SDimitry Andric 21600b57cec5SDimitry Andric const auto WarnOnInit = [this, &CK] { 21610b57cec5SDimitry Andric Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 21620b57cec5SDimitry Andric ? diag::warn_cxx14_compat_init_statement 21630b57cec5SDimitry Andric : diag::ext_init_statement) 21640b57cec5SDimitry Andric << (CK == Sema::ConditionKind::Switch); 21650b57cec5SDimitry Andric }; 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric // Determine what kind of thing we have. 21680b57cec5SDimitry Andric switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) { 21690b57cec5SDimitry Andric case ConditionOrInitStatement::Expression: { 2170fe6060f1SDimitry Andric // If this is a for loop, we're entering its condition. 2171fe6060f1SDimitry Andric ForConditionScope.enter(/*IsConditionVariable=*/false); 2172fe6060f1SDimitry Andric 21730b57cec5SDimitry Andric ProhibitAttributes(attrs); 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andric // We can have an empty expression here. 21760b57cec5SDimitry Andric // if (; true); 21770b57cec5SDimitry Andric if (InitStmt && Tok.is(tok::semi)) { 21780b57cec5SDimitry Andric WarnOnInit(); 21790b57cec5SDimitry Andric SourceLocation SemiLoc = Tok.getLocation(); 21800b57cec5SDimitry Andric if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID()) { 21810b57cec5SDimitry Andric Diag(SemiLoc, diag::warn_empty_init_statement) 21820b57cec5SDimitry Andric << (CK == Sema::ConditionKind::Switch) 21830b57cec5SDimitry Andric << FixItHint::CreateRemoval(SemiLoc); 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric ConsumeToken(); 21860b57cec5SDimitry Andric *InitStmt = Actions.ActOnNullStmt(SemiLoc); 218704eeddc0SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK, MissingOK); 21880b57cec5SDimitry Andric } 21890b57cec5SDimitry Andric 21900b57cec5SDimitry Andric // Parse the expression. 21910b57cec5SDimitry Andric ExprResult Expr = ParseExpression(); // expression 21920b57cec5SDimitry Andric if (Expr.isInvalid()) 21930b57cec5SDimitry Andric return Sema::ConditionError(); 21940b57cec5SDimitry Andric 21950b57cec5SDimitry Andric if (InitStmt && Tok.is(tok::semi)) { 21960b57cec5SDimitry Andric WarnOnInit(); 21970b57cec5SDimitry Andric *InitStmt = Actions.ActOnExprStmt(Expr.get()); 21980b57cec5SDimitry Andric ConsumeToken(); 219904eeddc0SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK, MissingOK); 22000b57cec5SDimitry Andric } 22010b57cec5SDimitry Andric 220204eeddc0SDimitry Andric return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK, 220304eeddc0SDimitry Andric MissingOK); 22040b57cec5SDimitry Andric } 22050b57cec5SDimitry Andric 22060b57cec5SDimitry Andric case ConditionOrInitStatement::InitStmtDecl: { 22070b57cec5SDimitry Andric WarnOnInit(); 2208349cc55cSDimitry Andric DeclGroupPtrTy DG; 22090b57cec5SDimitry Andric SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 2210349cc55cSDimitry Andric if (Tok.is(tok::kw_using)) 2211349cc55cSDimitry Andric DG = ParseAliasDeclarationInInitStatement( 2212349cc55cSDimitry Andric DeclaratorContext::SelectionInit, attrs); 221381ad6265SDimitry Andric else { 221481ad6265SDimitry Andric ParsedAttributes DeclSpecAttrs(AttrFactory); 2215349cc55cSDimitry Andric DG = ParseSimpleDeclaration(DeclaratorContext::SelectionInit, DeclEnd, 221681ad6265SDimitry Andric attrs, DeclSpecAttrs, /*RequireSemi=*/true); 221781ad6265SDimitry Andric } 22180b57cec5SDimitry Andric *InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd); 221904eeddc0SDimitry Andric return ParseCXXCondition(nullptr, Loc, CK, MissingOK); 22200b57cec5SDimitry Andric } 22210b57cec5SDimitry Andric 22220b57cec5SDimitry Andric case ConditionOrInitStatement::ForRangeDecl: { 2223fe6060f1SDimitry Andric // This is 'for (init-stmt; for-range-decl : range-expr)'. 2224fe6060f1SDimitry Andric // We're not actually in a for loop yet, so 'break' and 'continue' aren't 2225fe6060f1SDimitry Andric // permitted here. 22260b57cec5SDimitry Andric assert(FRI && "should not parse a for range declaration here"); 22270b57cec5SDimitry Andric SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 222881ad6265SDimitry Andric ParsedAttributes DeclSpecAttrs(AttrFactory); 222981ad6265SDimitry Andric DeclGroupPtrTy DG = ParseSimpleDeclaration( 223081ad6265SDimitry Andric DeclaratorContext::ForInit, DeclEnd, attrs, DeclSpecAttrs, false, FRI); 22310b57cec5SDimitry Andric FRI->LoopVar = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); 22320b57cec5SDimitry Andric return Sema::ConditionResult(); 22330b57cec5SDimitry Andric } 22340b57cec5SDimitry Andric 22350b57cec5SDimitry Andric case ConditionOrInitStatement::ConditionDecl: 22360b57cec5SDimitry Andric case ConditionOrInitStatement::Error: 22370b57cec5SDimitry Andric break; 22380b57cec5SDimitry Andric } 22390b57cec5SDimitry Andric 2240fe6060f1SDimitry Andric // If this is a for loop, we're entering its condition. 2241fe6060f1SDimitry Andric ForConditionScope.enter(/*IsConditionVariable=*/true); 2242fe6060f1SDimitry Andric 22430b57cec5SDimitry Andric // type-specifier-seq 22440b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 22450b57cec5SDimitry Andric ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition); 22460b57cec5SDimitry Andric 22470b57cec5SDimitry Andric // declarator 224881ad6265SDimitry Andric Declarator DeclaratorInfo(DS, attrs, DeclaratorContext::Condition); 22490b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 22500b57cec5SDimitry Andric 22510b57cec5SDimitry Andric // simple-asm-expr[opt] 22520b57cec5SDimitry Andric if (Tok.is(tok::kw_asm)) { 22530b57cec5SDimitry Andric SourceLocation Loc; 2254480093f4SDimitry Andric ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc)); 22550b57cec5SDimitry Andric if (AsmLabel.isInvalid()) { 22560b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi); 22570b57cec5SDimitry Andric return Sema::ConditionError(); 22580b57cec5SDimitry Andric } 22590b57cec5SDimitry Andric DeclaratorInfo.setAsmLabel(AsmLabel.get()); 22600b57cec5SDimitry Andric DeclaratorInfo.SetRangeEnd(Loc); 22610b57cec5SDimitry Andric } 22620b57cec5SDimitry Andric 22630b57cec5SDimitry Andric // If attributes are present, parse them. 22640b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 22650b57cec5SDimitry Andric 22660b57cec5SDimitry Andric // Type-check the declaration itself. 22670b57cec5SDimitry Andric DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 22680b57cec5SDimitry Andric DeclaratorInfo); 22690b57cec5SDimitry Andric if (Dcl.isInvalid()) 22700b57cec5SDimitry Andric return Sema::ConditionError(); 22710b57cec5SDimitry Andric Decl *DeclOut = Dcl.get(); 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric // '=' assignment-expression 22740b57cec5SDimitry Andric // If a '==' or '+=' is found, suggest a fixit to '='. 22750b57cec5SDimitry Andric bool CopyInitialization = isTokenEqualOrEqualTypo(); 22760b57cec5SDimitry Andric if (CopyInitialization) 22770b57cec5SDimitry Andric ConsumeToken(); 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andric ExprResult InitExpr = ExprError(); 22800b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 22810b57cec5SDimitry Andric Diag(Tok.getLocation(), 22820b57cec5SDimitry Andric diag::warn_cxx98_compat_generalized_initializer_lists); 22830b57cec5SDimitry Andric InitExpr = ParseBraceInitializer(); 22840b57cec5SDimitry Andric } else if (CopyInitialization) { 22850b57cec5SDimitry Andric PreferredType.enterVariableInit(Tok.getLocation(), DeclOut); 22860b57cec5SDimitry Andric InitExpr = ParseAssignmentExpression(); 22870b57cec5SDimitry Andric } else if (Tok.is(tok::l_paren)) { 22880b57cec5SDimitry Andric // This was probably an attempt to initialize the variable. 22890b57cec5SDimitry Andric SourceLocation LParen = ConsumeParen(), RParen = LParen; 22900b57cec5SDimitry Andric if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) 22910b57cec5SDimitry Andric RParen = ConsumeParen(); 22920b57cec5SDimitry Andric Diag(DeclOut->getLocation(), 22930b57cec5SDimitry Andric diag::err_expected_init_in_condition_lparen) 22940b57cec5SDimitry Andric << SourceRange(LParen, RParen); 22950b57cec5SDimitry Andric } else { 22960b57cec5SDimitry Andric Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition); 22970b57cec5SDimitry Andric } 22980b57cec5SDimitry Andric 22990b57cec5SDimitry Andric if (!InitExpr.isInvalid()) 23000b57cec5SDimitry Andric Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization); 23010b57cec5SDimitry Andric else 23020b57cec5SDimitry Andric Actions.ActOnInitializerError(DeclOut); 23030b57cec5SDimitry Andric 23040b57cec5SDimitry Andric Actions.FinalizeDeclaration(DeclOut); 23050b57cec5SDimitry Andric return Actions.ActOnConditionVariable(DeclOut, Loc, CK); 23060b57cec5SDimitry Andric } 23070b57cec5SDimitry Andric 23080b57cec5SDimitry Andric /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 23090b57cec5SDimitry Andric /// This should only be called when the current token is known to be part of 23100b57cec5SDimitry Andric /// simple-type-specifier. 23110b57cec5SDimitry Andric /// 23120b57cec5SDimitry Andric /// simple-type-specifier: 23130b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier[opt] type-name 23140b57cec5SDimitry Andric /// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 23150b57cec5SDimitry Andric /// char 23160b57cec5SDimitry Andric /// wchar_t 23170b57cec5SDimitry Andric /// bool 23180b57cec5SDimitry Andric /// short 23190b57cec5SDimitry Andric /// int 23200b57cec5SDimitry Andric /// long 23210b57cec5SDimitry Andric /// signed 23220b57cec5SDimitry Andric /// unsigned 23230b57cec5SDimitry Andric /// float 23240b57cec5SDimitry Andric /// double 23250b57cec5SDimitry Andric /// void 23260b57cec5SDimitry Andric /// [GNU] typeof-specifier 23270b57cec5SDimitry Andric /// [C++0x] auto [TODO] 23280b57cec5SDimitry Andric /// 23290b57cec5SDimitry Andric /// type-name: 23300b57cec5SDimitry Andric /// class-name 23310b57cec5SDimitry Andric /// enum-name 23320b57cec5SDimitry Andric /// typedef-name 23330b57cec5SDimitry Andric /// 23340b57cec5SDimitry Andric void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 23350b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 23360b57cec5SDimitry Andric const char *PrevSpec; 23370b57cec5SDimitry Andric unsigned DiagID; 23380b57cec5SDimitry Andric SourceLocation Loc = Tok.getLocation(); 23390b57cec5SDimitry Andric const clang::PrintingPolicy &Policy = 23400b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy(); 23410b57cec5SDimitry Andric 23420b57cec5SDimitry Andric switch (Tok.getKind()) { 23430b57cec5SDimitry Andric case tok::identifier: // foo::bar 23440b57cec5SDimitry Andric case tok::coloncolon: // ::foo::bar 23450b57cec5SDimitry Andric llvm_unreachable("Annotation token should already be formed!"); 23460b57cec5SDimitry Andric default: 23470b57cec5SDimitry Andric llvm_unreachable("Not a simple-type-specifier token!"); 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andric // type-name 23500b57cec5SDimitry Andric case tok::annot_typename: { 23510b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 23520b57cec5SDimitry Andric getTypeAnnotation(Tok), Policy); 23530b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 23540b57cec5SDimitry Andric ConsumeAnnotationToken(); 23550b57cec5SDimitry Andric DS.Finish(Actions, Policy); 23560b57cec5SDimitry Andric return; 23570b57cec5SDimitry Andric } 23580b57cec5SDimitry Andric 23590eae32dcSDimitry Andric case tok::kw__ExtInt: 23600eae32dcSDimitry Andric case tok::kw__BitInt: { 23610eae32dcSDimitry Andric DiagnoseBitIntUse(Tok); 23625ffd83dbSDimitry Andric ExprResult ER = ParseExtIntegerArgument(); 23635ffd83dbSDimitry Andric if (ER.isInvalid()) 23645ffd83dbSDimitry Andric DS.SetTypeSpecError(); 23655ffd83dbSDimitry Andric else 23660eae32dcSDimitry Andric DS.SetBitIntType(Loc, ER.get(), PrevSpec, DiagID, Policy); 23675ffd83dbSDimitry Andric 23685ffd83dbSDimitry Andric // Do this here because we have already consumed the close paren. 23695ffd83dbSDimitry Andric DS.SetRangeEnd(PrevTokLocation); 23705ffd83dbSDimitry Andric DS.Finish(Actions, Policy); 23715ffd83dbSDimitry Andric return; 23725ffd83dbSDimitry Andric } 23735ffd83dbSDimitry Andric 23740b57cec5SDimitry Andric // builtin types 23750b57cec5SDimitry Andric case tok::kw_short: 2376e8d8bef9SDimitry Andric DS.SetTypeSpecWidth(TypeSpecifierWidth::Short, Loc, PrevSpec, DiagID, 2377e8d8bef9SDimitry Andric Policy); 23780b57cec5SDimitry Andric break; 23790b57cec5SDimitry Andric case tok::kw_long: 2380e8d8bef9SDimitry Andric DS.SetTypeSpecWidth(TypeSpecifierWidth::Long, Loc, PrevSpec, DiagID, 2381e8d8bef9SDimitry Andric Policy); 23820b57cec5SDimitry Andric break; 23830b57cec5SDimitry Andric case tok::kw___int64: 2384e8d8bef9SDimitry Andric DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc, PrevSpec, DiagID, 2385e8d8bef9SDimitry Andric Policy); 23860b57cec5SDimitry Andric break; 23870b57cec5SDimitry Andric case tok::kw_signed: 2388e8d8bef9SDimitry Andric DS.SetTypeSpecSign(TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID); 23890b57cec5SDimitry Andric break; 23900b57cec5SDimitry Andric case tok::kw_unsigned: 2391e8d8bef9SDimitry Andric DS.SetTypeSpecSign(TypeSpecifierSign::Unsigned, Loc, PrevSpec, DiagID); 23920b57cec5SDimitry Andric break; 23930b57cec5SDimitry Andric case tok::kw_void: 23940b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy); 23950b57cec5SDimitry Andric break; 239681ad6265SDimitry Andric case tok::kw_auto: 239781ad6265SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID, Policy); 239881ad6265SDimitry Andric break; 23990b57cec5SDimitry Andric case tok::kw_char: 24000b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy); 24010b57cec5SDimitry Andric break; 24020b57cec5SDimitry Andric case tok::kw_int: 24030b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy); 24040b57cec5SDimitry Andric break; 24050b57cec5SDimitry Andric case tok::kw___int128: 24060b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy); 24070b57cec5SDimitry Andric break; 24085ffd83dbSDimitry Andric case tok::kw___bf16: 24095ffd83dbSDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy); 24105ffd83dbSDimitry Andric break; 24110b57cec5SDimitry Andric case tok::kw_half: 24120b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy); 24130b57cec5SDimitry Andric break; 24140b57cec5SDimitry Andric case tok::kw_float: 24150b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy); 24160b57cec5SDimitry Andric break; 24170b57cec5SDimitry Andric case tok::kw_double: 24180b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy); 24190b57cec5SDimitry Andric break; 24200b57cec5SDimitry Andric case tok::kw__Float16: 24210b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy); 24220b57cec5SDimitry Andric break; 24230b57cec5SDimitry Andric case tok::kw___float128: 24240b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); 24250b57cec5SDimitry Andric break; 2426349cc55cSDimitry Andric case tok::kw___ibm128: 2427349cc55cSDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec, DiagID, Policy); 2428349cc55cSDimitry Andric break; 24290b57cec5SDimitry Andric case tok::kw_wchar_t: 24300b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy); 24310b57cec5SDimitry Andric break; 24320b57cec5SDimitry Andric case tok::kw_char8_t: 24330b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy); 24340b57cec5SDimitry Andric break; 24350b57cec5SDimitry Andric case tok::kw_char16_t: 24360b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy); 24370b57cec5SDimitry Andric break; 24380b57cec5SDimitry Andric case tok::kw_char32_t: 24390b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy); 24400b57cec5SDimitry Andric break; 24410b57cec5SDimitry Andric case tok::kw_bool: 24420b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy); 24430b57cec5SDimitry Andric break; 24445f757f3fSDimitry Andric case tok::kw__Accum: 24455f757f3fSDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy); 24465f757f3fSDimitry Andric break; 24475f757f3fSDimitry Andric case tok::kw__Fract: 24485f757f3fSDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy); 24495f757f3fSDimitry Andric break; 24505f757f3fSDimitry Andric case tok::kw__Sat: 24515f757f3fSDimitry Andric DS.SetTypeSpecSat(Loc, PrevSpec, DiagID); 24525f757f3fSDimitry Andric break; 24530b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) \ 24540b57cec5SDimitry Andric case tok::kw_##ImgType##_t: \ 24550b57cec5SDimitry Andric DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \ 24560b57cec5SDimitry Andric Policy); \ 24570b57cec5SDimitry Andric break; 24580b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric case tok::annot_decltype: 24610b57cec5SDimitry Andric case tok::kw_decltype: 24620b57cec5SDimitry Andric DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); 24630b57cec5SDimitry Andric return DS.Finish(Actions, Policy); 24640b57cec5SDimitry Andric 2465*0fca6ea1SDimitry Andric case tok::annot_pack_indexing_type: 2466*0fca6ea1SDimitry Andric DS.SetRangeEnd(ParsePackIndexingType(DS)); 2467*0fca6ea1SDimitry Andric return DS.Finish(Actions, Policy); 2468*0fca6ea1SDimitry Andric 24690b57cec5SDimitry Andric // GNU typeof support. 24700b57cec5SDimitry Andric case tok::kw_typeof: 24710b57cec5SDimitry Andric ParseTypeofSpecifier(DS); 24720b57cec5SDimitry Andric DS.Finish(Actions, Policy); 24730b57cec5SDimitry Andric return; 24740b57cec5SDimitry Andric } 24750b57cec5SDimitry Andric ConsumeAnyToken(); 24760b57cec5SDimitry Andric DS.SetRangeEnd(PrevTokLocation); 24770b57cec5SDimitry Andric DS.Finish(Actions, Policy); 24780b57cec5SDimitry Andric } 24790b57cec5SDimitry Andric 24800b57cec5SDimitry Andric /// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 24810b57cec5SDimitry Andric /// [dcl.name]), which is a non-empty sequence of type-specifiers, 24820b57cec5SDimitry Andric /// e.g., "const short int". Note that the DeclSpec is *not* finished 24830b57cec5SDimitry Andric /// by parsing the type-specifier-seq, because these sequences are 24840b57cec5SDimitry Andric /// typically followed by some form of declarator. Returns true and 24850b57cec5SDimitry Andric /// emits diagnostics if this is not a type-specifier-seq, false 24860b57cec5SDimitry Andric /// otherwise. 24870b57cec5SDimitry Andric /// 24880b57cec5SDimitry Andric /// type-specifier-seq: [C++ 8.1] 24890b57cec5SDimitry Andric /// type-specifier type-specifier-seq[opt] 24900b57cec5SDimitry Andric /// 2491bdd1243dSDimitry Andric bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS, DeclaratorContext Context) { 2492bdd1243dSDimitry Andric ParseSpecifierQualifierList(DS, AS_none, 2493bdd1243dSDimitry Andric getDeclSpecContextFromDeclaratorContext(Context)); 24940b57cec5SDimitry Andric DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy()); 24950b57cec5SDimitry Andric return false; 24960b57cec5SDimitry Andric } 24970b57cec5SDimitry Andric 24980b57cec5SDimitry Andric /// Finish parsing a C++ unqualified-id that is a template-id of 24990b57cec5SDimitry Andric /// some form. 25000b57cec5SDimitry Andric /// 25010b57cec5SDimitry Andric /// This routine is invoked when a '<' is encountered after an identifier or 25020b57cec5SDimitry Andric /// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 25030b57cec5SDimitry Andric /// whether the unqualified-id is actually a template-id. This routine will 25040b57cec5SDimitry Andric /// then parse the template arguments and form the appropriate template-id to 25050b57cec5SDimitry Andric /// return to the caller. 25060b57cec5SDimitry Andric /// 25070b57cec5SDimitry Andric /// \param SS the nested-name-specifier that precedes this template-id, if 25080b57cec5SDimitry Andric /// we're actually parsing a qualified-id. 25090b57cec5SDimitry Andric /// 25105ffd83dbSDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 25115ffd83dbSDimitry Andric /// expression, the type of the base object whose member is being accessed. 25125ffd83dbSDimitry Andric /// 25135ffd83dbSDimitry Andric /// \param ObjectHadErrors this unqualified-id occurs within a member access 25145ffd83dbSDimitry Andric /// expression, indicates whether the original subexpressions had any errors. 25155ffd83dbSDimitry Andric /// 25160b57cec5SDimitry Andric /// \param Name for constructor and destructor names, this is the actual 25170b57cec5SDimitry Andric /// identifier that may be a template-name. 25180b57cec5SDimitry Andric /// 25190b57cec5SDimitry Andric /// \param NameLoc the location of the class-name in a constructor or 25200b57cec5SDimitry Andric /// destructor. 25210b57cec5SDimitry Andric /// 25220b57cec5SDimitry Andric /// \param EnteringContext whether we're entering the scope of the 25230b57cec5SDimitry Andric /// nested-name-specifier. 25240b57cec5SDimitry Andric /// 25250b57cec5SDimitry Andric /// \param Id as input, describes the template-name or operator-function-id 25260b57cec5SDimitry Andric /// that precedes the '<'. If template arguments were parsed successfully, 25270b57cec5SDimitry Andric /// will be updated with the template-id. 25280b57cec5SDimitry Andric /// 25290b57cec5SDimitry Andric /// \param AssumeTemplateId When true, this routine will assume that the name 25300b57cec5SDimitry Andric /// refers to a template without performing name lookup to verify. 25310b57cec5SDimitry Andric /// 25320b57cec5SDimitry Andric /// \returns true if a parse error occurred, false otherwise. 25335ffd83dbSDimitry Andric bool Parser::ParseUnqualifiedIdTemplateId( 25345ffd83dbSDimitry Andric CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, 25355ffd83dbSDimitry Andric SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, 25365ffd83dbSDimitry Andric bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId) { 25370b57cec5SDimitry Andric assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id"); 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric TemplateTy Template; 25400b57cec5SDimitry Andric TemplateNameKind TNK = TNK_Non_template; 25410b57cec5SDimitry Andric switch (Id.getKind()) { 25420b57cec5SDimitry Andric case UnqualifiedIdKind::IK_Identifier: 25430b57cec5SDimitry Andric case UnqualifiedIdKind::IK_OperatorFunctionId: 25440b57cec5SDimitry Andric case UnqualifiedIdKind::IK_LiteralOperatorId: 25450b57cec5SDimitry Andric if (AssumeTemplateId) { 25460b57cec5SDimitry Andric // We defer the injected-class-name checks until we've found whether 25470b57cec5SDimitry Andric // this template-id is used to form a nested-name-specifier or not. 25485ffd83dbSDimitry Andric TNK = Actions.ActOnTemplateName(getCurScope(), SS, TemplateKWLoc, Id, 25495ffd83dbSDimitry Andric ObjectType, EnteringContext, Template, 25505ffd83dbSDimitry Andric /*AllowInjectedClassName*/ true); 25510b57cec5SDimitry Andric } else { 25520b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 25530b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, 25540b57cec5SDimitry Andric TemplateKWLoc.isValid(), Id, 25550b57cec5SDimitry Andric ObjectType, EnteringContext, Template, 25560b57cec5SDimitry Andric MemberOfUnknownSpecialization); 25570b57cec5SDimitry Andric // If lookup found nothing but we're assuming that this is a template 25580b57cec5SDimitry Andric // name, double-check that makes sense syntactically before committing 25590b57cec5SDimitry Andric // to it. 25600b57cec5SDimitry Andric if (TNK == TNK_Undeclared_template && 25610b57cec5SDimitry Andric isTemplateArgumentList(0) == TPResult::False) 25620b57cec5SDimitry Andric return false; 25630b57cec5SDimitry Andric 25640b57cec5SDimitry Andric if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && 25650b57cec5SDimitry Andric ObjectType && isTemplateArgumentList(0) == TPResult::True) { 25665ffd83dbSDimitry Andric // If we had errors before, ObjectType can be dependent even without any 25675ffd83dbSDimitry Andric // templates, do not report missing template keyword in that case. 25685ffd83dbSDimitry Andric if (!ObjectHadErrors) { 25690b57cec5SDimitry Andric // We have something like t->getAs<T>(), where getAs is a 25700b57cec5SDimitry Andric // member of an unknown specialization. However, this will only 25710b57cec5SDimitry Andric // parse correctly as a template, so suggest the keyword 'template' 25720b57cec5SDimitry Andric // before 'getAs' and treat this as a dependent template name. 25730b57cec5SDimitry Andric std::string Name; 25740b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_Identifier) 25755ffd83dbSDimitry Andric Name = std::string(Id.Identifier->getName()); 25760b57cec5SDimitry Andric else { 25770b57cec5SDimitry Andric Name = "operator "; 25780b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) 25790b57cec5SDimitry Andric Name += getOperatorSpelling(Id.OperatorFunctionId.Operator); 25800b57cec5SDimitry Andric else 25810b57cec5SDimitry Andric Name += Id.Identifier->getName(); 25820b57cec5SDimitry Andric } 25830b57cec5SDimitry Andric Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) 25840b57cec5SDimitry Andric << Name 25850b57cec5SDimitry Andric << FixItHint::CreateInsertion(Id.StartLocation, "template "); 25865ffd83dbSDimitry Andric } 25875ffd83dbSDimitry Andric TNK = Actions.ActOnTemplateName( 25880b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext, 25890b57cec5SDimitry Andric Template, /*AllowInjectedClassName*/ true); 25905ffd83dbSDimitry Andric } else if (TNK == TNK_Non_template) { 25915ffd83dbSDimitry Andric return false; 25920b57cec5SDimitry Andric } 25930b57cec5SDimitry Andric } 25940b57cec5SDimitry Andric break; 25950b57cec5SDimitry Andric 25960b57cec5SDimitry Andric case UnqualifiedIdKind::IK_ConstructorName: { 25970b57cec5SDimitry Andric UnqualifiedId TemplateName; 25980b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 25990b57cec5SDimitry Andric TemplateName.setIdentifier(Name, NameLoc); 26000b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 26010b57cec5SDimitry Andric TemplateName, ObjectType, 26020b57cec5SDimitry Andric EnteringContext, Template, 26030b57cec5SDimitry Andric MemberOfUnknownSpecialization); 26045ffd83dbSDimitry Andric if (TNK == TNK_Non_template) 26055ffd83dbSDimitry Andric return false; 26060b57cec5SDimitry Andric break; 26070b57cec5SDimitry Andric } 26080b57cec5SDimitry Andric 26090b57cec5SDimitry Andric case UnqualifiedIdKind::IK_DestructorName: { 26100b57cec5SDimitry Andric UnqualifiedId TemplateName; 26110b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 26120b57cec5SDimitry Andric TemplateName.setIdentifier(Name, NameLoc); 26130b57cec5SDimitry Andric if (ObjectType) { 26145ffd83dbSDimitry Andric TNK = Actions.ActOnTemplateName( 26150b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType, 26160b57cec5SDimitry Andric EnteringContext, Template, /*AllowInjectedClassName*/ true); 26170b57cec5SDimitry Andric } else { 26180b57cec5SDimitry Andric TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 26190b57cec5SDimitry Andric TemplateName, ObjectType, 26200b57cec5SDimitry Andric EnteringContext, Template, 26210b57cec5SDimitry Andric MemberOfUnknownSpecialization); 26220b57cec5SDimitry Andric 26230b57cec5SDimitry Andric if (TNK == TNK_Non_template && !Id.DestructorName.get()) { 26240b57cec5SDimitry Andric Diag(NameLoc, diag::err_destructor_template_id) 26250b57cec5SDimitry Andric << Name << SS.getRange(); 26265ffd83dbSDimitry Andric // Carry on to parse the template arguments before bailing out. 26270b57cec5SDimitry Andric } 26280b57cec5SDimitry Andric } 26290b57cec5SDimitry Andric break; 26300b57cec5SDimitry Andric } 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric default: 26330b57cec5SDimitry Andric return false; 26340b57cec5SDimitry Andric } 26350b57cec5SDimitry Andric 26360b57cec5SDimitry Andric // Parse the enclosed template argument list. 26370b57cec5SDimitry Andric SourceLocation LAngleLoc, RAngleLoc; 26380b57cec5SDimitry Andric TemplateArgList TemplateArgs; 263904eeddc0SDimitry Andric if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, RAngleLoc, 264004eeddc0SDimitry Andric Template)) 26410b57cec5SDimitry Andric return true; 26420b57cec5SDimitry Andric 26435ffd83dbSDimitry Andric // If this is a non-template, we already issued a diagnostic. 26445ffd83dbSDimitry Andric if (TNK == TNK_Non_template) 26455ffd83dbSDimitry Andric return true; 26465ffd83dbSDimitry Andric 26470b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_Identifier || 26480b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId || 26490b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) { 26500b57cec5SDimitry Andric // Form a parsed representation of the template-id to be stored in the 26510b57cec5SDimitry Andric // UnqualifiedId. 26520b57cec5SDimitry Andric 26530b57cec5SDimitry Andric // FIXME: Store name for literal operator too. 2654*0fca6ea1SDimitry Andric const IdentifierInfo *TemplateII = 26550b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier 26560b57cec5SDimitry Andric : nullptr; 26570b57cec5SDimitry Andric OverloadedOperatorKind OpKind = 26580b57cec5SDimitry Andric Id.getKind() == UnqualifiedIdKind::IK_Identifier 26590b57cec5SDimitry Andric ? OO_None 26600b57cec5SDimitry Andric : Id.OperatorFunctionId.Operator; 26610b57cec5SDimitry Andric 26620b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( 266355e4f9d5SDimitry Andric TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK, 26645ffd83dbSDimitry Andric LAngleLoc, RAngleLoc, TemplateArgs, /*ArgsInvalid*/false, TemplateIds); 26650b57cec5SDimitry Andric 26660b57cec5SDimitry Andric Id.setTemplateId(TemplateId); 26670b57cec5SDimitry Andric return false; 26680b57cec5SDimitry Andric } 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric // Bundle the template arguments together. 26710b57cec5SDimitry Andric ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); 26720b57cec5SDimitry Andric 26730b57cec5SDimitry Andric // Constructor and destructor names. 26740b57cec5SDimitry Andric TypeResult Type = Actions.ActOnTemplateIdType( 26750b57cec5SDimitry Andric getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc, 26760b57cec5SDimitry Andric TemplateArgsPtr, RAngleLoc, /*IsCtorOrDtorName=*/true); 26770b57cec5SDimitry Andric if (Type.isInvalid()) 26780b57cec5SDimitry Andric return true; 26790b57cec5SDimitry Andric 26800b57cec5SDimitry Andric if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName) 26810b57cec5SDimitry Andric Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 26820b57cec5SDimitry Andric else 26830b57cec5SDimitry Andric Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 26840b57cec5SDimitry Andric 26850b57cec5SDimitry Andric return false; 26860b57cec5SDimitry Andric } 26870b57cec5SDimitry Andric 26880b57cec5SDimitry Andric /// Parse an operator-function-id or conversion-function-id as part 26890b57cec5SDimitry Andric /// of a C++ unqualified-id. 26900b57cec5SDimitry Andric /// 26910b57cec5SDimitry Andric /// This routine is responsible only for parsing the operator-function-id or 26920b57cec5SDimitry Andric /// conversion-function-id; it does not handle template arguments in any way. 26930b57cec5SDimitry Andric /// 26940b57cec5SDimitry Andric /// \code 26950b57cec5SDimitry Andric /// operator-function-id: [C++ 13.5] 26960b57cec5SDimitry Andric /// 'operator' operator 26970b57cec5SDimitry Andric /// 26980b57cec5SDimitry Andric /// operator: one of 26990b57cec5SDimitry Andric /// new delete new[] delete[] 27000b57cec5SDimitry Andric /// + - * / % ^ & | ~ 27010b57cec5SDimitry Andric /// ! = < > += -= *= /= %= 27020b57cec5SDimitry Andric /// ^= &= |= << >> >>= <<= == != 27030b57cec5SDimitry Andric /// <= >= && || ++ -- , ->* -> 27040b57cec5SDimitry Andric /// () [] <=> 27050b57cec5SDimitry Andric /// 27060b57cec5SDimitry Andric /// conversion-function-id: [C++ 12.3.2] 27070b57cec5SDimitry Andric /// operator conversion-type-id 27080b57cec5SDimitry Andric /// 27090b57cec5SDimitry Andric /// conversion-type-id: 27100b57cec5SDimitry Andric /// type-specifier-seq conversion-declarator[opt] 27110b57cec5SDimitry Andric /// 27120b57cec5SDimitry Andric /// conversion-declarator: 27130b57cec5SDimitry Andric /// ptr-operator conversion-declarator[opt] 27140b57cec5SDimitry Andric /// \endcode 27150b57cec5SDimitry Andric /// 27160b57cec5SDimitry Andric /// \param SS The nested-name-specifier that preceded this unqualified-id. If 27170b57cec5SDimitry Andric /// non-empty, then we are parsing the unqualified-id of a qualified-id. 27180b57cec5SDimitry Andric /// 27190b57cec5SDimitry Andric /// \param EnteringContext whether we are entering the scope of the 27200b57cec5SDimitry Andric /// nested-name-specifier. 27210b57cec5SDimitry Andric /// 27220b57cec5SDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 27230b57cec5SDimitry Andric /// expression, the type of the base object whose member is being accessed. 27240b57cec5SDimitry Andric /// 27250b57cec5SDimitry Andric /// \param Result on a successful parse, contains the parsed unqualified-id. 27260b57cec5SDimitry Andric /// 27270b57cec5SDimitry Andric /// \returns true if parsing fails, false otherwise. 27280b57cec5SDimitry Andric bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 27290b57cec5SDimitry Andric ParsedType ObjectType, 27300b57cec5SDimitry Andric UnqualifiedId &Result) { 27310b57cec5SDimitry Andric assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 27320b57cec5SDimitry Andric 27330b57cec5SDimitry Andric // Consume the 'operator' keyword. 27340b57cec5SDimitry Andric SourceLocation KeywordLoc = ConsumeToken(); 27350b57cec5SDimitry Andric 27360b57cec5SDimitry Andric // Determine what kind of operator name we have. 27370b57cec5SDimitry Andric unsigned SymbolIdx = 0; 27380b57cec5SDimitry Andric SourceLocation SymbolLocations[3]; 27390b57cec5SDimitry Andric OverloadedOperatorKind Op = OO_None; 27400b57cec5SDimitry Andric switch (Tok.getKind()) { 27410b57cec5SDimitry Andric case tok::kw_new: 27420b57cec5SDimitry Andric case tok::kw_delete: { 27430b57cec5SDimitry Andric bool isNew = Tok.getKind() == tok::kw_new; 27440b57cec5SDimitry Andric // Consume the 'new' or 'delete'. 27450b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = ConsumeToken(); 27460b57cec5SDimitry Andric // Check for array new/delete. 27470b57cec5SDimitry Andric if (Tok.is(tok::l_square) && 27480b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) { 27490b57cec5SDimitry Andric // Consume the '[' and ']'. 27500b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 27510b57cec5SDimitry Andric T.consumeOpen(); 27520b57cec5SDimitry Andric T.consumeClose(); 27530b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 27540b57cec5SDimitry Andric return true; 27550b57cec5SDimitry Andric 27560b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 27570b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 27580b57cec5SDimitry Andric Op = isNew? OO_Array_New : OO_Array_Delete; 27590b57cec5SDimitry Andric } else { 27600b57cec5SDimitry Andric Op = isNew? OO_New : OO_Delete; 27610b57cec5SDimitry Andric } 27620b57cec5SDimitry Andric break; 27630b57cec5SDimitry Andric } 27640b57cec5SDimitry Andric 27650b57cec5SDimitry Andric #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 27660b57cec5SDimitry Andric case tok::Token: \ 27670b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 27680b57cec5SDimitry Andric Op = OO_##Name; \ 27690b57cec5SDimitry Andric break; 27700b57cec5SDimitry Andric #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 27710b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.def" 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andric case tok::l_paren: { 27740b57cec5SDimitry Andric // Consume the '(' and ')'. 27750b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 27760b57cec5SDimitry Andric T.consumeOpen(); 27770b57cec5SDimitry Andric T.consumeClose(); 27780b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 27790b57cec5SDimitry Andric return true; 27800b57cec5SDimitry Andric 27810b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 27820b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 27830b57cec5SDimitry Andric Op = OO_Call; 27840b57cec5SDimitry Andric break; 27850b57cec5SDimitry Andric } 27860b57cec5SDimitry Andric 27870b57cec5SDimitry Andric case tok::l_square: { 27880b57cec5SDimitry Andric // Consume the '[' and ']'. 27890b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 27900b57cec5SDimitry Andric T.consumeOpen(); 27910b57cec5SDimitry Andric T.consumeClose(); 27920b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 27930b57cec5SDimitry Andric return true; 27940b57cec5SDimitry Andric 27950b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 27960b57cec5SDimitry Andric SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 27970b57cec5SDimitry Andric Op = OO_Subscript; 27980b57cec5SDimitry Andric break; 27990b57cec5SDimitry Andric } 28000b57cec5SDimitry Andric 28010b57cec5SDimitry Andric case tok::code_completion: { 2802fe6060f1SDimitry Andric // Don't try to parse any further. 2803fe6060f1SDimitry Andric cutOffParsing(); 28040b57cec5SDimitry Andric // Code completion for the operator name. 2805*0fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteOperatorName(getCurScope()); 28060b57cec5SDimitry Andric return true; 28070b57cec5SDimitry Andric } 28080b57cec5SDimitry Andric 28090b57cec5SDimitry Andric default: 28100b57cec5SDimitry Andric break; 28110b57cec5SDimitry Andric } 28120b57cec5SDimitry Andric 28130b57cec5SDimitry Andric if (Op != OO_None) { 28140b57cec5SDimitry Andric // We have parsed an operator-function-id. 28150b57cec5SDimitry Andric Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 28160b57cec5SDimitry Andric return false; 28170b57cec5SDimitry Andric } 28180b57cec5SDimitry Andric 28190b57cec5SDimitry Andric // Parse a literal-operator-id. 28200b57cec5SDimitry Andric // 28210b57cec5SDimitry Andric // literal-operator-id: C++11 [over.literal] 28220b57cec5SDimitry Andric // operator string-literal identifier 28230b57cec5SDimitry Andric // operator user-defined-string-literal 28240b57cec5SDimitry Andric 28250b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) { 28260b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); 28270b57cec5SDimitry Andric 28280b57cec5SDimitry Andric SourceLocation DiagLoc; 28290b57cec5SDimitry Andric unsigned DiagId = 0; 28300b57cec5SDimitry Andric 28310b57cec5SDimitry Andric // We're past translation phase 6, so perform string literal concatenation 28320b57cec5SDimitry Andric // before checking for "". 28330b57cec5SDimitry Andric SmallVector<Token, 4> Toks; 28340b57cec5SDimitry Andric SmallVector<SourceLocation, 4> TokLocs; 28350b57cec5SDimitry Andric while (isTokenStringLiteral()) { 28360b57cec5SDimitry Andric if (!Tok.is(tok::string_literal) && !DiagId) { 28370b57cec5SDimitry Andric // C++11 [over.literal]p1: 28380b57cec5SDimitry Andric // The string-literal or user-defined-string-literal in a 28390b57cec5SDimitry Andric // literal-operator-id shall have no encoding-prefix [...]. 28400b57cec5SDimitry Andric DiagLoc = Tok.getLocation(); 28410b57cec5SDimitry Andric DiagId = diag::err_literal_operator_string_prefix; 28420b57cec5SDimitry Andric } 28430b57cec5SDimitry Andric Toks.push_back(Tok); 28440b57cec5SDimitry Andric TokLocs.push_back(ConsumeStringToken()); 28450b57cec5SDimitry Andric } 28460b57cec5SDimitry Andric 28470b57cec5SDimitry Andric StringLiteralParser Literal(Toks, PP); 28480b57cec5SDimitry Andric if (Literal.hadError) 28490b57cec5SDimitry Andric return true; 28500b57cec5SDimitry Andric 28510b57cec5SDimitry Andric // Grab the literal operator's suffix, which will be either the next token 28520b57cec5SDimitry Andric // or a ud-suffix from the string literal. 2853fe6060f1SDimitry Andric bool IsUDSuffix = !Literal.getUDSuffix().empty(); 28540b57cec5SDimitry Andric IdentifierInfo *II = nullptr; 28550b57cec5SDimitry Andric SourceLocation SuffixLoc; 2856fe6060f1SDimitry Andric if (IsUDSuffix) { 28570b57cec5SDimitry Andric II = &PP.getIdentifierTable().get(Literal.getUDSuffix()); 28580b57cec5SDimitry Andric SuffixLoc = 28590b57cec5SDimitry Andric Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()], 28600b57cec5SDimitry Andric Literal.getUDSuffixOffset(), 28610b57cec5SDimitry Andric PP.getSourceManager(), getLangOpts()); 28620b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 28630b57cec5SDimitry Andric II = Tok.getIdentifierInfo(); 28640b57cec5SDimitry Andric SuffixLoc = ConsumeToken(); 28650b57cec5SDimitry Andric TokLocs.push_back(SuffixLoc); 28660b57cec5SDimitry Andric } else { 28670b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::identifier; 28680b57cec5SDimitry Andric return true; 28690b57cec5SDimitry Andric } 28700b57cec5SDimitry Andric 28710b57cec5SDimitry Andric // The string literal must be empty. 28720b57cec5SDimitry Andric if (!Literal.GetString().empty() || Literal.Pascal) { 28730b57cec5SDimitry Andric // C++11 [over.literal]p1: 28740b57cec5SDimitry Andric // The string-literal or user-defined-string-literal in a 28750b57cec5SDimitry Andric // literal-operator-id shall [...] contain no characters 28760b57cec5SDimitry Andric // other than the implicit terminating '\0'. 28770b57cec5SDimitry Andric DiagLoc = TokLocs.front(); 28780b57cec5SDimitry Andric DiagId = diag::err_literal_operator_string_not_empty; 28790b57cec5SDimitry Andric } 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andric if (DiagId) { 28820b57cec5SDimitry Andric // This isn't a valid literal-operator-id, but we think we know 28830b57cec5SDimitry Andric // what the user meant. Tell them what they should have written. 28840b57cec5SDimitry Andric SmallString<32> Str; 28850b57cec5SDimitry Andric Str += "\"\""; 28860b57cec5SDimitry Andric Str += II->getName(); 28870b57cec5SDimitry Andric Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement( 28880b57cec5SDimitry Andric SourceRange(TokLocs.front(), TokLocs.back()), Str); 28890b57cec5SDimitry Andric } 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc); 28920b57cec5SDimitry Andric 2893fe6060f1SDimitry Andric return Actions.checkLiteralOperatorId(SS, Result, IsUDSuffix); 28940b57cec5SDimitry Andric } 28950b57cec5SDimitry Andric 28960b57cec5SDimitry Andric // Parse a conversion-function-id. 28970b57cec5SDimitry Andric // 28980b57cec5SDimitry Andric // conversion-function-id: [C++ 12.3.2] 28990b57cec5SDimitry Andric // operator conversion-type-id 29000b57cec5SDimitry Andric // 29010b57cec5SDimitry Andric // conversion-type-id: 29020b57cec5SDimitry Andric // type-specifier-seq conversion-declarator[opt] 29030b57cec5SDimitry Andric // 29040b57cec5SDimitry Andric // conversion-declarator: 29050b57cec5SDimitry Andric // ptr-operator conversion-declarator[opt] 29060b57cec5SDimitry Andric 29070b57cec5SDimitry Andric // Parse the type-specifier-seq. 29080b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 2909bdd1243dSDimitry Andric if (ParseCXXTypeSpecifierSeq( 2910bdd1243dSDimitry Andric DS, DeclaratorContext::ConversionId)) // FIXME: ObjectType? 29110b57cec5SDimitry Andric return true; 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric // Parse the conversion-declarator, which is merely a sequence of 29140b57cec5SDimitry Andric // ptr-operators. 291581ad6265SDimitry Andric Declarator D(DS, ParsedAttributesView::none(), 291681ad6265SDimitry Andric DeclaratorContext::ConversionId); 29170b57cec5SDimitry Andric ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr); 29180b57cec5SDimitry Andric 29190b57cec5SDimitry Andric // Finish up the type. 29207a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(D); 29210b57cec5SDimitry Andric if (Ty.isInvalid()) 29220b57cec5SDimitry Andric return true; 29230b57cec5SDimitry Andric 29240b57cec5SDimitry Andric // Note that this is a conversion-function-id. 29250b57cec5SDimitry Andric Result.setConversionFunctionId(KeywordLoc, Ty.get(), 29260b57cec5SDimitry Andric D.getSourceRange().getEnd()); 29270b57cec5SDimitry Andric return false; 29280b57cec5SDimitry Andric } 29290b57cec5SDimitry Andric 29300b57cec5SDimitry Andric /// Parse a C++ unqualified-id (or a C identifier), which describes the 29310b57cec5SDimitry Andric /// name of an entity. 29320b57cec5SDimitry Andric /// 29330b57cec5SDimitry Andric /// \code 29340b57cec5SDimitry Andric /// unqualified-id: [C++ expr.prim.general] 29350b57cec5SDimitry Andric /// identifier 29360b57cec5SDimitry Andric /// operator-function-id 29370b57cec5SDimitry Andric /// conversion-function-id 29380b57cec5SDimitry Andric /// [C++0x] literal-operator-id [TODO] 29390b57cec5SDimitry Andric /// ~ class-name 29400b57cec5SDimitry Andric /// template-id 29410b57cec5SDimitry Andric /// 29420b57cec5SDimitry Andric /// \endcode 29430b57cec5SDimitry Andric /// 29440b57cec5SDimitry Andric /// \param SS The nested-name-specifier that preceded this unqualified-id. If 29450b57cec5SDimitry Andric /// non-empty, then we are parsing the unqualified-id of a qualified-id. 29460b57cec5SDimitry Andric /// 29475ffd83dbSDimitry Andric /// \param ObjectType if this unqualified-id occurs within a member access 29485ffd83dbSDimitry Andric /// expression, the type of the base object whose member is being accessed. 29495ffd83dbSDimitry Andric /// 29505ffd83dbSDimitry Andric /// \param ObjectHadErrors if this unqualified-id occurs within a member access 29515ffd83dbSDimitry Andric /// expression, indicates whether the original subexpressions had any errors. 29525ffd83dbSDimitry Andric /// When true, diagnostics for missing 'template' keyword will be supressed. 29535ffd83dbSDimitry Andric /// 29540b57cec5SDimitry Andric /// \param EnteringContext whether we are entering the scope of the 29550b57cec5SDimitry Andric /// nested-name-specifier. 29560b57cec5SDimitry Andric /// 29570b57cec5SDimitry Andric /// \param AllowDestructorName whether we allow parsing of a destructor name. 29580b57cec5SDimitry Andric /// 29590b57cec5SDimitry Andric /// \param AllowConstructorName whether we allow parsing a constructor name. 29600b57cec5SDimitry Andric /// 29610b57cec5SDimitry Andric /// \param AllowDeductionGuide whether we allow parsing a deduction guide name. 29620b57cec5SDimitry Andric /// 29630b57cec5SDimitry Andric /// \param Result on a successful parse, contains the parsed unqualified-id. 29640b57cec5SDimitry Andric /// 29650b57cec5SDimitry Andric /// \returns true if parsing fails, false otherwise. 29665ffd83dbSDimitry Andric bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, 29675ffd83dbSDimitry Andric bool ObjectHadErrors, bool EnteringContext, 29680b57cec5SDimitry Andric bool AllowDestructorName, 29690b57cec5SDimitry Andric bool AllowConstructorName, 29700b57cec5SDimitry Andric bool AllowDeductionGuide, 29710b57cec5SDimitry Andric SourceLocation *TemplateKWLoc, 29720b57cec5SDimitry Andric UnqualifiedId &Result) { 29730b57cec5SDimitry Andric if (TemplateKWLoc) 29740b57cec5SDimitry Andric *TemplateKWLoc = SourceLocation(); 29750b57cec5SDimitry Andric 29760b57cec5SDimitry Andric // Handle 'A::template B'. This is for template-ids which have not 29770b57cec5SDimitry Andric // already been annotated by ParseOptionalCXXScopeSpecifier(). 29780b57cec5SDimitry Andric bool TemplateSpecified = false; 29790b57cec5SDimitry Andric if (Tok.is(tok::kw_template)) { 29800b57cec5SDimitry Andric if (TemplateKWLoc && (ObjectType || SS.isSet())) { 29810b57cec5SDimitry Andric TemplateSpecified = true; 29820b57cec5SDimitry Andric *TemplateKWLoc = ConsumeToken(); 29830b57cec5SDimitry Andric } else { 29840b57cec5SDimitry Andric SourceLocation TemplateLoc = ConsumeToken(); 29850b57cec5SDimitry Andric Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) 29860b57cec5SDimitry Andric << FixItHint::CreateRemoval(TemplateLoc); 29870b57cec5SDimitry Andric } 29880b57cec5SDimitry Andric } 29890b57cec5SDimitry Andric 29900b57cec5SDimitry Andric // unqualified-id: 29910b57cec5SDimitry Andric // identifier 29920b57cec5SDimitry Andric // template-id (when it hasn't already been annotated) 29930b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 2994bdd1243dSDimitry Andric ParseIdentifier: 29950b57cec5SDimitry Andric // Consume the identifier. 29960b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 29970b57cec5SDimitry Andric SourceLocation IdLoc = ConsumeToken(); 29980b57cec5SDimitry Andric 29990b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 30000b57cec5SDimitry Andric // If we're not in C++, only identifiers matter. Record the 30010b57cec5SDimitry Andric // identifier and return. 30020b57cec5SDimitry Andric Result.setIdentifier(Id, IdLoc); 30030b57cec5SDimitry Andric return false; 30040b57cec5SDimitry Andric } 30050b57cec5SDimitry Andric 30060b57cec5SDimitry Andric ParsedTemplateTy TemplateName; 30070b57cec5SDimitry Andric if (AllowConstructorName && 30080b57cec5SDimitry Andric Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { 30090b57cec5SDimitry Andric // We have parsed a constructor name. 30100b57cec5SDimitry Andric ParsedType Ty = Actions.getConstructorName(*Id, IdLoc, getCurScope(), SS, 30110b57cec5SDimitry Andric EnteringContext); 30120b57cec5SDimitry Andric if (!Ty) 30130b57cec5SDimitry Andric return true; 30140b57cec5SDimitry Andric Result.setConstructorName(Ty, IdLoc, IdLoc); 301506c3fb27SDimitry Andric } else if (getLangOpts().CPlusPlus17 && AllowDeductionGuide && 301606c3fb27SDimitry Andric SS.isEmpty() && 301706c3fb27SDimitry Andric Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc, SS, 30180b57cec5SDimitry Andric &TemplateName)) { 30190b57cec5SDimitry Andric // We have parsed a template-name naming a deduction guide. 30200b57cec5SDimitry Andric Result.setDeductionGuideName(TemplateName, IdLoc); 30210b57cec5SDimitry Andric } else { 30220b57cec5SDimitry Andric // We have parsed an identifier. 30230b57cec5SDimitry Andric Result.setIdentifier(Id, IdLoc); 30240b57cec5SDimitry Andric } 30250b57cec5SDimitry Andric 30260b57cec5SDimitry Andric // If the next token is a '<', we may have a template. 30270b57cec5SDimitry Andric TemplateTy Template; 30280b57cec5SDimitry Andric if (Tok.is(tok::less)) 30290b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 30305ffd83dbSDimitry Andric SS, ObjectType, ObjectHadErrors, 30315ffd83dbSDimitry Andric TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, 30325ffd83dbSDimitry Andric EnteringContext, Result, TemplateSpecified); 3033*0fca6ea1SDimitry Andric 3034*0fca6ea1SDimitry Andric if (TemplateSpecified) { 3035*0fca6ea1SDimitry Andric TemplateNameKind TNK = 3036*0fca6ea1SDimitry Andric Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result, 3037*0fca6ea1SDimitry Andric ObjectType, EnteringContext, Template, 3038*0fca6ea1SDimitry Andric /*AllowInjectedClassName=*/true); 3039*0fca6ea1SDimitry Andric if (TNK == TNK_Non_template) 30400b57cec5SDimitry Andric return true; 30410b57cec5SDimitry Andric 3042*0fca6ea1SDimitry Andric // C++2c [tem.names]p6 3043*0fca6ea1SDimitry Andric // A name prefixed by the keyword template shall be followed by a template 3044*0fca6ea1SDimitry Andric // argument list or refer to a class template or an alias template. 3045*0fca6ea1SDimitry Andric if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name || 3046*0fca6ea1SDimitry Andric TNK == TNK_Var_template) && 3047*0fca6ea1SDimitry Andric !Tok.is(tok::less)) 3048*0fca6ea1SDimitry Andric Diag(IdLoc, diag::missing_template_arg_list_after_template_kw); 3049*0fca6ea1SDimitry Andric } 30500b57cec5SDimitry Andric return false; 30510b57cec5SDimitry Andric } 30520b57cec5SDimitry Andric 30530b57cec5SDimitry Andric // unqualified-id: 30540b57cec5SDimitry Andric // template-id (already parsed and annotated) 30550b57cec5SDimitry Andric if (Tok.is(tok::annot_template_id)) { 30560b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 30570b57cec5SDimitry Andric 30585ffd83dbSDimitry Andric // FIXME: Consider passing invalid template-ids on to callers; they may 30595ffd83dbSDimitry Andric // be able to recover better than we can. 30605ffd83dbSDimitry Andric if (TemplateId->isInvalid()) { 30615ffd83dbSDimitry Andric ConsumeAnnotationToken(); 30625ffd83dbSDimitry Andric return true; 30635ffd83dbSDimitry Andric } 30645ffd83dbSDimitry Andric 30650b57cec5SDimitry Andric // If the template-name names the current class, then this is a constructor 30660b57cec5SDimitry Andric if (AllowConstructorName && TemplateId->Name && 30670b57cec5SDimitry Andric Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 30680b57cec5SDimitry Andric if (SS.isSet()) { 30690b57cec5SDimitry Andric // C++ [class.qual]p2 specifies that a qualified template-name 30700b57cec5SDimitry Andric // is taken as the constructor name where a constructor can be 30710b57cec5SDimitry Andric // declared. Thus, the template arguments are extraneous, so 30720b57cec5SDimitry Andric // complain about them and remove them entirely. 30730b57cec5SDimitry Andric Diag(TemplateId->TemplateNameLoc, 30740b57cec5SDimitry Andric diag::err_out_of_line_constructor_template_id) 30750b57cec5SDimitry Andric << TemplateId->Name 30760b57cec5SDimitry Andric << FixItHint::CreateRemoval( 30770b57cec5SDimitry Andric SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 30780b57cec5SDimitry Andric ParsedType Ty = Actions.getConstructorName( 30790b57cec5SDimitry Andric *TemplateId->Name, TemplateId->TemplateNameLoc, getCurScope(), SS, 30800b57cec5SDimitry Andric EnteringContext); 30810b57cec5SDimitry Andric if (!Ty) 30820b57cec5SDimitry Andric return true; 30830b57cec5SDimitry Andric Result.setConstructorName(Ty, TemplateId->TemplateNameLoc, 30840b57cec5SDimitry Andric TemplateId->RAngleLoc); 30850b57cec5SDimitry Andric ConsumeAnnotationToken(); 30860b57cec5SDimitry Andric return false; 30870b57cec5SDimitry Andric } 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric Result.setConstructorTemplateId(TemplateId); 30900b57cec5SDimitry Andric ConsumeAnnotationToken(); 30910b57cec5SDimitry Andric return false; 30920b57cec5SDimitry Andric } 30930b57cec5SDimitry Andric 30940b57cec5SDimitry Andric // We have already parsed a template-id; consume the annotation token as 30950b57cec5SDimitry Andric // our unqualified-id. 30960b57cec5SDimitry Andric Result.setTemplateId(TemplateId); 30970b57cec5SDimitry Andric SourceLocation TemplateLoc = TemplateId->TemplateKWLoc; 30980b57cec5SDimitry Andric if (TemplateLoc.isValid()) { 30990b57cec5SDimitry Andric if (TemplateKWLoc && (ObjectType || SS.isSet())) 31000b57cec5SDimitry Andric *TemplateKWLoc = TemplateLoc; 31010b57cec5SDimitry Andric else 31020b57cec5SDimitry Andric Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) 31030b57cec5SDimitry Andric << FixItHint::CreateRemoval(TemplateLoc); 31040b57cec5SDimitry Andric } 31050b57cec5SDimitry Andric ConsumeAnnotationToken(); 31060b57cec5SDimitry Andric return false; 31070b57cec5SDimitry Andric } 31080b57cec5SDimitry Andric 31090b57cec5SDimitry Andric // unqualified-id: 31100b57cec5SDimitry Andric // operator-function-id 31110b57cec5SDimitry Andric // conversion-function-id 31120b57cec5SDimitry Andric if (Tok.is(tok::kw_operator)) { 31130b57cec5SDimitry Andric if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 31140b57cec5SDimitry Andric return true; 31150b57cec5SDimitry Andric 31160b57cec5SDimitry Andric // If we have an operator-function-id or a literal-operator-id and the next 31170b57cec5SDimitry Andric // token is a '<', we may have a 31180b57cec5SDimitry Andric // 31190b57cec5SDimitry Andric // template-id: 31200b57cec5SDimitry Andric // operator-function-id < template-argument-list[opt] > 31210b57cec5SDimitry Andric TemplateTy Template; 31220b57cec5SDimitry Andric if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId || 31230b57cec5SDimitry Andric Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) && 31240b57cec5SDimitry Andric Tok.is(tok::less)) 31250b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 31265ffd83dbSDimitry Andric SS, ObjectType, ObjectHadErrors, 31275ffd83dbSDimitry Andric TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr, 31285ffd83dbSDimitry Andric SourceLocation(), EnteringContext, Result, TemplateSpecified); 31290b57cec5SDimitry Andric else if (TemplateSpecified && 31305ffd83dbSDimitry Andric Actions.ActOnTemplateName( 31310b57cec5SDimitry Andric getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, 31320b57cec5SDimitry Andric EnteringContext, Template, 31330b57cec5SDimitry Andric /*AllowInjectedClassName*/ true) == TNK_Non_template) 31340b57cec5SDimitry Andric return true; 31350b57cec5SDimitry Andric 31360b57cec5SDimitry Andric return false; 31370b57cec5SDimitry Andric } 31380b57cec5SDimitry Andric 31390b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && 31400b57cec5SDimitry Andric (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 31410b57cec5SDimitry Andric // C++ [expr.unary.op]p10: 31420b57cec5SDimitry Andric // There is an ambiguity in the unary-expression ~X(), where X is a 31430b57cec5SDimitry Andric // class-name. The ambiguity is resolved in favor of treating ~ as a 31440b57cec5SDimitry Andric // unary complement rather than treating ~X as referring to a destructor. 31450b57cec5SDimitry Andric 31460b57cec5SDimitry Andric // Parse the '~'. 31470b57cec5SDimitry Andric SourceLocation TildeLoc = ConsumeToken(); 31480b57cec5SDimitry Andric 31495ffd83dbSDimitry Andric if (TemplateSpecified) { 31505ffd83dbSDimitry Andric // C++ [temp.names]p3: 31515ffd83dbSDimitry Andric // A name prefixed by the keyword template shall be a template-id [...] 31525ffd83dbSDimitry Andric // 31535ffd83dbSDimitry Andric // A template-id cannot begin with a '~' token. This would never work 31545ffd83dbSDimitry Andric // anyway: x.~A<int>() would specify that the destructor is a template, 31555ffd83dbSDimitry Andric // not that 'A' is a template. 31565ffd83dbSDimitry Andric // 31575ffd83dbSDimitry Andric // FIXME: Suggest replacing the attempted destructor name with a correct 31585ffd83dbSDimitry Andric // destructor name and recover. (This is not trivial if this would become 31595ffd83dbSDimitry Andric // a pseudo-destructor name). 31605ffd83dbSDimitry Andric Diag(*TemplateKWLoc, diag::err_unexpected_template_in_destructor_name) 31615ffd83dbSDimitry Andric << Tok.getLocation(); 31625ffd83dbSDimitry Andric return true; 31635ffd83dbSDimitry Andric } 31645ffd83dbSDimitry Andric 31650b57cec5SDimitry Andric if (SS.isEmpty() && Tok.is(tok::kw_decltype)) { 31660b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 31670b57cec5SDimitry Andric SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 31680b57cec5SDimitry Andric if (ParsedType Type = 31690b57cec5SDimitry Andric Actions.getDestructorTypeForDecltype(DS, ObjectType)) { 31700b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, Type, EndLoc); 31710b57cec5SDimitry Andric return false; 31720b57cec5SDimitry Andric } 31730b57cec5SDimitry Andric return true; 31740b57cec5SDimitry Andric } 31750b57cec5SDimitry Andric 31760b57cec5SDimitry Andric // Parse the class-name. 31770b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 31780b57cec5SDimitry Andric Diag(Tok, diag::err_destructor_tilde_identifier); 31790b57cec5SDimitry Andric return true; 31800b57cec5SDimitry Andric } 31810b57cec5SDimitry Andric 31820b57cec5SDimitry Andric // If the user wrote ~T::T, correct it to T::~T. 31830b57cec5SDimitry Andric DeclaratorScopeObj DeclScopeObj(*this, SS); 31845ffd83dbSDimitry Andric if (NextToken().is(tok::coloncolon)) { 31850b57cec5SDimitry Andric // Don't let ParseOptionalCXXScopeSpecifier() "correct" 31860b57cec5SDimitry Andric // `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`, 31870b57cec5SDimitry Andric // it will confuse this recovery logic. 31880b57cec5SDimitry Andric ColonProtectionRAIIObject ColonRAII(*this, false); 31890b57cec5SDimitry Andric 31900b57cec5SDimitry Andric if (SS.isSet()) { 31910b57cec5SDimitry Andric AnnotateScopeToken(SS, /*NewAnnotation*/true); 31920b57cec5SDimitry Andric SS.clear(); 31930b57cec5SDimitry Andric } 31945ffd83dbSDimitry Andric if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, ObjectHadErrors, 31955ffd83dbSDimitry Andric EnteringContext)) 31960b57cec5SDimitry Andric return true; 31970b57cec5SDimitry Andric if (SS.isNotEmpty()) 31980b57cec5SDimitry Andric ObjectType = nullptr; 31990b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) || 32000b57cec5SDimitry Andric !SS.isSet()) { 32010b57cec5SDimitry Andric Diag(TildeLoc, diag::err_destructor_tilde_scope); 32020b57cec5SDimitry Andric return true; 32030b57cec5SDimitry Andric } 32040b57cec5SDimitry Andric 32050b57cec5SDimitry Andric // Recover as if the tilde had been written before the identifier. 32060b57cec5SDimitry Andric Diag(TildeLoc, diag::err_destructor_tilde_scope) 32070b57cec5SDimitry Andric << FixItHint::CreateRemoval(TildeLoc) 32080b57cec5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "~"); 32090b57cec5SDimitry Andric 32100b57cec5SDimitry Andric // Temporarily enter the scope for the rest of this function. 32110b57cec5SDimitry Andric if (Actions.ShouldEnterDeclaratorScope(getCurScope(), SS)) 32120b57cec5SDimitry Andric DeclScopeObj.EnterDeclaratorScope(); 32130b57cec5SDimitry Andric } 32140b57cec5SDimitry Andric 32150b57cec5SDimitry Andric // Parse the class-name (or template-name in a simple-template-id). 32160b57cec5SDimitry Andric IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 32170b57cec5SDimitry Andric SourceLocation ClassNameLoc = ConsumeToken(); 32180b57cec5SDimitry Andric 32190b57cec5SDimitry Andric if (Tok.is(tok::less)) { 32200b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc); 32210b57cec5SDimitry Andric return ParseUnqualifiedIdTemplateId( 32225ffd83dbSDimitry Andric SS, ObjectType, ObjectHadErrors, 32235ffd83dbSDimitry Andric TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName, 32245ffd83dbSDimitry Andric ClassNameLoc, EnteringContext, Result, TemplateSpecified); 32250b57cec5SDimitry Andric } 32260b57cec5SDimitry Andric 32270b57cec5SDimitry Andric // Note that this is a destructor name. 32285f757f3fSDimitry Andric ParsedType Ty = 32295f757f3fSDimitry Andric Actions.getDestructorName(*ClassName, ClassNameLoc, getCurScope(), SS, 32305f757f3fSDimitry Andric ObjectType, EnteringContext); 32310b57cec5SDimitry Andric if (!Ty) 32320b57cec5SDimitry Andric return true; 32330b57cec5SDimitry Andric 32340b57cec5SDimitry Andric Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 32350b57cec5SDimitry Andric return false; 32360b57cec5SDimitry Andric } 32370b57cec5SDimitry Andric 3238bdd1243dSDimitry Andric switch (Tok.getKind()) { 3239bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: 3240bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 3241bdd1243dSDimitry Andric if (!NextToken().is(tok::l_paren)) { 3242bdd1243dSDimitry Andric Tok.setKind(tok::identifier); 3243bdd1243dSDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 3244bdd1243dSDimitry Andric << Tok.getIdentifierInfo()->getName() << 0; 3245bdd1243dSDimitry Andric goto ParseIdentifier; 3246bdd1243dSDimitry Andric } 3247bdd1243dSDimitry Andric [[fallthrough]]; 3248bdd1243dSDimitry Andric default: 3249bdd1243dSDimitry Andric Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus; 32500b57cec5SDimitry Andric return true; 32510b57cec5SDimitry Andric } 3252bdd1243dSDimitry Andric } 32530b57cec5SDimitry Andric 32540b57cec5SDimitry Andric /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 32550b57cec5SDimitry Andric /// memory in a typesafe manner and call constructors. 32560b57cec5SDimitry Andric /// 32570b57cec5SDimitry Andric /// This method is called to parse the new expression after the optional :: has 32580b57cec5SDimitry Andric /// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 32590b57cec5SDimitry Andric /// is its location. Otherwise, "Start" is the location of the 'new' token. 32600b57cec5SDimitry Andric /// 32610b57cec5SDimitry Andric /// new-expression: 32620b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 32630b57cec5SDimitry Andric /// new-initializer[opt] 32640b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 32650b57cec5SDimitry Andric /// new-initializer[opt] 32660b57cec5SDimitry Andric /// 32670b57cec5SDimitry Andric /// new-placement: 32680b57cec5SDimitry Andric /// '(' expression-list ')' 32690b57cec5SDimitry Andric /// 32700b57cec5SDimitry Andric /// new-type-id: 32710b57cec5SDimitry Andric /// type-specifier-seq new-declarator[opt] 32720b57cec5SDimitry Andric /// [GNU] attributes type-specifier-seq new-declarator[opt] 32730b57cec5SDimitry Andric /// 32740b57cec5SDimitry Andric /// new-declarator: 32750b57cec5SDimitry Andric /// ptr-operator new-declarator[opt] 32760b57cec5SDimitry Andric /// direct-new-declarator 32770b57cec5SDimitry Andric /// 32780b57cec5SDimitry Andric /// new-initializer: 32790b57cec5SDimitry Andric /// '(' expression-list[opt] ')' 32800b57cec5SDimitry Andric /// [C++0x] braced-init-list 32810b57cec5SDimitry Andric /// 32820b57cec5SDimitry Andric ExprResult 32830b57cec5SDimitry Andric Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 32840b57cec5SDimitry Andric assert(Tok.is(tok::kw_new) && "expected 'new' token"); 32850b57cec5SDimitry Andric ConsumeToken(); // Consume 'new' 32860b57cec5SDimitry Andric 32870b57cec5SDimitry Andric // A '(' now can be a new-placement or the '(' wrapping the type-id in the 32880b57cec5SDimitry Andric // second form of new-expression. It can't be a new-type-id. 32890b57cec5SDimitry Andric 32900b57cec5SDimitry Andric ExprVector PlacementArgs; 32910b57cec5SDimitry Andric SourceLocation PlacementLParen, PlacementRParen; 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric SourceRange TypeIdParens; 32940b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 329581ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 329681ad6265SDimitry Andric DeclaratorContext::CXXNew); 32970b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 32980b57cec5SDimitry Andric // If it turns out to be a placement, we change the type location. 32990b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 33000b57cec5SDimitry Andric T.consumeOpen(); 33010b57cec5SDimitry Andric PlacementLParen = T.getOpenLocation(); 33020b57cec5SDimitry Andric if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 33030b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 33040b57cec5SDimitry Andric return ExprError(); 33050b57cec5SDimitry Andric } 33060b57cec5SDimitry Andric 33070b57cec5SDimitry Andric T.consumeClose(); 33080b57cec5SDimitry Andric PlacementRParen = T.getCloseLocation(); 33090b57cec5SDimitry Andric if (PlacementRParen.isInvalid()) { 33100b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 33110b57cec5SDimitry Andric return ExprError(); 33120b57cec5SDimitry Andric } 33130b57cec5SDimitry Andric 33140b57cec5SDimitry Andric if (PlacementArgs.empty()) { 33150b57cec5SDimitry Andric // Reset the placement locations. There was no placement. 33160b57cec5SDimitry Andric TypeIdParens = T.getRange(); 33170b57cec5SDimitry Andric PlacementLParen = PlacementRParen = SourceLocation(); 33180b57cec5SDimitry Andric } else { 33190b57cec5SDimitry Andric // We still need the type. 33200b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 33210b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 33220b57cec5SDimitry Andric T.consumeOpen(); 33230b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 33240b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 33250b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 33260b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 33270b57cec5SDimitry Andric T.consumeClose(); 33280b57cec5SDimitry Andric TypeIdParens = T.getRange(); 33290b57cec5SDimitry Andric } else { 33300b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 33310b57cec5SDimitry Andric if (ParseCXXTypeSpecifierSeq(DS)) 33320b57cec5SDimitry Andric DeclaratorInfo.setInvalidType(true); 33330b57cec5SDimitry Andric else { 33340b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 33350b57cec5SDimitry Andric ParseDeclaratorInternal(DeclaratorInfo, 33360b57cec5SDimitry Andric &Parser::ParseDirectNewDeclarator); 33370b57cec5SDimitry Andric } 33380b57cec5SDimitry Andric } 33390b57cec5SDimitry Andric } 33400b57cec5SDimitry Andric } else { 33410b57cec5SDimitry Andric // A new-type-id is a simplified type-id, where essentially the 33420b57cec5SDimitry Andric // direct-declarator is replaced by a direct-new-declarator. 33430b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 334406c3fb27SDimitry Andric if (ParseCXXTypeSpecifierSeq(DS, DeclaratorContext::CXXNew)) 33450b57cec5SDimitry Andric DeclaratorInfo.setInvalidType(true); 33460b57cec5SDimitry Andric else { 33470b57cec5SDimitry Andric DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 33480b57cec5SDimitry Andric ParseDeclaratorInternal(DeclaratorInfo, 33490b57cec5SDimitry Andric &Parser::ParseDirectNewDeclarator); 33500b57cec5SDimitry Andric } 33510b57cec5SDimitry Andric } 33520b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) { 33530b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 33540b57cec5SDimitry Andric return ExprError(); 33550b57cec5SDimitry Andric } 33560b57cec5SDimitry Andric 33570b57cec5SDimitry Andric ExprResult Initializer; 33580b57cec5SDimitry Andric 33590b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 33600b57cec5SDimitry Andric SourceLocation ConstructorLParen, ConstructorRParen; 33610b57cec5SDimitry Andric ExprVector ConstructorArgs; 33620b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 33630b57cec5SDimitry Andric T.consumeOpen(); 33640b57cec5SDimitry Andric ConstructorLParen = T.getOpenLocation(); 33650b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 33660b57cec5SDimitry Andric auto RunSignatureHelp = [&]() { 33677a6dacacSDimitry Andric ParsedType TypeRep = Actions.ActOnTypeName(DeclaratorInfo).get(); 33685ffd83dbSDimitry Andric QualType PreferredType; 33695ffd83dbSDimitry Andric // ActOnTypeName might adjust DeclaratorInfo and return a null type even 33705ffd83dbSDimitry Andric // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on 33715ffd83dbSDimitry Andric // `new decltype(invalid) (^)`. 33725ffd83dbSDimitry Andric if (TypeRep) 3373*0fca6ea1SDimitry Andric PreferredType = 3374*0fca6ea1SDimitry Andric Actions.CodeCompletion().ProduceConstructorSignatureHelp( 337504eeddc0SDimitry Andric TypeRep.get()->getCanonicalTypeInternal(), 3376*0fca6ea1SDimitry Andric DeclaratorInfo.getEndLoc(), ConstructorArgs, 3377*0fca6ea1SDimitry Andric ConstructorLParen, 337804eeddc0SDimitry Andric /*Braced=*/false); 33790b57cec5SDimitry Andric CalledSignatureHelp = true; 33800b57cec5SDimitry Andric return PreferredType; 33810b57cec5SDimitry Andric }; 3382bdd1243dSDimitry Andric if (ParseExpressionList(ConstructorArgs, [&] { 33830b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 33840b57cec5SDimitry Andric RunSignatureHelp); 33850b57cec5SDimitry Andric })) { 33860b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 33870b57cec5SDimitry Andric RunSignatureHelp(); 33880b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 33890b57cec5SDimitry Andric return ExprError(); 33900b57cec5SDimitry Andric } 33910b57cec5SDimitry Andric } 33920b57cec5SDimitry Andric T.consumeClose(); 33930b57cec5SDimitry Andric ConstructorRParen = T.getCloseLocation(); 33940b57cec5SDimitry Andric if (ConstructorRParen.isInvalid()) { 33950b57cec5SDimitry Andric SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); 33960b57cec5SDimitry Andric return ExprError(); 33970b57cec5SDimitry Andric } 33980b57cec5SDimitry Andric Initializer = Actions.ActOnParenListExpr(ConstructorLParen, 33990b57cec5SDimitry Andric ConstructorRParen, 34000b57cec5SDimitry Andric ConstructorArgs); 34010b57cec5SDimitry Andric } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) { 34020b57cec5SDimitry Andric Diag(Tok.getLocation(), 34030b57cec5SDimitry Andric diag::warn_cxx98_compat_generalized_initializer_lists); 34040b57cec5SDimitry Andric Initializer = ParseBraceInitializer(); 34050b57cec5SDimitry Andric } 34060b57cec5SDimitry Andric if (Initializer.isInvalid()) 34070b57cec5SDimitry Andric return Initializer; 34080b57cec5SDimitry Andric 34090b57cec5SDimitry Andric return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 34100b57cec5SDimitry Andric PlacementArgs, PlacementRParen, 34110b57cec5SDimitry Andric TypeIdParens, DeclaratorInfo, Initializer.get()); 34120b57cec5SDimitry Andric } 34130b57cec5SDimitry Andric 34140b57cec5SDimitry Andric /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 34150b57cec5SDimitry Andric /// passed to ParseDeclaratorInternal. 34160b57cec5SDimitry Andric /// 34170b57cec5SDimitry Andric /// direct-new-declarator: 34180b57cec5SDimitry Andric /// '[' expression[opt] ']' 34190b57cec5SDimitry Andric /// direct-new-declarator '[' constant-expression ']' 34200b57cec5SDimitry Andric /// 34210b57cec5SDimitry Andric void Parser::ParseDirectNewDeclarator(Declarator &D) { 34220b57cec5SDimitry Andric // Parse the array dimensions. 34230b57cec5SDimitry Andric bool First = true; 34240b57cec5SDimitry Andric while (Tok.is(tok::l_square)) { 34250b57cec5SDimitry Andric // An array-size expression can't start with a lambda. 34260b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 34270b57cec5SDimitry Andric continue; 34280b57cec5SDimitry Andric 34290b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 34300b57cec5SDimitry Andric T.consumeOpen(); 34310b57cec5SDimitry Andric 34320b57cec5SDimitry Andric ExprResult Size = 34330b57cec5SDimitry Andric First ? (Tok.is(tok::r_square) ? ExprResult() : ParseExpression()) 34340b57cec5SDimitry Andric : ParseConstantExpression(); 34350b57cec5SDimitry Andric if (Size.isInvalid()) { 34360b57cec5SDimitry Andric // Recover 34370b57cec5SDimitry Andric SkipUntil(tok::r_square, StopAtSemi); 34380b57cec5SDimitry Andric return; 34390b57cec5SDimitry Andric } 34400b57cec5SDimitry Andric First = false; 34410b57cec5SDimitry Andric 34420b57cec5SDimitry Andric T.consumeClose(); 34430b57cec5SDimitry Andric 34440b57cec5SDimitry Andric // Attributes here appertain to the array type. C++11 [expr.new]p5. 34450b57cec5SDimitry Andric ParsedAttributes Attrs(AttrFactory); 34460b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attrs); 34470b57cec5SDimitry Andric 34480b57cec5SDimitry Andric D.AddTypeInfo(DeclaratorChunk::getArray(0, 34490b57cec5SDimitry Andric /*isStatic=*/false, /*isStar=*/false, 34500b57cec5SDimitry Andric Size.get(), T.getOpenLocation(), 34510b57cec5SDimitry Andric T.getCloseLocation()), 34520b57cec5SDimitry Andric std::move(Attrs), T.getCloseLocation()); 34530b57cec5SDimitry Andric 34540b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 34550b57cec5SDimitry Andric return; 34560b57cec5SDimitry Andric } 34570b57cec5SDimitry Andric } 34580b57cec5SDimitry Andric 34590b57cec5SDimitry Andric /// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 34600b57cec5SDimitry Andric /// This ambiguity appears in the syntax of the C++ new operator. 34610b57cec5SDimitry Andric /// 34620b57cec5SDimitry Andric /// new-expression: 34630b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 34640b57cec5SDimitry Andric /// new-initializer[opt] 34650b57cec5SDimitry Andric /// 34660b57cec5SDimitry Andric /// new-placement: 34670b57cec5SDimitry Andric /// '(' expression-list ')' 34680b57cec5SDimitry Andric /// 34690b57cec5SDimitry Andric bool Parser::ParseExpressionListOrTypeId( 34700b57cec5SDimitry Andric SmallVectorImpl<Expr*> &PlacementArgs, 34710b57cec5SDimitry Andric Declarator &D) { 34720b57cec5SDimitry Andric // The '(' was already consumed. 34730b57cec5SDimitry Andric if (isTypeIdInParens()) { 34740b57cec5SDimitry Andric ParseSpecifierQualifierList(D.getMutableDeclSpec()); 34750b57cec5SDimitry Andric D.SetSourceRange(D.getDeclSpec().getSourceRange()); 34760b57cec5SDimitry Andric ParseDeclarator(D); 34770b57cec5SDimitry Andric return D.isInvalidType(); 34780b57cec5SDimitry Andric } 34790b57cec5SDimitry Andric 34800b57cec5SDimitry Andric // It's not a type, it has to be an expression list. 3481bdd1243dSDimitry Andric return ParseExpressionList(PlacementArgs); 34820b57cec5SDimitry Andric } 34830b57cec5SDimitry Andric 34840b57cec5SDimitry Andric /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 34850b57cec5SDimitry Andric /// to free memory allocated by new. 34860b57cec5SDimitry Andric /// 34870b57cec5SDimitry Andric /// This method is called to parse the 'delete' expression after the optional 34880b57cec5SDimitry Andric /// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 34890b57cec5SDimitry Andric /// and "Start" is its location. Otherwise, "Start" is the location of the 34900b57cec5SDimitry Andric /// 'delete' token. 34910b57cec5SDimitry Andric /// 34920b57cec5SDimitry Andric /// delete-expression: 34930b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 34940b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 34950b57cec5SDimitry Andric ExprResult 34960b57cec5SDimitry Andric Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 34970b57cec5SDimitry Andric assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 34980b57cec5SDimitry Andric ConsumeToken(); // Consume 'delete' 34990b57cec5SDimitry Andric 35000b57cec5SDimitry Andric // Array delete? 35010b57cec5SDimitry Andric bool ArrayDelete = false; 35020b57cec5SDimitry Andric if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) { 35030b57cec5SDimitry Andric // C++11 [expr.delete]p1: 35040b57cec5SDimitry Andric // Whenever the delete keyword is followed by empty square brackets, it 35050b57cec5SDimitry Andric // shall be interpreted as [array delete]. 35060b57cec5SDimitry Andric // [Footnote: A lambda expression with a lambda-introducer that consists 35070b57cec5SDimitry Andric // of empty square brackets can follow the delete keyword if 35080b57cec5SDimitry Andric // the lambda expression is enclosed in parentheses.] 35090b57cec5SDimitry Andric 35100b57cec5SDimitry Andric const Token Next = GetLookAheadToken(2); 35110b57cec5SDimitry Andric 35120b57cec5SDimitry Andric // Basic lookahead to check if we have a lambda expression. 35130b57cec5SDimitry Andric if (Next.isOneOf(tok::l_brace, tok::less) || 35140b57cec5SDimitry Andric (Next.is(tok::l_paren) && 35150b57cec5SDimitry Andric (GetLookAheadToken(3).is(tok::r_paren) || 35160b57cec5SDimitry Andric (GetLookAheadToken(3).is(tok::identifier) && 35170b57cec5SDimitry Andric GetLookAheadToken(4).is(tok::identifier))))) { 35180b57cec5SDimitry Andric TentativeParsingAction TPA(*this); 35190b57cec5SDimitry Andric SourceLocation LSquareLoc = Tok.getLocation(); 35200b57cec5SDimitry Andric SourceLocation RSquareLoc = NextToken().getLocation(); 35210b57cec5SDimitry Andric 35220b57cec5SDimitry Andric // SkipUntil can't skip pairs of </*...*/>; don't emit a FixIt in this 35230b57cec5SDimitry Andric // case. 35240b57cec5SDimitry Andric SkipUntil({tok::l_brace, tok::less}, StopBeforeMatch); 35250b57cec5SDimitry Andric SourceLocation RBraceLoc; 35260b57cec5SDimitry Andric bool EmitFixIt = false; 35270b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 35280b57cec5SDimitry Andric ConsumeBrace(); 35290b57cec5SDimitry Andric SkipUntil(tok::r_brace, StopBeforeMatch); 35300b57cec5SDimitry Andric RBraceLoc = Tok.getLocation(); 35310b57cec5SDimitry Andric EmitFixIt = true; 35320b57cec5SDimitry Andric } 35330b57cec5SDimitry Andric 35340b57cec5SDimitry Andric TPA.Revert(); 35350b57cec5SDimitry Andric 35360b57cec5SDimitry Andric if (EmitFixIt) 35370b57cec5SDimitry Andric Diag(Start, diag::err_lambda_after_delete) 35380b57cec5SDimitry Andric << SourceRange(Start, RSquareLoc) 35390b57cec5SDimitry Andric << FixItHint::CreateInsertion(LSquareLoc, "(") 35400b57cec5SDimitry Andric << FixItHint::CreateInsertion( 35410b57cec5SDimitry Andric Lexer::getLocForEndOfToken( 35420b57cec5SDimitry Andric RBraceLoc, 0, Actions.getSourceManager(), getLangOpts()), 35430b57cec5SDimitry Andric ")"); 35440b57cec5SDimitry Andric else 35450b57cec5SDimitry Andric Diag(Start, diag::err_lambda_after_delete) 35460b57cec5SDimitry Andric << SourceRange(Start, RSquareLoc); 35470b57cec5SDimitry Andric 35480b57cec5SDimitry Andric // Warn that the non-capturing lambda isn't surrounded by parentheses 35490b57cec5SDimitry Andric // to disambiguate it from 'delete[]'. 35500b57cec5SDimitry Andric ExprResult Lambda = ParseLambdaExpression(); 35510b57cec5SDimitry Andric if (Lambda.isInvalid()) 35520b57cec5SDimitry Andric return ExprError(); 35530b57cec5SDimitry Andric 35540b57cec5SDimitry Andric // Evaluate any postfix expressions used on the lambda. 35550b57cec5SDimitry Andric Lambda = ParsePostfixExpressionSuffix(Lambda); 35560b57cec5SDimitry Andric if (Lambda.isInvalid()) 35570b57cec5SDimitry Andric return ExprError(); 35580b57cec5SDimitry Andric return Actions.ActOnCXXDelete(Start, UseGlobal, /*ArrayForm=*/false, 35590b57cec5SDimitry Andric Lambda.get()); 35600b57cec5SDimitry Andric } 35610b57cec5SDimitry Andric 35620b57cec5SDimitry Andric ArrayDelete = true; 35630b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 35640b57cec5SDimitry Andric 35650b57cec5SDimitry Andric T.consumeOpen(); 35660b57cec5SDimitry Andric T.consumeClose(); 35670b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 35680b57cec5SDimitry Andric return ExprError(); 35690b57cec5SDimitry Andric } 35700b57cec5SDimitry Andric 3571480093f4SDimitry Andric ExprResult Operand(ParseCastExpression(AnyCastExpr)); 35720b57cec5SDimitry Andric if (Operand.isInvalid()) 35730b57cec5SDimitry Andric return Operand; 35740b57cec5SDimitry Andric 35750b57cec5SDimitry Andric return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get()); 35760b57cec5SDimitry Andric } 35770b57cec5SDimitry Andric 357855e4f9d5SDimitry Andric /// ParseRequiresExpression - Parse a C++2a requires-expression. 357955e4f9d5SDimitry Andric /// C++2a [expr.prim.req]p1 358055e4f9d5SDimitry Andric /// A requires-expression provides a concise way to express requirements on 358155e4f9d5SDimitry Andric /// template arguments. A requirement is one that can be checked by name 358255e4f9d5SDimitry Andric /// lookup (6.4) or by checking properties of types and expressions. 358355e4f9d5SDimitry Andric /// 358455e4f9d5SDimitry Andric /// requires-expression: 358555e4f9d5SDimitry Andric /// 'requires' requirement-parameter-list[opt] requirement-body 358655e4f9d5SDimitry Andric /// 358755e4f9d5SDimitry Andric /// requirement-parameter-list: 358855e4f9d5SDimitry Andric /// '(' parameter-declaration-clause[opt] ')' 358955e4f9d5SDimitry Andric /// 359055e4f9d5SDimitry Andric /// requirement-body: 359155e4f9d5SDimitry Andric /// '{' requirement-seq '}' 359255e4f9d5SDimitry Andric /// 359355e4f9d5SDimitry Andric /// requirement-seq: 359455e4f9d5SDimitry Andric /// requirement 359555e4f9d5SDimitry Andric /// requirement-seq requirement 359655e4f9d5SDimitry Andric /// 359755e4f9d5SDimitry Andric /// requirement: 359855e4f9d5SDimitry Andric /// simple-requirement 359955e4f9d5SDimitry Andric /// type-requirement 360055e4f9d5SDimitry Andric /// compound-requirement 360155e4f9d5SDimitry Andric /// nested-requirement 360255e4f9d5SDimitry Andric ExprResult Parser::ParseRequiresExpression() { 360355e4f9d5SDimitry Andric assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword"); 360455e4f9d5SDimitry Andric SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires' 360555e4f9d5SDimitry Andric 360655e4f9d5SDimitry Andric llvm::SmallVector<ParmVarDecl *, 2> LocalParameterDecls; 36075f757f3fSDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 360855e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) { 360955e4f9d5SDimitry Andric // requirement parameter list is present. 361055e4f9d5SDimitry Andric ParseScope LocalParametersScope(this, Scope::FunctionPrototypeScope | 361155e4f9d5SDimitry Andric Scope::DeclScope); 361255e4f9d5SDimitry Andric Parens.consumeOpen(); 361355e4f9d5SDimitry Andric if (!Tok.is(tok::r_paren)) { 361455e4f9d5SDimitry Andric ParsedAttributes FirstArgAttrs(getAttrFactory()); 361555e4f9d5SDimitry Andric SourceLocation EllipsisLoc; 361655e4f9d5SDimitry Andric llvm::SmallVector<DeclaratorChunk::ParamInfo, 2> LocalParameters; 3617e8d8bef9SDimitry Andric ParseParameterDeclarationClause(DeclaratorContext::RequiresExpr, 361855e4f9d5SDimitry Andric FirstArgAttrs, LocalParameters, 361955e4f9d5SDimitry Andric EllipsisLoc); 362055e4f9d5SDimitry Andric if (EllipsisLoc.isValid()) 362155e4f9d5SDimitry Andric Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis); 362255e4f9d5SDimitry Andric for (auto &ParamInfo : LocalParameters) 362355e4f9d5SDimitry Andric LocalParameterDecls.push_back(cast<ParmVarDecl>(ParamInfo.Param)); 362455e4f9d5SDimitry Andric } 362555e4f9d5SDimitry Andric Parens.consumeClose(); 362655e4f9d5SDimitry Andric } 362755e4f9d5SDimitry Andric 362855e4f9d5SDimitry Andric BalancedDelimiterTracker Braces(*this, tok::l_brace); 362955e4f9d5SDimitry Andric if (Braces.expectAndConsume()) 363055e4f9d5SDimitry Andric return ExprError(); 363155e4f9d5SDimitry Andric 363255e4f9d5SDimitry Andric // Start of requirement list 363355e4f9d5SDimitry Andric llvm::SmallVector<concepts::Requirement *, 2> Requirements; 363455e4f9d5SDimitry Andric 363555e4f9d5SDimitry Andric // C++2a [expr.prim.req]p2 363655e4f9d5SDimitry Andric // Expressions appearing within a requirement-body are unevaluated operands. 363755e4f9d5SDimitry Andric EnterExpressionEvaluationContext Ctx( 363855e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 363955e4f9d5SDimitry Andric 364055e4f9d5SDimitry Andric ParseScope BodyScope(this, Scope::DeclScope); 3641bdd1243dSDimitry Andric // Create a separate diagnostic pool for RequiresExprBodyDecl. 3642bdd1243dSDimitry Andric // Dependent diagnostics are attached to this Decl and non-depenedent 3643bdd1243dSDimitry Andric // diagnostics are surfaced after this parse. 3644bdd1243dSDimitry Andric ParsingDeclRAIIObject ParsingBodyDecl(*this, ParsingDeclRAIIObject::NoParent); 364555e4f9d5SDimitry Andric RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr( 364655e4f9d5SDimitry Andric RequiresKWLoc, LocalParameterDecls, getCurScope()); 364755e4f9d5SDimitry Andric 364855e4f9d5SDimitry Andric if (Tok.is(tok::r_brace)) { 364955e4f9d5SDimitry Andric // Grammar does not allow an empty body. 365055e4f9d5SDimitry Andric // requirement-body: 365155e4f9d5SDimitry Andric // { requirement-seq } 365255e4f9d5SDimitry Andric // requirement-seq: 365355e4f9d5SDimitry Andric // requirement 365455e4f9d5SDimitry Andric // requirement-seq requirement 365555e4f9d5SDimitry Andric Diag(Tok, diag::err_empty_requires_expr); 365655e4f9d5SDimitry Andric // Continue anyway and produce a requires expr with no requirements. 365755e4f9d5SDimitry Andric } else { 365855e4f9d5SDimitry Andric while (!Tok.is(tok::r_brace)) { 365955e4f9d5SDimitry Andric switch (Tok.getKind()) { 366055e4f9d5SDimitry Andric case tok::l_brace: { 366155e4f9d5SDimitry Andric // Compound requirement 366255e4f9d5SDimitry Andric // C++ [expr.prim.req.compound] 366355e4f9d5SDimitry Andric // compound-requirement: 366455e4f9d5SDimitry Andric // '{' expression '}' 'noexcept'[opt] 366555e4f9d5SDimitry Andric // return-type-requirement[opt] ';' 366655e4f9d5SDimitry Andric // return-type-requirement: 366755e4f9d5SDimitry Andric // trailing-return-type 366855e4f9d5SDimitry Andric // '->' cv-qualifier-seq[opt] constrained-parameter 366955e4f9d5SDimitry Andric // cv-qualifier-seq[opt] abstract-declarator[opt] 367055e4f9d5SDimitry Andric BalancedDelimiterTracker ExprBraces(*this, tok::l_brace); 367155e4f9d5SDimitry Andric ExprBraces.consumeOpen(); 367255e4f9d5SDimitry Andric ExprResult Expression = 367355e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 367455e4f9d5SDimitry Andric if (!Expression.isUsable()) { 367555e4f9d5SDimitry Andric ExprBraces.skipToEnd(); 367655e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 367755e4f9d5SDimitry Andric break; 367855e4f9d5SDimitry Andric } 367955e4f9d5SDimitry Andric if (ExprBraces.consumeClose()) 368055e4f9d5SDimitry Andric ExprBraces.skipToEnd(); 368155e4f9d5SDimitry Andric 368255e4f9d5SDimitry Andric concepts::Requirement *Req = nullptr; 368355e4f9d5SDimitry Andric SourceLocation NoexceptLoc; 368455e4f9d5SDimitry Andric TryConsumeToken(tok::kw_noexcept, NoexceptLoc); 368555e4f9d5SDimitry Andric if (Tok.is(tok::semi)) { 368655e4f9d5SDimitry Andric Req = Actions.ActOnCompoundRequirement(Expression.get(), NoexceptLoc); 368755e4f9d5SDimitry Andric if (Req) 368855e4f9d5SDimitry Andric Requirements.push_back(Req); 368955e4f9d5SDimitry Andric break; 369055e4f9d5SDimitry Andric } 369155e4f9d5SDimitry Andric if (!TryConsumeToken(tok::arrow)) 369255e4f9d5SDimitry Andric // User probably forgot the arrow, remind them and try to continue. 369355e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_missing_arrow) 369455e4f9d5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "->"); 369555e4f9d5SDimitry Andric // Try to parse a 'type-constraint' 369655e4f9d5SDimitry Andric if (TryAnnotateTypeConstraint()) { 369755e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 369855e4f9d5SDimitry Andric break; 369955e4f9d5SDimitry Andric } 370055e4f9d5SDimitry Andric if (!isTypeConstraintAnnotation()) { 370155e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_expected_type_constraint); 370255e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 370355e4f9d5SDimitry Andric break; 370455e4f9d5SDimitry Andric } 370513138422SDimitry Andric CXXScopeSpec SS; 370613138422SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 370713138422SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 370813138422SDimitry Andric Tok.getAnnotationRange(), 370913138422SDimitry Andric SS); 371055e4f9d5SDimitry Andric ConsumeAnnotationToken(); 371113138422SDimitry Andric } 371255e4f9d5SDimitry Andric 371355e4f9d5SDimitry Andric Req = Actions.ActOnCompoundRequirement( 371455e4f9d5SDimitry Andric Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok), 371555e4f9d5SDimitry Andric TemplateParameterDepth); 371655e4f9d5SDimitry Andric ConsumeAnnotationToken(); 371755e4f9d5SDimitry Andric if (Req) 371855e4f9d5SDimitry Andric Requirements.push_back(Req); 371955e4f9d5SDimitry Andric break; 372055e4f9d5SDimitry Andric } 372155e4f9d5SDimitry Andric default: { 372255e4f9d5SDimitry Andric bool PossibleRequiresExprInSimpleRequirement = false; 372355e4f9d5SDimitry Andric if (Tok.is(tok::kw_requires)) { 372455e4f9d5SDimitry Andric auto IsNestedRequirement = [&] { 372555e4f9d5SDimitry Andric RevertingTentativeParsingAction TPA(*this); 372655e4f9d5SDimitry Andric ConsumeToken(); // 'requires' 372755e4f9d5SDimitry Andric if (Tok.is(tok::l_brace)) 372855e4f9d5SDimitry Andric // This is a requires expression 372955e4f9d5SDimitry Andric // requires (T t) { 373055e4f9d5SDimitry Andric // requires { t++; }; 373155e4f9d5SDimitry Andric // ... ^ 373255e4f9d5SDimitry Andric // } 373355e4f9d5SDimitry Andric return false; 373455e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) { 373555e4f9d5SDimitry Andric // This might be the parameter list of a requires expression 373655e4f9d5SDimitry Andric ConsumeParen(); 373755e4f9d5SDimitry Andric auto Res = TryParseParameterDeclarationClause(); 373855e4f9d5SDimitry Andric if (Res != TPResult::False) { 373955e4f9d5SDimitry Andric // Skip to the closing parenthesis 374055e4f9d5SDimitry Andric unsigned Depth = 1; 374155e4f9d5SDimitry Andric while (Depth != 0) { 37425f757f3fSDimitry Andric bool FoundParen = SkipUntil(tok::l_paren, tok::r_paren, 37435f757f3fSDimitry Andric SkipUntilFlags::StopBeforeMatch); 37445f757f3fSDimitry Andric if (!FoundParen) 37455f757f3fSDimitry Andric break; 374655e4f9d5SDimitry Andric if (Tok.is(tok::l_paren)) 374755e4f9d5SDimitry Andric Depth++; 374855e4f9d5SDimitry Andric else if (Tok.is(tok::r_paren)) 374955e4f9d5SDimitry Andric Depth--; 375055e4f9d5SDimitry Andric ConsumeAnyToken(); 375155e4f9d5SDimitry Andric } 375255e4f9d5SDimitry Andric // requires (T t) { 375355e4f9d5SDimitry Andric // requires () ? 375455e4f9d5SDimitry Andric // ... ^ 375555e4f9d5SDimitry Andric // - OR - 375655e4f9d5SDimitry Andric // requires (int x) ? 375755e4f9d5SDimitry Andric // ... ^ 375855e4f9d5SDimitry Andric // } 375955e4f9d5SDimitry Andric if (Tok.is(tok::l_brace)) 376055e4f9d5SDimitry Andric // requires (...) { 376155e4f9d5SDimitry Andric // ^ - a requires expression as a 376255e4f9d5SDimitry Andric // simple-requirement. 376355e4f9d5SDimitry Andric return false; 376455e4f9d5SDimitry Andric } 376555e4f9d5SDimitry Andric } 376655e4f9d5SDimitry Andric return true; 376755e4f9d5SDimitry Andric }; 376855e4f9d5SDimitry Andric if (IsNestedRequirement()) { 376955e4f9d5SDimitry Andric ConsumeToken(); 377055e4f9d5SDimitry Andric // Nested requirement 377155e4f9d5SDimitry Andric // C++ [expr.prim.req.nested] 377255e4f9d5SDimitry Andric // nested-requirement: 377355e4f9d5SDimitry Andric // 'requires' constraint-expression ';' 377455e4f9d5SDimitry Andric ExprResult ConstraintExpr = 377555e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); 377655e4f9d5SDimitry Andric if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) { 377755e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, 377855e4f9d5SDimitry Andric SkipUntilFlags::StopBeforeMatch); 377955e4f9d5SDimitry Andric break; 378055e4f9d5SDimitry Andric } 378155e4f9d5SDimitry Andric if (auto *Req = 378255e4f9d5SDimitry Andric Actions.ActOnNestedRequirement(ConstraintExpr.get())) 378355e4f9d5SDimitry Andric Requirements.push_back(Req); 378455e4f9d5SDimitry Andric else { 378555e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, 378655e4f9d5SDimitry Andric SkipUntilFlags::StopBeforeMatch); 378755e4f9d5SDimitry Andric break; 378855e4f9d5SDimitry Andric } 378955e4f9d5SDimitry Andric break; 379055e4f9d5SDimitry Andric } else 379155e4f9d5SDimitry Andric PossibleRequiresExprInSimpleRequirement = true; 379255e4f9d5SDimitry Andric } else if (Tok.is(tok::kw_typename)) { 379355e4f9d5SDimitry Andric // This might be 'typename T::value_type;' (a type requirement) or 379455e4f9d5SDimitry Andric // 'typename T::value_type{};' (a simple requirement). 379555e4f9d5SDimitry Andric TentativeParsingAction TPA(*this); 379655e4f9d5SDimitry Andric 379755e4f9d5SDimitry Andric // We need to consume the typename to allow 'requires { typename a; }' 379855e4f9d5SDimitry Andric SourceLocation TypenameKWLoc = ConsumeToken(); 379904eeddc0SDimitry Andric if (TryAnnotateOptionalCXXScopeToken()) { 380013138422SDimitry Andric TPA.Commit(); 380155e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 380255e4f9d5SDimitry Andric break; 380355e4f9d5SDimitry Andric } 380455e4f9d5SDimitry Andric CXXScopeSpec SS; 380555e4f9d5SDimitry Andric if (Tok.is(tok::annot_cxxscope)) { 380655e4f9d5SDimitry Andric Actions.RestoreNestedNameSpecifierAnnotation( 380755e4f9d5SDimitry Andric Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS); 380855e4f9d5SDimitry Andric ConsumeAnnotationToken(); 380955e4f9d5SDimitry Andric } 381055e4f9d5SDimitry Andric 381155e4f9d5SDimitry Andric if (Tok.isOneOf(tok::identifier, tok::annot_template_id) && 381255e4f9d5SDimitry Andric !NextToken().isOneOf(tok::l_brace, tok::l_paren)) { 381355e4f9d5SDimitry Andric TPA.Commit(); 381455e4f9d5SDimitry Andric SourceLocation NameLoc = Tok.getLocation(); 381555e4f9d5SDimitry Andric IdentifierInfo *II = nullptr; 381655e4f9d5SDimitry Andric TemplateIdAnnotation *TemplateId = nullptr; 381755e4f9d5SDimitry Andric if (Tok.is(tok::identifier)) { 381855e4f9d5SDimitry Andric II = Tok.getIdentifierInfo(); 381955e4f9d5SDimitry Andric ConsumeToken(); 382055e4f9d5SDimitry Andric } else { 382155e4f9d5SDimitry Andric TemplateId = takeTemplateIdAnnotation(Tok); 382255e4f9d5SDimitry Andric ConsumeAnnotationToken(); 38235ffd83dbSDimitry Andric if (TemplateId->isInvalid()) 38245ffd83dbSDimitry Andric break; 382555e4f9d5SDimitry Andric } 382655e4f9d5SDimitry Andric 382755e4f9d5SDimitry Andric if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS, 382855e4f9d5SDimitry Andric NameLoc, II, 382955e4f9d5SDimitry Andric TemplateId)) { 383055e4f9d5SDimitry Andric Requirements.push_back(Req); 383155e4f9d5SDimitry Andric } 383255e4f9d5SDimitry Andric break; 383355e4f9d5SDimitry Andric } 383455e4f9d5SDimitry Andric TPA.Revert(); 383555e4f9d5SDimitry Andric } 383655e4f9d5SDimitry Andric // Simple requirement 383755e4f9d5SDimitry Andric // C++ [expr.prim.req.simple] 383855e4f9d5SDimitry Andric // simple-requirement: 383955e4f9d5SDimitry Andric // expression ';' 384055e4f9d5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 384155e4f9d5SDimitry Andric ExprResult Expression = 384255e4f9d5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 384355e4f9d5SDimitry Andric if (!Expression.isUsable()) { 384455e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 384555e4f9d5SDimitry Andric break; 384655e4f9d5SDimitry Andric } 384755e4f9d5SDimitry Andric if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement) 3848349cc55cSDimitry Andric Diag(StartLoc, diag::err_requires_expr_in_simple_requirement) 384955e4f9d5SDimitry Andric << FixItHint::CreateInsertion(StartLoc, "requires"); 385055e4f9d5SDimitry Andric if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get())) 385155e4f9d5SDimitry Andric Requirements.push_back(Req); 385255e4f9d5SDimitry Andric else { 385355e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 385455e4f9d5SDimitry Andric break; 385555e4f9d5SDimitry Andric } 385655e4f9d5SDimitry Andric // User may have tried to put some compound requirement stuff here 385755e4f9d5SDimitry Andric if (Tok.is(tok::kw_noexcept)) { 385855e4f9d5SDimitry Andric Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept) 385955e4f9d5SDimitry Andric << FixItHint::CreateInsertion(StartLoc, "{") 386055e4f9d5SDimitry Andric << FixItHint::CreateInsertion(Tok.getLocation(), "}"); 386155e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 386255e4f9d5SDimitry Andric break; 386355e4f9d5SDimitry Andric } 386455e4f9d5SDimitry Andric break; 386555e4f9d5SDimitry Andric } 386655e4f9d5SDimitry Andric } 386755e4f9d5SDimitry Andric if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) { 386855e4f9d5SDimitry Andric SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); 386955e4f9d5SDimitry Andric TryConsumeToken(tok::semi); 387055e4f9d5SDimitry Andric break; 387155e4f9d5SDimitry Andric } 387255e4f9d5SDimitry Andric } 387355e4f9d5SDimitry Andric if (Requirements.empty()) { 387455e4f9d5SDimitry Andric // Don't emit an empty requires expr here to avoid confusing the user with 387555e4f9d5SDimitry Andric // other diagnostics quoting an empty requires expression they never 387655e4f9d5SDimitry Andric // wrote. 387755e4f9d5SDimitry Andric Braces.consumeClose(); 387855e4f9d5SDimitry Andric Actions.ActOnFinishRequiresExpr(); 387955e4f9d5SDimitry Andric return ExprError(); 388055e4f9d5SDimitry Andric } 388155e4f9d5SDimitry Andric } 388255e4f9d5SDimitry Andric Braces.consumeClose(); 388355e4f9d5SDimitry Andric Actions.ActOnFinishRequiresExpr(); 3884bdd1243dSDimitry Andric ParsingBodyDecl.complete(Body); 38855f757f3fSDimitry Andric return Actions.ActOnRequiresExpr( 38865f757f3fSDimitry Andric RequiresKWLoc, Body, Parens.getOpenLocation(), LocalParameterDecls, 38875f757f3fSDimitry Andric Parens.getCloseLocation(), Requirements, Braces.getCloseLocation()); 388855e4f9d5SDimitry Andric } 388955e4f9d5SDimitry Andric 38900b57cec5SDimitry Andric static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) { 38910b57cec5SDimitry Andric switch (kind) { 38920b57cec5SDimitry Andric default: llvm_unreachable("Not a known type trait"); 38930b57cec5SDimitry Andric #define TYPE_TRAIT_1(Spelling, Name, Key) \ 38940b57cec5SDimitry Andric case tok::kw_ ## Spelling: return UTT_ ## Name; 38950b57cec5SDimitry Andric #define TYPE_TRAIT_2(Spelling, Name, Key) \ 38960b57cec5SDimitry Andric case tok::kw_ ## Spelling: return BTT_ ## Name; 38970b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 38980b57cec5SDimitry Andric #define TYPE_TRAIT_N(Spelling, Name, Key) \ 38990b57cec5SDimitry Andric case tok::kw_ ## Spelling: return TT_ ## Name; 39000b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 39010b57cec5SDimitry Andric } 39020b57cec5SDimitry Andric } 39030b57cec5SDimitry Andric 39040b57cec5SDimitry Andric static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { 39050b57cec5SDimitry Andric switch (kind) { 39065ffd83dbSDimitry Andric default: 39075ffd83dbSDimitry Andric llvm_unreachable("Not a known array type trait"); 39085ffd83dbSDimitry Andric #define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \ 39095ffd83dbSDimitry Andric case tok::kw_##Spelling: \ 39105ffd83dbSDimitry Andric return ATT_##Name; 39115ffd83dbSDimitry Andric #include "clang/Basic/TokenKinds.def" 39120b57cec5SDimitry Andric } 39130b57cec5SDimitry Andric } 39140b57cec5SDimitry Andric 39150b57cec5SDimitry Andric static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { 39160b57cec5SDimitry Andric switch (kind) { 39175ffd83dbSDimitry Andric default: 39185ffd83dbSDimitry Andric llvm_unreachable("Not a known unary expression trait."); 39195ffd83dbSDimitry Andric #define EXPRESSION_TRAIT(Spelling, Name, Key) \ 39205ffd83dbSDimitry Andric case tok::kw_##Spelling: \ 39215ffd83dbSDimitry Andric return ET_##Name; 39225ffd83dbSDimitry Andric #include "clang/Basic/TokenKinds.def" 39230b57cec5SDimitry Andric } 39240b57cec5SDimitry Andric } 39250b57cec5SDimitry Andric 39260b57cec5SDimitry Andric /// Parse the built-in type-trait pseudo-functions that allow 39270b57cec5SDimitry Andric /// implementation of the TR1/C++11 type traits templates. 39280b57cec5SDimitry Andric /// 39290b57cec5SDimitry Andric /// primary-expression: 39300b57cec5SDimitry Andric /// unary-type-trait '(' type-id ')' 39310b57cec5SDimitry Andric /// binary-type-trait '(' type-id ',' type-id ')' 39320b57cec5SDimitry Andric /// type-trait '(' type-id-seq ')' 39330b57cec5SDimitry Andric /// 39340b57cec5SDimitry Andric /// type-id-seq: 39350b57cec5SDimitry Andric /// type-id ...[opt] type-id-seq[opt] 39360b57cec5SDimitry Andric /// 39370b57cec5SDimitry Andric ExprResult Parser::ParseTypeTrait() { 39380b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 39390b57cec5SDimitry Andric 39400b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 39410b57cec5SDimitry Andric 39420b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 39430b57cec5SDimitry Andric if (Parens.expectAndConsume()) 39440b57cec5SDimitry Andric return ExprError(); 39450b57cec5SDimitry Andric 39460b57cec5SDimitry Andric SmallVector<ParsedType, 2> Args; 39470b57cec5SDimitry Andric do { 39480b57cec5SDimitry Andric // Parse the next type. 3949*0fca6ea1SDimitry Andric TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, 3950*0fca6ea1SDimitry Andric getLangOpts().CPlusPlus 3951*0fca6ea1SDimitry Andric ? DeclaratorContext::TemplateTypeArg 3952*0fca6ea1SDimitry Andric : DeclaratorContext::TypeName); 39530b57cec5SDimitry Andric if (Ty.isInvalid()) { 39540b57cec5SDimitry Andric Parens.skipToEnd(); 39550b57cec5SDimitry Andric return ExprError(); 39560b57cec5SDimitry Andric } 39570b57cec5SDimitry Andric 39580b57cec5SDimitry Andric // Parse the ellipsis, if present. 39590b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) { 39600b57cec5SDimitry Andric Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken()); 39610b57cec5SDimitry Andric if (Ty.isInvalid()) { 39620b57cec5SDimitry Andric Parens.skipToEnd(); 39630b57cec5SDimitry Andric return ExprError(); 39640b57cec5SDimitry Andric } 39650b57cec5SDimitry Andric } 39660b57cec5SDimitry Andric 39670b57cec5SDimitry Andric // Add this type to the list of arguments. 39680b57cec5SDimitry Andric Args.push_back(Ty.get()); 39690b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 39700b57cec5SDimitry Andric 39710b57cec5SDimitry Andric if (Parens.consumeClose()) 39720b57cec5SDimitry Andric return ExprError(); 39730b57cec5SDimitry Andric 39740b57cec5SDimitry Andric SourceLocation EndLoc = Parens.getCloseLocation(); 39750b57cec5SDimitry Andric 39760b57cec5SDimitry Andric return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc); 39770b57cec5SDimitry Andric } 39780b57cec5SDimitry Andric 39790b57cec5SDimitry Andric /// ParseArrayTypeTrait - Parse the built-in array type-trait 39800b57cec5SDimitry Andric /// pseudo-functions. 39810b57cec5SDimitry Andric /// 39820b57cec5SDimitry Andric /// primary-expression: 39830b57cec5SDimitry Andric /// [Embarcadero] '__array_rank' '(' type-id ')' 39840b57cec5SDimitry Andric /// [Embarcadero] '__array_extent' '(' type-id ',' expression ')' 39850b57cec5SDimitry Andric /// 39860b57cec5SDimitry Andric ExprResult Parser::ParseArrayTypeTrait() { 39870b57cec5SDimitry Andric ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); 39880b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 39890b57cec5SDimitry Andric 39900b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 39910b57cec5SDimitry Andric if (T.expectAndConsume()) 39920b57cec5SDimitry Andric return ExprError(); 39930b57cec5SDimitry Andric 3994*0fca6ea1SDimitry Andric TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, 3995*0fca6ea1SDimitry Andric DeclaratorContext::TemplateTypeArg); 39960b57cec5SDimitry Andric if (Ty.isInvalid()) { 39970b57cec5SDimitry Andric SkipUntil(tok::comma, StopAtSemi); 39980b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 39990b57cec5SDimitry Andric return ExprError(); 40000b57cec5SDimitry Andric } 40010b57cec5SDimitry Andric 40020b57cec5SDimitry Andric switch (ATT) { 40030b57cec5SDimitry Andric case ATT_ArrayRank: { 40040b57cec5SDimitry Andric T.consumeClose(); 40050b57cec5SDimitry Andric return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), nullptr, 40060b57cec5SDimitry Andric T.getCloseLocation()); 40070b57cec5SDimitry Andric } 40080b57cec5SDimitry Andric case ATT_ArrayExtent: { 40090b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 40100b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 40110b57cec5SDimitry Andric return ExprError(); 40120b57cec5SDimitry Andric } 40130b57cec5SDimitry Andric 40140b57cec5SDimitry Andric ExprResult DimExpr = ParseExpression(); 40150b57cec5SDimitry Andric T.consumeClose(); 40160b57cec5SDimitry Andric 4017*0fca6ea1SDimitry Andric if (DimExpr.isInvalid()) 4018*0fca6ea1SDimitry Andric return ExprError(); 4019*0fca6ea1SDimitry Andric 40200b57cec5SDimitry Andric return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), 40210b57cec5SDimitry Andric T.getCloseLocation()); 40220b57cec5SDimitry Andric } 40230b57cec5SDimitry Andric } 40240b57cec5SDimitry Andric llvm_unreachable("Invalid ArrayTypeTrait!"); 40250b57cec5SDimitry Andric } 40260b57cec5SDimitry Andric 40270b57cec5SDimitry Andric /// ParseExpressionTrait - Parse built-in expression-trait 40280b57cec5SDimitry Andric /// pseudo-functions like __is_lvalue_expr( xxx ). 40290b57cec5SDimitry Andric /// 40300b57cec5SDimitry Andric /// primary-expression: 40310b57cec5SDimitry Andric /// [Embarcadero] expression-trait '(' expression ')' 40320b57cec5SDimitry Andric /// 40330b57cec5SDimitry Andric ExprResult Parser::ParseExpressionTrait() { 40340b57cec5SDimitry Andric ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); 40350b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 40360b57cec5SDimitry Andric 40370b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 40380b57cec5SDimitry Andric if (T.expectAndConsume()) 40390b57cec5SDimitry Andric return ExprError(); 40400b57cec5SDimitry Andric 40410b57cec5SDimitry Andric ExprResult Expr = ParseExpression(); 40420b57cec5SDimitry Andric 40430b57cec5SDimitry Andric T.consumeClose(); 40440b57cec5SDimitry Andric 40450b57cec5SDimitry Andric return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), 40460b57cec5SDimitry Andric T.getCloseLocation()); 40470b57cec5SDimitry Andric } 40480b57cec5SDimitry Andric 40490b57cec5SDimitry Andric 40500b57cec5SDimitry Andric /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 40510b57cec5SDimitry Andric /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 40520b57cec5SDimitry Andric /// based on the context past the parens. 40530b57cec5SDimitry Andric ExprResult 40540b57cec5SDimitry Andric Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 40550b57cec5SDimitry Andric ParsedType &CastTy, 40560b57cec5SDimitry Andric BalancedDelimiterTracker &Tracker, 40570b57cec5SDimitry Andric ColonProtectionRAIIObject &ColonProt) { 40580b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus && "Should only be called for C++!"); 40590b57cec5SDimitry Andric assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 40600b57cec5SDimitry Andric assert(isTypeIdInParens() && "Not a type-id!"); 40610b57cec5SDimitry Andric 40620b57cec5SDimitry Andric ExprResult Result(true); 40630b57cec5SDimitry Andric CastTy = nullptr; 40640b57cec5SDimitry Andric 40650b57cec5SDimitry Andric // We need to disambiguate a very ugly part of the C++ syntax: 40660b57cec5SDimitry Andric // 40670b57cec5SDimitry Andric // (T())x; - type-id 40680b57cec5SDimitry Andric // (T())*x; - type-id 40690b57cec5SDimitry Andric // (T())/x; - expression 40700b57cec5SDimitry Andric // (T()); - expression 40710b57cec5SDimitry Andric // 40720b57cec5SDimitry Andric // The bad news is that we cannot use the specialized tentative parser, since 40730b57cec5SDimitry Andric // it can only verify that the thing inside the parens can be parsed as 40740b57cec5SDimitry Andric // type-id, it is not useful for determining the context past the parens. 40750b57cec5SDimitry Andric // 40760b57cec5SDimitry Andric // The good news is that the parser can disambiguate this part without 40770b57cec5SDimitry Andric // making any unnecessary Action calls. 40780b57cec5SDimitry Andric // 40790b57cec5SDimitry Andric // It uses a scheme similar to parsing inline methods. The parenthesized 40800b57cec5SDimitry Andric // tokens are cached, the context that follows is determined (possibly by 40810b57cec5SDimitry Andric // parsing a cast-expression), and then we re-introduce the cached tokens 40820b57cec5SDimitry Andric // into the token stream and parse them appropriately. 40830b57cec5SDimitry Andric 40840b57cec5SDimitry Andric ParenParseOption ParseAs; 40850b57cec5SDimitry Andric CachedTokens Toks; 40860b57cec5SDimitry Andric 40870b57cec5SDimitry Andric // Store the tokens of the parentheses. We will parse them after we determine 40880b57cec5SDimitry Andric // the context that follows them. 40890b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { 40900b57cec5SDimitry Andric // We didn't find the ')' we expected. 40910b57cec5SDimitry Andric Tracker.consumeClose(); 40920b57cec5SDimitry Andric return ExprError(); 40930b57cec5SDimitry Andric } 40940b57cec5SDimitry Andric 40950b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 40960b57cec5SDimitry Andric ParseAs = CompoundLiteral; 40970b57cec5SDimitry Andric } else { 40980b57cec5SDimitry Andric bool NotCastExpr; 40990b57cec5SDimitry Andric if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 41000b57cec5SDimitry Andric NotCastExpr = true; 41010b57cec5SDimitry Andric } else { 41020b57cec5SDimitry Andric // Try parsing the cast-expression that may follow. 41030b57cec5SDimitry Andric // If it is not a cast-expression, NotCastExpr will be true and no token 41040b57cec5SDimitry Andric // will be consumed. 41050b57cec5SDimitry Andric ColonProt.restore(); 4106480093f4SDimitry Andric Result = ParseCastExpression(AnyCastExpr, 41070b57cec5SDimitry Andric false/*isAddressofOperand*/, 41080b57cec5SDimitry Andric NotCastExpr, 41090b57cec5SDimitry Andric // type-id has priority. 41100b57cec5SDimitry Andric IsTypeCast); 41110b57cec5SDimitry Andric } 41120b57cec5SDimitry Andric 41130b57cec5SDimitry Andric // If we parsed a cast-expression, it's really a type-id, otherwise it's 41140b57cec5SDimitry Andric // an expression. 41150b57cec5SDimitry Andric ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 41160b57cec5SDimitry Andric } 41170b57cec5SDimitry Andric 41180b57cec5SDimitry Andric // Create a fake EOF to mark end of Toks buffer. 41190b57cec5SDimitry Andric Token AttrEnd; 41200b57cec5SDimitry Andric AttrEnd.startToken(); 41210b57cec5SDimitry Andric AttrEnd.setKind(tok::eof); 41220b57cec5SDimitry Andric AttrEnd.setLocation(Tok.getLocation()); 41230b57cec5SDimitry Andric AttrEnd.setEofData(Toks.data()); 41240b57cec5SDimitry Andric Toks.push_back(AttrEnd); 41250b57cec5SDimitry Andric 41260b57cec5SDimitry Andric // The current token should go after the cached tokens. 41270b57cec5SDimitry Andric Toks.push_back(Tok); 41280b57cec5SDimitry Andric // Re-enter the stored parenthesized tokens into the token stream, so we may 41290b57cec5SDimitry Andric // parse them now. 41300b57cec5SDimitry Andric PP.EnterTokenStream(Toks, /*DisableMacroExpansion*/ true, 41310b57cec5SDimitry Andric /*IsReinject*/ true); 41320b57cec5SDimitry Andric // Drop the current token and bring the first cached one. It's the same token 41330b57cec5SDimitry Andric // as when we entered this function. 41340b57cec5SDimitry Andric ConsumeAnyToken(); 41350b57cec5SDimitry Andric 41360b57cec5SDimitry Andric if (ParseAs >= CompoundLiteral) { 41370b57cec5SDimitry Andric // Parse the type declarator. 41380b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 413981ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 414081ad6265SDimitry Andric DeclaratorContext::TypeName); 41410b57cec5SDimitry Andric { 41420b57cec5SDimitry Andric ColonProtectionRAIIObject InnerColonProtection(*this); 41430b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 41440b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 41450b57cec5SDimitry Andric } 41460b57cec5SDimitry Andric 41470b57cec5SDimitry Andric // Match the ')'. 41480b57cec5SDimitry Andric Tracker.consumeClose(); 41490b57cec5SDimitry Andric ColonProt.restore(); 41500b57cec5SDimitry Andric 41510b57cec5SDimitry Andric // Consume EOF marker for Toks buffer. 41520b57cec5SDimitry Andric assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); 41530b57cec5SDimitry Andric ConsumeAnyToken(); 41540b57cec5SDimitry Andric 41550b57cec5SDimitry Andric if (ParseAs == CompoundLiteral) { 41560b57cec5SDimitry Andric ExprType = CompoundLiteral; 41570b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 41580b57cec5SDimitry Andric return ExprError(); 41590b57cec5SDimitry Andric 41607a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo); 41610b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), 41620b57cec5SDimitry Andric Tracker.getOpenLocation(), 41630b57cec5SDimitry Andric Tracker.getCloseLocation()); 41640b57cec5SDimitry Andric } 41650b57cec5SDimitry Andric 41660b57cec5SDimitry Andric // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 41670b57cec5SDimitry Andric assert(ParseAs == CastExpr); 41680b57cec5SDimitry Andric 41690b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 41700b57cec5SDimitry Andric return ExprError(); 41710b57cec5SDimitry Andric 41720b57cec5SDimitry Andric // Result is what ParseCastExpression returned earlier. 41730b57cec5SDimitry Andric if (!Result.isInvalid()) 41740b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), 41750b57cec5SDimitry Andric DeclaratorInfo, CastTy, 41760b57cec5SDimitry Andric Tracker.getCloseLocation(), Result.get()); 41770b57cec5SDimitry Andric return Result; 41780b57cec5SDimitry Andric } 41790b57cec5SDimitry Andric 41800b57cec5SDimitry Andric // Not a compound literal, and not followed by a cast-expression. 41810b57cec5SDimitry Andric assert(ParseAs == SimpleExpr); 41820b57cec5SDimitry Andric 41830b57cec5SDimitry Andric ExprType = SimpleExpr; 41840b57cec5SDimitry Andric Result = ParseExpression(); 41850b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 41860b57cec5SDimitry Andric Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 41870b57cec5SDimitry Andric Tok.getLocation(), Result.get()); 41880b57cec5SDimitry Andric 41890b57cec5SDimitry Andric // Match the ')'. 41900b57cec5SDimitry Andric if (Result.isInvalid()) { 41910b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 41920b57cec5SDimitry Andric ConsumeAnyToken(); 41930b57cec5SDimitry Andric assert(Tok.getEofData() == AttrEnd.getEofData()); 41940b57cec5SDimitry Andric ConsumeAnyToken(); 41950b57cec5SDimitry Andric return ExprError(); 41960b57cec5SDimitry Andric } 41970b57cec5SDimitry Andric 41980b57cec5SDimitry Andric Tracker.consumeClose(); 41990b57cec5SDimitry Andric // Consume EOF marker for Toks buffer. 42000b57cec5SDimitry Andric assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); 42010b57cec5SDimitry Andric ConsumeAnyToken(); 42020b57cec5SDimitry Andric return Result; 42030b57cec5SDimitry Andric } 42040b57cec5SDimitry Andric 42050b57cec5SDimitry Andric /// Parse a __builtin_bit_cast(T, E). 42060b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinBitCast() { 42070b57cec5SDimitry Andric SourceLocation KWLoc = ConsumeToken(); 42080b57cec5SDimitry Andric 42090b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 42100b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast")) 42110b57cec5SDimitry Andric return ExprError(); 42120b57cec5SDimitry Andric 42130b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 42140b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 42150b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 42160b57cec5SDimitry Andric 42170b57cec5SDimitry Andric // Parse the abstract-declarator, if present. 421881ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 421981ad6265SDimitry Andric DeclaratorContext::TypeName); 42200b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 42210b57cec5SDimitry Andric 42220b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 42230b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::comma; 42240b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 42250b57cec5SDimitry Andric return ExprError(); 42260b57cec5SDimitry Andric } 42270b57cec5SDimitry Andric 42280b57cec5SDimitry Andric ExprResult Operand = ParseExpression(); 42290b57cec5SDimitry Andric 42300b57cec5SDimitry Andric if (T.consumeClose()) 42310b57cec5SDimitry Andric return ExprError(); 42320b57cec5SDimitry Andric 42330b57cec5SDimitry Andric if (Operand.isInvalid() || DeclaratorInfo.isInvalidType()) 42340b57cec5SDimitry Andric return ExprError(); 42350b57cec5SDimitry Andric 42360b57cec5SDimitry Andric return Actions.ActOnBuiltinBitCastExpr(KWLoc, DeclaratorInfo, Operand, 42370b57cec5SDimitry Andric T.getCloseLocation()); 42380b57cec5SDimitry Andric } 4239