aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp59
1 files changed, 9 insertions, 50 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index ed44679a88..7e94af391f 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1725,26 +1725,15 @@ void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) {
CGM.ErrorUnsupported(CurFuncDecl, "lambda conversion to block");
}
-void CodeGenFunction::EmitLambdaThunkBody(llvm::Function *Fn,
- const CGFunctionInfo &FnInfo,
- const CXXRecordDecl *Lambda) {
+void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
+ const CXXRecordDecl *Lambda = MD->getParent();
DeclarationName Name
= getContext().DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_const_result Calls = Lambda->lookup(Name);
- CXXMethodDecl *MD = cast<CXXMethodDecl>(*Calls.first++);
+ CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(*Calls.first++);
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
QualType ResultType = FPT->getResultType();
- // Begin function
- FunctionArgList FunctionArgs;
- for (FunctionDecl::param_const_iterator I = MD->param_begin(),
- E = MD->param_end(); I != E; ++I) {
- ParmVarDecl *Param = *I;
- FunctionArgs.push_back(Param);
- }
- StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
- SourceLocation());
-
// Start building arguments for forwarding call
CallArgList CallArgs;
@@ -1760,7 +1749,7 @@ void CodeGenFunction::EmitLambdaThunkBody(llvm::Function *Fn,
}
// Get the address of the call operator.
- GlobalDecl GD(MD);
+ GlobalDecl GD(CallOperator);
const CGFunctionInfo &CalleeFnInfo = CGM.getTypes().getFunctionInfo(GD);
llvm::Type *Ty =
CGM.getTypes().GetFunctionType(CalleeFnInfo, FPT->isVariadic());
@@ -1769,54 +1758,24 @@ void CodeGenFunction::EmitLambdaThunkBody(llvm::Function *Fn,
// Determine whether we have a return value slot to use.
ReturnValueSlot Slot;
if (!ResultType->isVoidType() &&
- FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+ CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
hasAggregateLLVMType(CurFnInfo->getReturnType()))
Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
// Now emit our call.
- RValue RV = EmitCall(CalleeFnInfo, Callee, Slot, CallArgs, MD);
+ RValue RV = EmitCall(CalleeFnInfo, Callee, Slot, CallArgs, CallOperator);
// Forward the returned value
if (!ResultType->isVoidType() && Slot.isNull())
EmitReturnOfRValue(RV, ResultType);
-
- // End the function.
- FinishFunction();
}
-llvm::Constant *
-CodeGenFunction::EmitLambdaConvertedFnPtr(const CXXMethodDecl *MD) {
- QualType FnTy = MD->getResultType()->getPointeeType();
- CanQual<FunctionProtoType> CanFnTy =
- CGM.getContext().getCanonicalType(FnTy)->getAs<FunctionProtoType>();
- llvm::FunctionType *FnLLVMTy = cast<llvm::FunctionType>(CGM.getTypes().ConvertType(FnTy));
- const CXXRecordDecl *Lambda = MD->getParent();
- const CGFunctionInfo &FnInfo = CGM.getTypes().getFunctionInfo(CanFnTy);
-
- if (CanFnTy->isVariadic()) {
+void CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) {
+ if (MD->isVariadic()) {
// FIXME: Making this work correctly is nasty because it requires either
// cloning the body of the call operator or making the call operator forward.
CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
- return llvm::UndefValue::get(FnLLVMTy->getPointerTo());
}
- // Build a declaration for the function which this function will
- // return a pointer to.
- // FIXME: Should the "thunk" actually be part of the AST? That would allow
- // the conversion to function pointer to be constexpr...
- std::string MangledName =
- (llvm::Twine(CurFn->getName()) + "_lambdacallthunk").str();
- llvm::Function *Fn =
- llvm::Function::Create(FnLLVMTy, llvm::Function::InternalLinkage,
- MangledName, &CGM.getModule());
-
- // Emit the definition of the new function.
- CodeGenFunction(CGM).EmitLambdaThunkBody(Fn, FnInfo, Lambda);
- return Fn;
-}
-
-void CodeGenFunction::EmitLambdaToFunctionPointerBody(FunctionArgList &Args) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurFuncDecl);
- EmitReturnOfRValue(RValue::get(EmitLambdaConvertedFnPtr(MD)),
- MD->getResultType());
+ EmitLambdaDelegatingInvokeBody(MD);
}