Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / mangle-abi-tag.cpp
blob91325c48c246d7edde1fbbc0cee2ce5f13fb8383
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
6 struct __attribute__((abi_tag("A", "B"))) A { };
8 struct B: A { };
10 template<class T>
12 struct C {
15 struct D { A* p; };
17 template<class T>
18 struct __attribute__((abi_tag("C", "D"))) E {
21 struct __attribute__((abi_tag("A", "B"))) F { };
23 A a1;
24 // CHECK-DAG: @_Z2a1B1AB1B =
26 __attribute__((abi_tag("C", "D")))
27 A a2;
28 // CHECK-DAG: @_Z2a2B1AB1BB1CB1D =
30 B a3;
31 // CHECK-DAG: @a3 =
33 C<A> a4;
34 // CHECK-DAG: @_Z2a4B1AB1B =
36 D a5;
37 // CHECK-DAG: @a5 =
39 E<int> a6;
40 // CHECK-DAG: @_Z2a6B1CB1D =
42 E<A> a7;
43 // CHECK-DAG: @_Z2a7B1AB1BB1CB1D =
45 template<>
46 struct E<float> {
47 static float a8;
49 float E<float>::a8;
50 // CHECK-DAG: @_ZN1EB1CB1DIfE2a8E =
52 template<>
53 struct E<F> {
54 static bool a9;
56 bool E<F>::a9;
57 // CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E =
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 =
67 struct __attribute__((abi_tag("A"))) B11 {
68 static A10 b;
70 A10 B11::b;
71 // B11[abi:A]::b[abi:B]
72 // CHECK-DAG: @_ZN3B11B1A1bB1BE =
74 __attribute__ ((abi_tag("C", "D")))
75 void* f1() {
76 return 0;
78 // CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(
80 __attribute__ ((abi_tag("C", "D")))
81 A* f2() {
82 return 0;
84 // CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(
86 B* f3() {
87 return 0;
89 // CHECK-DAG: define {{.*}} @_Z2f3v(
91 C<A>* f4() {
92 return 0;
94 // CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(
96 D* f5() {
97 return 0;
99 // CHECK-DAG: define {{.*}} @_Z2f5v(
101 E<char>* f6() {
102 return 0;
104 // CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(
106 E<A>* f7() {
107 return 0;
109 // CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(
111 void f8(E<A>*) {
113 // CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(
115 inline namespace Names1 __attribute__((__abi_tag__)) {
116 class C1 {};
118 C1 f9() { return C1(); }
119 // CHECK-DAG: @_Z2f9B6Names1v(
121 inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) {
122 class C2 {};
124 C2 f10() { return C2(); }
125 // CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(
127 void __attribute__((abi_tag("A"))) f11(A) {}
128 // f11[abi:A](A[abi:A][abi:B])
129 // CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(
131 A f12(A) { return A(); }
132 // f12(A[abi:A][abi:B])
133 // CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(
135 inline void f13() {
136 struct L {
137 static E<int>* foo() {
138 static A10 a;
139 return 0;
142 L::foo();
144 void f13_test() {
145 f13();
147 // f13()::L::foo[abi:C][abi:D]()
148 // CHECK-DAG: define linkonce_odr {{(dso_local )?}}{{(noundef )?}}ptr @_ZZ3f13vEN1L3fooB1CB1DEv(
150 // f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
151 // CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
153 // guard variable for f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
154 // CHECK-DAG: @_ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
156 struct __attribute__((abi_tag("TAG"))) A14 {
157 A14 f14();
159 A14 A14::f14() {
160 return A14();
162 // A14[abi:TAG]::f14()
163 // CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev(
165 template<class T>
166 T f15() {
167 return T();
169 void f15_test() {
170 f15<A14>();
172 // A14[abi:TAG] f15<A14[abi:TAG]>()
173 // CHECK-DAG: define linkonce_odr {{.+}} @_Z3f15I3A14B3TAGET_v(
175 template<class T>
176 A14 f16() {
177 return A14();
179 void f16_test() {
180 f16<int>();
182 // A14[abi:TAG] f16<int>()
183 // CHECK-DAG: define linkonce_odr {{.+}} @_Z3f16IiE3A14B3TAGv(
185 template<class T>
186 struct __attribute__((abi_tag("TAG"))) A17 {
187 A17 operator+(const A17& a) {
188 return a;
191 void f17_test() {
192 A17<int> a, b;
193 a + b;
195 // A17[abi:TAG]<int>::operator+(A17[abi:TAG]<int> const&)
196 // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A17B3TAGIiEplERKS0_(
198 struct A18 {
199 operator A() { return A(); }
201 void f18_test() {
202 A a = A18();
204 // A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!
205 // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv(
207 namespace N19 {
208 class A {};
209 class __attribute__((abi_tag("B"))) B {};
210 class D {};
211 class F {};
213 template<typename T, B F(T, D)>
214 class C {};
216 B foo(A, D);
218 void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) {
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_(
223 namespace pr30440 {
225 template<class F> void g(F);
226 template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
228 // CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIXfp_EEfp_EEEDpT_(
230 void pr30440_test () {
231 h();