Author: Timm Bäder Date: 2023-10-05T09:46:15+02:00 New Revision: 57147bb25303aef5edf251d1f2243e75dc687aec
URL: https://github.com/llvm/llvm-project/commit/57147bb25303aef5edf251d1f2243e75dc687aec DIFF: https://github.com/llvm/llvm-project/commit/57147bb25303aef5edf251d1f2243e75dc687aec.diff LOG: [clang][Interp] Support LambdaThisCaptures Differential Revision: https://reviews.llvm.org/D154262 Added: Modified: 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 Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index ea4e48cb4262772..a634ee288f57c99 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -64,8 +64,8 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { this->LambdaCaptures[Cap.first] = { Offset, Cap.second->getType()->isReferenceType()}; } - // FIXME: LambdaThisCapture - (void)LTC; + if (LTC) + this->LambdaThisCapture = R->getField(LTC)->Offset; } } diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.h b/clang/lib/AST/Interp/ByteCodeEmitter.h index d184484a9197f93..5520f8c3006106f 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.h +++ b/clang/lib/AST/Interp/ByteCodeEmitter.h @@ -67,7 +67,8 @@ class ByteCodeEmitter { 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; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 00d3b469d9049f6..3cf8bf874b1d210 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2305,6 +2305,10 @@ template <class Emitter> 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); } diff --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h index c63e46bbf347bdf..1128e0fb09f0de8 100644 --- a/clang/lib/AST/Interp/EvalEmitter.h +++ b/clang/lib/AST/Interp/EvalEmitter.h @@ -73,7 +73,8 @@ class EvalEmitter : public SourceMapper { 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; diff --git a/clang/test/AST/Interp/lambda.cpp b/clang/test/AST/Interp/lambda.cpp index da1d706af1d0501..f8400898acc0c05 100644 --- a/clang/test/AST/Interp/lambda.cpp +++ b/clang/test/AST/Interp/lambda.cpp @@ -179,3 +179,24 @@ namespace LambdasAsParams { } 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), ""); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits