summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-05-31 01:17:04 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-05-31 01:17:04 +0000
commitb5a45bb77e05647f04bbd9780d70aabe9f251155 (patch)
tree1ccaf0c1585826b9245a8253bea9150801f2f46c /clang/lib
parenta35c50c9a4d1c15b4830c40013e73ec7933f8f6c (diff)
downloadbcm5719-llvm-b5a45bb77e05647f04bbd9780d70aabe9f251155.tar.gz
bcm5719-llvm-b5a45bb77e05647f04bbd9780d70aabe9f251155.zip
Defer building 'this' captures until we have left the capturing region
and returned to the context in which 'this' should be captured. This means we now always mark 'this' referenced from the context in which it's actually referenced, rather than potentially from some context nested within that. llvm-svn: 362182
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp35
-rw-r--r--clang/lib/Sema/SemaLambda.cpp23
-rw-r--r--clang/lib/Sema/SemaStmt.cpp6
4 files changed, 25 insertions, 41 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 759eb531c50..6bd7b4e0711 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12943,7 +12943,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,
} else if (C.capturesThis()) {
LSI->addThisCapture(/*Nested*/ false, C.getLocation(), I->getType(),
- /*Expr*/ nullptr, C.getCaptureKind() == LCK_StarThis);
+ C.getCaptureKind() == LCK_StarThis);
} else {
LSI->addVLATypeCapture(C.getLocation(), I->getCapturedVLAType(),
I->getType());
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 6e67968929a..ac050fa1ef5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1134,24 +1134,6 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {
}
}
-static Expr *captureThis(Sema &S, ASTContext &Context, RecordDecl *RD,
- QualType ThisTy, QualType CaptureType,
- SourceLocation Loc, const bool ByCopy) {
- Expr *This = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/ true);
- if (ByCopy) {
- Expr *StarThis = S.CreateBuiltinUnaryOp(Loc, UO_Deref, This).get();
- InitializedEntity Entity =
- InitializedEntity::InitializeLambdaCapture(nullptr, CaptureType, Loc);
- InitializationKind InitKind =
- InitializationKind::CreateDirect(Loc, Loc, Loc);
- InitializationSequence Init(S, Entity, InitKind, StarThis);
- ExprResult ER = Init.Perform(S, Entity, InitKind, StarThis);
- if (ER.isInvalid()) return nullptr;
- return ER.get();
- }
- return This;
-}
-
bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt,
const bool ByCopy) {
@@ -1241,13 +1223,10 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
dyn_cast<LambdaScopeInfo>(FunctionScopes[MaxFunctionScopesIndex])) &&
"Only a lambda can capture the enclosing object (referred to by "
"*this) by copy");
- // FIXME: We need to delay this marking in PotentiallyPotentiallyEvaluated
- // contexts.
QualType ThisTy = getCurrentThisType();
for (int idx = MaxFunctionScopesIndex; NumCapturingClosures;
--idx, --NumCapturingClosures) {
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
- Expr *ThisExpr = nullptr;
// The type of the corresponding data member (not a 'this' pointer if 'by
// copy').
@@ -1261,20 +1240,8 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
CaptureType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
}
- if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
- // For lambda expressions, build a field and an initializing expression,
- // and capture the *enclosing object* by copy only if this is the first
- // iteration.
- ThisExpr = captureThis(*this, Context, LSI->Lambda, ThisTy, CaptureType,
- Loc, ByCopy && idx == MaxFunctionScopesIndex);
-
- } else if (CapturedRegionScopeInfo *RSI
- = dyn_cast<CapturedRegionScopeInfo>(FunctionScopes[idx]))
- ThisExpr = captureThis(*this, Context, RSI->TheRecordDecl, ThisTy,
- CaptureType, Loc, false /*ByCopy*/);
-
bool isNested = NumCapturingClosures > 1;
- CSI->addThisCapture(isNested, Loc, CaptureType, ThisExpr, ByCopy);
+ CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy);
}
return false;
}
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index a17a3da67fd..d3f3b60926f 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1431,6 +1431,24 @@ static void addBlockPointerConversion(Sema &S,
Class->addDecl(Conversion);
}
+ExprResult Sema::performThisCaptureInitialization(const Capture &Cap,
+ bool IsImplicit) {
+ QualType ThisTy = getCurrentThisType();
+ SourceLocation Loc = Cap.getLocation();
+ Expr *This = BuildCXXThisExpr(Loc, ThisTy, IsImplicit);
+ if (Cap.isReferenceCapture())
+ return This;
+
+ // Capture (by copy) of '*this'.
+ Expr *StarThis = CreateBuiltinUnaryOp(Loc, UO_Deref, This).get();
+ InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture(
+ nullptr, Cap.getCaptureType(), Loc);
+ InitializationKind InitKind =
+ InitializationKind::CreateDirect(Loc, Loc, Loc);
+ InitializationSequence Init(*this, Entity, InitKind, StarThis);
+ return Init.Perform(*this, Entity, InitKind, StarThis);
+}
+
static ExprResult performLambdaVarCaptureInitialization(
Sema &S, const Capture &Capture, FieldDecl *Field,
SourceLocation ImplicitCaptureLoc, bool IsImplicitCapture) {
@@ -1680,10 +1698,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
getLocForEndOfToken(CaptureDefaultLoc), ", this");
}
+ ExprResult Init = performThisCaptureInitialization(From, IsImplicit);
Captures.push_back(
LambdaCapture(From.getLocation(), IsImplicit,
From.isCopyCapture() ? LCK_StarThis : LCK_This));
- CaptureInits.push_back(From.getThisInitExpr());
+ CaptureInits.push_back(Init.get());
continue;
}
if (From.isVLATypeCapture()) {
@@ -1703,8 +1722,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
? Var->getInit()
: performLambdaVarCaptureInitialization(
*this, From, Field, CaptureDefaultLoc, IsImplicit);
- if (Init.isInvalid())
- return ExprError();
CaptureInits.push_back(Init.get());
}
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7a9a801b188..3a7acd20274 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4235,9 +4235,11 @@ buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
FieldDecl *Field = S.BuildCaptureField(RSI->TheRecordDecl, Cap);
if (Cap.isThisCapture()) {
+ ExprResult Init =
+ S.performThisCaptureInitialization(Cap, /*Implicit*/ true);
Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
CapturedStmt::VCK_This));
- CaptureInits.push_back(Cap.getThisInitExpr());
+ CaptureInits.push_back(Init.get());
continue;
} else if (Cap.isVLATypeCapture()) {
Captures.push_back(
@@ -4256,8 +4258,6 @@ buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
// perform a copy here!
ExprResult Init = S.BuildDeclarationNameExpr(
CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
- if (Init.isInvalid())
- return true;
Captures.push_back(CapturedStmt::Capture(Loc,
Cap.isReferenceCapture()
OpenPOWER on IntegriCloud