forked from OSchip/llvm-project
Make explicit captures which cause implicit captures work correctly.
llvm-svn: 149719
This commit is contained in:
parent
24af850470
commit
a023e0c619
|
@ -2284,7 +2284,11 @@ public:
|
|||
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);
|
||||
|
|
|
@ -9453,7 +9453,8 @@ static bool shouldAddConstForScope(CapturingScopeInfo *CSI, VarDecl *VD) {
|
|||
// 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 @@ void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc) {
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
|
@ -5030,12 +5030,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
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 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
<< 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();
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace ReturnDeduction {
|
|||
|
||||
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 @@ namespace ImplicitCapture {
|
|||
[=]() { 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 @@ namespace ImplicitCapture {
|
|||
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}}
|
||||
|
|
Loading…
Reference in New Issue