Skip to content

[cxx-interop] Avoid linker errors for multiple instantiations of a templated struct with non-type parameters #66957

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2647,11 +2647,34 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
appendIdentifier(protocol->getObjCRuntimeNameAsString());
} else if (auto ctsd = dyn_cast<clang::ClassTemplateSpecializationDecl>(namedDecl)) {
// If this is a `ClassTemplateSpecializationDecl`, it was
// imported as a Swift decl with `__CxxTemplateInst...` name.
// `ClassTemplateSpecializationDecl`'s name does not include information about
// template arguments, and in order to prevent name clashes we use the
// name of the Swift decl which does include template arguments.
appendIdentifier(nominal->getName().str());
// imported as a Swift decl with `X<...>` name. Some types will be
// imported as X<_>, for instance, if they have non-type templated
// parameters. To disambiguate different specializations of the same
// templated type, we use a different mangling mechanism for C++ template
// specializations.
auto &clangCtx = ctsd->getASTContext();
// Itanium mangler produces valid Swift identifiers, use it to generate a
// name for this instantiation.
std::unique_ptr<clang::MangleContext> clangMangler{
clang::ItaniumMangleContext::create(clangCtx,
clangCtx.getDiagnostics())};

llvm::SmallString<128> storage;
llvm::raw_svector_ostream buffer(storage);
clangMangler->mangleTypeName(clangCtx.getRecordType(ctsd), buffer);
// The Itanium mangler does not provide a way to get the mangled
// representation of a type. Instead, we call mangleTypeName() that
// returns the name of the RTTI typeinfo symbol, and remove the _ZTS
// prefix. Then we prepend __CxxTemplateInst to reduce chances of conflict
// with regular C and C++ structs.
llvm::SmallString<128> mangledNameStorage;
llvm::raw_svector_ostream mangledName(mangledNameStorage);
assert(buffer.str().take_front(4) == "_ZTS");
mangledName << CXX_TEMPLATE_INST_PREFIX << buffer.str().drop_front(4);

StringRef mangledId =
decl->getASTContext().AllocateCopy(mangledName.str());
appendIdentifier(mangledId.str());
} else {
appendIdentifier(namedDecl->getName());
}
Expand Down
12 changes: 6 additions & 6 deletions test/Interop/Cxx/namespace/class-inline-namespace-irgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension Parent.TypedefInInlineChild {
return ""
}
}
// CHECK: define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"()
// CHECK: define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11b7Child21e2InbC4IcEEV4testE6stringSSvg"()

