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
6struct __attribute__((abi_tag("A", "B"))) A { };
7
8struct B: A { };
9
10template<class T>
11
12struct C {
13};
14
15struct D { A* p; };
16
17template<class T>
18struct __attribute__((abi_tag("C", "D"))) E {
19};
20
21struct __attribute__((abi_tag("A", "B"))) F { };
22
23A a1;
24// CHECK-DAG: @_Z2a1B1AB1B =
25
26__attribute__((abi_tag("C", "D")))
27A a2;
28// CHECK-DAG: @_Z2a2B1AB1BB1CB1D =
29
30B a3;
31// CHECK-DAG: @a3 =
32
33C<A> a4;
34// CHECK-DAG: @_Z2a4B1AB1B =
35
36D a5;
37// CHECK-DAG: @a5 =
38
39E<int> a6;
40// CHECK-DAG: @_Z2a6B1CB1D =
41
42E<A> a7;
43// CHECK-DAG: @_Z2a7B1AB1BB1CB1D =
44
45template<>
46struct E<float> {
47  static float a8;
48};
49float E<float>::a8;
50// CHECK-DAG: @_ZN1EB1CB1DIfE2a8E =
51
52template<>
53struct E<F> {
54  static bool a9;
55};
56bool E<F>::a9;
57// CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E =
58
59struct __attribute__((abi_tag("A", "B"))) A10 {
60  virtual ~A10() {}
61} a10;
62// vtable
63// CHECK-DAG: @_ZTV3A10B1AB1B =
64// typeinfo
65// CHECK-DAG: @_ZTI3A10B1AB1B =
66
67struct __attribute__((abi_tag("A"))) B11 {
68  static A10 b;
69};
70A10 B11::b;
71// B11[abi:A]::b[abi:B]
72// CHECK-DAG: @_ZN3B11B1A1bB1BE =
73
74__attribute__ ((abi_tag("C", "D")))
75void* f1() {
76  return 0;
77}
78// CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(
79
80__attribute__ ((abi_tag("C", "D")))
81A* f2() {
82  return 0;
83}
84// CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(
85
86B* f3() {
87  return 0;
88}
89// CHECK-DAG: define {{.*}} @_Z2f3v(
90
91C<A>* f4() {
92  return 0;
93}
94// CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(
95
96D* f5() {
97  return 0;
98}
99// CHECK-DAG: define {{.*}} @_Z2f5v(
100
101E<char>* f6() {
102  return 0;
103}
104// CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(
105
106E<A>* f7() {
107  return 0;
108}
109// CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(
110
111void f8(E<A>*) {
112}
113// CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(
114
115inline namespace Names1 __attribute__((__abi_tag__)) {
116    class C1 {};
117}
118C1 f9() { return C1(); }
119// CHECK-DAG: @_Z2f9B6Names1v(
120
121inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) {
122    class C2 {};
123}
124C2 f10() { return C2(); }
125// CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(
126
127void __attribute__((abi_tag("A"))) f11(A) {}
128// f11[abi:A](A[abi:A][abi:B])
129// CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(
130
131A f12(A) { return A(); }
132// f12(A[abi:A][abi:B])
133// CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(
134
135inline void f13() {
136  struct L {
137    static E<int>* foo() {
138      static A10 a;
139      return 0;
140    }
141  };
142  L::foo();
143}
144void f13_test() {
145  f13();
146}
147// f13()::L::foo[abi:C][abi:D]()
148// CHECK-DAG: define linkonce_odr %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
156struct __attribute__((abi_tag("TAG"))) A14 {
157  A14 f14();
158};
159A14 A14::f14() {
160  return A14();
161}
162// A14[abi:TAG]::f14()
163// CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev(
164
165template<class T>
166T f15() {
167  return T();
168}
169void f15_test() {
170  f15<A14>();
171}
172// A14[abi:TAG] f15<A14[abi:TAG]>()
173// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f15I3A14B3TAGET_v(
174
175template<class T>
176A14 f16() {
177  return A14();
178}
179void f16_test() {
180  f16<int>();
181}
182// A14[abi:TAG] f16<int>()
183// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f16IiE3A14B3TAGv(
184
185template<class T>
186struct __attribute__((abi_tag("TAG"))) A17 {
187  A17 operator+(const A17& a) {
188    return a;
189  }
190};
191void 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
198struct A18 {
199  operator A() { return A(); }
200};
201void 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