diff options
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index da39e2e2237..222c1182629 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1101,10 +1101,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, return false; } -static void -tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc, - SourceLocation &ConstexprLoc, - SourceLocation &DeclEndLoc) { +static void tryConsumeLambdaSpecifierToken(Parser &P, + SourceLocation &MutableLoc, + SourceLocation &ConstexprLoc, + SourceLocation &ConstevalLoc, + SourceLocation &DeclEndLoc) { assert(MutableLoc.isInvalid()); assert(ConstexprLoc.isInvalid()); // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc @@ -1132,6 +1133,15 @@ tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc, ConstexprLoc = P.ConsumeToken(); DeclEndLoc = ConstexprLoc; break /*switch*/; + case tok::kw_consteval: + if (ConstevalLoc.isValid()) { + P.Diag(P.getCurToken().getLocation(), + diag::err_lambda_decl_specifier_repeated) + << 2 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); + } + ConstevalLoc = P.ConsumeToken(); + DeclEndLoc = ConstevalLoc; + break /*switch*/; default: return; } @@ -1147,12 +1157,25 @@ addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, : diag::warn_cxx14_compat_constexpr_on_lambda); const char *PrevSpec = nullptr; unsigned DiagID = 0; - DS.SetConstexprSpec(ConstexprLoc, PrevSpec, DiagID); + DS.SetConstexprSpec(CSK_constexpr, ConstexprLoc, PrevSpec, DiagID); assert(PrevSpec == nullptr && DiagID == 0 && "Constexpr cannot have been set previously!"); } } +static void addConstevalToLambdaDeclSpecifier(Parser &P, + SourceLocation ConstevalLoc, + DeclSpec &DS) { + if (ConstevalLoc.isValid()) { + P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval); + const char *PrevSpec = nullptr; + unsigned DiagID = 0; + DS.SetConstexprSpec(CSK_consteval, ConstevalLoc, PrevSpec, DiagID); + if (DiagID != 0) + P.Diag(ConstevalLoc, DiagID) << PrevSpec; + } +} + /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda /// expression. ExprResult Parser::ParseLambdaExpressionAfterIntroducer( @@ -1263,14 +1286,16 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // compatible with MSVC. MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc); - // Parse mutable-opt and/or constexpr-opt, and update the DeclEndLoc. + // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update the + // DeclEndLoc. SourceLocation MutableLoc; SourceLocation ConstexprLoc; - tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc, - DeclEndLoc); + SourceLocation ConstevalLoc; + tryConsumeLambdaSpecifierToken(*this, MutableLoc, ConstexprLoc, + ConstevalLoc, DeclEndLoc); addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); - + addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); // Parse exception-specification[opt]. ExceptionSpecificationType ESpecType = EST_None; SourceRange ESpecRange; @@ -1322,7 +1347,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( TrailingReturnType), std::move(Attr), DeclEndLoc); } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, - tok::kw_constexpr) || + tok::kw_constexpr, tok::kw_consteval) || (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { // It's common to forget that one needs '()' before 'mutable', an attribute // specifier, or the result type. Deal with this. @@ -1333,6 +1358,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( case tok::kw___attribute: case tok::l_square: TokKind = 2; break; case tok::kw_constexpr: TokKind = 3; break; + case tok::kw_consteval: TokKind = 4; break; default: llvm_unreachable("Unknown token kind"); } |