1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: %target-swiftxx-frontend -emit-ir -I %t/Inputs -validate-tbd-against-ir=none %t/test.swift | %FileCheck %s
// RUN: %target-swiftxx-frontend -verify -emit-ir -I %t/Inputs -validate-tbd-against-ir=none %t/test.swift -Xcc -DDELETED -o /dev/null
//--- Inputs/module.modulemap
module VtableDestructorRef {
header "test.h"
requires cplusplus
}
//--- Inputs/test.h
namespace impl {
#ifdef DELETED
template<class T>
class BaseClass
{
public:
~BaseClass() = delete;
};
template<class Fp, class T>
class Func: public BaseClass<T>
{
Fp x;
public:
inline explicit Func(Fp x);
Func(const Func &) = delete;
~Func();
};
#else
template<class T>
class BaseClass
{
public:
virtual ~BaseClass() {}
};
template<class Fp, class T>
class Func: public BaseClass<T>
{
Fp x;
public:
inline explicit Func(Fp x) : x(x) {}
};
#endif
template <class _Fp> class ValueFunc;
template <class _Rp, class... _ArgTypes> class ValueFunc<_Rp(_ArgTypes...)>
{
typedef impl::BaseClass<_Rp(_ArgTypes...)> FuncTy;
FuncTy* _Nullable f;
public:
template <class _Fp>
ValueFunc(_Fp fp) {
typedef impl::Func<_Fp, _Rp(_ArgTypes...)> _Fun;
f = ::new _Fun(fp);
}
ValueFunc(ValueFunc&& other) {
if (other.f == nullptr)
f = nullptr;
else
{
f = other.f;
other.f = nullptr;
}
}
};
template<class _Rp>
class Function;
template<class _Rp, class ..._ArgTypes>
class Function<_Rp(_ArgTypes...)> {
ValueFunc<_Rp(_ArgTypes...)> f;
public:
template<class _Fp>
Function(_Fp);
};
template <class _Rp, class... _ArgTypes>
template <class _Fp>
Function<_Rp(_ArgTypes...)>::Function(_Fp f) : f(f) {}
}
class MyFutureBase {
public:
void OnCompletion(impl::Function<void(const MyFutureBase&)> callback) const;
};
template<class T>
class MyFuture : public MyFutureBase {
public:
void OnCompletion(
void (* _Nonnull completion)(void * _Nullable),
void * _Nullable user_data) const {
MyFutureBase::OnCompletion(
[completion, user_data](const MyFutureBase&) {
completion(user_data);
});
}
};
using MyFutureInt = MyFuture<int>;
//--- test.swift
import VtableDestructorRef
public func test() {
let f = MyFutureInt()
f.OnCompletion({ _ in
print("done")
}, nil)
}
// Make sure we reach the virtual destructor of 'Func'.
// CHECK: define linkonce_odr {{.*}} @{{_ZN4impl4FuncIZNK8MyFutureIiE12OnCompletionEPFvPvES3_EUlRK12MyFutureBaseE_FvS8_EED2Ev|"\?\?1\?\$BaseClass@\$\$A6AXAEBVMyFutureBase@@@Z@impl@@UEAA@XZ"}}
|