This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG57147bb25303: [clang][Interp] Support LambdaThisCaptures (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D154262?vs=536427&id=557605#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154262/new/ https://reviews.llvm.org/D154262 Files: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/lib/AST/Interp/ByteCodeEmitter.h clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/EvalEmitter.h clang/test/AST/Interp/lambda.cpp Index: clang/test/AST/Interp/lambda.cpp =================================================================== --- clang/test/AST/Interp/lambda.cpp +++ clang/test/AST/Interp/lambda.cpp @@ -179,3 +179,24 @@ } static_assert(heh() == 1.0); } + +namespace ThisCapture { + class Foo { + public: + int b = 32; + int a; + + constexpr Foo() : a([this](){ return b + 1;}()) {} + + constexpr int Aplus2() const { + auto F = [this]() { + return a + 2; + }; + + return F(); + } + }; + constexpr Foo F; + static_assert(F.a == 33, ""); + static_assert(F.Aplus2() == (33 + 2), ""); +} Index: clang/lib/AST/Interp/EvalEmitter.h =================================================================== --- clang/lib/AST/Interp/EvalEmitter.h +++ clang/lib/AST/Interp/EvalEmitter.h @@ -73,7 +73,8 @@ llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params; /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; - unsigned LambdaThisCapture; + /// Offset of the This parameter in a lambda record. + unsigned LambdaThisCapture = 0; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2305,6 +2305,10 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { if (DiscardResult) return true; + + if (this->LambdaThisCapture > 0) + return this->emitGetThisFieldPtr(this->LambdaThisCapture, E); + return this->emitThis(E); } Index: clang/lib/AST/Interp/ByteCodeEmitter.h =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.h +++ clang/lib/AST/Interp/ByteCodeEmitter.h @@ -67,7 +67,8 @@ llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params; /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; - unsigned LambdaThisCapture; + /// Offset of the This parameter in a lambda record. + unsigned LambdaThisCapture = 0; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -64,8 +64,8 @@ this->LambdaCaptures[Cap.first] = { Offset, Cap.second->getType()->isReferenceType()}; } - // FIXME: LambdaThisCapture - (void)LTC; + if (LTC) + this->LambdaThisCapture = R->getField(LTC)->Offset; } }
Index: clang/test/AST/Interp/lambda.cpp =================================================================== --- clang/test/AST/Interp/lambda.cpp +++ clang/test/AST/Interp/lambda.cpp @@ -179,3 +179,24 @@ } static_assert(heh() == 1.0); } + +namespace ThisCapture { + class Foo { + public: + int b = 32; + int a; + + constexpr Foo() : a([this](){ return b + 1;}()) {} + + constexpr int Aplus2() const { + auto F = [this]() { + return a + 2; + }; + + return F(); + } + }; + constexpr Foo F; + static_assert(F.a == 33, ""); + static_assert(F.Aplus2() == (33 + 2), ""); +} Index: clang/lib/AST/Interp/EvalEmitter.h =================================================================== --- clang/lib/AST/Interp/EvalEmitter.h +++ clang/lib/AST/Interp/EvalEmitter.h @@ -73,7 +73,8 @@ llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params; /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; - unsigned LambdaThisCapture; + /// Offset of the This parameter in a lambda record. + unsigned LambdaThisCapture = 0; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2305,6 +2305,10 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { if (DiscardResult) return true; + + if (this->LambdaThisCapture > 0) + return this->emitGetThisFieldPtr(this->LambdaThisCapture, E); + return this->emitThis(E); } Index: clang/lib/AST/Interp/ByteCodeEmitter.h =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.h +++ clang/lib/AST/Interp/ByteCodeEmitter.h @@ -67,7 +67,8 @@ llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params; /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; - unsigned LambdaThisCapture; + /// Offset of the This parameter in a lambda record. + unsigned LambdaThisCapture = 0; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -64,8 +64,8 @@ this->LambdaCaptures[Cap.first] = { Offset, Cap.second->getType()->isReferenceType()}; } - // FIXME: LambdaThisCapture - (void)LTC; + if (LTC) + this->LambdaThisCapture = R->getField(LTC)->Offset; } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits