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"
@@ -751,10 +752,10 @@ tryEmitAsBridgingConversion(SILGenFunction &SGF, Expr *E, bool isExplicit,
751
752
auto subExpr = result.SubExpr ;
752
753
753
754
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);
758
759
759
760
// Only use this special pattern for AnyErasure conversions when we're
760
761
// emitting into a peephole.
@@ -1731,11 +1732,21 @@ static ManagedValue emitAnyClosureExpr(SILGenFunction &SGF, Expr *e,
1731
1732
}
1732
1733
}
1733
1734
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
+
1739
1750
ManagedValue result;
1740
1751
1741
1752
// We're converting between C function pointer types. They better be
@@ -1770,9 +1781,9 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
1770
1781
return result;
1771
1782
}
1772
1783
1773
- static
1774
- ManagedValue emitCFunctionPointer (SILGenFunction &SGF ,
1775
- FunctionConversionExpr *conversionExpr ) {
1784
+ static ManagedValue emitCFunctionPointer (SILGenFunction &SGF,
1785
+ FunctionConversionExpr *conversionExpr ,
1786
+ SGFContext C ) {
1776
1787
auto expr = conversionExpr->getSubExpr ();
1777
1788
1778
1789
// Look through base-ignored exprs to get to the function ref.
@@ -1806,20 +1817,33 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
1806
1817
#endif
1807
1818
semanticExpr = conv->getSubExpr ()->getSemanticsProvidingExpr ();
1808
1819
}
1809
-
1820
+
1821
+ const clang::Type *destFnType = nullptr ;
1822
+
1810
1823
if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
1811
1824
setLocFromConcreteDeclRef (declRef->getDeclRef ());
1812
1825
} else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
1813
1826
setLocFromConcreteDeclRef (memberRef->getMember ());
1814
1827
} 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
+ });
1823
1847
} else {
1824
1848
llvm_unreachable (" c function pointer converted from a non-concrete decl ref" );
1825
1849
}
@@ -1855,13 +1879,10 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
1855
1879
}
1856
1880
1857
1881
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
+ });
1865
1886
}
1866
1887
1867
1888
// Change the representation without changing the signature or
@@ -2118,7 +2139,7 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
2118
2139
FunctionTypeRepresentation::CFunctionPointer) {
2119
2140
// A "conversion" of a DeclRef a C function pointer is done by referencing
2120
2141
// the thunk (or original C function) with the C calling convention.
2121
- result = emitCFunctionPointer (SGF, e);
2142
+ result = emitCFunctionPointer (SGF, e, C );
2122
2143
} else {
2123
2144
// Ok, we're converting a C function pointer value to another C function
2124
2145
// pointer.
@@ -2128,10 +2149,9 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
2128
2149
2129
2150
// Possibly bitcast the C function pointer to account for ABI-compatible
2130
2151
// 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; });
2135
2155
}
2136
2156
return RValue (SGF, e, result);
2137
2157
}
0 commit comments