|
6 | 6 | #define JOIN2(x, y) x##y
|
7 | 7 | #define JOIN(x, y) JOIN2(x, y)
|
8 | 8 | #define UNIQ(name) JOIN(name, __LINE__)
|
9 |
| -#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } |
| 9 | +#define USEMEMFUNC(class, func) auto UNIQ(use) = &class::func; |
10 | 10 |
|
11 | 11 | template <class T>
|
12 | 12 | class c {
|
| 13 | + // MinGW-GCC does not apply 'dllexport' to inline member function in dll-exported template but clang does from long ago. |
13 | 14 | void f() {}
|
| 15 | + void g(); |
| 16 | + inline static int u = 0; |
| 17 | + static int v; |
14 | 18 | };
|
| 19 | +template <class T> void c<T>::g() {} |
| 20 | +template <class T> int c<T>::v = 0; |
15 | 21 |
|
| 22 | +// #1 |
16 | 23 | template class __declspec(dllexport) c<int>;
|
17 | 24 |
|
18 |
| -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv |
19 |
| - |
| 25 | +// #2 |
20 | 26 | extern template class __declspec(dllexport) c<char>;
|
21 | 27 | template class c<char>;
|
22 | 28 |
|
23 |
| -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv |
24 |
| - |
| 29 | +// #3 |
25 | 30 | extern template class c<double>;
|
26 |
| -template class __declspec(dllexport) c<double>; |
| 31 | +template class __declspec(dllexport) c<double>; // expected-warning {{ 'dllexport' attribute ignored on explicit instantiation definition }} |
27 | 32 |
|
28 |
| -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv |
29 | 33 |
|
30 | 34 | template <class T>
|
31 | 35 | struct outer {
|
32 |
| - void f(); |
| 36 | + void f() {} |
| 37 | + void g(); |
| 38 | + inline static int u = 0; |
| 39 | + static int v; |
| 40 | + // MinGW-GCC and Clang does not apply 'dllexport' to inner type and its sub-elements in template class. |
33 | 41 | struct inner {
|
34 |
| - void f(); |
| 42 | + void f() {} |
| 43 | + void g(); |
| 44 | + inline static int u = 0; |
| 45 | + static int v; |
35 | 46 | };
|
36 | 47 | };
|
37 | 48 |
|
38 |
| -template <class T> void outer<T>::f() {} |
39 |
| -template <class T> void outer<T>::inner::f() {} |
| 49 | +template <class T> void outer<T>::g() {} |
| 50 | +template <class T> void outer<T>::inner::g() {} |
| 51 | +template <class T> int outer<T>::v = 0; |
| 52 | +template <class T> int outer<T>::inner::v = 0; |
40 | 53 |
|
41 |
| -template class __declspec(dllexport) outer<int>; |
| 54 | +// #4 |
| 55 | +template struct __declspec(dllexport) outer<int>; |
42 | 56 |
|
43 |
| -// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv |
44 |
| -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv |
45 |
| - |
46 |
| -extern template class __declspec(dllimport) outer<char>; |
| 57 | +// #5 |
| 58 | +extern template struct __declspec(dllimport) outer<char>; |
47 | 59 | USEMEMFUNC(outer<char>, f)
|
| 60 | +USEMEMFUNC(outer<char>, g) |
| 61 | +USEMEMFUNC(outer<char>, u) |
| 62 | +USEMEMFUNC(outer<char>, v) |
48 | 63 | USEMEMFUNC(outer<char>::inner, f)
|
| 64 | +USEMEMFUNC(outer<char>::inner, g) |
| 65 | +USEMEMFUNC(outer<char>::inner, u) |
| 66 | +USEMEMFUNC(outer<char>::inner, v) |
| 67 | + |
| 68 | + |
| 69 | +// #1 variables |
| 70 | +// CHECK: @_ZN1cIiE1uE = {{.*}} dllexport {{.*}} |
| 71 | +// CHECK: @_ZN1cIiE1vE = {{.*}} dllexport {{.*}} |
| 72 | + |
| 73 | +// #2 variables |
| 74 | +// CHECK: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} |
| 75 | +// CHECK: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} |
| 76 | + |
| 77 | +// #3 variables |
| 78 | +// CHECK: @_ZN1cIdE1uE = {{.*}} |
| 79 | +// CHECK-NOT: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} |
| 80 | +// CHECK: @_ZN1cIdE1vE = {{.*}} |
| 81 | +// CHECK-NOT: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} |
| 82 | + |
| 83 | +// #4 variables |
| 84 | +// CHECK: @_ZN5outerIiE1uE = {{.*}} dllexport {{.*}} |
| 85 | +// CHECK: @_ZN5outerIiE1vE = {{.*}} dllexport {{.*}} |
| 86 | +// CHECK: @_ZN5outerIiE5inner1uE = {{.*}} |
| 87 | +// CHECK-NOT: @_ZN5outerIiE5inner1uE = {{.*}} dllexport {{.*}} |
| 88 | +// CHECK: @_ZN5outerIiE5inner1vE = {{.*}} |
| 89 | +// CHECK-NOT: @_ZN5outerIiE5inner1vE = {{.*}} dllexport {{.*}} |
| 90 | + |
| 91 | +// #5 variables |
| 92 | +// CHECK: @_ZN5outerIcE1uE = external dllimport {{.*}} |
| 93 | +// CHECK: @_ZN5outerIcE1vE = external dllimport {{.*}} |
| 94 | +// CHECK-NOT: @_ZN5outerIcE5inner1uE = dllimport {{.*}} |
| 95 | +// CHECK-NOT: @_ZN5outerIcE5inner1vE = dllimport {{.*}} |
| 96 | +// CHECK: @_ZN5outerIcE5inner1uE = external {{.*}} |
| 97 | +// CHECK: @_ZN5outerIcE5inner1vE = external {{.*}} |
| 98 | + |
| 99 | + |
| 100 | +// #1 functions |
| 101 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv |
| 102 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1gEv |
| 103 | + |
| 104 | +// #2 functions |
| 105 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv |
| 106 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1gEv |
| 107 | + |
| 108 | +// #3 functions |
| 109 | +// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv |
| 110 | +// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1gEv |
| 111 | + |
| 112 | +// #4 functions |
| 113 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv |
| 114 | +// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1gEv |
| 115 | +// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv |
| 116 | +// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1gEv |
49 | 117 |
|
| 118 | +// #5 functions |
50 | 119 | // CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv
|
51 |
| -// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv |
| 120 | +// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1gEv |
| 121 | +// CHECK-NOT: declare dllimport {{.*}} @_ZN5outerIcE5inner1fEv |
| 122 | +// CHECK-NOT: declare dllimport {{.*}} @_ZN5outerIcE5inner1gEv |
| 123 | +// CHECK-NOT: define {{.*}} @_ZN5outerIcE1fEv |
| 124 | +// CHECK-NOT: define {{.*}} @_ZN5outerIcE5inner1fEv |
| 125 | +// CHECK-NOT: define {{.*}} @_ZN5outerIcE1gEv |
| 126 | +// CHECK-NOT: define {{.*}} @_ZN5outerIcE5inner1gEv |
0 commit comments