46
46
#include " swift/Basic/Defer.h"
47
47
#include " swift/Basic/SourceManager.h"
48
48
#include " swift/Basic/type_traits.h"
49
+ #include " swift/SIL/AbstractionPattern.h"
49
50
#include " swift/SIL/Consumption.h"
50
51
#include " swift/SIL/DynamicCasts.h"
51
52
#include " swift/SIL/SILArgument.h"
@@ -749,10 +750,10 @@ tryEmitAsBridgingConversion(SILGenFunction &SGF, Expr *E, bool isExplicit,
749
750
auto subExpr = result.SubExpr ;
750
751
751
752
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);
756
757
757
758
// Only use this special pattern for AnyErasure conversions when we're
758
759
// emitting into a peephole.
@@ -1723,11 +1724,21 @@ static ManagedValue emitAnyClosureExpr(SILGenFunction &SGF, Expr *e,
1723
1724
}
1724
1725
}
1725
1726
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
+
1731
1742
ManagedValue result;
1732
1743
1733
1744
// We're converting between C function pointer types. They better be
@@ -1762,9 +1773,9 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
1762
1773
return result;
1763
1774
}
1764
1775
1765
- static
1766
- ManagedValue emitCFunctionPointer (SILGenFunction &SGF ,
1767
- FunctionConversionExpr *conversionExpr ) {
1776
+ static ManagedValue emitCFunctionPointer (SILGenFunction &SGF,
1777
+ FunctionConversionExpr *conversionExpr ,
1778
+ SGFContext C ) {
1768
1779
auto expr = conversionExpr->getSubExpr ();
1769
1780
1770
1781
// Look through base-ignored exprs to get to the function ref.
@@ -1798,20 +1809,33 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
1798
1809
#endif
1799
1810
semanticExpr = conv->getSubExpr ()->getSemanticsProvidingExpr ();
1800
1811
}
1801
-
1812
+
1813
+ const clang::Type *destFnType = nullptr ;
1814
+
1802
1815
if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
1803
1816
setLocFromConcreteDeclRef (declRef->getDeclRef ());
1804
1817
} else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
1805
1818
setLocFromConcreteDeclRef (memberRef->getMember ());
1806
1819
} 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
+ });
1815
1839
} else {
1816
1840
llvm_unreachable (" c function pointer converted from a non-concrete decl ref" );
1817
1841
}
@@ -1847,13 +1871,10 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
1847
1871
}
1848
1872
1849
1873
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
+ });
1857
1878
}
1858
1879
1859
1880
// Change the representation without changing the signature or
@@ -2110,7 +2131,7 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
2110
2131
FunctionTypeRepresentation::CFunctionPointer) {
2111
2132
// A "conversion" of a DeclRef a C function pointer is done by referencing
2112
2133
// the thunk (or original C function) with the C calling convention.
2113
- result = emitCFunctionPointer (SGF, e);
2134
+ result = emitCFunctionPointer (SGF, e, C );
2114
2135
} else {
2115
2136
// Ok, we're converting a C function pointer value to another C function
2116
2137
// pointer.
@@ -2120,10 +2141,9 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
2120
2141
2121
2142
// Possibly bitcast the C function pointer to account for ABI-compatible
2122
2143
// 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; });
2127
2147
}
2128
2148
return RValue (SGF, e, result);
2129
2149
}
0 commit comments