1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
|