Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10
      2 // RUN: FileCheck %s < %t.ll
      3 // RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll
      4 
      5 struct A { int a; int b; };
      6 struct B { int b; };
      7 struct C : B, A { };
      8 
      9 // Zero init.
     10 namespace ZeroInit {
     11   // CHECK-GLOBAL: @_ZN8ZeroInit1aE = global i64 -1
     12   int A::* a;
     13 
     14   // CHECK-GLOBAL: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
     15   int A::* aa[2];
     16 
     17   // CHECK-GLOBAL: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
     18   int A::* aaa[2][2];
     19 
     20   // CHECK-GLOBAL: @_ZN8ZeroInit1bE = global i64 -1,
     21   int A::* b = 0;
     22 
     23   // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }
     24   struct {
     25     int A::*a;
     26   } sa;
     27   void test_sa() { (void) sa; } // force emission
     28 
     29   // CHECK-GLOBAL: @_ZN8ZeroInit3ssaE = internal
     30   // CHECK-GLOBAL: [2 x i64] [i64 -1, i64 -1]
     31   struct {
     32     int A::*aa[2];
     33   } ssa[2];
     34   void test_ssa() { (void) ssa; }
     35 
     36   // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } }
     37   struct {
     38     struct {
     39       int A::*pa;
     40     } s;
     41   } ss;
     42   void test_ss() { (void) ss; }
     43 
     44   struct A {
     45     int A::*a;
     46     int b;
     47   };
     48 
     49   struct B {
     50     A a[10];
     51     char c;
     52     int B::*b;
     53   };
     54 
     55   struct C : A, B { int j; };
     56   // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} <{ %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.ZeroInit::A"] [%"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0, [4 x i8] zeroinitializer }>, align 8
     57   C c;
     58 }
     59 
     60 // PR5674
     61 namespace PR5674 {
     62   // CHECK-GLOBAL: @_ZN6PR56742pbE = global i64 4
     63   int A::*pb = &A::b;
     64 }
     65 
     66 // Casts.
     67 namespace Casts {
     68 
     69 int A::*pa;
     70 int C::*pc;
     71 
     72 void f() {
     73   // CHECK:      store i64 -1, i64* @_ZN5Casts2paE
     74   pa = 0;
     75 
     76   // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2paE, align 8
     77   // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4
     78   // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
     79   // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
     80   // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE
     81   pc = pa;
     82 
     83   // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2pcE, align 8
     84   // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4
     85   // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
     86   // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
     87   // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2paE
     88   pa = static_cast<int A::*>(pc);
     89 }
     90 
     91 }
     92 
     93 // Comparisons
     94 namespace Comparisons {
     95   void f() {
     96     int A::*a;
     97 
     98     // CHECK: icmp ne i64 {{.*}}, -1
     99     if (a) { }
    100 
    101     // CHECK: icmp ne i64 {{.*}}, -1
    102     if (a != 0) { }
    103 
    104     // CHECK: icmp ne i64 -1, {{.*}}
    105     if (0 != a) { }
    106 
    107     // CHECK: icmp eq i64 {{.*}}, -1
    108     if (a == 0) { }
    109 
    110     // CHECK: icmp eq i64 -1, {{.*}}
    111     if (0 == a) { }
    112   }
    113 }
    114 
    115 namespace ValueInit {
    116 
    117 struct A {
    118   int A::*a;
    119 
    120   char c;
    121 
    122   A();
    123 };
    124 
    125 // CHECK-LABEL: define void @_ZN9ValueInit1AC2Ev(%"struct.ValueInit::A"* %this) unnamed_addr
    126 // CHECK: store i64 -1, i64*
    127 // CHECK: ret void
    128 A::A() : a() {}
    129 
    130 }
    131 
    132 namespace VirtualBases {
    133 
    134 struct A {
    135   char c;
    136   int A::*i;
    137 };
    138 
    139 // CHECK-GLOBAL: @_ZN12VirtualBases1bE = global %"struct.VirtualBases::B" { i32 (...)** null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
    140 struct B : virtual A { };
    141 B b;
    142 
    143 // CHECK-GLOBAL: @_ZN12VirtualBases1cE = global %"struct.VirtualBases::C" { i32 (...)** null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
    144 struct C : virtual A { int A::*i; };
    145 C c;
    146 
    147 // CHECK-GLOBAL: @_ZN12VirtualBases1dE = global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
    148 struct D : C { int A::*i; };
    149 D d;
    150 
    151 }
    152 
    153 namespace Test1 {
    154 
    155 // Don't crash when A contains a bit-field.
    156 struct A {
    157   int A::* a;
    158   int b : 10;
    159 };
    160 A a;
    161 
    162 }
    163 
    164 namespace BoolPtrToMember {
    165   struct X {
    166     bool member;
    167   };
    168 
    169   // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
    170   bool &f(X &x, bool X::*member) {
    171     // CHECK: {{bitcast.* to i8\*}}
    172     // CHECK-NEXT: getelementptr inbounds i8, i8*
    173     // CHECK-NEXT: ret i8*
    174     return x.*member;
    175   }
    176 }
    177 
    178 namespace PR8507 {
    179 
    180 struct S;
    181 void f(S* p, double S::*pm) {
    182   if (0 < p->*pm) {
    183   }
    184 }
    185 
    186 }
    187 
    188 namespace test4 {
    189   struct A             { int A_i; };
    190   struct B : virtual A { int A::*B_p; };
    191   struct C : virtual B { int    *C_p; };
    192   struct D :         C { int    *D_p; };
    193 
    194   // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
    195   D d;
    196 }
    197 
    198 namespace PR11487 {
    199   union U
    200   {
    201     int U::* mptr;
    202     char x[16];
    203   } x;
    204   // CHECK-GLOBAL: @_ZN7PR114871xE = global %"union.PR11487::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
    205 
    206 }
    207 
    208 namespace PR13097 {
    209   struct X { int x; X(const X&); };
    210   struct A {
    211     int qq;
    212       X x;
    213   };
    214   A f();
    215   X g() { return f().*&A::x; }
    216   // CHECK-LABEL: define void @_ZN7PR130971gEv
    217   // CHECK: call void @_ZN7PR130971fEv
    218   // CHECK-NOT: memcpy
    219   // CHECK: call void @_ZN7PR130971XC1ERKS0_
    220 }
    221 
    222 namespace PR21089 {
    223 struct A {
    224   bool : 1;
    225   int A::*x;
    226   bool y;
    227   A();
    228 };
    229 struct B : A {
    230 };
    231 B b;
    232 // CHECK-GLOBAL: @_ZN7PR210891bE = global %"struct.PR21089::B" { %"struct.PR21089::A.base" <{ i8 0, [7 x i8] zeroinitializer, i64 -1, i8 0 }>, [7 x i8] zeroinitializer }, align 8
    233 }
    234 
    235 namespace PR21282 {
    236 union U {
    237   int U::*x;
    238   long y[2];
    239 };
    240 U u;
    241 // CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
    242 }
    243 
    244 namespace FlexibleArrayMember {
    245 struct S {
    246   int S::*x[];
    247 };
    248 S s;
    249 // CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
    250 }
    251 
    252 namespace IndirectPDM {
    253 union U {
    254   union {
    255     int U::*m;
    256   };
    257 };
    258 U u;
    259 // CHECK-GLOBAL: @_ZN11IndirectPDM1uE = global %"union.IndirectPDM::U" { %union.anon { i64 -1 } }, align 8
    260 }
    261