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"
@@ -749,10 +750,10 @@ tryEmitAsBridgingConversion(SILGenFunction &SGF, Expr *E, bool isExplicit,
749750 auto subExpr = result.SubExpr ;
750751
751752 CanType resultType = E->getType ()->getCanonicalType ();
752- Conversion conversion =
753- Conversion::getBridging ( kind, subExpr->getType ()->getCanonicalType (),
754- resultType, SGF.getLoweredType (resultType),
755- isExplicit);
753+ Conversion conversion = Conversion::getBridging (
754+ kind, subExpr->getType ()->getCanonicalType (), resultType ,
755+ SGF.getLoweredType (resultType), AbstractionPattern (subExpr-> getType () ),
756+ isExplicit);
756757
757758 // Only use this special pattern for AnyErasure conversions when we're
758759 // emitting into a peephole.
@@ -1723,11 +1724,21 @@ static ManagedValue emitAnyClosureExpr(SILGenFunction &SGF, Expr *e,
17231724 }
17241725}
17251726
1726- static ManagedValue convertCFunctionSignature (SILGenFunction &SGF,
1727- FunctionConversionExpr *e,
1728- SILType loweredResultTy,
1729- llvm::function_ref<ManagedValue ()> fnEmitter) {
1730- SILType loweredDestTy = SGF.getLoweredType (e->getType ());
1727+ static ManagedValue
1728+ convertCFunctionSignature (SILGenFunction &SGF, FunctionConversionExpr *e,
1729+ SILType loweredResultTy, SGFContext C,
1730+ llvm::function_ref<ManagedValue()> fnEmitter) {
1731+ SILType loweredDestTy;
1732+ auto destTy = e->getType ();
1733+ if (const auto init = C.getAsConversion ()) {
1734+ SILType loweredDestOptTy = init->getConversion ().getLoweredResultType ();
1735+ if (auto objTy = loweredDestOptTy.getOptionalObjectType ())
1736+ loweredDestTy = objTy;
1737+ else
1738+ loweredDestTy = loweredDestOptTy;
1739+ } else
1740+ loweredDestTy = SGF.getLoweredType (destTy);
1741+
17311742 ManagedValue result;
17321743
17331744 // We're converting between C function pointer types. They better be
@@ -1762,9 +1773,9 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
17621773 return result;
17631774}
17641775
1765- static
1766- ManagedValue emitCFunctionPointer (SILGenFunction &SGF ,
1767- FunctionConversionExpr *conversionExpr ) {
1776+ static ManagedValue emitCFunctionPointer (SILGenFunction &SGF,
1777+ FunctionConversionExpr *conversionExpr ,
1778+ SGFContext C ) {
17681779 auto expr = conversionExpr->getSubExpr ();
17691780
17701781 // Look through base-ignored exprs to get to the function ref.
@@ -1798,20 +1809,33 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
17981809#endif
17991810 semanticExpr = conv->getSubExpr ()->getSemanticsProvidingExpr ();
18001811 }
1801-
1812+
1813+ const clang::Type *destFnType = nullptr ;
1814+
18021815 if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
18031816 setLocFromConcreteDeclRef (declRef->getDeclRef ());
18041817 } else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
18051818 setLocFromConcreteDeclRef (memberRef->getMember ());
18061819 } else if (isAnyClosureExpr (semanticExpr)) {
1807- (void ) emitAnyClosureExpr (SGF, semanticExpr,
1808- [&](AbstractClosureExpr *closure) {
1809- // Emit the closure body.
1810- SGF.SGM .emitClosure (closure, SGF.getClosureTypeInfo (closure));
1811-
1812- loc = closure;
1813- return ManagedValue ();
1814- });
1820+ if (auto init = C.getAsConversion ()) {
1821+ auto conv = init->getConversion ();
1822+ auto origParamType = conv.getBridgingOriginalInputType ();
1823+ if (origParamType.isClangType ())
1824+ destFnType = origParamType.getClangType ();
1825+ }
1826+ (void )emitAnyClosureExpr (
1827+ SGF, semanticExpr, [&](AbstractClosureExpr *closure) {
1828+ // Emit the closure body.
1829+ auto functionInfo = SGF.getClosureTypeInfo (closure);
1830+ if (destFnType) {
1831+ functionInfo.OrigType =
1832+ AbstractionPattern (functionInfo.OrigType .getType (), destFnType);
1833+ SGF.SGM .Types .withClosureTypeInfo (closure, functionInfo, [] {});
1834+ }
1835+ SGF.SGM .emitClosure (closure, functionInfo);
1836+ loc = closure;
1837+ return ManagedValue::forInContext ();
1838+ });
18151839 } else {
18161840 llvm_unreachable (" c function pointer converted from a non-concrete decl ref" );
18171841 }
@@ -1847,13 +1871,10 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
18471871 }
18481872
18491873 return convertCFunctionSignature (
1850- SGF, conversionExpr,
1851- constantInfo.getSILType (),
1852- [&]() -> ManagedValue {
1853- SILValue cRef = SGF.emitGlobalFunctionRef (expr, constant);
1854- return ManagedValue::forObjectRValueWithoutOwnership (
1855- cRef);
1856- });
1874+ SGF, conversionExpr, constantInfo.getSILType (), C, [&]() -> ManagedValue {
1875+ SILValue cRef = SGF.emitGlobalFunctionRef (expr, constant);
1876+ return ManagedValue::forObjectRValueWithoutOwnership (cRef);
1877+ });
18571878}
18581879
18591880// Change the representation without changing the signature or
@@ -2110,7 +2131,7 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21102131 FunctionTypeRepresentation::CFunctionPointer) {
21112132 // A "conversion" of a DeclRef a C function pointer is done by referencing
21122133 // the thunk (or original C function) with the C calling convention.
2113- result = emitCFunctionPointer (SGF, e);
2134+ result = emitCFunctionPointer (SGF, e, C );
21142135 } else {
21152136 // Ok, we're converting a C function pointer value to another C function
21162137 // pointer.
@@ -2120,10 +2141,9 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21202141
21212142 // Possibly bitcast the C function pointer to account for ABI-compatible
21222143 // parameter and result type conversions
2123- result = convertCFunctionSignature (SGF, e, result.getType (),
2124- [&]() -> ManagedValue {
2125- return result;
2126- });
2144+ result =
2145+ convertCFunctionSignature (SGF, e, result.getType (), C,
2146+ [&]() -> ManagedValue { return result; });
21272147 }
21282148 return RValue (SGF, e, result);
21292149 }
0 commit comments