1 | // RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - | FileCheck %s |
2 | // RUN: %clang_cc1 %s -emit-llvm -triple i686-linux-gnu -std=c++11 -o - | FileCheck %s |
3 | // RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - | FileCheck %s |
4 | // RUN: %clang_cc1 %s -emit-llvm -triple powerpc64le-unknown-linux-gnu -std=c++11 -o - | FileCheck %s |
5 | |
6 | struct __attribute__((abi_tag("A", "B"))) A { }; |
7 | |
8 | struct B: A { }; |
9 | |
10 | template<class T> |
11 | |
12 | struct C { |
13 | }; |
14 | |
15 | struct D { A* p; }; |
16 | |
17 | template<class T> |
18 | struct __attribute__((abi_tag("C", "D"))) E { |
19 | }; |
20 | |
21 | struct __attribute__((abi_tag("A", "B"))) F { }; |
22 | |
23 | A a1; |
24 | // CHECK-DAG: @_Z2a1B1AB1B = |
25 | |
26 | __attribute__((abi_tag("C", "D"))) |
27 | A a2; |
28 | // CHECK-DAG: @_Z2a2B1AB1BB1CB1D = |
29 | |
30 | B a3; |
31 | // CHECK-DAG: @a3 = |
32 | |
33 | C<A> a4; |
34 | // CHECK-DAG: @_Z2a4B1AB1B = |
35 | |
36 | D a5; |
37 | // CHECK-DAG: @a5 = |
38 | |
39 | E<int> a6; |
40 | // CHECK-DAG: @_Z2a6B1CB1D = |
41 | |
42 | E<A> a7; |
43 | // CHECK-DAG: @_Z2a7B1AB1BB1CB1D = |
44 | |
45 | template<> |
46 | struct E<float> { |
47 | static float a8; |
48 | }; |
49 | float E<float>::a8; |
50 | // CHECK-DAG: @_ZN1EB1CB1DIfE2a8E = |
51 | |
52 | template<> |
53 | struct E<F> { |
54 | static bool a9; |
55 | }; |
56 | bool E<F>::a9; |
57 | // CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E = |
58 | |
59 | struct __attribute__((abi_tag("A", "B"))) A10 { |
60 | virtual ~A10() {} |
61 | } a10; |
62 | // vtable |
63 | // CHECK-DAG: @_ZTV3A10B1AB1B = |
64 | // typeinfo |
65 | // CHECK-DAG: @_ZTI3A10B1AB1B = |
66 | |
67 | struct __attribute__((abi_tag("A"))) B11 { |
68 | static A10 b; |
69 | }; |
70 | A10 B11::b; |
71 | // B11[abi:A]::b[abi:B] |
72 | // CHECK-DAG: @_ZN3B11B1A1bB1BE = |
73 | |
74 | __attribute__ ((abi_tag("C", "D"))) |
75 | void* f1() { |
76 | return 0; |
77 | } |
78 | // CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv( |
79 | |
80 | __attribute__ ((abi_tag("C", "D"))) |
81 | A* f2() { |
82 | return 0; |
83 | } |
84 | // CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv( |
85 | |
86 | B* f3() { |
87 | return 0; |
88 | } |
89 | // CHECK-DAG: define {{.*}} @_Z2f3v( |
90 | |
91 | C<A>* f4() { |
92 | return 0; |
93 | } |
94 | // CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv( |
95 | |
96 | D* f5() { |
97 | return 0; |
98 | } |
99 | // CHECK-DAG: define {{.*}} @_Z2f5v( |
100 | |
101 | E<char>* f6() { |
102 | return 0; |
103 | } |
104 | // CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv( |
105 | |
106 | E<A>* f7() { |
107 | return 0; |
108 | } |
109 | // CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv( |
110 | |
111 | void f8(E<A>*) { |
112 | } |
113 | // CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE( |
114 | |
115 | inline namespace Names1 __attribute__((__abi_tag__)) { |
116 | class C1 {}; |
117 | } |
118 | C1 f9() { return C1(); } |
119 | // CHECK-DAG: @_Z2f9B6Names1v( |
120 | |
121 | inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) { |
122 | class C2 {}; |
123 | } |
124 | C2 f10() { return C2(); } |
125 | // CHECK-DAG: @_Z3f10B4Tag1B4Tag2v( |
126 | |
127 | void __attribute__((abi_tag("A"))) f11(A) {} |
128 | // f11[abi:A](A[abi:A][abi:B]) |
129 | // CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B( |
130 | |
131 | A f12(A) { return A(); } |
132 | // f12(A[abi:A][abi:B]) |
133 | // CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B( |
134 | |
135 | inline void f13() { |
136 | struct L { |
137 | static E<int>* foo() { |
138 | static A10 a; |
139 | return 0; |
140 | } |
141 | }; |
142 | L::foo(); |
143 | } |
144 | void f13_test() { |
145 | f13(); |
146 | } |
147 | // f13()::L::foo[abi:C][abi:D]() |
148 | // CHECK-DAG: define linkonce_odr {{(dso_local )?}}%struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv( |
149 | |
150 | // f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B] |
151 | // CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B = |
152 | |
153 | // guard variable for f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B] |
154 | // CHECK-DAG: @_ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B = |
155 | |
156 | struct __attribute__((abi_tag("TAG"))) A14 { |
157 | A14 f14(); |
158 | }; |
159 | A14 A14::f14() { |
160 | return A14(); |
161 | } |
162 | // A14[abi:TAG]::f14() |
163 | // CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev( |
164 | |
165 | template<class T> |
166 | T f15() { |
167 | return T(); |
168 | } |
169 | void f15_test() { |
170 | f15<A14>(); |
171 | } |
172 | // A14[abi:TAG] f15<A14[abi:TAG]>() |
173 | // CHECK-DAG: define linkonce_odr {{.+}} @_Z3f15I3A14B3TAGET_v( |
174 | |
175 | template<class T> |
176 | A14 f16() { |
177 | return A14(); |
178 | } |
179 | void f16_test() { |
180 | f16<int>(); |
181 | } |
182 | // A14[abi:TAG] f16<int>() |
183 | // CHECK-DAG: define linkonce_odr {{.+}} @_Z3f16IiE3A14B3TAGv( |
184 | |
185 | template<class T> |
186 | struct __attribute__((abi_tag("TAG"))) A17 { |
187 | A17 operator+(const A17& a) { |
188 | return a; |
189 | } |
190 | }; |
191 | void f17_test() { |
192 | A17<int> a, b; |
193 | a + b; |
194 | } |
195 | // A17[abi:TAG]<int>::operator+(A17[abi:TAG]<int> const&) |
196 | // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A17B3TAGIiEplERKS0_( |
197 | |
198 | struct A18 { |
199 | operator A() { return A(); } |
200 | }; |
201 | void f18_test() { |
202 | A a = A18(); |
203 | } |
204 | // A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice! |
205 | // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv( |
206 | |
207 | namespace N19 { |
208 | class A {}; |
209 | class __attribute__((abi_tag("B"))) B {}; |
210 | class D {}; |
211 | class F {}; |
212 | |
213 | template<typename T, B F(T, D)> |
214 | class C {}; |
215 | |
216 | B foo(A, D); |
217 | } |
218 | void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) { |
219 | } |
220 | // f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D) |
221 | // CHECK-DAG: define {{(dso_local )?}}void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_( |
222 | |
223 | namespace pr30440 { |
224 | |
225 | template<class F> void g(F); |
226 | template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) { |
227 | } |
228 | // CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIL_ZZNS_1hEDpT_E1aEEfp_EEES2_( |
229 | |
230 | void pr30440_test () { |
231 | h(); |
232 | } |
233 | |
234 | } |
235 | |