Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s
      2 // rdar://9208606
      3 
      4 struct MyStruct {
      5   int x;
      6   int y;
      7   int z;
      8 };
      9 
     10 @interface MyClass {
     11   MyStruct _foo;
     12 }
     13 
     14 @property (assign, readwrite) const MyStruct& foo;
     15 
     16 - (const MyStruct&) foo;
     17 - (void) setFoo:(const MyStruct&)inFoo;
     18 @end
     19 
     20 void test0() {
     21   MyClass* myClass;
     22   MyStruct myStruct;
     23 
     24   myClass.foo = myStruct;
     25 
     26   const MyStruct& currentMyStruct = myClass.foo;   
     27 }
     28 
     29 // CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
     30 // CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
     31 
     32 namespace test1 {
     33   struct A { A(); A(const A&); A&operator=(const A&); ~A(); };
     34 }
     35 @interface Test1 {
     36   test1::A ivar;
     37 }
     38 @property (nonatomic) const test1::A &prop1;
     39 @end
     40 @implementation Test1
     41 @synthesize prop1 = ivar;
     42 @end
     43 // CHECK:    define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"(
     44 // CHECK:      [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8
     45 // CHECK:      [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** [[SELF]]
     46 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     47 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 0
     48 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
     49 // CHECK-NEXT: ret [[A]]* [[T3]]
     50 
     51 // CHECK:    define internal void @"\01-[Test1 setProp1:]"(
     52 // CHECK:      call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_(
     53 // CHECK-NEXT: ret void
     54 
     55 // rdar://problem/10497174
     56 @interface Test2
     57 @property int prop;
     58 @end
     59 
     60 // The fact that these are all non-dependent is critical.
     61 template <class T> void test2(Test2 *a) {
     62   int x = a.prop;
     63   a.prop = x;
     64   a.prop += x;
     65 }
     66 template void test2<int>(Test2*);
     67 // CHECK-LABEL: define weak_odr void @_Z5test2IiEvP5Test2(
     68 // CHECK: [[X:%.*]] = alloca i32,
     69 // CHECK:      @objc_msgSend
     70 // CHECK:      store i32 {{%.*}}, i32* [[X]],
     71 // CHECK:      load i32, i32* [[X]],
     72 // CHECK:      @objc_msgSend
     73 // CHECK:      @objc_msgSend
     74 // CHECK:      load i32, i32* [[X]],
     75 // CHECK-NEXT: add nsw
     76 // CHECK:      @objc_msgSend
     77 // CHECK-NEXT: ret void
     78 
     79 // Same as the previous test, but instantiation-dependent.
     80 template <class T> void test3(Test2 *a) {
     81   int x = (sizeof(T), a).prop;
     82   a.prop = (sizeof(T), x);
     83   a.prop += (sizeof(T), x);
     84 }
     85 template void test3<int>(Test2*);
     86 // CHECK-LABEL: define weak_odr void @_Z5test3IiEvP5Test2(
     87 // CHECK: [[X:%.*]] = alloca i32,
     88 // CHECK:      @objc_msgSend
     89 // CHECK:      store i32 {{%.*}}, i32* [[X]],
     90 // CHECK:      load i32, i32* [[X]],
     91 // CHECK:      @objc_msgSend
     92 // CHECK:      @objc_msgSend
     93 // CHECK:      load i32, i32* [[X]],
     94 // CHECK-NEXT: add nsw
     95 // CHECK:      @objc_msgSend
     96 // CHECK-NEXT: ret void
     97