summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2016-08-16 02:11:53 +0000
committerFaisal Vali <faisalv@yahoo.com>2016-08-16 02:11:53 +0000
commitf95bed858efd9fa2a63c15a8edf21e84a2560a4d (patch)
treef262c85250f532cab72362712cd78b2b835e7ef9
parent18a55edb0878d9bcb38a90c4ae4ade3f63d8f998 (diff)
downloadclang-f95bed858efd9fa2a63c15a8edf21e84a2560a4d.tar.gz
[Branch 3.9] Remove any traces of partial constexpr lambda implementation
This patch essentially reverses all the changes from the following commit: https://reviews.llvm.org/rL264513 for branch 3.9. Requested by Richard and Approved by Hans here: https://reviews.llvm.org/D23485 git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@278771 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td11
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--lib/AST/ExprConstant.cpp18
-rw-r--r--lib/Parse/ParseExprCXX.cpp65
-rw-r--r--lib/Sema/SemaLambda.cpp21
-rw-r--r--lib/Sema/TreeTransform.h4
-rw-r--r--test/Parser/cxx1z-constexpr-lambdas.cpp31
-rw-r--r--test/SemaCXX/cxx1z-constexpr-lambdas.cpp36
9 files changed, 12 insertions, 183 deletions
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 03ed8aa745..039888ba66 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -158,12 +158,6 @@ def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"integer-overflow">>;
-// This is a temporary diagnostic, and shall be removed once our
-// implementation is complete, and like the preceding constexpr notes belongs
-// in Sema.
-def note_unimplemented_constexpr_lambda_feature_ast : Note<
- "unimplemented constexpr lambda feature: %0 (coming soon!)">;
-
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index e5c64681e4..45044e6267 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -780,20 +780,11 @@ def warn_cxx98_compat_lambda : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_missing_parens : Error<
"lambda requires '()' before %select{'mutable'|return type|"
- "attribute specifier|'constexpr'}0">;
-def err_lambda_decl_specifier_repeated : Error<
- "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">;
+ "attribute specifier}0">;
// C++1z lambda expressions
def err_expected_star_this_capture : Error<
"expected 'this' following '*' in lambda capture list">;
-// C++1z constexpr lambda expressions
-def warn_cxx14_compat_constexpr_on_lambda : Warning<
- "constexpr on lambda expressions is incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def ext_constexpr_on_lambda_cxx1z : ExtWarn<
- "'constexpr' on lambda expressions is a C++1z extension">, InGroup<CXX1z>;
-
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 25aa805dac..10a8a5ac53 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -5111,8 +5111,7 @@ public:
SourceRange IntroducerRange,
TypeSourceInfo *MethodType,
SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- bool IsConstexprSpecified);
+ ArrayRef<ParmVarDecl *> Params);
/// \brief Endow the lambda scope info with the relevant properties.
void buildLambdaScope(sema::LambdaScopeInfo *LSI,
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index a25a6c7e51..df944e8f25 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -36,7 +36,6 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/ASTLambda.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
@@ -2126,22 +2125,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
// If this is a local variable, dig out its value.
if (Frame) {
Result = Frame->getTemporary(VD);
- if (!Result) {
- // Assume variables referenced within a lambda's call operator that were
- // not declared within the call operator are captures and during checking
- // of a potential constant expression, assume they are unknown constant
- // expressions.
- assert(isLambdaCallOperator(Frame->Callee) &&
- (VD->getDeclContext() != Frame->Callee || VD->isInitCapture()) &&
- "missing value for local variable");
- if (Info.checkingPotentialConstantExpression())
- return false;
- // FIXME: implement capture evaluation during constant expr evaluation.
- Info.FFDiag(E->getLocStart(),
- diag::note_unimplemented_constexpr_lambda_feature_ast)
- << "captures not currently allowed";
- return false;
- }
+ assert(Result && "missing value for local variable");
return true;
}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index b09d7dbc12..85c1301fc9 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1053,58 +1053,6 @@ bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
return false;
}
-static void
-tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc,
- SourceLocation &ConstexprLoc,
- SourceLocation &DeclEndLoc) {
- assert(MutableLoc.isInvalid());
- assert(ConstexprLoc.isInvalid());
- // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc
- // to the final of those locations. Emit an error if we have multiple
- // copies of those keywords and recover.
-
- while (true) {
- switch (P.getCurToken().getKind()) {
- case tok::kw_mutable: {
- if (MutableLoc.isValid()) {
- P.Diag(P.getCurToken().getLocation(),
- diag::err_lambda_decl_specifier_repeated)
- << 0 << FixItHint::CreateRemoval(P.getCurToken().getLocation());
- }
- MutableLoc = P.ConsumeToken();
- DeclEndLoc = MutableLoc;
- break /*switch*/;
- }
- case tok::kw_constexpr:
- if (ConstexprLoc.isValid()) {
- P.Diag(P.getCurToken().getLocation(),
- diag::err_lambda_decl_specifier_repeated)
- << 1 << FixItHint::CreateRemoval(P.getCurToken().getLocation());
- }
- ConstexprLoc = P.ConsumeToken();
- DeclEndLoc = ConstexprLoc;
- break /*switch*/;
- default:
- return;
- }
- }
-}
-
-static void
-addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc,
- DeclSpec &DS) {
- if (ConstexprLoc.isValid()) {
- P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus1z
- ? diag::ext_constexpr_on_lambda_cxx1z
- : diag::warn_cxx14_compat_constexpr_on_lambda);
- const char *PrevSpec = nullptr;
- unsigned DiagID = 0;
- DS.SetConstexprSpec(ConstexprLoc, PrevSpec, DiagID);
- assert(PrevSpec == nullptr && DiagID == 0 &&
- "Constexpr cannot have been set previously!");
- }
-}
-
/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
/// expression.
ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
@@ -1163,13 +1111,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// compatible with MSVC.
MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc);
- // Parse mutable-opt and/or constexpr-opt, and update the DeclEndLoc.
+ // Parse 'mutable'[opt].
SourceLocation MutableLoc;
- SourceLocation ConstexprLoc;
- tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc,
- DeclEndLoc);
-
- addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS);
+ if (TryConsumeToken(tok::kw_mutable, MutableLoc))
+ DeclEndLoc = MutableLoc;
// Parse exception-specification[opt].
ExceptionSpecificationType ESpecType = EST_None;
@@ -1227,8 +1172,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
LParenLoc, FunLocalRangeEnd, D,
TrailingReturnType),
Attr, DeclEndLoc);
- } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,
- tok::kw_constexpr) ||
+ } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute) ||
(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.
@@ -1238,7 +1182,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
case tok::arrow: TokKind = 1; break;
case tok::kw___attribute:
case tok::l_square: TokKind = 2; break;
- case tok::kw_constexpr: TokKind = 3; break;
default: llvm_unreachable("Unknown token kind");
}
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 1b8410d7f4..8a2bf929df 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -355,8 +355,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
SourceRange IntroducerRange,
TypeSourceInfo *MethodTypeInfo,
SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- const bool IsConstexprSpecified) {
+ ArrayRef<ParmVarDecl *> Params) {
QualType MethodType = MethodTypeInfo->getType();
TemplateParameterList *TemplateParams =
getGenericLambdaTemplateParameterList(getCurLambda(), *this);
@@ -393,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
MethodType, MethodTypeInfo,
SC_None,
/*isInline=*/true,
- IsConstexprSpecified,
+ /*isConstExpr=*/false,
EndLoc);
Method->setAccess(AS_public);
@@ -878,9 +877,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo,
KnownDependent, Intro.Default);
- CXXMethodDecl *Method =
- startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params,
- ParamInfo.getDeclSpec().isConstexprSpecified());
+ CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
+ MethodTyInfo, EndLoc, Params);
if (ExplicitParams)
CheckCXXDefaultArguments(Method);
@@ -1599,17 +1597,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
CaptureInits, ArrayIndexVars,
ArrayIndexStarts, EndLoc,
ContainsUnexpandedParameterPack);
- // If the lambda expression's call operator is not explicitly marked constexpr
- // and we are not in a dependent context, analyze the call operator to infer
- // its constexpr-ness, supressing diagnostics while doing so.
- if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() &&
- !CallOperator->isConstexpr() &&
- !Class->getDeclContext()->isDependentContext()) {
- TentativeAnalysisScope DiagnosticScopeGuard(*this);
- CallOperator->setConstexpr(
- CheckConstexprFunctionDecl(CallOperator) &&
- CheckConstexprFunctionBody(CallOperator, CallOperator->getBody()));
- }
if (!CurContext->isDependentContext()) {
switch (ExprEvalContexts.back().Context) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 36859f61d3..7224eef848 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -10222,9 +10222,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
Class, E->getIntroducerRange(), NewCallOpTSI,
E->getCallOperator()->getLocEnd(),
- NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
- E->getCallOperator()->isConstexpr());
-
+ NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams());
LSI->CallOperator = NewCallOperator;
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
diff --git a/test/Parser/cxx1z-constexpr-lambdas.cpp b/test/Parser/cxx1z-constexpr-lambdas.cpp
deleted file mode 100644
index ea000e361c..0000000000
--- a/test/Parser/cxx1z-constexpr-lambdas.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z %s -verify
-// RUN: %clang_cc1 -std=c++14 %s -verify
-// RUN: %clang_cc1 -std=c++11 %s -verify
-
-
-auto XL0 = [] constexpr { }; //expected-error{{requires '()'}} expected-error{{expected body}}
-auto XL1 = [] () mutable
- mutable //expected-error{{cannot appear multiple times}}
- mutable { }; //expected-error{{cannot appear multiple times}}
-
-#if __cplusplus > 201402L
-auto XL2 = [] () constexpr mutable constexpr { }; //expected-error{{cannot appear multiple times}}
-auto L = []() mutable constexpr { };
-auto L2 = []() constexpr { };
-auto L4 = []() constexpr mutable { };
-auto XL16 = [] () constexpr
- mutable
- constexpr //expected-error{{cannot appear multiple times}}
- mutable //expected-error{{cannot appear multiple times}}
- mutable //expected-error{{cannot appear multiple times}}
- constexpr //expected-error{{cannot appear multiple times}}
- constexpr //expected-error{{cannot appear multiple times}}
- { };
-
-#else
-auto L = []() mutable constexpr {return 0; }; //expected-warning{{is a C++1z extension}}
-auto L2 = []() constexpr { return 0;};//expected-warning{{is a C++1z extension}}
-auto L4 = []() constexpr mutable { return 0; }; //expected-warning{{is a C++1z extension}}
-#endif
-
-
diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
deleted file mode 100644
index 8e7657fb6e..0000000000
--- a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s
-
-namespace test_constexpr_checking {
-
-namespace ns1 {
- struct NonLit { ~NonLit(); }; //expected-note{{not literal}}
- auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}}
-} // end ns1
-
-namespace ns2 {
- auto L = [](int I) constexpr { asm("non-constexpr"); }; //expected-error{{not allowed in constexpr function}}
-} // end ns1
-
-} // end ns test_constexpr_checking
-
-namespace test_constexpr_call {
-
-namespace ns1 {
- auto L = [](int I) { return I; };
- static_assert(L(3) == 3);
-} // end ns1
-namespace ns2 {
- auto L = [](auto a) { return a; };
- static_assert(L(3) == 3);
- static_assert(L(3.14) == 3.14);
-}
-namespace ns3 {
- auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}}
- constexpr int I = //expected-error{{must be initialized by a constant expression}}
- L(3); //expected-note{{non-constexpr function}}
-}
-
-} // end ns test_constexpr_call \ No newline at end of file