[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGenObjCXX / property-reference.mm
blobc07ecd9a955488061d464d8b839d29f589b6a4b2
1 // RUN: %clang_cc1 -no-opaque-pointers %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s
2 // rdar://9208606
4 struct MyStruct {
5   int x;
6   int y;
7   int z;
8 };
10 @interface MyClass {
11   MyStruct _foo;
14 @property (assign, readwrite) const MyStruct& foo;
16 - (const MyStruct&) foo;
17 - (void) setFoo:(const MyStruct&)inFoo;
18 @end
20 void test0() {
21   MyClass* myClass;
22   MyStruct myStruct;
24   myClass.foo = myStruct;
26   const MyStruct& currentMyStruct = myClass.foo;   
29 // CHECK: [[C:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
30 // CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
32 namespace test1 {
33   struct A { A(); A(const A&); A&operator=(const A&); ~A(); };
35 @interface Test1 {
36   test1::A ivar;
38 @property (nonatomic) const test1::A &prop1;
39 @end
40 @implementation Test1
41 @synthesize prop1 = ivar;
42 @end
43 // CHECK:    define internal noundef nonnull align {{[0-9]+}} 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]]
51 // CHECK:    define internal void @"\01-[Test1 setProp1:]"(
52 // CHECK:      call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_(
53 // CHECK-NEXT: ret void
55 // rdar://problem/10497174
56 @interface Test2
57 @property int prop;
58 @end
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;
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
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);
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