3333#include " swift/SIL/SILArgument.h"
3434#include " swift/SIL/TypeLowering.h"
3535
36+ #include " clang/AST/ASTContext.h"
37+
3638using namespace swift ;
3739using namespace Lowering ;
3840
@@ -139,6 +141,46 @@ SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
139141 return B.createFunctionRefFor (loc, f);
140142}
141143
144+ static const clang::Type *prependParameterType (
145+ ASTContext &ctx,
146+ const clang::Type *oldBlockPtrTy,
147+ const clang::Type *newParameterTy) {
148+ if (!oldBlockPtrTy)
149+ return nullptr ;
150+
151+ SmallVector<clang::QualType, 4 > newParamTypes;
152+ newParamTypes.push_back (clang::QualType (newParameterTy, 0 ));
153+ clang::QualType returnType;
154+ clang::FunctionProtoType::ExtProtoInfo newExtProtoInfo{};
155+ using ExtParameterInfo = clang::FunctionProtoType::ExtParameterInfo;
156+ SmallVector<ExtParameterInfo, 4 > newExtParamInfos;
157+
158+ auto blockPtrTy = cast<clang::BlockPointerType>(oldBlockPtrTy);
159+ auto blockPointeeTy = blockPtrTy->getPointeeType ().getTypePtr ();
160+ if (auto fnNoProtoTy = dyn_cast<clang::FunctionNoProtoType>(blockPointeeTy)) {
161+ returnType = fnNoProtoTy->getReturnType ();
162+ newExtProtoInfo.ExtInfo = fnNoProtoTy->getExtInfo ();
163+ } else {
164+ auto fnProtoTy = cast<clang::FunctionProtoType>(blockPointeeTy);
165+ llvm::copy (fnProtoTy->getParamTypes (), std::back_inserter (newParamTypes));
166+ returnType = fnProtoTy->getReturnType ();
167+ newExtProtoInfo = fnProtoTy->getExtProtoInfo ();
168+ auto extParamInfos = fnProtoTy->getExtParameterInfosOrNull ();
169+ if (extParamInfos) {
170+ auto oldExtParamInfos =
171+ ArrayRef<ExtParameterInfo>(extParamInfos, fnProtoTy->getNumParams ());
172+ newExtParamInfos.push_back (clang::FunctionProtoType::ExtParameterInfo ());
173+ llvm::copy (oldExtParamInfos, std::back_inserter (newExtParamInfos));
174+ newExtProtoInfo.ExtParameterInfos = newExtParamInfos.data ();
175+ }
176+ }
177+
178+ auto &clangCtx = ctx.getClangModuleLoader ()->getClangASTContext ();
179+ auto newFnTy =
180+ clangCtx.getFunctionType (returnType, newParamTypes, newExtProtoInfo);
181+ return clangCtx.getPointerType (newFnTy).getTypePtr ();
182+ }
183+
142184SILFunction *
143185SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction (
144186 CanSILFunctionType blockType,
@@ -159,10 +201,17 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
159201 std::copy (blockType->getParameters ().begin (),
160202 blockType->getParameters ().end (),
161203 std::back_inserter (implArgs));
204+
205+ auto newClangTy = prependParameterType (
206+ getASTContext (),
207+ blockType->getClangTypeInfo ().getType (),
208+ getASTContext ().getClangTypeForIRGen (blockStorageTy));
162209
163210 auto implTy = SILFunctionType::get (GenericSignature (),
164- blockType->getExtInfo ()
165- .withRepresentation (SILFunctionTypeRepresentation::CFunctionPointer),
211+ blockType->getExtInfo ().intoBuilder ()
212+ .withRepresentation (SILFunctionTypeRepresentation::CFunctionPointer)
213+ .withClangFunctionType (newClangTy)
214+ .build (),
166215 SILCoroutineKind::None,
167216 ParameterConvention::Direct_Unowned,
168217 implArgs, {}, blockType->getResults (),
0 commit comments