diff options
Diffstat (limited to 'clang/test/CodeGenObjCXX/property-reference.mm')
| -rw-r--r-- | clang/test/CodeGenObjCXX/property-reference.mm | 96 | 
1 files changed, 96 insertions, 0 deletions
| diff --git a/clang/test/CodeGenObjCXX/property-reference.mm b/clang/test/CodeGenObjCXX/property-reference.mm new file mode 100644 index 0000000..4897f6d --- /dev/null +++ b/clang/test/CodeGenObjCXX/property-reference.mm @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-fragile-abi -emit-llvm -o - | FileCheck %s +// rdar://9208606 + +struct MyStruct { +  int x; +  int y; +  int z; +}; + +@interface MyClass { +  MyStruct _foo; +} + +@property (assign, readwrite) const MyStruct& foo; + +- (const MyStruct&) foo; +- (void) setFoo:(const MyStruct&)inFoo; +@end + +void test0() { +  MyClass* myClass; +  MyStruct myStruct; + +  myClass.foo = myStruct; + +  const MyStruct& currentMyStruct = myClass.foo;    +} + +// CHECK: [[C:%.*]] = call %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend +// CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]] + +namespace test1 { +  struct A { A(); A(const A&); A&operator=(const A&); ~A(); }; +} +@interface Test1 { +  test1::A ivar; +} +@property (nonatomic) const test1::A &prop1; +@end +@implementation Test1 +@synthesize prop1 = ivar; +@end +// CHECK:    define internal [[A:%.*]]* @"\01-[Test1 prop1]"( +// CHECK:      [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8 +// CHECK:      [[T0:%.*]] = load [[TEST1]]** [[SELF]] +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 0 +// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* +// CHECK-NEXT: ret [[A]]* [[T3]] + +// CHECK:    define internal void @"\01-[Test1 setProp1:]"( +// CHECK:      call [[A]]* @_ZN5test11AaSERKS0_( +// CHECK-NEXT: ret void + +// rdar://problem/10497174 +@interface Test2 +@property int prop; +@end + +// The fact that these are all non-dependent is critical. +template <class T> void test2(Test2 *a) { +  int x = a.prop; +  a.prop = x; +  a.prop += x; +} +template void test2<int>(Test2*); +// CHECK: define weak_odr void @_Z5test2IiEvP5Test2( +// CHECK: [[X:%.*]] = alloca i32, +// CHECK:      @objc_msgSend +// CHECK:      store i32 {{%.*}}, i32* [[X]], +// CHECK:      load i32* [[X]], +// CHECK:      @objc_msgSend +// CHECK:      @objc_msgSend +// CHECK:      load i32* [[X]], +// CHECK-NEXT: add nsw +// CHECK:      @objc_msgSend +// CHECK-NEXT: ret void + +// Same as the previous test, but instantiation-dependent. +template <class T> void test3(Test2 *a) { +  int x = (sizeof(T), a).prop; +  a.prop = (sizeof(T), x); +  a.prop += (sizeof(T), x); +} +template void test3<int>(Test2*); +// CHECK: define weak_odr void @_Z5test3IiEvP5Test2( +// CHECK: [[X:%.*]] = alloca i32, +// CHECK:      @objc_msgSend +// CHECK:      store i32 {{%.*}}, i32* [[X]], +// CHECK:      load i32* [[X]], +// CHECK:      @objc_msgSend +// CHECK:      @objc_msgSend +// CHECK:      load i32* [[X]], +// CHECK-NEXT: add nsw +// CHECK:      @objc_msgSend +// CHECK-NEXT: ret void | 
