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