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 |