Skip to content

Commit

Permalink
[clang][Interp] Lambda This captures can be non-pointers
Browse files Browse the repository at this point in the history
If they are captured by value.
  • Loading branch information
tbaederr committed Mar 1, 2024
1 parent 64216ba commit 68516bf
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 6 deletions.
8 changes: 6 additions & 2 deletions clang/lib/AST/Interp/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
this->LambdaCaptures[Cap.first] = {
Offset, Cap.second->getType()->isReferenceType()};
}
if (LTC)
this->LambdaThisCapture = R->getField(LTC)->Offset;
if (LTC) {
QualType CaptureType = R->getField(LTC)->Decl->getType();
this->LambdaThisCapture = {R->getField(LTC)->Offset,
CaptureType->isReferenceType() ||
CaptureType->isPointerType()};
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/ByteCodeEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ByteCodeEmitter {
/// Lambda captures.
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
/// Offset of the This parameter in a lambda record.
unsigned LambdaThisCapture = 0;
ParamOffset LambdaThisCapture{0, false};
/// Local descriptors.
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;

Expand Down
7 changes: 5 additions & 2 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2934,8 +2934,11 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
if (DiscardResult)
return true;

if (this->LambdaThisCapture > 0)
return this->emitGetThisFieldPtr(this->LambdaThisCapture, E);
if (this->LambdaThisCapture.Offset > 0) {
if (this->LambdaThisCapture.IsPtr)
return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
}

return this->emitThis(E);
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/EvalEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class EvalEmitter : public SourceMapper {
/// Lambda captures.
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
/// Offset of the This parameter in a lambda record.
unsigned LambdaThisCapture = 0;
ParamOffset LambdaThisCapture{0, false};
/// Local descriptors.
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;

Expand Down
13 changes: 13 additions & 0 deletions clang/test/AST/Interp/lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,16 @@ namespace LambdaToAPValue {
static_assert(g() == f(), "");
}
}

namespace ns2_capture_this_byval {
struct S {
int s;
constexpr S(int s) : s{s} { }
constexpr auto f(S o) {
return [*this,o] (auto a) { return s + o.s + a.s; };
}
};

constexpr auto L = S{5}.f(S{10});
static_assert(L(S{100}) == 115, "");
} // end test_captures_1::ns2_capture_this_byval

0 comments on commit 68516bf

Please sign in to comment.