summaryrefslogtreecommitdiff
path: root/clang/test/CodeGenObjCXX/property-reference.mm
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenObjCXX/property-reference.mm')
-rw-r--r--clang/test/CodeGenObjCXX/property-reference.mm96
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