// 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 // 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 // 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 // CHECK: v17@0:8{vector=}16 // CHECK: {vector=} // CHECK: v24@0:816 template struct vector { vector(); vector(T1,T2,T3); }; typedef vector< float, float, float > vector3f; @interface SceneNode { vector3f position; } @property (assign, nonatomic) vector3f position; @end @interface MyOpenGLView { @public vector3f position; } @property vector3f position; @end @implementation MyOpenGLView @synthesize position; -(void)awakeFromNib { SceneNode *sn; vector3f VF3(1.0, 1.0, 1.0); [sn setPosition:VF3]; } @end class Int3 { int x, y, z; }; // Enforce @encoding for member pointers. @interface MemPtr {} - (void) foo: (int (Int3::*)) member; @end @implementation MemPtr - (void) foo: (int (Int3::*)) member { } @end typedef float HGVec4f __attribute__ ((vector_size(16))); @interface RedBalloonHGXFormWrapper { HGVec4f m_Transform[4]; } @end @implementation RedBalloonHGXFormWrapper @end namespace rdar9357400 { template struct fixed { template struct rebind { typedef fixed other; }; }; template class fixed_1D { public: typedef Element value_type; typedef value_type array_impl[Size]; protected: array_impl m_data; }; template class vector; template class vector< Element, fixed > : public fixed_1D { }; typedef vector< float, fixed<4> > vector4f; // FIXME: This difference is due to D76801. It was probably an unintentional change. Maybe we want to undo it? // @encoding for C++ is dependent on the TypePrinter implementation, which is a known issue. But since there // are currently no system frameworks that vend Objective-C++ types, a potential ABI break caused by changes // to the TypePrinter should not be a concern. // CHECKCXX98: @_ZN11rdar93574002ggE ={{.*}} constant [45 x i8] c"{vector >=[4f]}\00" // CHECKCXX20: @_ZN11rdar93574002ggE ={{.*}} constant [44 x i8] c"{vector>=[4f]}\00" extern const char gg[] = @encode(vector4f); } namespace rdar9624314 { struct B2 { int x; }; struct B3 {}; struct S : B2, B3 {}; // CHECK: @_ZN11rdar96243142ggE ={{.*}} constant [6 x i8] c"{S=i}\00" extern const char gg[] = @encode(S); struct S2 { unsigned : 0; int x; unsigned : 0; }; // CHECK: @_ZN11rdar96243142g2E ={{.*}} constant [11 x i8] c"{S2=b0ib0}\00" extern const char g2[] = @encode(S2); } namespace test { class Foo { public: virtual void f() {}; }; class Bar { public: virtual void g() {}; }; class Zoo : virtual public Foo, virtual public Bar { public: int x; int y; }; // CHECK: @_ZN4test3ecdE ={{.*}} constant [15 x i8] c"{Zoo=^^?ii^^?}\00" extern const char ecd[] = @encode(Zoo); } struct Base1 { char x; }; struct DBase : public Base1 { double x; virtual ~DBase(); }; struct Sub_with_virt : virtual DBase { long x; }; struct Sub2 : public Sub_with_virt, public Base1, virtual DBase { float x; }; // CHECK: @g1 ={{.*}} constant [10 x i8] c"{Base1=c}\00" extern const char g1[] = @encode(Base1); // CHECK: @g2 ={{.*}} constant [14 x i8] c"{DBase=^^?cd}\00" extern const char g2[] = @encode(DBase); // CHECK: @g3 ={{.*}} constant [26 x i8] c"{Sub_with_virt=^^?q^^?cd}\00" extern const char g3[] = @encode(Sub_with_virt); // CHECK: @g4 ={{.*}} constant [19 x i8] c"{Sub2=^^?qcf^^?cd}\00" extern const char g4[] = @encode(Sub2); // http://llvm.org/PR9927 class allocator { }; class basic_string { struct _Alloc_hider : allocator { char* _M_p; }; _Alloc_hider _M_dataplus; }; // CHECK: @g5 ={{.*}} constant [32 x i8] c"{basic_string={_Alloc_hider=*}}\00" extern const char g5[] = @encode(basic_string); // PR10990 struct CefBase { virtual ~CefBase() {} }; struct CefBrowser : public virtual CefBase {}; struct CefBrowserImpl : public CefBrowser {}; // CHECK: @g6 ={{.*}} constant [21 x i8] c"{CefBrowserImpl=^^?}\00" extern const char g6[] = @encode(CefBrowserImpl); // PR10990_2 struct CefBase2 { virtual ~CefBase2() {} int i; }; struct CefBrowser2 : public virtual CefBase2 {}; struct CefBrowserImpl2 : public CefBrowser2 {}; // CHECK: @g7 ={{.*}} constant [26 x i8] c"{CefBrowserImpl2=^^?^^?i}\00" extern const char g7[] = @encode(CefBrowserImpl2); struct Empty {}; struct X : Empty { int array[10]; }; struct Y : Empty { X vec; }; // CHECK: @g8 ={{.*}} constant [14 x i8] c"{Y={X=[10i]}}\00" extern const char g8[] = @encode(Y); class dynamic_class { public: virtual ~dynamic_class(); }; @interface has_dynamic_class_ivar @end @implementation has_dynamic_class_ivar { dynamic_class dynamic_class_ivar; } @end // CHECK: private unnamed_addr constant [41 x i8] c"{dynamic_class=\22_vptr$dynamic_class\22^^?}\00" namespace PR17142 { struct A { virtual ~A(); }; struct B : virtual A { int y; }; struct C { virtual ~C(); int z; }; struct D : C, B { int a; }; struct E : D {}; // CHECK: @_ZN7PR171421xE ={{.*}} constant [14 x i8] c"{E=^^?i^^?ii}\00" extern const char x[] = @encode(E); } // This test used to cause infinite recursion. template struct S { typedef T Ty; Ty *t; }; @interface N { S a; } @end @implementation N @end const char *expand_struct() { // CHECK: @{{.*}} = private unnamed_addr constant [13 x i8] c"{N={S=@}}\00" return @encode(N); } #if __cplusplus >= 202002L namespace PR48048 { struct F {}; struct I { int m; [[no_unique_address]] F n; }; // CHECKCXX20: @_ZN7PR480481xE ={{.*}} constant [6 x i8] c"{I=i}\00" extern const char x[] = @encode(I); } #endif namespace test_cxx_template_specialization { template struct B0 { T a; }; struct D0 : B0 {}; struct D1 : D0 {}; struct D2 : virtual B0 {}; struct S0 { B0 a; }; struct S1 { B0 *a; }; struct S2 { S1 *a; }; template union U0 { T a; }; typedef B0 TD0; typedef B0 *Array0[4]; template struct Outer0 { struct Inner0 { int a; }; template struct Inner1 { T a; T1 b; }; }; // CHECK: @[[STR22:.*]] = {{.*}} [12 x i8] c"{B0=i}\00" // CHECK: @_ZN32test_cxx_template_specialization2b0E = global ptr @[[STR22]] // CHECK-NO-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [3 x i8] c"^v\00" // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]] // CHECK-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [13 x i8] c"^{B0=i}\00" // CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b02E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d0E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d1E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d2E = global ptr @[[STR23]] // CHECK: @[[STR24:.*]] = {{.*}} [7 x i8] c"^^{D2}\00" // CHECK: @_ZN32test_cxx_template_specialization3d21E = global ptr @[[STR24]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s0E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s1E = global ptr @[[STR23]] // CHECK: @[[STR25:.*]] = {{.*}} [12 x i8] c"^{S2=^{S1}}\00" // CHECK: @_ZN32test_cxx_template_specialization2s2E = global ptr @[[STR25]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2u0E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3td0E = global ptr @[[STR23]] // CHECK-NO-TEMP-SPEC: @[[STR26:.*]] = {{.*}} [6 x i8] c"[4^v]\00" // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2a0E = global ptr @[[STR26]] // CHECK: @[[STR27:.*]] = {{.*}} [11 x i8] c"^{Inner0=}\00" // CHECK: @_ZN32test_cxx_template_specialization6inner0E = global ptr @[[STR27]] // CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @.str.23 // CHECK-TEMP-SPEC: @[[STR34:.*]] = {{.*}} [18 x i8] c"^{Inner1=}\00" // CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @[[STR34]] const char *b0 = @encode(B0); const char *b01 = @encode(B0 *); const char *b02 = @encode(B0 &); const char *d0 = @encode(D0 *); const char *d1 = @encode(D1 *); const char *d2 = @encode(D2 *); const char *d21 = @encode(D2 **); const char *s0 = @encode(S0 *); const char *s1 = @encode(S1 *); const char *s2 = @encode(S2 *); const char *u0 = @encode(U0 *); const char *td0 = @encode(TD0 *); const char *a0 = @encode(Array0); const char *inner0 = @encode(Outer0::Inner0 *); const char *inner1 = @encode(Outer0::Inner1 *); } #if __cplusplus >= 202002L namespace GH71250 { struct Empty {}; struct S { [[no_unique_address]] Empty a; long b; long c; }; // CHECKCXX20: @_ZN7GH712501sE = constant [7 x i8] c"{S=qq}\00", align 1 extern const char s[] = @encode(S); } #endif