4646#include " swift/Basic/Defer.h"
4747#include " swift/Basic/SourceManager.h"
4848#include " swift/Basic/type_traits.h"
49+ #include " swift/SIL/AbstractionPattern.h"
4950#include " swift/SIL/Consumption.h"
5051#include " swift/SIL/DynamicCasts.h"
5152#include " swift/SIL/SILArgument.h"
@@ -751,10 +752,10 @@ tryEmitAsBridgingConversion(SILGenFunction &SGF, Expr *E, bool isExplicit,
751752 auto subExpr = result.SubExpr ;
752753
753754 CanType resultType = E->getType ()->getCanonicalType ();
754- Conversion conversion =
755- Conversion::getBridging ( kind, subExpr->getType ()->getCanonicalType (),
756- resultType, SGF.getLoweredType (resultType),
757- isExplicit);
755+ Conversion conversion = Conversion::getBridging (
756+ kind, subExpr->getType ()->getCanonicalType (), resultType ,
757+ SGF.getLoweredType (resultType), AbstractionPattern (subExpr-> getType () ),
758+ isExplicit);
758759
759760 // Only use this special pattern for AnyErasure conversions when we're
760761 // emitting into a peephole.
@@ -1731,11 +1732,21 @@ static ManagedValue emitAnyClosureExpr(SILGenFunction &SGF, Expr *e,
17311732 }
17321733}
17331734
1734- static ManagedValue convertCFunctionSignature (SILGenFunction &SGF,
1735- FunctionConversionExpr *e,
1736- SILType loweredResultTy,
1737- llvm::function_ref<ManagedValue ()> fnEmitter) {
1738- SILType loweredDestTy = SGF.getLoweredType (e->getType ());
1735+ static ManagedValue
1736+ convertCFunctionSignature (SILGenFunction &SGF, FunctionConversionExpr *e,
1737+ SILType loweredResultTy, SGFContext C,
1738+ llvm::function_ref<ManagedValue()> fnEmitter) {
1739+ SILType loweredDestTy;
1740+ auto destTy = e->getType ();
1741+ if (const auto init = C.getAsConversion ()) {
1742+ SILType loweredDestOptTy = init->getConversion ().getLoweredResultType ();
1743+ if (auto objTy = loweredDestOptTy.getOptionalObjectType ())
1744+ loweredDestTy = objTy;
1745+ else
1746+ loweredDestTy = loweredDestOptTy;
1747+ } else
1748+ loweredDestTy = SGF.getLoweredType (destTy);
1749+
17391750 ManagedValue result;
17401751
17411752 // We're converting between C function pointer types. They better be
@@ -1770,9 +1781,9 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
17701781 return result;
17711782}
17721783
1773- static
1774- ManagedValue emitCFunctionPointer (SILGenFunction &SGF ,
1775- FunctionConversionExpr *conversionExpr ) {
1784+ static ManagedValue emitCFunctionPointer (SILGenFunction &SGF,
1785+ FunctionConversionExpr *conversionExpr ,
1786+ SGFContext C ) {
17761787 auto expr = conversionExpr->getSubExpr ();
17771788
17781789 // Look through base-ignored exprs to get to the function ref.
@@ -1806,20 +1817,33 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
18061817#endif
18071818 semanticExpr = conv->getSubExpr ()->getSemanticsProvidingExpr ();
18081819 }
1809-
1820+
1821+ const clang::Type *destFnType = nullptr ;
1822+
18101823 if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
18111824 setLocFromConcreteDeclRef (declRef->getDeclRef ());
18121825 } else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
18131826 setLocFromConcreteDeclRef (memberRef->getMember ());
18141827 } else if (isAnyClosureExpr (semanticExpr)) {
1815- (void ) emitAnyClosureExpr (SGF, semanticExpr,
1816- [&](AbstractClosureExpr *closure) {
1817- // Emit the closure body.
1818- SGF.SGM .emitClosure (closure, SGF.getClosureTypeInfo (closure));
1819-
1820- loc = closure;
1821- return ManagedValue ();
1822- });
1828+ if (auto init = C.getAsConversion ()) {
1829+ auto conv = init->getConversion ();
1830+ auto origParamType = conv.getBridgingOriginalInputType ();
1831+ if (origParamType.isClangType ())
1832+ destFnType = origParamType.getClangType ();
1833+ }
1834+ (void )emitAnyClosureExpr (
1835+ SGF, semanticExpr, [&](AbstractClosureExpr *closure) {
1836+ // Emit the closure body.
1837+ auto functionInfo = SGF.getClosureTypeInfo (closure);
1838+ if (destFnType) {
1839+ functionInfo.OrigType =
1840+ AbstractionPattern (functionInfo.OrigType .getType (), destFnType);
1841+ SGF.SGM .Types .withClosureTypeInfo (closure, functionInfo, [] {});
1842+ }
1843+ SGF.SGM .emitClosure (closure, functionInfo);
1844+ loc = closure;
1845+ return ManagedValue::forInContext ();
1846+ });
18231847 } else {
18241848 llvm_unreachable (" c function pointer converted from a non-concrete decl ref" );
18251849 }
@@ -1855,13 +1879,10 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
18551879 }
18561880
18571881 return convertCFunctionSignature (
1858- SGF, conversionExpr,
1859- constantInfo.getSILType (),
1860- [&]() -> ManagedValue {
1861- SILValue cRef = SGF.emitGlobalFunctionRef (expr, constant);
1862- return ManagedValue::forObjectRValueWithoutOwnership (
1863- cRef);
1864- });
1882+ SGF, conversionExpr, constantInfo.getSILType (), C, [&]() -> ManagedValue {
1883+ SILValue cRef = SGF.emitGlobalFunctionRef (expr, constant);
1884+ return ManagedValue::forObjectRValueWithoutOwnership (cRef);
1885+ });
18651886}
18661887
18671888// Change the representation without changing the signature or
@@ -2118,7 +2139,7 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21182139 FunctionTypeRepresentation::CFunctionPointer) {
21192140 // A "conversion" of a DeclRef a C function pointer is done by referencing
21202141 // the thunk (or original C function) with the C calling convention.
2121- result = emitCFunctionPointer (SGF, e);
2142+ result = emitCFunctionPointer (SGF, e, C );
21222143 } else {
21232144 // Ok, we're converting a C function pointer value to another C function
21242145 // pointer.
@@ -2128,10 +2149,9 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21282149
21292150 // Possibly bitcast the C function pointer to account for ABI-compatible
21302151 // parameter and result type conversions
2131- result = convertCFunctionSignature (SGF, e, result.getType (),
2132- [&]() -> ManagedValue {
2133- return result;
2134- });
2152+ result =
2153+ convertCFunctionSignature (SGF, e, result.getType (), C,
2154+ [&]() -> ManagedValue { return result; });
21352155 }
21362156 return RValue (SGF, e, result);
21372157 }
0 commit comments