extension Parent.InInlineChild {
func doSomething() {
Expand All @@ -70,22 +70,22 @@ extension Parent.InlineChild.InSecondInlineChild {
}
// define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO06SecondbC0O02IndbC0V4testE1ySivg"()

// CHECK: define hidden swiftcc {{.*}} @"$s4test3useySSSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"
// CHECK: define hidden swiftcc {{.*}} @"$s4test3useySSSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11d7Child21g2IndE4IcEEVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11b7Child21e2InbC4IcEEV4testE6stringSSvg"
func use(_ x: Parent.TypedefInInlineChild) -> String {
let s = x.string
return s
}

// CHECK: define hidden swiftcc {{.*}} @"$s4test4use2ySSSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"
// CHECK: define hidden swiftcc {{.*}} @"$s4test4use2ySSSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11d7Child21g2IndE4IcEEVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11b7Child21e2InbC4IcEEV4testE6stringSSvg"
func use2(_ x: Parent.InlineChild.TypedefInInlineChild) -> String {
let s = x.string
return s
}

// define swiftcc void @"$s4testAAyySo6ParentO11InlineChildO02IncD0VF"()
// CHECK: alloca %TSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV
// CHECK: alloca %TSo6ParentO11InlineChildO027__CxxTemplateInstN6Parent11b7Child21e2InbC4IcEEV
// CHECK: call {{.*}} @{{_ZN6Parent11InlineChild21TemplateInInlineChildIcEC|"\?\?0\?\$TemplateInInlineChild@D@InlineChild@Parent@@QEAA@XZ"}}
// CHECK: call swiftcc void @"$sSo6ParentO11InlineChildO02InbC0V4testE11doSomethingyyF"(
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO06SecondbC0O02IndbC0V4testE1xSivg"(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CxxStdlib

// CHECK: @"\01L_selector(UTF8String)"
// CHECK: @objc_msgSend
// CHECK: call swiftcc void @"$sSo3stdO3__1O0067basic_stringInt8char_traitsInt8allocatorInt8_FABErpaBGcqaGHerapGgqaV9CxxStdlibEyAFSPys4Int8VGSgcfC"
// CHECK: call swiftcc void @"$sSo3stdO3__1O056__CxxTemplateInstNSt3__112basic_stringIcNS_11char_traitsh15EENS_9allocatorH4EEEEV0B6StdlibEyAFSPys4Int8VGSgcfC"

let ObjCStr: NSString = "hello"
let CxxStr = std.string(ObjCStr.utf8String) // Should not crash here
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ using size_t = __SIZE_TYPE__;
template <class T, size_t Size> struct MagicArray { T t[Size]; };

typedef MagicArray<int, 2> MagicIntPair;
typedef MagicArray<int, 3> MagicIntTriple;

#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_NON_TYPE_PARAMETER_H
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ public func returnInstantiation() -> WrappedMagicInt {
return WrappedMagicInt()
}

// CHECK: $s4main20receiveInstantiationyySo0025MagicWrapperInt32_lsFCfibVzF(%TSo0025MagicWrapperInt32_lsFCfibV* ---> @$s4main20receiveInstantiationyySo0025MagicWrapperInt32_lsFCfibVzF(%TSo0025MagicWrapperInt32_lsFCfibV*
// CHECK: $s4main19returnInstantiationSo0025MagicWrapperInt32_lsFCfibVyF() ---> @$s4main19returnInstantiationSo0025MagicWrapperInt32_lsFCfibVyF()
// CHECK: $s4main20receiveInstantiationyySo34__CxxTemplateInst12MagicWrapperIiEVzF(%TSo34__CxxTemplateInst12MagicWrapperIiEV* ---> @$s4main20receiveInstantiationyySo34__CxxTemplateInst12MagicWrapperIiEVzF(%TSo34__CxxTemplateInst12MagicWrapperIiEV*
// CHECK: $s4main19returnInstantiationSo34__CxxTemplateInst12MagicWrapperIiEVyF() ---> @$s4main19returnInstantiationSo34__CxxTemplateInst12MagicWrapperIiEVyF()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-experimental-cxx-interop | %FileCheck %s

import ClassTemplateNonTypeParameter

let p = MagicIntPair()
let t = MagicIntTriple()

// CHECK: @"${{s4main1pSo36__CxxTemplateInst10MagicArrayIiLm2EEVvp|s4main1pSo36__CxxTemplateInst10MagicArrayIiLy2EEVvp}}"
// CHECK: @"${{s4main1tSo36__CxxTemplateInst10MagicArrayIiLm3EEVvp|s4main1tSo36__CxxTemplateInst10MagicArrayIiLy3EEVvp}}"
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ var TemplatesTestSuite = TestSuite("TemplatesTestSuite")
TemplatesTestSuite.test("typedeffed-non-type-parameter") {
let pair = MagicIntPair(t: (1, 2))
expectEqual(pair.t, (1, 2))

let triple = MagicIntTriple(t: (1, 2, 3))
expectEqual(triple.t, (1, 2, 3))
}

// TODO: This test doesn't work because Swift doesn't support defaulted generic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public func getMagicNumberForLinkageComparison() -> Any {
// CHECK: $sSo11MagicNumberVMf" = linkonce_odr hidden constant
// CHECK: $sSo11MagicNumberVML" = linkonce_odr hidden global

// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVWV" = linkonce_odr hidden constant
// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVMn" = linkonce_odr hidden constant
// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVMf" = linkonce_odr hidden constant
// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVML" = linkonce_odr hidden global
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVWV" = linkonce_odr hidden constant
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVMn" = linkonce_odr hidden constant
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVMf" = linkonce_odr hidden constant
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVML" = linkonce_odr hidden global

// CHECK: $sSo11MagicNumberVMB" = linkonce_odr hidden constant
// CHECK: $sSo11MagicNumberVMF" = linkonce_odr hidden constant

// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVMB" = linkonce_odr hidden constant
// CHECK: $sSo0031MagicWrapperMagicNumber_IJFJhAbVMF" = linkonce_odr hidden constant
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVMB" = linkonce_odr hidden constant
// CHECK: $sSo034__CxxTemplateInst12MagicWrapperI11D7NumberEVMF" = linkonce_odr hidden constant
6 changes: 3 additions & 3 deletions test/Interop/Cxx/templates/mangling-irgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import Mangling
public func receiveInstantiation(_ i: inout WrappedMagicInt) {}

// Don't forget to update manglings.txt when changing s4main20receiveInstantiationyySo34__CxxTemplateInst12MagicWrapperIiEVzF
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20receiveInstantiationyySo0025MagicWrapperInt32_lsFCfibVzF"(%TSo0025MagicWrapperInt32_lsFCfibV* nocapture dereferenceable(1) %0)
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20receiveInstantiationyySo34__CxxTemplateInst12MagicWrapperIiEVzF"(%TSo34__CxxTemplateInst12MagicWrapperIiEV* nocapture dereferenceable(1) %0)

public func receiveInstantiation(_ i: inout WrappedMagicBool) {}

// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20receiveInstantiationyySo0024MagicWrapperBool_npAIefbVzF"(%TSo0024MagicWrapperBool_npAIefbV* nocapture dereferenceable(1) %0)
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20receiveInstantiationyySo34__CxxTemplateInst12MagicWrapperIbEVzF"(%TSo34__CxxTemplateInst12MagicWrapperIbEV* nocapture dereferenceable(1) %0)

public func returnInstantiation() -> WrappedMagicInt {
return WrappedMagicInt()
}

// Don't forget to update manglings.txt when changing s4main19returnInstantiationSo34__CxxTemplateInst12MagicWrapperIiEVyF
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main19returnInstantiationSo0025MagicWrapperInt32_lsFCfibVyF"()
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main19returnInstantiationSo34__CxxTemplateInst12MagicWrapperIiEVyF"()

6 changes: 3 additions & 3 deletions test/Interop/Cxx/templates/mangling-silgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import Mangling
public func recvInstantiation(_ i: inout WrappedMagicInt) {}

// CHECK: // recvInstantiation(_:)
// CHECK: sil @$s4main17recvInstantiationyySo0025MagicWrapperInt32_lsFCfibVzF : $@convention(thin) (@inout MagicWrapper<Int32>) -> ()
// CHECK: sil @$s4main17recvInstantiationyySo34__CxxTemplateInst12MagicWrapperIiEVzF : $@convention(thin) (@inout MagicWrapper<Int32>) -> ()

public func recvInstantiation(_ i: inout WrappedMagicBool) {}

// CHECK: // recvInstantiation(_:)
// CHECK: sil @$s4main17recvInstantiationyySo0024MagicWrapperBool_npAIefbVzF : $@convention(thin) (@inout MagicWrapper<Bool>) -> ()
// CHECK: sil @$s4main17recvInstantiationyySo34__CxxTemplateInst12MagicWrapperIbEVzF : $@convention(thin) (@inout MagicWrapper<Bool>) -> ()

public func returnInstantiation() -> WrappedMagicInt {
return WrappedMagicInt()
}

// CHECK: // returnInstantiation()
// CHECK: sil @$s4main19returnInstantiationSo0025MagicWrapperInt32_lsFCfibVyF : $@convention(thin) () -> MagicWrapper<Int32>
// CHECK: sil @$s4main19returnInstantiationSo34__CxxTemplateInst12MagicWrapperIiEVyF : $@convention(thin) () -> MagicWrapper<Int32>
20 changes: 10 additions & 10 deletions test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,15 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: #endif


// CHECK: SWIFT_EXTERN void $s8UseCxxTy13retNonTrivialSo2nsO0031NonTrivialTemplateInt32_fbGJhubVyF(SWIFT_INDIRECT_RESULT void * _Nonnull) SWIFT_NOEXCEPT SWIFT_CALL; // retNonTrivial()
// CHECK: SWIFT_EXTERN void $s8UseCxxTy13retNonTrivialSo2nsO02__b18TemplateInstN2ns18efH4IiEEVyF(SWIFT_INDIRECT_RESULT void * _Nonnull) SWIFT_NOEXCEPT SWIFT_CALL; // retNonTrivial()
// CHECK: SWIFT_EXTERN struct swift_interop_returnStub_UseCxxTy_uint32_t_0_4 $s8UseCxxTy10retTrivialSo0E0VyF(void) SWIFT_NOEXCEPT SWIFT_CALL; // retTrivial()

// CHECK: ns::Immortal *_Nonnull retImmortal() noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: return _impl::$s8UseCxxTy11retImmortalSo2nsO0E0VyF();
// CHECK-NEXT: }

// CHECK: ns::ImmortalTemplate<int> *_Nonnull retImmortalTemplate() noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: return _impl::$s8UseCxxTy19retImmortalTemplateSo2nsO0029ImmortalTemplateInt32_hEFAhqbVyF();
// CHECK-NEXT: return _impl::$s8UseCxxTy19retImmortalTemplateSo2nsO02__bf10InstN2ns16eF4IiEEVyF();
// CHECK-NEXT: }

// CHECK: } // end namespace
Expand All @@ -173,7 +173,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: namespace _impl {
// CHECK-EMPTY:
// CHECK-NEXT: // Type metadata accessor for NonTrivialTemplateInt
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO0031NonTrivialTemplateInt32_fbGJhubVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC4IiEEVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-EMPTY:
// CHECK-EMPTY:
// CHECK-NEXT: } // namespace _impl
Expand All @@ -185,7 +185,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: template<>
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplateInt> {
// CHECK-NEXT: static SWIFT_INLINE_THUNK void * _Nonnull getTypeMetadata() {
// CHECK-NEXT: return _impl::$sSo2nsO0031NonTrivialTemplateInt32_fbGJhubVMa(0)._0;
// CHECK-NEXT: return _impl::$sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC4IiEEVMa(0)._0;
// CHECK-NEXT: }
// CHECK-NEXT: };
// CHECK-NEXT: namespace _impl{
Expand All @@ -200,7 +200,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK: SWIFT_INLINE_THUNK ns::NonTrivialTemplate<int> retNonTrivial() noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: alignas(alignof(ns::NonTrivialTemplate<int>)) char storage[sizeof(ns::NonTrivialTemplate<int>)];
// CHECK-NEXT: auto * _Nonnull storageObjectPtr = reinterpret_cast<ns::NonTrivialTemplate<int> *>(storage);
// CHECK-NEXT: _impl::$s8UseCxxTy13retNonTrivialSo2nsO0031NonTrivialTemplateInt32_fbGJhubVyF(storage);
// CHECK-NEXT: _impl::$s8UseCxxTy13retNonTrivialSo2nsO02__b18TemplateInstN2ns18efH4IiEEVyF(storage);
// CHECK-NEXT: ns::NonTrivialTemplate<int> result(static_cast<ns::NonTrivialTemplate<int> &&>(*storageObjectPtr));
// CHECK-NEXT: storageObjectPtr->~NonTrivialTemplate();
// CHECK-NEXT: return result;
Expand All @@ -212,7 +212,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: namespace _impl {
// CHECK-EMPTY:
// CHECK-NEXT: // Type metadata accessor for NonTrivialTemplateTrivial
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO0037NonTrivialTemplateTrivialinNS_CsGGkdcVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC20INS_11TrivialinNSEEEVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
// CHECK-EMPTY:
// CHECK-EMPTY:
// CHECK-NEXT: } // namespace _impl
Expand All @@ -224,7 +224,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: template<>
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplateTrivial> {
// CHECK-NEXT: static SWIFT_INLINE_THUNK void * _Nonnull getTypeMetadata() {
// CHECK-NEXT: return _impl::$sSo2nsO0037NonTrivialTemplateTrivialinNS_CsGGkdcVMa(0)._0;
// CHECK-NEXT: return _impl::$sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC20INS_11TrivialinNSEEEVMa(0)._0;
// CHECK-NEXT: }
// CHECK-NEXT: };
// CHECK-NEXT: namespace _impl{
Expand All @@ -239,7 +239,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: SWIFT_INLINE_THUNK ns::NonTrivialTemplate<ns::TrivialinNS> retNonTrivial2() noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
// CHECK-NEXT: alignas(alignof(ns::NonTrivialTemplate<ns::TrivialinNS>)) char storage[sizeof(ns::NonTrivialTemplate<ns::TrivialinNS>)];
// CHECK-NEXT: auto * _Nonnull storageObjectPtr = reinterpret_cast<ns::NonTrivialTemplate<ns::TrivialinNS> *>(storage);
// CHECK-NEXT: _impl::$s8UseCxxTy14retNonTrivial2So2nsO0037NonTrivialTemplateTrivialinNS_CsGGkdcVyF(storage);
// CHECK-NEXT: _impl::$s8UseCxxTy14retNonTrivial2So2nsO02__b18TemplateInstN2ns18e7TrivialH20INS_11TrivialinNSEEEVyF(storage);
// CHECK-NEXT: ns::NonTrivialTemplate<ns::TrivialinNS> result(static_cast<ns::NonTrivialTemplate<ns::TrivialinNS> &&>(*storageObjectPtr));
// CHECK-NEXT: storageObjectPtr->~NonTrivialTemplate();
// CHECK-NEXT: return result;
Expand Down Expand Up @@ -268,11 +268,11 @@ public func takeTrivialInout(_ x: inout Trivial) {
// CHECK-NEXT: }

// CHECK: void takeImmortalTemplate(ns::ImmortalTemplate<int> *_Nonnull x) noexcept SWIFT_SYMBOL({{.*}}) {
// CHECK-NEXT: return _impl::$s8UseCxxTy20takeImmortalTemplateyySo2nsO0029ImmortalTemplateInt32_hEFAhqbVF(x);
// CHECK-NEXT: return _impl::$s8UseCxxTy20takeImmortalTemplateyySo2nsO02__bf10InstN2ns16eF4IiEEVF(x);
// CHECK-NEXT: }

// CHECK: SWIFT_INLINE_THUNK void takeNonTrivial2(const ns::NonTrivialTemplate<ns::TrivialinNS>& x) noexcept SWIFT_SYMBOL({{.*}}) {
// CHECK-NEXT: return _impl::$s8UseCxxTy15takeNonTrivial2yySo2nsO0037NonTrivialTemplateTrivialinNS_CsGGkdcVF(swift::_impl::getOpaquePointer(x));
// CHECK-NEXT: return _impl::$s8UseCxxTy15takeNonTrivial2yySo2nsO02__b18TemplateInstN2ns18e7TrivialH20INS_11TrivialinNSEEEVF(swift::_impl::getOpaquePointer(x));
// CHECK-NEXT: }

// CHECK: SWIFT_INLINE_THUNK void takeTrivial(const Trivial& x) noexcept SWIFT_SYMBOL({{.*}}) {
Expand Down