1// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX98,CHECK-NO-TEMP-SPEC %s
2// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-NO-TEMP-SPEC %s
3// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -fobjc-encode-cxx-class-template-spec -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-TEMP-SPEC %s
4
5// CHECK: v17@0:8{vector<float, float, float>=}16
6// CHECK: {vector<float, float, float>=}
7// CHECK: v24@0:816
8
9template <typename T1, typename T2, typename T3> struct vector {
10  vector();
11  vector(T1,T2,T3);
12};
13
14typedef vector< float, float, float > vector3f;
15
16@interface SceneNode
17{
18 vector3f position;
19}
20
21@property (assign, nonatomic) vector3f position;
22
23@end
24
25@interface MyOpenGLView
26{
27@public
28  vector3f position;
29}
30@property vector3f position;
31@end
32
33@implementation MyOpenGLView
34
35@synthesize position;
36
37-(void)awakeFromNib {
38 SceneNode *sn;
39 vector3f VF3(1.0, 1.0, 1.0);
40 [sn setPosition:VF3];
41}
42@end
43
44
45class Int3 { int x, y, z; };
46
47// Enforce @encoding for member pointers.
48@interface MemPtr {}
49- (void) foo: (int (Int3::*)) member;
50@end
51@implementation MemPtr
52- (void) foo: (int (Int3::*)) member {
53}
54@end
55
56// rdar: // 8519948
57typedef float HGVec4f __attribute__ ((vector_size(16)));
58
59@interface RedBalloonHGXFormWrapper {
60  HGVec4f m_Transform[4];
61}
62@end
63
64@implementation RedBalloonHGXFormWrapper
65@end
66
67// rdar://9357400
68namespace rdar9357400 {
69  template<int Dim1 = -1, int Dim2 = -1> struct fixed {
70      template<int D> struct rebind { typedef fixed<D> other; };
71  };
72
73  template<typename Element, int Size>
74  class fixed_1D
75  {
76  public:
77      typedef Element value_type;
78      typedef value_type array_impl[Size];
79    protected:
80      array_impl                  m_data;
81  };
82
83  template<typename Element, typename Alloc>
84  class vector;
85
86  template<typename Element, int Size>
87  class vector< Element, fixed<Size> >
88  : public fixed_1D<Element,Size> { };
89
90  typedef vector< float,  fixed<4> > vector4f;
91
92  // FIXME: This difference is due to D76801. It was probably an unintentional change. Maybe we want to undo it?
93  // CHECKCXX98: @_ZN11rdar93574002ggE ={{.*}} constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
94  // CHECKCXX20: @_ZN11rdar93574002ggE ={{.*}} constant [48 x i8] c"{vector<float, rdar9357400::fixed<4, -1>>=[4f]}\00"
95  extern const char gg[] = @encode(vector4f);
96}
97
98// rdar://9624314
99namespace rdar9624314 {
100  struct B2 { int x; };
101  struct B3 {};
102  struct S : B2, B3 {};
103
104  // CHECK: @_ZN11rdar96243142ggE ={{.*}} constant [6 x i8] c"{S=i}\00"
105  extern const char gg[] = @encode(S);
106
107  struct S2 { unsigned : 0; int x; unsigned : 0; };
108  // CHECK: @_ZN11rdar96243142g2E ={{.*}} constant [11 x i8] c"{S2=b0ib0}\00"
109  extern const char g2[] = @encode(S2);
110}
111
112namespace test {
113  class Foo {
114  public:
115   virtual void f() {};
116  };
117
118  class Bar {
119  public:
120   virtual void g() {};
121  };
122
123  class Zoo : virtual public Foo, virtual public Bar {
124  public:
125   int x;
126   int y;
127  };
128
129  // CHECK: @_ZN4test3ecdE ={{.*}} constant [15 x i8] c"{Zoo=^^?ii^^?}\00"
130  extern const char ecd[] = @encode(Zoo);
131}
132
133struct Base1 {
134  char x;
135};
136
137struct DBase : public Base1 {
138  double x;
139  virtual ~DBase();
140};
141
142struct Sub_with_virt : virtual DBase {
143  long x;
144};
145
146struct Sub2 : public Sub_with_virt, public Base1, virtual DBase {
147  float x;
148};
149
150// CHECK: @g1 ={{.*}} constant [10 x i8] c"{Base1=c}\00"
151extern const char g1[] = @encode(Base1);
152
153// CHECK: @g2 ={{.*}} constant [14 x i8] c"{DBase=^^?cd}\00"
154extern const char g2[] = @encode(DBase);
155
156// CHECK: @g3 ={{.*}} constant [26 x i8] c"{Sub_with_virt=^^?q^^?cd}\00"
157extern const char g3[] = @encode(Sub_with_virt);
158
159// CHECK: @g4 ={{.*}} constant [19 x i8] c"{Sub2=^^?qcf^^?cd}\00"
160extern const char g4[] = @encode(Sub2);
161
162// http://llvm.org/PR9927
163class allocator {
164};
165class basic_string     {
166struct _Alloc_hider : allocator       {
167char* _M_p;
168};
169_Alloc_hider _M_dataplus;
170};
171
172// CHECK: @g5 ={{.*}} constant [32 x i8] c"{basic_string={_Alloc_hider=*}}\00"
173extern const char g5[] = @encode(basic_string);
174
175
176// PR10990
177struct CefBase {
178  virtual ~CefBase() {}
179};
180struct CefBrowser : public virtual CefBase {};
181struct CefBrowserImpl : public CefBrowser {};
182// CHECK: @g6 ={{.*}} constant [21 x i8] c"{CefBrowserImpl=^^?}\00"
183extern const char g6[] = @encode(CefBrowserImpl);
184
185// PR10990_2
186struct CefBase2 {
187  virtual ~CefBase2() {}
188  int i;
189};
190struct CefBrowser2 : public virtual CefBase2 {};
191struct CefBrowserImpl2 : public CefBrowser2 {};
192// CHECK: @g7 ={{.*}} constant [26 x i8] c"{CefBrowserImpl2=^^?^^?i}\00"
193extern const char g7[] = @encode(CefBrowserImpl2);
194
195// <rdar://problem/11324167>
196struct Empty {};
197
198struct X : Empty {
199  int array[10];
200};
201
202struct Y : Empty {
203  X vec;
204};
205
206// CHECK: @g8 ={{.*}} constant [14 x i8] c"{Y={X=[10i]}}\00"
207extern const char g8[] = @encode(Y);
208
209
210class dynamic_class {
211public:
212  virtual ~dynamic_class();
213};
214@interface has_dynamic_class_ivar
215@end
216@implementation has_dynamic_class_ivar {
217  dynamic_class dynamic_class_ivar;
218}
219@end
220// CHECK: private unnamed_addr constant [41 x i8] c"{dynamic_class=\22_vptr$dynamic_class\22^^?}\00"
221
222namespace PR17142 {
223  struct A { virtual ~A(); };
224  struct B : virtual A { int y; };
225  struct C { virtual ~C(); int z; };
226  struct D : C, B { int a; };
227  struct E : D {};
228  // CHECK: @_ZN7PR171421xE ={{.*}} constant [14 x i8] c"{E=^^?i^^?ii}\00"
229  extern const char x[] = @encode(E);
230}
231
232// This test used to cause infinite recursion.
233template<typename T>
234struct S {
235  typedef T Ty;
236  Ty *t;
237};
238
239@interface N
240{
241  S<N> a;
242}
243@end
244
245@implementation N
246@end
247
248const char *expand_struct() {
249  // CHECK: @{{.*}} = private unnamed_addr constant [13 x i8] c"{N={S<N>=@}}\00"
250  return @encode(N);
251}
252
253#if __cplusplus >= 202002L
254namespace PR48048 {
255  struct F {};
256  struct I {
257    int m;
258    [[no_unique_address]] F n;
259  };
260  // CHECKCXX20: @_ZN7PR480481xE ={{.*}} constant [6 x i8] c"{I=i}\00"
261  extern const char x[] = @encode(I);
262}
263#endif
264
265namespace test_cxx_template_specialization {
266template <class T>
267struct B0 {
268  T a;
269};
270struct D0 : B0<int> {};
271struct D1 : D0 {};
272struct D2 : virtual B0<int> {};
273struct S0 {
274  B0<int> a;
275};
276struct S1 {
277  B0<int> *a;
278};
279struct S2 {
280  S1 *a;
281};
282template <class T>
283union U0 {
284  T a;
285};
286typedef B0<int> TD0;
287typedef B0<int> *Array0[4];
288
289template <class T>
290struct Outer0 {
291  struct Inner0 {
292    int a;
293  };
294  template <class T1>
295  struct Inner1 {
296    T a;
297    T1 b;
298  };
299};
300
301// CHECK: @[[STR22:.*]] = {{.*}} [12 x i8] c"{B0<int>=i}\00"
302// CHECK: @_ZN32test_cxx_template_specialization2b0E = {{.*}} ([12 x i8], [12 x i8]* @[[STR22]], i32 0, i32 0)
303// CHECK-NO-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [3 x i8] c"^v\00"
304// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
305// CHECK-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [13 x i8] c"^{B0<int>=i}\00"
306// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = {{.*}} ([13 x i8], [13 x i8]* @[[STR23]], i32 0, i32 0)
307// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b02E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
308// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
309// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d1E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
310// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d2E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
311// CHECK: @[[STR24:.*]] = {{.*}} [7 x i8] c"^^{D2}\00"
312// CHECK: @_ZN32test_cxx_template_specialization3d21E = {{.*}} ([7 x i8], [7 x i8]* @[[STR24]], i32 0, i32 0)
313// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
314// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s1E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
315// CHECK: @[[STR25:.*]] = {{.*}} [12 x i8] c"^{S2=^{S1}}\00"
316// CHECK: @_ZN32test_cxx_template_specialization2s2E = {{.*}} ([12 x i8], [12 x i8]* @[[STR25]], i32 0, i32 0)
317// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2u0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
318// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3td0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
319// CHECK-NO-TEMP-SPEC: @[[STR26:.*]] = {{.*}} [6 x i8] c"[4^v]\00"
320// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2a0E = {{.*}} ([6 x i8], [6 x i8]* @[[STR26]], i32 0, i32 0)
321// CHECK: @[[STR27:.*]] = {{.*}} [11 x i8] c"^{Inner0=}\00"
322// CHECK: @_ZN32test_cxx_template_specialization6inner0E = {{.*}} ([11 x i8], [11 x i8]* @[[STR27]], i32 0, i32 0)
323// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = {{.*}} ([3 x i8], [3 x i8]* @.str.23, i32 0, i32 0)
324// CHECK-TEMP-SPEC: @[[STR34:.*]] = {{.*}} [18 x i8] c"^{Inner1<float>=}\00"
325// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = {{.*}} ([18 x i8], [18 x i8]* @[[STR34]], i32 0, i32 0)
326
327const char *b0 = @encode(B0<int>);
328const char *b01 = @encode(B0<int> *);
329const char *b02 = @encode(B0<int> &);
330const char *d0 = @encode(D0 *);
331const char *d1 = @encode(D1 *);
332const char *d2 = @encode(D2 *);
333const char *d21 = @encode(D2 **);
334const char *s0 = @encode(S0 *);
335const char *s1 = @encode(S1 *);
336const char *s2 = @encode(S2 *);
337const char *u0 = @encode(U0<int> *);
338const char *td0 = @encode(TD0 *);
339const char *a0 = @encode(Array0);
340const char *inner0 = @encode(Outer0<int>::Inner0 *);
341const char *inner1 = @encode(Outer0<int>::Inner1<float> *);
342}
343