diff --git a/include/swift/SIL/SILBridging.h b/include/swift/SIL/SILBridging.h index bd80b32860b5b..2647a3cb7b098 100644 --- a/include/swift/SIL/SILBridging.h +++ b/include/swift/SIL/SILBridging.h @@ -927,7 +927,7 @@ struct BridgedSuccessorArray { }; struct BridgedDeclRef { - uint64_t storage[4]; + uint64_t storage[3]; BRIDGED_INLINE BridgedDeclRef(swift::SILDeclRef declRef); BRIDGED_INLINE swift::SILDeclRef unbridged() const; @@ -938,7 +938,7 @@ struct BridgedDeclRef { }; struct BridgedVTableEntry { - uint64_t storage[6]; + uint64_t storage[5]; enum class Kind { Normal, @@ -980,7 +980,7 @@ struct OptionalBridgedVTable { }; struct BridgedWitnessTableEntry { - uint64_t storage[6]; + uint64_t storage[5]; enum class Kind { invalid, diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h index 390fcacf1ff54..6991c53ea9a79 100644 --- a/include/swift/SIL/SILDeclRef.h +++ b/include/swift/SIL/SILDeclRef.h @@ -32,10 +32,6 @@ namespace llvm { class raw_ostream; } -namespace clang { -class Type; -} - namespace swift { enum class EffectsKind : uint8_t; class AbstractFunctionDecl; @@ -212,9 +208,6 @@ struct SILDeclRef { const GenericSignatureImpl *, CustomAttr *> pointer; - // Type of closure thunk. - const clang::Type *thunkType = nullptr; - /// Returns the type of AST node location being stored by the SILDeclRef. LocKind getLocKind() const { if (loc.is()) @@ -268,10 +261,11 @@ struct SILDeclRef { /// for the containing ClassDecl. /// - If 'loc' is a global VarDecl, this returns its GlobalAccessor /// SILDeclRef. - explicit SILDeclRef(Loc loc, bool isForeign = false, - bool isDistributed = false, - bool isDistributedLocal = false, - const clang::Type *thunkType = nullptr); + explicit SILDeclRef( + Loc loc, + bool isForeign = false, + bool isDistributed = false, + bool isDistributedLocal = false); /// See above put produces a prespecialization according to the signature. explicit SILDeclRef(Loc loc, GenericSignature prespecializationSig); diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 5d1f5d9304909..32048d47e3251 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -135,15 +135,11 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind, bool isForeign, isAsyncLetClosure(0), pointer(derivativeId) {} SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, - bool asDistributed, bool asDistributedKnownToBeLocal, - const clang::Type *thunkType) + bool asDistributed, bool asDistributedKnownToBeLocal) : isRuntimeAccessible(false), backDeploymentKind(SILDeclRef::BackDeploymentKind::None), defaultArgIndex(0), isAsyncLetClosure(0), - pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr), - thunkType(thunkType) { - assert((!thunkType || baseLoc.is()) && - "thunk type is needed only for closures"); + pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr) { if (auto *vd = baseLoc.dyn_cast()) { if (auto *fd = dyn_cast(vd)) { // Map FuncDecls directly to Func SILDeclRefs. @@ -173,8 +169,6 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, llvm_unreachable("invalid loc decl for SILDeclRef!"); } } else if (auto *ACE = baseLoc.dyn_cast()) { - assert((!asForeign || thunkType) && - "thunk type needed for foreign type for closures"); loc = ACE; kind = Kind::Func; if (ACE->getASTContext().LangOpts.hasFeature( diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 2ab1bba3f8be3..a9d1098c551c4 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -3991,10 +3991,12 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant( // The type of the native-to-foreign thunk for a swift closure. if (constant.isForeign && constant.hasClosureExpr() && shouldStoreClangType(TC.getDeclRefRepresentation(constant))) { - assert(!extInfoBuilder.getClangTypeInfo().empty() && - "clang type not found"); - AbstractionPattern pattern = AbstractionPattern( - origLoweredInterfaceType, extInfoBuilder.getClangTypeInfo().getType()); + auto clangType = TC.Context.getClangFunctionType( + origLoweredInterfaceType->getParams(), + origLoweredInterfaceType->getResult(), + FunctionTypeRepresentation::CFunctionPointer); + AbstractionPattern pattern = + AbstractionPattern(origLoweredInterfaceType, clangType); return getSILFunctionTypeForAbstractCFunction( TC, pattern, origLoweredInterfaceType, extInfoBuilder, constant); } @@ -4502,13 +4504,9 @@ getAbstractionPatternForConstant(ASTContext &ctx, SILDeclRef constant, if (!constant.isForeign) return AbstractionPattern(fnType); - if (constant.thunkType) - return AbstractionPattern(fnType, constant.thunkType); - auto bridgedFn = getBridgedFunction(constant); if (!bridgedFn) return AbstractionPattern(fnType); - const clang::Decl *clangDecl = bridgedFn->getClangDecl(); if (!clangDecl) return AbstractionPattern(fnType); diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 6a7545049ca5f..ff233994c533c 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -1315,9 +1315,8 @@ static SILValue emitObjCUnconsumedArgument(SILGenFunction &SGF, SILLocation loc, SILValue arg) { auto &lowering = SGF.getTypeLowering(arg->getType()); - // If arg is non-trivial and has an address type, make a +1 copy and operate - // on that. - if (!lowering.isTrivial() && arg->getType().isAddress()) { + // If address-only, make a +1 copy and operate on that. + if (lowering.isAddressOnly() && SGF.useLoweredAddresses()) { auto tmp = SGF.emitTemporaryAllocation(loc, arg->getType().getObjectType()); SGF.B.createCopyAddr(loc, arg, tmp, IsNotTake, IsInitialization); return tmp; @@ -1449,11 +1448,6 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk, auto buf = SGF.emitTemporaryAllocation(loc, native.getType()); native.forwardInto(SGF, loc, buf); native = SGF.emitManagedBufferWithCleanup(buf); - } else if (!fnConv.isSILIndirect(nativeInputs[i]) && - native.getType().isAddress()) { - // Load the value if the argument has an address type and the native - // function expects the argument to be passed directly. - native = SGF.emitManagedLoadCopy(loc, native.getValue()); } if (nativeInputs[i].isConsumedInCaller()) { diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 851fdfb2006ae..9e4f24313ca0b 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1723,19 +1723,7 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF, FunctionConversionExpr *e, SILType loweredResultTy, llvm::function_ref fnEmitter) { - SILType loweredDestTy; - auto destTy = e->getType(); - auto clangInfo = - destTy->castTo()->getExtInfo().getClangTypeInfo(); - if (clangInfo.empty()) - loweredDestTy = SGF.getLoweredType(destTy); - else - // This won't be necessary after we stop dropping clang types when - // canonicalizing function types. - loweredDestTy = SGF.getLoweredType( - AbstractionPattern(destTy->getCanonicalType(), clangInfo.getType()), - destTy); - + SILType loweredDestTy = SGF.getLoweredType(e->getType()); ManagedValue result; // We're converting between C function pointer types. They better be @@ -1806,9 +1794,7 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF, #endif semanticExpr = conv->getSubExpr()->getSemanticsProvidingExpr(); } - - const clang::Type *destFnType = nullptr; - + if (auto declRef = dyn_cast(semanticExpr)) { setLocFromConcreteDeclRef(declRef->getDeclRef()); } else if (auto memberRef = dyn_cast(semanticExpr)) { @@ -1822,18 +1808,12 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF, loc = closure; return ManagedValue(); }); - auto clangInfo = conversionExpr->getType() - ->castTo() - ->getExtInfo() - .getClangTypeInfo(); - if (!clangInfo.empty()) - destFnType = clangInfo.getType(); } else { llvm_unreachable("c function pointer converted from a non-concrete decl ref"); } // Produce a reference to the C-compatible entry point for the function. - SILDeclRef constant(loc, /*foreign*/ true, false, false, destFnType); + SILDeclRef constant(loc, /*foreign*/ true); SILConstantInfo constantInfo = SGF.getConstantInfo(SGF.getTypeExpansionContext(), constant); diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 9ed70fc9e4d81..a80f90ba840dd 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -8176,6 +8176,9 @@ class SwiftToClangBasicReader : llvm::Expected ModuleFile::getClangType(ClangTypeID TID) { + if (!getContext().LangOpts.UseClangFunctionTypes) + return nullptr; + if (TID == 0) return nullptr; diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 7f5cbd5ca598d..da933c85bfe3e 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -5714,7 +5714,10 @@ class Serializer::TypeSerializer : public TypeVisitor { using namespace decls_block; auto resultType = S.addTypeRef(fnTy->getResult()); - auto clangType = S.addClangTypeRef(fnTy->getClangTypeInfo().getType()); + auto clangType = + S.getASTContext().LangOpts.UseClangFunctionTypes + ? S.addClangTypeRef(fnTy->getClangTypeInfo().getType()) + : ClangTypeID(0); auto isolation = encodeIsolation(fnTy->getIsolation()); diff --git a/test/Interop/Cxx/class/Inputs/closure.h b/test/Interop/Cxx/class/Inputs/closure.h index fa04d441f55df..7081ff54c7b08 100644 --- a/test/Interop/Cxx/class/Inputs/closure.h +++ b/test/Interop/Cxx/class/Inputs/closure.h @@ -10,10 +10,6 @@ struct NonTrivial { int *p; }; -struct Trivial { - int i; -}; - void cfunc(void (^ _Nonnull block)(NonTrivial)) noexcept { block(NonTrivial()); } @@ -49,13 +45,4 @@ void cfuncARCWeak(ARCWeak) noexcept; void (* _Nonnull getFnPtr() noexcept)(NonTrivial) noexcept; void (* _Nonnull getFnPtr2() noexcept)(ARCWeak) noexcept; -void cfuncConstRefNonTrivial(void (*_Nonnull)(const NonTrivial &)); -void cfuncConstRefTrivial(void (*_Nonnull)(const Trivial &)); -void blockConstRefNonTrivial(void (^_Nonnull)(const NonTrivial &)); -void blockConstRefTrivial(void (^_Nonnull)(const Trivial &)); -#if __OBJC__ -void cfuncConstRefStrong(void (*_Nonnull)(const ARCStrong &)); -void blockConstRefStrong(void (^_Nonnull)(const ARCStrong &)); -#endif - #endif // __CLOSURE__ diff --git a/test/Interop/Cxx/class/closure-thunk-macosx.swift b/test/Interop/Cxx/class/closure-thunk-macosx.swift index f8ce0a681e00c..3fedb04ca1328 100644 --- a/test/Interop/Cxx/class/closure-thunk-macosx.swift +++ b/test/Interop/Cxx/class/closure-thunk-macosx.swift @@ -35,88 +35,3 @@ public func testClosureToFuncPtr() { public func testClosureToBlockReturnNonTrivial() { cfuncReturnNonTrivial({() -> NonTrivial in return NonTrivial() }) } - -// CHECK-LABEL: sil private [thunk] [ossa] @$s4main22testConstRefNonTrivialyyFySo0eF0VcfU_To : $@convention(c) (@in_guaranteed NonTrivial) -> () { -// CHECK: bb0(%[[V0:.*]] : $*NonTrivial): -// CHECK: %[[V1:.*]] = alloc_stack $NonTrivial -// CHECK: copy_addr %[[V0]] to [init] %[[V1]] : $*NonTrivial -// CHECK: %[[V3:.*]] = function_ref @$s4main22testConstRefNonTrivialyyFySo0eF0VcfU_ : $@convention(thin) (@in_guaranteed NonTrivial) -> () -// CHECK: %[[V4:.*]] = apply %[[V3]](%[[V1]]) : $@convention(thin) (@in_guaranteed NonTrivial) -> () -// CHECK: destroy_addr %[[V1]] : $*NonTrivial -// CHECK: dealloc_stack %[[V1]] : $*NonTrivial -// CHECK: return %[[V4]] : $() - -public func testConstRefNonTrivial() { - cfuncConstRefNonTrivial({S in }); -} - -// CHECK-LABEL: sil private [thunk] [ossa] @$s4main19testConstRefTrivialyyFySo0E0VcfU_To : $@convention(c) (@in_guaranteed Trivial) -> () { -// CHECK: bb0(%[[V0:.*]] : $*Trivial): -// CHECK: %[[V1:.*]] = load [trivial] %[[V0]] : $*Trivial -// CHECK: %[[V2:.*]] = function_ref @$s4main19testConstRefTrivialyyFySo0E0VcfU_ : $@convention(thin) (Trivial) -> () -// CHECK: %[[V3:.*]] = apply %[[V2]](%[[V1]]) : $@convention(thin) (Trivial) -> () -// CHECK: return %[[V3]] : $() - -public func testConstRefTrivial() { - cfuncConstRefTrivial({S in }); -} - -// CHECK-LABEL: sil private [thunk] [ossa] @$s4main18testConstRefStrongyyFySo9ARCStrongVcfU_To : $@convention(c) (@in_guaranteed ARCStrong) -> () { -// CHECK: bb0(%[[V0:.*]] : $*ARCStrong): -// CHECK: %[[V1:.*]] = alloc_stack $ARCStrong -// CHECK: copy_addr %[[V0]] to [init] %[[V1]] : $*ARCStrong -// CHECK: %[[V3:.*]] = load [copy] %[[V1]] : $*ARCStrong -// CHECK: %[[V4:.*]] = begin_borrow %[[V3]] : $ARCStrong -// CHECK: %[[V5:.*]] = function_ref @$s4main18testConstRefStrongyyFySo9ARCStrongVcfU_ : $@convention(thin) (@guaranteed ARCStrong) -> () -// CHECK: %[[V6:.*]] = apply %[[V5]](%[[V4]]) : $@convention(thin) (@guaranteed ARCStrong) -> () -// CHECK: end_borrow %[[V4]] : $ARCStrong -// CHECK: destroy_value %[[V3]] : $ARCStrong -// CHECK: destroy_addr %[[V1]] : $*ARCStrong -// CHECK: dealloc_stack %[[V1]] : $*ARCStrong -// CHECK: return %[[V6]] : $() - -public func testConstRefStrong() { - cfuncConstRefStrong({S in }); -} - -// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSo10NonTrivialVIegn_ABIeyBn_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed NonTrivial) -> (), @in_guaranteed NonTrivial) -> () { -// CHECK: bb0(%[[V0:.*]] : $*@block_storage @callee_guaranteed (@in_guaranteed NonTrivial) -> (), %[[V1:.*]] : $*NonTrivial): -// CHECK: %[[V2:.*]] = project_block_storage %[[V0]] : $*@block_storage @callee_guaranteed (@in_guaranteed NonTrivial) -> () -// CHECK: %[[V3:.*]] = load [copy] %[[V2]] : $*@callee_guaranteed (@in_guaranteed NonTrivial) -> () -// CHECK: %[[V4:.*]] = begin_borrow %[[V3]] : $@callee_guaranteed (@in_guaranteed NonTrivial) -> () -// CHECK: apply %[[V4]](%[[V1]]) : $@callee_guaranteed (@in_guaranteed NonTrivial) -> () -// CHECK: end_borrow %[[V4]] : $@callee_guaranteed (@in_guaranteed NonTrivial) -> () -// CHECK: destroy_value %[[V3]] : $@callee_guaranteed (@in_guaranteed NonTrivial) -> () - -public func testBlockConstRefNonTrivial() { - blockConstRefNonTrivial({S in }); -} - -// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSo7TrivialVIegy_ABIeyBn_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (Trivial) -> (), @in_guaranteed Trivial) -> () { -// CHECK: bb0(%[[V0:.*]] : $*@block_storage @callee_guaranteed (Trivial) -> (), %[[V1:.*]] : $*Trivial): -// CHECK: %[[V2:.*]] = project_block_storage %[[V0]] : $*@block_storage @callee_guaranteed (Trivial) -> () -// CHECK: %[[V3:.*]] = load [copy] %[[V2]] : $*@callee_guaranteed (Trivial) -> () -// CHECK: %[[V4:.*]] = load [trivial] %[[V1]] : $*Trivial -// CHECK: %[[V5:.*]] = begin_borrow %[[V3]] : $@callee_guaranteed (Trivial) -> () -// CHECK: apply %[[V5]](%[[V4]]) : $@callee_guaranteed (Trivial) -> () -// CHECK: end_borrow %[[V5]] : $@callee_guaranteed (Trivial) -> () -// CHECK: destroy_value %[[V3]] : $@callee_guaranteed (Trivial) -> () - -public func testBlockConstRefTrivial() { - blockConstRefTrivial({S in }); -} - -// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSo9ARCStrongVIegg_ABIeyBn_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@guaranteed ARCStrong) -> (), @in_guaranteed ARCStrong) -> () { -// CHECK: bb0(%[[V0:.*]] : $*@block_storage @callee_guaranteed (@guaranteed ARCStrong) -> (), %[[V1:.*]] : $*ARCStrong): -// CHECK: %[[V2:.*]] = project_block_storage %[[V0]] : $*@block_storage @callee_guaranteed (@guaranteed ARCStrong) -> () -// CHECK: %[[V3:.*]] = load [copy] %[[V2]] : $*@callee_guaranteed (@guaranteed ARCStrong) -> () -// CHECK: %[[V4:.*]] = load_borrow %[[V1]] : $*ARCStrong -// CHECK: %[[V5:.*]] = begin_borrow %[[V3]] : $@callee_guaranteed (@guaranteed ARCStrong) -> () -// CHECK: apply %[[V5]](%[[V4]]) : $@callee_guaranteed (@guaranteed ARCStrong) -> () -// CHECK: end_borrow %[[V5]] : $@callee_guaranteed (@guaranteed ARCStrong) -> () -// CHECK: end_borrow %[[V4]] : $ARCStrong -// CHECK: destroy_value %[[V3]] : $@callee_guaranteed (@guaranteed ARCStrong) -> () - -public func testBlockConstRefStrong() { - blockConstRefStrong({S in }); -} diff --git a/test/Interop/Cxx/stdlib/use-std-function.swift b/test/Interop/Cxx/stdlib/use-std-function.swift index 05772fb337217..a2a6aaf0ce5f5 100644 --- a/test/Interop/Cxx/stdlib/use-std-function.swift +++ b/test/Interop/Cxx/stdlib/use-std-function.swift @@ -65,11 +65,12 @@ StdFunctionTestSuite.test("FunctionStringToString init from closure and pass as expectEqual(std.string("prefixabcabc"), res) } -StdFunctionTestSuite.test("FunctionStringToStringConstRef init from closure and pass as parameter") { - let res = invokeFunctionTwiceConstRef(.init({ $0 + std.string("abc") }), - std.string("prefix")) - expectEqual(std.string("prefixabcabc"), res) -} +// FIXME: assertion for address-only closure params (rdar://124501345) +//StdFunctionTestSuite.test("FunctionStringToStringConstRef init from closure and pass as parameter") { +// let res = invokeFunctionTwiceConstRef(.init({ $0 + std.string("abc") }), +// std.string("prefix")) +// expectEqual(std.string("prefixabcabc"), res) +//} #endif runAllTests() diff --git a/test/Serialization/Inputs/convention_c_function.swift b/test/Serialization/Inputs/convention_c_function.swift deleted file mode 100644 index 5ae74013b29ec..0000000000000 --- a/test/Serialization/Inputs/convention_c_function.swift +++ /dev/null @@ -1,3 +0,0 @@ -public func foo(fn: @convention(c) () -> ()) -> () { - fn() -} diff --git a/test/Serialization/clang-function-types-convention-c.swift b/test/Serialization/clang-function-types-convention-c.swift deleted file mode 100644 index 0e1a9b2e9710a..0000000000000 --- a/test/Serialization/clang-function-types-convention-c.swift +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %S/Inputs/convention_c_function.swift -// RUN: llvm-bcanalyzer %t/convention_c_function.swiftmodule | %FileCheck -check-prefix=CHECK-BCANALYZER %s -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -I %t %s | %FileCheck %s - -import convention_c_function - -// CHECK-BCANALYZER-LABEL: (INDEX_BLOCK): -// CHECK-BCANALYZER: CLANG_TYPE_OFFSETS - -// Test that the assertion in SILDeclRef doesn't fail. - -// CHECK-LABEL: sil [ossa] @$s4main3baryyF : $@convention(thin) () -> () { -// CHECK: %[[V0:.*]] = function_ref @$s4main3baryyFyycfU_To : $@convention(c) () -> () -// CHECK: %[[V1:.*]] = function_ref @$s21convention_c_function3foo2fnyyyXC_tF : $@convention(thin) (@convention(c) () -> ()) -> () -// CHECK: apply %[[V1]](%[[V0]]) : $@convention(thin) (@convention(c) () -> ()) -> () - -public func bar() { - foo(fn : {}) -} -