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 {
~A10A1060 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")))
f1()75 void* f1() {
76 return 0;
77 }
78 // CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(
79
80 __attribute__ ((abi_tag("C", "D")))
f2()81 A* f2() {
82 return 0;
83 }
84 // CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(
85
f3()86 B* f3() {
87 return 0;
88 }
89 // CHECK-DAG: define {{.*}} @_Z2f3v(
90
f4()91 C<A>* f4() {
92 return 0;
93 }
94 // CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(
95
f5()96 D* f5() {
97 return 0;
98 }
99 // CHECK-DAG: define {{.*}} @_Z2f5v(
100
f6()101 E<char>* f6() {
102 return 0;
103 }
104 // CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(
105
f7()106 E<A>* f7() {
107 return 0;
108 }
109 // CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(
110
f8(E<A> *)111 void f8(E<A>*) {
112 }
113 // CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(
114
115 inline namespace Names1 __attribute__((__abi_tag__)) {
116 class C1 {};
117 }
f9()118 C1 f9() { return C1(); }
119 // CHECK-DAG: @_Z2f9B6Names1v(
120
121 inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) {
122 class C2 {};
123 }
f10()124 C2 f10() { return C2(); }
125 // CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(
126
f11(A)127 void __attribute__((abi_tag("A"))) f11(A) {}
128 // f11[abi:A](A[abi:A][abi:B])
129 // CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(
130
f12(A)131 A f12(A) { return A(); }
132 // f12(A[abi:A][abi:B])
133 // CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(
134
f13()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 }
f13_test()144 void f13_test() {
145 f13();
146 }
147 // f13()::L::foo[abi:C][abi:D]()
148 // CHECK-DAG: define linkonce_odr {{(dso_local )?}}{{(noundef )?}}ptr @_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 };
f14()159 A14 A14::f14() {
160 return A14();
161 }
162 // A14[abi:TAG]::f14()
163 // CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev(
164
165 template<class T>
f15()166 T f15() {
167 return T();
168 }
f15_test()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>
f16()176 A14 f16() {
177 return A14();
178 }
f16_test()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 {
operator +A17187 A17 operator+(const A17& a) {
188 return a;
189 }
190 };
f17_test()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 {
operator AA18199 operator A() { return A(); }
200 };
f18_test()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 }
f19_test(N19::C<N19::A,& N19::foo>,N19::F,N19::D)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);
h(A...a)226 template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
227 }
228 // CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIXfp_EEfp_EEEDpT_(
229
pr30440_test()230 void pr30440_test () {
231 h();
232 }
233
234 }
235