@@ -681,6 +681,62 @@ static unsigned findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes(
681681 return firstNonEmpty;
682682}
683683
684+
685+ llvm::Function *irgen::getThinToThickForwarder (IRGenModule &IGM,
686+ const Optional<FunctionPointer> &staticFnPtr,
687+ const CanSILFunctionType origType) {
688+ auto origSig = IGM.getSignature (origType);
689+ llvm::FunctionType *origFnTy = origSig.getType ();
690+ auto origTy = origSig.getType ()->getPointerTo ();
691+
692+ llvm::SmallVector<llvm::Type *, 4 > thunkParams;
693+
694+ for (unsigned i = 0 ; i < origFnTy->getNumParams (); ++i)
695+ thunkParams.push_back (origFnTy->getParamType (i));
696+
697+ thunkParams.push_back (IGM.RefCountedPtrTy );
698+
699+ auto thunkType = llvm::FunctionType::get (origFnTy->getReturnType (),
700+ thunkParams,
701+ /* vararg*/ false );
702+
703+ StringRef FnName;
704+ if (staticFnPtr)
705+ FnName = staticFnPtr->getPointer ()->getName ();
706+
707+ IRGenMangler Mangler;
708+ std::string thunkName = Mangler.mangleThinToThickForwarder (FnName);
709+
710+
711+ // FIXME: Maybe cache the thunk by function and closure types?.
712+ llvm::Function *fwd =
713+ llvm::Function::Create (thunkType, llvm::Function::InternalLinkage,
714+ llvm::StringRef (thunkName), &IGM.Module );
715+
716+ fwd->setAttributes (origSig.getAttributes ());
717+ fwd->addAttribute (llvm::AttributeList::FirstArgIndex + origFnTy->getNumParams (), llvm::Attribute::SwiftSelf);
718+ IRGenFunction IGF (IGM, fwd);
719+ if (IGM.DebugInfo )
720+ IGM.DebugInfo ->emitArtificialFunction (IGF, fwd);
721+ auto args = IGF.collectParameters ();
722+ auto rawFnPtr = args.takeLast ();
723+
724+ // It comes out of the context as an i8*. Cast to the function type.
725+ rawFnPtr = IGF.Builder .CreateBitCast (rawFnPtr, origTy);
726+
727+ auto fnPtr = FunctionPointer (rawFnPtr, origSig);
728+
729+ auto result = IGF.Builder .CreateCall (fnPtr, args.claimAll ());
730+
731+ // Return the result, if we have one.
732+ if (result->getType ()->isVoidTy ())
733+ IGF.Builder .CreateRetVoid ();
734+ else
735+ IGF.Builder .CreateRet (result);
736+ return fwd;
737+ }
738+
739+
684740// / Emit the forwarding stub function for a partial application.
685741// /
686742// / If 'layout' is null, there is a single captured value of
0 commit comments