Skip to content

Commit 57147bb

Browse files
committed
[clang][Interp] Support LambdaThisCaptures
Differential Revision: https://reviews.llvm.org/D154262
1 parent cc2d951 commit 57147bb

File tree

5 files changed

+31
-4
lines changed

5 files changed

+31
-4
lines changed

clang/lib/AST/Interp/ByteCodeEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
6464
this->LambdaCaptures[Cap.first] = {
6565
Offset, Cap.second->getType()->isReferenceType()};
6666
}
67-
// FIXME: LambdaThisCapture
68-
(void)LTC;
67+
if (LTC)
68+
this->LambdaThisCapture = R->getField(LTC)->Offset;
6969
}
7070
}
7171

clang/lib/AST/Interp/ByteCodeEmitter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ class ByteCodeEmitter {
6767
llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;
6868
/// Lambda captures.
6969
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
70-
unsigned LambdaThisCapture;
70+
/// Offset of the This parameter in a lambda record.
71+
unsigned LambdaThisCapture = 0;
7172
/// Local descriptors.
7273
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
7374

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,6 +2305,10 @@ template <class Emitter>
23052305
bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
23062306
if (DiscardResult)
23072307
return true;
2308+
2309+
if (this->LambdaThisCapture > 0)
2310+
return this->emitGetThisFieldPtr(this->LambdaThisCapture, E);
2311+
23082312
return this->emitThis(E);
23092313
}
23102314

clang/lib/AST/Interp/EvalEmitter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ class EvalEmitter : public SourceMapper {
7373
llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;
7474
/// Lambda captures.
7575
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
76-
unsigned LambdaThisCapture;
76+
/// Offset of the This parameter in a lambda record.
77+
unsigned LambdaThisCapture = 0;
7778
/// Local descriptors.
7879
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
7980

clang/test/AST/Interp/lambda.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,24 @@ namespace LambdasAsParams {
179179
}
180180
static_assert(heh() == 1.0);
181181
}
182+
183+
namespace ThisCapture {
184+
class Foo {
185+
public:
186+
int b = 32;
187+
int a;
188+
189+
constexpr Foo() : a([this](){ return b + 1;}()) {}
190+
191+
constexpr int Aplus2() const {
192+
auto F = [this]() {
193+
return a + 2;
194+
};
195+
196+
return F();
197+
}
198+
};
199+
constexpr Foo F;
200+
static_assert(F.a == 33, "");
201+
static_assert(F.Aplus2() == (33 + 2), "");
202+
}

0 commit comments

Comments
 (0)