Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -O1 -o - %s | FileCheck %s
      2 // RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -std=c++03 -O0 -o - %s | FileCheck --check-prefix=CHECK-2 %s
      3 
      4 struct POD {
      5   int w, x, y, z;
      6 };
      7 
      8 struct PODLike {
      9   int w, x, y, z;
     10   PODLike();
     11   ~PODLike();
     12 };
     13 
     14 struct NonPOD {
     15   NonPOD();
     16   NonPOD(const NonPOD&);
     17   NonPOD& operator=(const NonPOD&);
     18 };
     19 
     20 struct Basic {
     21   int a, b, c, d;
     22   NonPOD np;
     23   int w, x, y, z;
     24 };
     25 
     26 struct PODMember {
     27   int a, b, c, d;
     28   POD p;
     29   NonPOD np;
     30   int w, x, y, z;
     31 };
     32 
     33 struct PODLikeMember {
     34   int a, b, c, d;
     35   PODLike pl;
     36   NonPOD np;
     37   int w, x, y, z;
     38 };
     39 
     40 struct ArrayMember {
     41   int a, b, c, d;
     42   int e[12];
     43   NonPOD np;
     44   int f[12];
     45   int w, x, y, z;
     46 };
     47 
     48 struct VolatileMember {
     49   int a, b, c, d;
     50   volatile int v;
     51   NonPOD np;
     52   int w, x, y, z;
     53 };
     54 
     55 struct BitfieldMember {
     56   int a, b, c, d;
     57   NonPOD np;
     58   int w : 6;
     59   int x : 6;
     60   int y : 6;
     61   int z : 6;
     62 };
     63 
     64 struct BitfieldMember2 {
     65   unsigned a : 1;
     66   unsigned b, c, d;
     67   NonPOD np;
     68 };
     69 
     70 struct InnerClassMember {
     71   struct {
     72     int a, b, c, d;
     73   } a;
     74   int b, c, d, e;
     75   NonPOD np;
     76   int w, x, y, z;
     77 };
     78 
     79 struct ReferenceMember {
     80   ReferenceMember(int &a, int &b, int &c, int &d)
     81     : a(a), b(b), c(c), d(d) {}
     82   int &a;
     83   int &b;
     84   NonPOD np;
     85   int &c;
     86   int &d;
     87 };
     88 
     89 struct __attribute__((packed)) PackedMembers {
     90   char c;
     91   NonPOD np;
     92   int w, x, y, z;
     93 };
     94 
     95 // COPY-ASSIGNMENT OPERATORS:
     96 
     97 // Assignment operators are output in the order they're encountered.
     98 
     99 #define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; }
    100 
    101 CALL_AO(Basic)
    102 CALL_AO(PODMember)
    103 CALL_AO(PODLikeMember)
    104 CALL_AO(ArrayMember)
    105 CALL_AO(VolatileMember)
    106 CALL_AO(BitfieldMember)
    107 CALL_AO(InnerClassMember)
    108 CALL_AO(PackedMembers)
    109 
    110 // Basic copy-assignment:
    111 // CHECK: define linkonce_odr %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic*)
    112 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    113 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    114 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    115 // CHECK: ret %struct.Basic* %this
    116 
    117 // PODMember copy-assignment:
    118 // CHECK: define linkonce_odr %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember*)
    119 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    120 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    121 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    122 // CHECK: ret %struct.PODMember* %this
    123 
    124 // PODLikeMember copy-assignment:
    125 // CHECK: define linkonce_odr %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
    126 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    127 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    128 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    129 // CHECK: ret %struct.PODLikeMember* %this
    130 
    131 // ArrayMember copy-assignment:
    132 // CHECK: define linkonce_odr %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
    133 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
    134 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    135 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
    136 // CHECK: ret %struct.ArrayMember* %this
    137 
    138 // VolatileMember copy-assignment:
    139 // CHECK: define linkonce_odr %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
    140 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    141 // CHECK: load volatile i32* {{.*}}, align 4
    142 // CHECK: store volatile i32 {{.*}}, align 4
    143 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    144 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    145 // CHECK: ret %struct.VolatileMember* %this
    146 
    147 // BitfieldMember copy-assignment:
    148 // CHECK: define linkonce_odr %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
    149 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    150 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    151 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
    152 // CHECK: ret %struct.BitfieldMember* %this
    153 
    154 // InnerClass copy-assignment:
    155 // CHECK: define linkonce_odr %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
    156 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    157 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    158 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    159 // CHECK: ret %struct.InnerClassMember* %this
    160 
    161 // PackedMembers copy-assignment:
    162 // CHECK: define linkonce_odr %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
    163 // CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
    164 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
    165 // CHECK: ret %struct.PackedMembers* %this
    166 
    167 // COPY-CONSTRUCTORS:
    168 
    169 // Clang outputs copy-constructors in the reverse of the order that
    170 // copy-constructor calls are encountered. Add functions that call the copy
    171 // constructors of the classes above in reverse order here.
    172 
    173 #define CALL_CC(T) T callCC##T(const T& b) { return b; }
    174 
    175 CALL_CC(PackedMembers)
    176 CALL_CC(BitfieldMember2)
    177 CALL_CC(ReferenceMember)
    178 CALL_CC(InnerClassMember)
    179 CALL_CC(BitfieldMember)
    180 CALL_CC(VolatileMember)
    181 CALL_CC(ArrayMember)
    182 CALL_CC(PODLikeMember)
    183 CALL_CC(PODMember)
    184 CALL_CC(Basic)
    185 
    186 // Basic copy-constructor:
    187 // CHECK: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic*)
    188 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    189 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    190 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    191 // CHECK: ret void
    192 
    193 // PODMember copy-constructor:
    194 // CHECK: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember*)
    195 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    196 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    197 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    198 // CHECK: ret void
    199 
    200 // PODLikeMember copy-constructor:
    201 // CHECK: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
    202 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    203 // CHECK: invoke void @_ZN6NonPODC1ERKS_
    204 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    205 // CHECK: ret void
    206 // CHECK: landingpad
    207 // CHECK: invoke void @_ZN7PODLikeD1Ev
    208 
    209 // ArrayMember copy-constructor:
    210 // CHECK: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
    211 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
    212 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    213 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
    214 // CHECK: ret void
    215 
    216 // VolatileMember copy-constructor:
    217 // CHECK: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
    218 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    219 // CHECK: load volatile i32* {{.*}}, align 4
    220 // CHECK: store volatile i32 {{.*}}, align 4
    221 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    222 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    223 // CHECK: ret void
    224 
    225 // BitfieldMember copy-constructor:
    226 // CHECK: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
    227 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    228 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    229 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
    230 // CHECK: ret void
    231 
    232 // InnerClass copy-constructor:
    233 // CHECK: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
    234 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
    235 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    236 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
    237 // CHECK: ret void
    238 
    239 // ReferenceMember copy-constructor:
    240 // CHECK: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember*)
    241 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
    242 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    243 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
    244 // CHECK: ret void
    245 
    246 // BitfieldMember2 copy-constructor:
    247 // CHECK-2: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2*)
    248 // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false)
    249 // CHECK-2: call void @_ZN6NonPODC1ERKS_
    250 // CHECK-2: ret void
    251 
    252 // PackedMembers copy-assignment:
    253 // CHECK: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
    254 // CHECK: tail call void @_ZN6NonPODC1ERKS_
    255 // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
    256 // CHECK: ret void
    257