forked from OSchip/llvm-project
Replace the broken LambdaCapture::isInitCapture API.
A LambdaCapture does not have sufficient information to correctly determine whether it is an init-capture or not. Doing so requires knowledge held in the LambdaExpr itself. It the case of a nested capture of an init-capture it is not sufficient to check (as LambdaCapture::isInitCapture did) whether the associated VarDecl was from an init-capture. This patch moves isInitCapture to LambdaExpr and updates Capture->isInitCapture() to Lambda->isInitCapture(Capture). llvm-svn: 236760
This commit is contained in:
parent
3d415cd2cd
commit
dd2ffea288
|
@ -791,7 +791,7 @@ template <typename Derived>
|
|||
bool
|
||||
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
|
||||
const LambdaCapture *C) {
|
||||
if (C->isInitCapture())
|
||||
if (LE->isInitCapture(C))
|
||||
TRY_TO(TraverseDecl(C->getCapturedVar()));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1452,6 +1452,9 @@ public:
|
|||
return CaptureDefaultLoc;
|
||||
}
|
||||
|
||||
/// \brief Determine whether one of this lambda's captures is an init-capture.
|
||||
bool isInitCapture(const LambdaCapture *Capture) const;
|
||||
|
||||
/// \brief An iterator that walks over the captures of the lambda,
|
||||
/// both implicit and explicit.
|
||||
typedef const Capture *capture_iterator;
|
||||
|
|
|
@ -85,11 +85,6 @@ public:
|
|||
(DeclAndBits.getInt() & Capture_ByCopy);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this is an init-capture.
|
||||
bool isInitCapture() const {
|
||||
return capturesVariable() && getCapturedVar()->isInitCapture();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the declaration of the local variable being
|
||||
/// captured.
|
||||
///
|
||||
|
|
|
@ -857,7 +857,7 @@ template <typename Derived>
|
|||
bool
|
||||
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
|
||||
const LambdaCapture *C) {
|
||||
if (C->isInitCapture())
|
||||
if (LE->isInitCapture(C))
|
||||
TRY_TO(TraverseDecl(C->getCapturedVar()));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1027,6 +1027,11 @@ LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
|
|||
return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars > 0);
|
||||
}
|
||||
|
||||
bool LambdaExpr::isInitCapture(const LambdaCapture *C) const {
|
||||
return (C->capturesVariable() && C->getCapturedVar()->isInitCapture() &&
|
||||
(getCallOperator() == C->getCapturedVar()->getDeclContext()));
|
||||
}
|
||||
|
||||
LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
|
||||
return getLambdaClass()->getLambdaData().Captures;
|
||||
}
|
||||
|
|
|
@ -1758,7 +1758,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
|
|||
break;
|
||||
|
||||
case LCK_ByRef:
|
||||
if (Node->getCaptureDefault() != LCD_ByRef || C->isInitCapture())
|
||||
if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
|
||||
OS << '&';
|
||||
OS << C->getCapturedVar()->getName();
|
||||
break;
|
||||
|
@ -1770,7 +1770,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
|
|||
llvm_unreachable("VLA type in explicit captures.");
|
||||
}
|
||||
|
||||
if (C->isInitCapture())
|
||||
if (Node->isInitCapture(C))
|
||||
PrintExpr(C->getCapturedVar()->getInit());
|
||||
}
|
||||
OS << ']';
|
||||
|
|
|
@ -9133,7 +9133,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|||
for (LambdaExpr::capture_iterator C = E->capture_begin(),
|
||||
CEnd = E->capture_end();
|
||||
C != CEnd; ++C) {
|
||||
if (!C->isInitCapture())
|
||||
if (!E->isInitCapture(C))
|
||||
continue;
|
||||
EnterExpressionEvaluationContext EEEC(getSema(),
|
||||
Sema::PotentiallyEvaluated);
|
||||
|
@ -9245,7 +9245,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|||
continue;
|
||||
|
||||
// Rebuild init-captures, including the implied field declaration.
|
||||
if (C->isInitCapture()) {
|
||||
if (E->isInitCapture(C)) {
|
||||
InitCaptureInfoTy InitExprTypePair =
|
||||
InitCaptureExprsAndTypes[C - E->capture_begin()];
|
||||
ExprResult Init = InitExprTypePair.first;
|
||||
|
|
|
@ -166,4 +166,27 @@ int test(T t = T{}) {
|
|||
|
||||
int run = test(); //expected-note {{instantiation}}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace classification_of_captures_of_init_captures {
|
||||
|
||||
template <typename T>
|
||||
void f() {
|
||||
[a = 24] () mutable {
|
||||
[&a] { a = 3; }();
|
||||
}();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void h() {
|
||||
[a = 24] (auto param) mutable {
|
||||
[&a] { a = 3; }();
|
||||
}(42);
|
||||
}
|
||||
|
||||
int run() {
|
||||
f<int>();
|
||||
h<int>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue