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 56typedef float HGVec4f __attribute__ ((vector_size(16))); 57 58@interface RedBalloonHGXFormWrapper { 59 HGVec4f m_Transform[4]; 60} 61@end 62 63@implementation RedBalloonHGXFormWrapper 64@end 65 66namespace rdar9357400 { 67 template<int Dim1 = -1, int Dim2 = -1> struct fixed { 68 template<int D> struct rebind { typedef fixed<D> other; }; 69 }; 70 71 template<typename Element, int Size> 72 class fixed_1D 73 { 74 public: 75 typedef Element value_type; 76 typedef value_type array_impl[Size]; 77 protected: 78 array_impl m_data; 79 }; 80 81 template<typename Element, typename Alloc> 82 class vector; 83 84 template<typename Element, int Size> 85 class vector< Element, fixed<Size> > 86 : public fixed_1D<Element,Size> { }; 87 88 typedef vector< float, fixed<4> > vector4f; 89 90 // FIXME: This difference is due to D76801. It was probably an unintentional change. Maybe we want to undo it? 91 // @encoding for C++ is dependent on the TypePrinter implementation, which is a known issue. But since there 92 // are currently no system frameworks that vend Objective-C++ types, a potential ABI break caused by changes 93 // to the TypePrinter should not be a concern. 94 // CHECKCXX98: @_ZN11rdar93574002ggE ={{.*}} constant [45 x i8] c"{vector<float, rdar9357400::fixed<4> >=[4f]}\00" 95 // CHECKCXX20: @_ZN11rdar93574002ggE ={{.*}} constant [44 x i8] c"{vector<float, rdar9357400::fixed<4>>=[4f]}\00" 96 extern const char gg[] = @encode(vector4f); 97} 98 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 195struct Empty {}; 196 197struct X : Empty { 198 int array[10]; 199}; 200 201struct Y : Empty { 202 X vec; 203}; 204 205// CHECK: @g8 ={{.*}} constant [14 x i8] c"{Y={X=[10i]}}\00" 206extern const char g8[] = @encode(Y); 207 208 209class dynamic_class { 210public: 211 virtual ~dynamic_class(); 212}; 213@interface has_dynamic_class_ivar 214@end 215@implementation has_dynamic_class_ivar { 216 dynamic_class dynamic_class_ivar; 217} 218@end 219// CHECK: private unnamed_addr constant [41 x i8] c"{dynamic_class=\22_vptr$dynamic_class\22^^?}\00" 220 221namespace PR17142 { 222 struct A { virtual ~A(); }; 223 struct B : virtual A { int y; }; 224 struct C { virtual ~C(); int z; }; 225 struct D : C, B { int a; }; 226 struct E : D {}; 227 // CHECK: @_ZN7PR171421xE ={{.*}} constant [14 x i8] c"{E=^^?i^^?ii}\00" 228 extern const char x[] = @encode(E); 229} 230 231// This test used to cause infinite recursion. 232template<typename T> 233struct S { 234 typedef T Ty; 235 Ty *t; 236}; 237 238@interface N 239{ 240 S<N> a; 241} 242@end 243 244@implementation N 245@end 246 247const char *expand_struct() { 248 // CHECK: @{{.*}} = private unnamed_addr constant [13 x i8] c"{N={S<N>=@}}\00" 249 return @encode(N); 250} 251 252#if __cplusplus >= 202002L 253namespace PR48048 { 254 struct F {}; 255 struct I { 256 int m; 257 [[no_unique_address]] F n; 258 }; 259 // CHECKCXX20: @_ZN7PR480481xE ={{.*}} constant [6 x i8] c"{I=i}\00" 260 extern const char x[] = @encode(I); 261} 262#endif 263 264namespace test_cxx_template_specialization { 265template <class T> 266struct B0 { 267 T a; 268}; 269struct D0 : B0<int> {}; 270struct D1 : D0 {}; 271struct D2 : virtual B0<int> {}; 272struct S0 { 273 B0<int> a; 274}; 275struct S1 { 276 B0<int> *a; 277}; 278struct S2 { 279 S1 *a; 280}; 281template <class T> 282union U0 { 283 T a; 284}; 285typedef B0<int> TD0; 286typedef B0<int> *Array0[4]; 287 288template <class T> 289struct Outer0 { 290 struct Inner0 { 291 int a; 292 }; 293 template <class T1> 294 struct Inner1 { 295 T a; 296 T1 b; 297 }; 298}; 299 300// CHECK: @[[STR22:.*]] = {{.*}} [12 x i8] c"{B0<int>=i}\00" 301// CHECK: @_ZN32test_cxx_template_specialization2b0E = global ptr @[[STR22]] 302// CHECK-NO-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [3 x i8] c"^v\00" 303// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]] 304// CHECK-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [13 x i8] c"^{B0<int>=i}\00" 305// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]] 306// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b02E = global ptr @[[STR23]] 307// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d0E = global ptr @[[STR23]] 308// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d1E = global ptr @[[STR23]] 309// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d2E = global ptr @[[STR23]] 310// CHECK: @[[STR24:.*]] = {{.*}} [7 x i8] c"^^{D2}\00" 311// CHECK: @_ZN32test_cxx_template_specialization3d21E = global ptr @[[STR24]] 312// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s0E = global ptr @[[STR23]] 313// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s1E = global ptr @[[STR23]] 314// CHECK: @[[STR25:.*]] = {{.*}} [12 x i8] c"^{S2=^{S1}}\00" 315// CHECK: @_ZN32test_cxx_template_specialization2s2E = global ptr @[[STR25]] 316// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2u0E = global ptr @[[STR23]] 317// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3td0E = global ptr @[[STR23]] 318// CHECK-NO-TEMP-SPEC: @[[STR26:.*]] = {{.*}} [6 x i8] c"[4^v]\00" 319// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2a0E = global ptr @[[STR26]] 320// CHECK: @[[STR27:.*]] = {{.*}} [11 x i8] c"^{Inner0=}\00" 321// CHECK: @_ZN32test_cxx_template_specialization6inner0E = global ptr @[[STR27]] 322// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @.str.23 323// CHECK-TEMP-SPEC: @[[STR34:.*]] = {{.*}} [18 x i8] c"^{Inner1<float>=}\00" 324// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @[[STR34]] 325 326const char *b0 = @encode(B0<int>); 327const char *b01 = @encode(B0<int> *); 328const char *b02 = @encode(B0<int> &); 329const char *d0 = @encode(D0 *); 330const char *d1 = @encode(D1 *); 331const char *d2 = @encode(D2 *); 332const char *d21 = @encode(D2 **); 333const char *s0 = @encode(S0 *); 334const char *s1 = @encode(S1 *); 335const char *s2 = @encode(S2 *); 336const char *u0 = @encode(U0<int> *); 337const char *td0 = @encode(TD0 *); 338const char *a0 = @encode(Array0); 339const char *inner0 = @encode(Outer0<int>::Inner0 *); 340const char *inner1 = @encode(Outer0<int>::Inner1<float> *); 341} 342 343#if __cplusplus >= 202002L 344namespace GH71250 { 345 struct Empty {}; 346 struct S { 347 [[no_unique_address]] Empty a; 348 long b; 349 long c; 350 }; 351 352 // CHECKCXX20: @_ZN7GH712501sE = constant [7 x i8] c"{S=qq}\00", align 1 353 extern const char s[] = @encode(S); 354} 355#endif 356