Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -debug-info-kind=limited -o - | FileCheck %s
      2 
      3 class S {
      4 public:
      5 	S& operator = (const S&);
      6 	S (const S&);
      7 	S ();
      8 };
      9 
     10 struct CGRect {
     11 	CGRect & operator = (const CGRect &);
     12 };
     13 
     14 @interface I {
     15   S position;
     16   CGRect bounds;
     17 }
     18 
     19 @property(assign, nonatomic) S position;
     20 @property CGRect bounds;
     21 @property CGRect frame;
     22 - (void)setFrame:(CGRect)frameRect;
     23 - (CGRect)frame;
     24 - (void) initWithOwner;
     25 - (CGRect)extent;
     26 - (void)dealloc;
     27 @end
     28 
     29 @implementation I
     30 @synthesize position;
     31 @synthesize bounds;
     32 @synthesize frame;
     33 
     34 // CHECK: define internal void @"\01-[I setPosition:]"
     35 // CHECK: call dereferenceable({{[0-9]+}}) %class.S* @_ZN1SaSERKS_
     36 // CHECK-NEXT: ret void
     37 
     38 // Don't attach debug locations to the prologue instructions. These were
     39 // leaking over from the previous function emission by accident.
     40 // CHECK: define internal void @"\01-[I setBounds:]"({{.*}} {
     41 // CHECK-NOT: !dbg
     42 // CHECK: call void @llvm.dbg.declare
     43 - (void)setFrame:(CGRect)frameRect {}
     44 - (CGRect)frame {return bounds;}
     45 
     46 - (void)initWithOwner {
     47   I* _labelLayer;
     48   CGRect labelLayerFrame = self.bounds;
     49   labelLayerFrame = self.bounds;
     50   _labelLayer.frame = labelLayerFrame;
     51 }
     52 
     53 // rdar://8366604
     54 - (void)dealloc
     55   {
     56       CGRect cgrect = self.extent;
     57   }
     58 - (struct CGRect)extent {return bounds;}
     59 
     60 @end
     61 
     62 // CHECK-LABEL: define i32 @main
     63 // CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* dereferenceable({{[0-9]+}}) {{%[a-zA-Z0-9\.]+}})
     64 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %class.S*)*)(i8* {{%[a-zA-Z0-9\.]+}}, i8* {{%[a-zA-Z0-9\.]+}}, %class.S* [[AGGTMP]])
     65 // CHECK-NEXT: ret i32 0
     66 int main() {
     67   I *i;
     68   S s1;
     69   i.position = s1;
     70   return 0;
     71 }
     72 
     73 // rdar://8379892
     74 // CHECK-LABEL: define void @_Z1fP1A
     75 // CHECK: call void @_ZN1XC1Ev(%struct.X* [[LVTEMP:%[a-zA-Z0-9\.]+]])
     76 // CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* dereferenceable({{[0-9]+}}) [[LVTEMP]])
     77 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.X*)*)({{.*}} %struct.X* [[AGGTMP]])
     78 struct X {
     79   X();
     80   X(const X&);
     81   ~X();
     82 };
     83 
     84 @interface A {
     85   X xval;
     86 }
     87 - (X)x;
     88 - (void)setX:(X)x;
     89 @end
     90 
     91 void f(A* a) {
     92   a.x = X();
     93 }
     94 
     95 // rdar://21801088
     96 //   Ensure that pseudo-objecet expressions that require the RHS to be
     97 //   rewritten don't result in crashes or redundant emission of code.
     98 struct B0 { long long x; };
     99 struct B1 { long long x; }; B1 operator+(B1, B1);
    100 struct B2 { B1 x; };
    101 struct B3 { B3(); B1 x; operator B1(); };
    102 @interface B
    103 @property B0 b0;
    104 @property B1 b1;
    105 @property B2 b2;
    106 @property B3 b3;
    107 @end
    108 
    109 int b_makeInt();
    110 
    111 // Note that there's a promotion from int to long long, so
    112 // the syntactic form of the RHS will be bogus.
    113 void testB0(B *b) {
    114   b.b0 = { b_makeInt() };
    115 }
    116 void testB1(B *b) {
    117   b.b1 += { b_makeInt() };
    118 }
    119 // CHECK:    define void @_Z6testB0P1B([[B:%.*]]*
    120 // CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
    121 // CHECK:      [[TEMP:%.*]] = alloca [[B0:%.*]], align 8
    122 // CHECK:      load [[B]]*, [[B]]** [[BVAR]]
    123 // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B0]], [[B0]]* [[TEMP]], i32 0, i32 0
    124 // CHECK-NEXT: [[T0:%.*]] = call i32 @_Z9b_makeIntv()
    125 // CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
    126 // CHECK-NEXT: store i64 [[T1]], i64* [[X]], align 8
    127 // CHECK-NOT:  call
    128 // CHECK:      call void @llvm.memcpy
    129 // CHECK-NOT:  call
    130 // CHECK:      call void bitcast {{.*}} @objc_msgSend
    131 // CHECK-NOT:  call
    132 // CHECK:      ret void
    133 
    134 // CHECK:    define void @_Z6testB1P1B([[B]]*
    135 // CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
    136 // CHECK:      load [[B]]*, [[B]]** [[BVAR]]
    137 // CHECK-NOT:  call
    138 // CHECK:      [[T0:%.*]] = call i64 bitcast {{.*}} @objc_msgSend
    139 // CHECK-NOT:  call
    140 // CHECK:      store i64 [[T0]],
    141 // CHECK-NOT:  call
    142 // CHECK:      [[T0:%.*]] = call i32 @_Z9b_makeIntv()
    143 // CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
    144 // CHECK-NEXT: store i64 [[T1]], i64* {{.*}}, align 8
    145 // CHECK-NOT:  call
    146 // CHECK:      [[T0:%.*]] = call i64 @_Zpl2B1S_
    147 // CHECK-NOT:  call
    148 // CHECK:      store i64 [[T0]],
    149 // CHECK-NOT:  call
    150 // CHECK:      call void @llvm.memcpy
    151 // CHECK-NOT:  call
    152 // CHECK:      call void bitcast {{.*}} @objc_msgSend
    153 // CHECK-NOT:  call
    154 // CHECK:      ret void
    155 
    156 // Another example of a conversion that needs to be applied
    157 // in the semantic form.
    158 void testB2(B *b) {
    159   b.b2 = { B3() };
    160 }
    161 
    162 // CHECK:    define void @_Z6testB2P1B([[B]]*
    163 // CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
    164 // CHECK:      load [[B]]*, [[B]]** [[BVAR]]
    165 // CHECK-NOT:  call
    166 // CHECK:      call void @_ZN2B3C1Ev(
    167 // CHECK-NEXT: [[T0:%.*]] = call i64 @_ZN2B3cv2B1Ev(
    168 // CHECK-NOT:  call
    169 // CHECK:      store i64 [[T0]],
    170 // CHECK-NOT:  call
    171 // CHECK:      call void @llvm.memcpy
    172 // CHECK-NOT:  call
    173 // CHECK:      call void bitcast {{.*}} @objc_msgSend
    174 // CHECK-NOT:  call
    175 // CHECK:      ret void
    176 
    177 // A similar test to B, but using overloaded function references.
    178 struct C1 {
    179   int x;
    180   friend C1 operator+(C1, void(&)());
    181 };
    182 @interface C
    183 @property void (*c0)();
    184 @property C1 c1;
    185 @end
    186 
    187 void c_helper();
    188 void c_helper(int);
    189 
    190 void testC0(C *c) {
    191   c.c0 = c_helper;
    192   c.c0 = &c_helper;
    193 }
    194 // CHECK:    define void @_Z6testC0P1C([[C:%.*]]*
    195 // CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
    196 // CHECK:      load [[C]]*, [[C]]** [[CVAR]]
    197 // CHECK-NOT:  call
    198 // CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
    199 // CHECK-NOT:  call
    200 // CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
    201 // CHECK-NOT:  call
    202 // CHECK:      ret void
    203 
    204 void testC1(C *c) {
    205   c.c1 += c_helper;
    206 }
    207 // CHECK:    define void @_Z6testC1P1C([[C]]*
    208 // CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
    209 // CHECK:      load [[C]]*, [[C]]** [[CVAR]]
    210 // CHECK-NOT:  call
    211 // CHECK:      [[T0:%.*]] = call i32 bitcast {{.*}} @objc_msgSend
    212 // CHECK-NOT:  call
    213 // CHECK:      store i32 [[T0]],
    214 // CHECK-NOT:  call
    215 // CHECK:      [[T0:%.*]] = call i32 @_Zpl2C1RFvvE({{.*}} @_Z8c_helperv
    216 // CHECK-NOT:  call
    217 // CHECK:      store i32 [[T0]],
    218 // CHECK-NOT:  call
    219 // CHECK:      call void @llvm.memcpy
    220 // CHECK-NOT:  call
    221 // CHECK:      call void bitcast {{.*}} @objc_msgSend
    222 // CHECK-NOT:  call
    223 // CHECK:      ret void
    224