356 lines · plain
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 %s2// 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 %s3// 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 %s4 5// CHECK: v17@0:8{vector<float, float, float>=}166// CHECK: {vector<float, float, float>=}7// CHECK: v24@0:8168 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 SceneNode17{18 vector3f position;19}20 21@property (assign, nonatomic) vector3f position;22 23@end24 25@interface MyOpenGLView26{27@public28 vector3f position;29}30@property vector3f position;31@end32 33@implementation MyOpenGLView34 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@end43 44 45class Int3 { int x, y, z; };46 47// Enforce @encoding for member pointers.48@interface MemPtr {}49- (void) foo: (int (Int3::*)) member;50@end51@implementation MemPtr52- (void) foo: (int (Int3::*)) member {53}54@end55 56typedef float HGVec4f __attribute__ ((vector_size(16)));57 58@interface RedBalloonHGXFormWrapper {59 HGVec4f m_Transform[4];60}61@end62 63@implementation RedBalloonHGXFormWrapper64@end65 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_1D73 {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 there92 // are currently no system frameworks that vend Objective-C++ types, a potential ABI break caused by changes93 // 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/PR9927163class 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// PR10990177struct 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_2186struct 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_ivar214@end215@implementation has_dynamic_class_ivar {216 dynamic_class dynamic_class_ivar;217}218@end219// 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 N239{240 S<N> a;241}242@end243 244@implementation N245@end246 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 >= 202002L253namespace 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#endif263 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.23323// 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 >= 202002L344namespace 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 1353 extern const char s[] = @encode(S);354}355#endif356