[cfe-commits] r149719 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/lambda-expressions.cpp
Eli Friedman
eli.friedman at gmail.com
Fri Feb 3 15:06:43 PST 2012
Author: efriedma
Date: Fri Feb 3 17:06:43 2012
New Revision: 149719
URL: http://llvm.org/viewvc/llvm-project?rev=149719&view=rev
Log:
Make explicit captures which cause implicit captures work correctly.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/lambda-expressions.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=149719&r1=149718&r2=149719&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 3 17:06:43 2012
@@ -2284,7 +2284,11 @@
void UpdateMarkingForLValueToRValue(Expr *E);
void CleanupVarDeclMarking();
- void TryCaptureVar(VarDecl *var, SourceLocation loc);
+ enum TryCaptureKind {
+ TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
+ };
+ void TryCaptureVar(VarDecl *var, SourceLocation loc,
+ TryCaptureKind Kind = TryCapture_Implicit);
void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
void MarkDeclarationsReferencedInExpr(Expr *E);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=149719&r1=149718&r2=149719&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb 3 17:06:43 2012
@@ -9453,7 +9453,8 @@
// Check if the variable needs to be captured; if so, try to perform
// the capture.
// FIXME: Add support for explicit captures.
-void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc) {
+void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc,
+ TryCaptureKind Kind) {
DeclContext *DC = CurContext;
if (var->getDeclContext() == DC) return;
if (!var->hasLocalStorage()) return;
@@ -9536,7 +9537,12 @@
}
bool byRef;
- if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None) {
+ bool isInnermostCapture = (i == e - 1);
+ if (isInnermostCapture && Kind == TryCapture_ExplicitByVal) {
+ byRef = false;
+ } else if (isInnermostCapture && Kind == TryCapture_ExplicitByRef) {
+ byRef = true;
+ } else if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None) {
// No capture-default
Diag(loc, diag::err_lambda_impcap) << var->getDeclName();
Diag(var->getLocation(), diag::note_previous_decl) << var->getDeclName();
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=149719&r1=149718&r2=149719&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Feb 3 17:06:43 2012
@@ -5030,12 +5030,6 @@
Diag(Var->getLocation(), diag::note_previous_decl) << C->Id;
continue;
}
-
- if (Var->hasAttr<BlocksAttr>()) {
- Diag(C->Loc, diag::err_lambda_capture_block) << C->Id;
- Diag(Var->getLocation(), diag::note_previous_decl) << C->Id;
- continue;
- }
// C++11 [expr.prim.lambda]p8:
// An identifier or this shall not appear more than once in a
@@ -5046,13 +5040,10 @@
<< SourceRange(LSI->getCapture(Var).getLocation());
continue;
}
-
- // FIXME: If this is capture by copy, make sure that we can in fact copy
- // the variable.
- // FIXME: Unify with normal capture path, so we get all of the necessary
- // nested captures.
- LSI->AddCapture(Var, /*isBlock*/false, C->Kind == LCK_ByRef,
- /*isNested=*/false, C->Loc, 0);
+
+ TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
+ TryCapture_ExplicitByVal;
+ TryCaptureVar(Var, C->Loc, Kind);
}
LSI->finishedExplicitCaptures();
Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=149719&r1=149718&r2=149719&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Fri Feb 3 17:06:43 2012
@@ -45,7 +45,7 @@
namespace ImplicitCapture {
void test() {
- int a = 0; // expected-note 3 {{declared}}
+ int a = 0; // expected-note 5 {{declared}}
[]() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}} expected-error {{not supported yet}}
[&]() { return a; }; // expected-error {{not supported yet}}
[=]() { return a; }; // expected-error {{not supported yet}}
@@ -53,6 +53,8 @@
[=]() { return [&]() { return a; }; }; // expected-error 2 {{not supported yet}}
[]() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-error 2 {{not supported yet}}
[]() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-error {{not supported yet}}
+ []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}} expected-error 2 {{not supported yet}}
+ [=]() { return [&a] { return a; }; }; // expected-error 2 {{not supported yet}}
const int b = 2;
[]() { return b; }; // expected-error {{not supported yet}}
@@ -64,8 +66,9 @@
d = 3;
[=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}} expected-error {{not supported yet}}
- __block int e; // expected-note {{declared}}
+ __block int e; // expected-note 3 {{declared}}
[&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}} expected-error {{not supported yet}}
+ [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}} expected-error {{not supported yet}}
int f[10]; // expected-note {{declared}}
[&]() { return f[2]; }; // expected-error {{not supported yet}}
More information about the cfe-commits
mailing list