@@ -23,6 +23,34 @@ using namespace clang;
23
23
using namespace clang ::interp;
24
24
25
25
Function *ByteCodeEmitter::compileFunc (const FunctionDecl *FuncDecl) {
26
+ bool IsLambdaStaticInvoker = false ;
27
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
28
+ MD && MD->isLambdaStaticInvoker ()) {
29
+ // For a lambda static invoker, we might have to pick a specialized
30
+ // version if the lambda is generic. In that case, the picked function
31
+ // will *NOT* be a static invoker anymore. However, it will still
32
+ // be a non-static member function, this (usually) requiring an
33
+ // instance pointer. We suppress that later in this function.
34
+ IsLambdaStaticInvoker = true ;
35
+
36
+ const CXXRecordDecl *ClosureClass = MD->getParent ();
37
+ assert (ClosureClass->captures_begin () == ClosureClass->captures_end ());
38
+ if (ClosureClass->isGenericLambda ()) {
39
+ const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator ();
40
+ assert (MD->isFunctionTemplateSpecialization () &&
41
+ " A generic lambda's static-invoker function must be a "
42
+ " template specialization" );
43
+ const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs ();
44
+ FunctionTemplateDecl *CallOpTemplate =
45
+ LambdaCallOp->getDescribedFunctionTemplate ();
46
+ void *InsertPos = nullptr ;
47
+ const FunctionDecl *CorrespondingCallOpSpecialization =
48
+ CallOpTemplate->findSpecialization (TAL->asArray (), InsertPos);
49
+ assert (CorrespondingCallOpSpecialization);
50
+ FuncDecl = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
51
+ }
52
+ }
53
+
26
54
// Set up argument indices.
27
55
unsigned ParamOffset = 0 ;
28
56
SmallVector<PrimType, 8 > ParamTypes;
@@ -46,7 +74,7 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
46
74
// InterpStack when calling the function.
47
75
bool HasThisPointer = false ;
48
76
if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
49
- if (MD->isImplicitObjectMemberFunction ()) {
77
+ if (MD->isImplicitObjectMemberFunction () && !IsLambdaStaticInvoker ) {
50
78
HasThisPointer = true ;
51
79
ParamTypes.push_back (PT_Ptr);
52
80
ParamOffsets.push_back (ParamOffset);
0 commit comments