From 27dd7d962bbf774988bc5e59d04a7743ed503514 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 17 Feb 2012 03:02:34 +0000 Subject: Rework the Sema/AST/IRgen dance for the lambda closure type's conversion to function pointer. Rather than having IRgen synthesize the body of this function, we instead introduce a static member function "__invoke" with the same signature as the lambda's operator() in the AST. Sema then generates a body for the conversion to function pointer which simply returns the address of __invoke. This approach makes it easier to evaluate a call to the conversion function as a constant, makes the linkage of the __invoke function follow the normal rules for member functions, and may make life easier down the road if we ever want to constexpr'ify some of lambdas. Note that IR generation is responsible for filling in the body of __invoke (Sema just adds a dummy body), because the body can't generally be expressed in C++. Eli, please review! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150783 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'lib/CodeGen/CodeGenFunction.cpp') diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 1034de736c..28c5935de0 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -448,13 +448,15 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, FD->hasAttr()) CGM.getCUDARuntime().EmitDeviceStubBody(*this, Args); else if (isa(FD) && - cast(FD)->getParent()->isLambda()) { - // The lambda conversion operators are special; the semantics can't be - // expressed in the AST, so IRGen needs to special-case them. - if (cast(FD)->isLambdaToBlockPointerConversion()) - EmitLambdaToBlockPointerBody(Args); - else - EmitLambdaToFunctionPointerBody(Args); + cast(FD)->isLambdaToBlockPointerConversion()) { + // The lambda conversion to block pointer is special; the semantics can't be + // expressed in the AST, so IRGen needs to special-case it. + EmitLambdaToBlockPointerBody(Args); + } else if (isa(FD) && + cast(FD)->isLambdaStaticInvoker()) { + // The lambda "__invoke" function is special, because it forwards or + // clones the body of the function call operator (but is actually static). + EmitLambdaStaticInvokeFunction(cast(FD)); } else EmitFunctionBody(Args); -- cgit v1.2.3-18-g5258