[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / CodeGenObjC / arc-property.m
blobf57be6b4f6be410a2534baa902ae35d61db42f3e
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -emit-llvm %s -o - | FileCheck %s
3 @interface Test0
4 - (void) setValue: (id) x;
5 @end
6 void test0(Test0 *t0, id value) {
7   t0.value = value;
9 // CHECK-LABEL: define{{.*}} void @test0(
10 // CHECK: call void @llvm.objc.storeStrong
11 // CHECK: call void @llvm.objc.storeStrong
12 // CHECK: @objc_msgSend
13 // CHECK: call void @llvm.objc.storeStrong(
14 // CHECK: call void @llvm.objc.storeStrong(
16 struct S1 { Class isa; };
17 @interface Test1
18 @property (nonatomic, strong) __attribute__((NSObject)) struct S1 *pointer;
19 @end
20 @implementation Test1
21 @synthesize pointer;
22 @end
23 //   The getter should be a simple load.
24 // CHECK:    define internal ptr @"\01-[Test1 pointer]"(
25 // CHECK:      [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
26 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 [[OFFSET]]
27 // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T1]], align 8
28 // CHECK-NEXT: ret ptr [[T3]]
30 //   The setter should be using objc_setProperty.
31 // CHECK:    define internal void @"\01-[Test1 setPointer:]"(
32 // CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
33 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
34 // CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext false, i1 noundef zeroext false)
35 // CHECK-NEXT: ret void
38 @interface Test2 {
39 @private
40   Class _theClass;
42 @property (copy) Class theClass;
43 @end
45 static Class theGlobalClass;
46 @implementation Test2
47 @synthesize theClass = _theClass;
48 - (void) test {
49   _theClass = theGlobalClass;
51 @end
52 // CHECK:    define internal void @"\01-[Test2 test]"(
53 // CHECK:      [[T0:%.*]] = load ptr, ptr @theGlobalClass, align 8
54 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr
55 // CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
56 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[OFFSET]]
57 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T3]], ptr [[T0]]) [[NUW:#[0-9]+]]
58 // CHECK-NEXT: ret void
60 // CHECK:    define internal ptr @"\01-[Test2 theClass]"(
61 // CHECK:      [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
62 // CHECK-NEXT: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef [[OFFSET]], i1 noundef zeroext true)
63 // CHECK-NEXT: ret ptr [[T0]]
65 // CHECK:    define internal void @"\01-[Test2 setTheClass:]"(
66 // CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
67 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
68 // CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext true, i1 noundef zeroext true)
69 // CHECK-NEXT: ret void
71 // CHECK:    define internal void @"\01-[Test2 .cxx_destruct]"(
72 // CHECK:      [[T0:%.*]] = load ptr, ptr
73 // CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
74 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[OFFSET]]
75 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T2]], ptr null) [[NUW]]
76 // CHECK-NEXT: ret void
78 @interface Test3
79 @property id copyMachine;
80 @end
82 void test3(Test3 *t) {
83   id x = t.copyMachine;
84   x = [t copyMachine];
86 // CHECK:    define{{.*}} void @test3(ptr
87 //   Prologue.
88 // CHECK:      [[T:%.*]] = alloca ptr,
89 // CHECK-NEXT: [[X:%.*]] = alloca ptr,
90 //   Property access.
91 // CHECK:      [[T0:%.*]] = load ptr, ptr [[T]],
92 // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
93 // CHECK-NEXT: [[T2:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])
94 // CHECK-NEXT: store ptr [[T2]], ptr [[X]],
95 //   Message send.
96 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]],
97 // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
98 // CHECK-NEXT: [[T2:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])
99 // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[X]],
100 // CHECK-NEXT: store ptr [[T2]], ptr [[X]],
101 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]])
102 //   Epilogue.
103 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
104 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T]], ptr null)
105 // CHECK-NEXT: ret void
107 @implementation Test3
108 - (id) copyMachine {
109   extern id test3_helper(void);
110   return test3_helper();
112 // CHECK:    define internal ptr @"\01-[Test3 copyMachine]"(
113 // CHECK:      [[T0:%.*]] = call ptr @test3_helper()
114 // CHECK-NEXT: [[T1:%.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]])
115 // CHECK-NEXT: ret ptr [[T1]]
116 - (void) setCopyMachine: (id) x {}
117 @end
119 // When synthesizing a property that's declared in multiple protocols, ensure
120 // that the setter is emitted if any of these declarations is readwrite.
121 @protocol ABC
122 @property (copy, nonatomic,  readonly) Test3 *someId;
123 @end
124 @protocol ABC__Mutable <ABC>
125 @property (copy, nonatomic, readwrite) Test3 *someId;
126 @end
128 @interface ABC_Class <ABC, ABC__Mutable>
129 @end
131 @implementation ABC_Class
132 @synthesize someId = _someId;
133 // CHECK:  define internal ptr @"\01-[ABC_Class someId]"
134 // CHECK:  define internal void @"\01-[ABC_Class setSomeId:]"(
135 @end
138 // CHECK: attributes [[NUW]] = { nounwind }