llvm-project

Форк
0
245 строк · 7.8 Кб
1
// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
2

3
struct my_complex_struct {
4
  int a, b;
5
};
6

7
struct my_aggregate_struct {
8
  int a, b;
9
  char buf[128];
10
};
11

12
__attribute__((objc_root_class))
13
@interface Root
14
- (int)getInt __attribute__((objc_direct));
15
@property(direct, readonly) int intProperty;
16
@property(direct, readonly) int intProperty2;
17
@property(direct, readonly) id objectProperty;
18
@end
19

20
@implementation Root
21
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty2]"
22
- (int)intProperty2 {
23
  return 42;
24
}
25

26
// CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"(
27
- (int)getInt __attribute__((objc_direct)) {
28
  // loading parameters
29
  // CHECK-LABEL: entry:
30
  // CHECK-NEXT: [[RETVAL:%.*]] = alloca
31
  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
32
  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
33

34
  // self nil-check
35
  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
36
  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
37
  // CHECK-NEXT: br i1 [[NILCHECK]],
38

39
  // setting return value to nil
40
  // CHECK-LABEL: objc_direct_method.self_is_nil:
41
  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
42
  // CHECK-NEXT: br label
43

44
  // set value
45
  // CHECK-LABEL: objc_direct_method.cont:
46
  // CHECK: store{{.*}}[[RETVAL]],
47
  // CHECK-NEXT: br label
48

49
  // return
50
  // CHECK-LABEL: return:
51
  // CHECK: {{%.*}} = load{{.*}}[[RETVAL]],
52
  // CHECK-NEXT: ret
53
  return 42;
54
}
55

56
// CHECK-LABEL: define hidden i32 @"\01+[Root classGetInt]"(
57
+ (int)classGetInt __attribute__((objc_direct)) {
58
  // loading parameters
59
  // CHECK-LABEL: entry:
60
  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
61
  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
62

63
  // [self self]
64
  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
65
  // CHECK-NEXT: [[SELFSEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
66
  // CHECK-NEXT: [[SELF0:%.*]] = call {{.*}} @objc_msgSend
67
  // CHECK-NEXT: store ptr [[SELF0]], ptr [[SELFADDR]],
68

69
  // return
70
  // CHECK-NEXT: ret
71
  return 42;
72
}
73

74
// CHECK-LABEL: define hidden i64 @"\01-[Root getComplex]"(
75
- (struct my_complex_struct)getComplex __attribute__((objc_direct)) {
76
  // loading parameters
77
  // CHECK-LABEL: entry:
78
  // CHECK-NEXT: [[RETVAL:%.*]] = alloca
79
  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
80
  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
81

82
  // self nil-check
83
  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
84
  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
85
  // CHECK-NEXT: br i1 [[NILCHECK]],
86

87
  // setting return value to nil
88
  // CHECK-LABEL: objc_direct_method.self_is_nil:
89
  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
90
  // CHECK-NEXT: br label
91

92
  // set value
93
  // CHECK-LABEL: objc_direct_method.cont:
94
  // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RETVAL]],
95
  // CHECK-NEXT: br label
96

97
  // return
98
  // CHECK-LABEL: return:
99
  // CHECK-NEXT: {{%.*}} = load{{.*}}[[RETVAL]],
100
  // CHECK-NEXT: ret
101
  struct my_complex_struct st = {.a = 42};
102
  return st;
103
}
104

105
// CHECK-LABEL: define hidden i64 @"\01+[Root classGetComplex]"(
106
+ (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) {
107
  struct my_complex_struct st = {.a = 42};
108
  return st;
109
  // CHECK: ret i64
110
}
111

112
// CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"(
113
- (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) {
114
  // CHECK: ptr dead_on_unwind noalias writable sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]],
115

116
  // loading parameters
117
  // CHECK-LABEL: entry:
118
  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
119
  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
120

121
  // self nil-check
122
  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
123
  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
124
  // CHECK-NEXT: br i1 [[NILCHECK]],
125

126
  // setting return value to nil
127
  // CHECK-LABEL: objc_direct_method.self_is_nil:
128
  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
129
  // CHECK-NEXT: br label
130

131
  // set value
132
  // CHECK-LABEL: objc_direct_method.cont:
133
  // CHECK: br label
134

135
  // return
136
  // CHECK-LABEL: return:
137
  // CHECK: ret void
138
  struct my_aggregate_struct st = {.a = 42};
139
  return st;
140
}
141

142
// CHECK-LABEL: define hidden void @"\01+[Root classGetAggregate]"(
143
+ (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {
144
  struct my_aggregate_struct st = {.a = 42};
145
  return st;
146
  // CHECK: ret void
147
}
148

149
// CHECK-LABEL: define hidden void @"\01-[Root accessCmd]"(
150
- (void)accessCmd __attribute__((objc_direct)) {
151
  // CHECK-LABEL: entry:
152
  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
153
  // CHECK-NEXT: [[CMDVAL:%_cmd]] = alloca ptr,
154

155
  // loading the _cmd selector
156
  // CHECK-LABEL: objc_direct_method.cont:
157
  // CHECK-NEXT: [[CMD1:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
158
  // CHECK-NEXT: store ptr [[CMD1]], ptr [[CMDVAL]],
159
  SEL sel = _cmd;
160
}
161

162
@end
163
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]"
164

165
// Check the synthesized objectProperty calls objc_getProperty(); this also
166
// checks that the synthesized method passes undef for the `cmd` argument.
167
// CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(
168
// CHECK-LABEL: objc_direct_method.cont:
169
// CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,
170
// CHECK-NEXT: [[IVAR:%.*]] = load {{.*}} @"OBJC_IVAR_$_Root._objectProperty",
171
// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef [[IVAR]], {{.*}})
172

173
@interface Foo : Root {
174
  id __strong _cause_cxx_destruct;
175
}
176
@property(nonatomic, readonly, direct) int getDirect_setDynamic;
177
@property(nonatomic, readonly) int getDynamic_setDirect;
178
@end
179

180
@interface Foo ()
181
@property(nonatomic, readwrite) int getDirect_setDynamic;
182
@property(nonatomic, readwrite, direct) int getDynamic_setDirect;
183
- (int)directMethodInExtension __attribute__((objc_direct));
184
@end
185

186
@interface Foo (Cat)
187
- (int)directMethodInCategory __attribute__((objc_direct));
188
@end
189

190
__attribute__((objc_direct_members))
191
@implementation Foo
192
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInExtension]"(
193
- (int)directMethodInExtension {
194
  return 42;
195
}
196
// CHECK-LABEL: define hidden i32 @"\01-[Foo getDirect_setDynamic]"(
197
// CHECK-LABEL: define internal void @"\01-[Foo setGetDirect_setDynamic:]"(
198
// CHECK-LABEL: define internal i32 @"\01-[Foo getDynamic_setDirect]"(
199
// CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"(
200
// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"(
201
@end
202

203
@implementation Foo (Cat)
204
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategory]"(
205
- (int)directMethodInCategory {
206
  return 42;
207
}
208
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategoryNoDecl]"(
209
- (int)directMethodInCategoryNoDecl __attribute__((objc_direct)) {
210
  return 42;
211
}
212
@end
213

214
int useRoot(Root *r) {
215
  // CHECK-LABEL: define{{.*}} i32 @useRoot
216
  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root getInt]"
217
  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty]"
218
  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty2]"
219
  return [r getInt] + [r intProperty] + [r intProperty2];
220
}
221

222
int useFoo(Foo *f) {
223
  // CHECK-LABEL: define{{.*}} i32 @useFoo
224
  // CHECK: call void @"\01-[Foo setGetDynamic_setDirect:]"
225
  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo getDirect_setDynamic]"
226
  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInExtension]"
227
  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategory]"
228
  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategoryNoDecl]"
229
  [f setGetDynamic_setDirect:1];
230
  return [f getDirect_setDynamic] +
231
         [f directMethodInExtension] +
232
         [f directMethodInCategory] +
233
         [f directMethodInCategoryNoDecl];
234
}
235

236
__attribute__((objc_root_class))
237
@interface RootDeclOnly
238
@property(direct, readonly) int intProperty;
239
@end
240

241
int useRootDeclOnly(RootDeclOnly *r) {
242
  // CHECK-LABEL: define{{.*}} i32 @useRootDeclOnly
243
  // CHECK: %{{[^ ]*}} = call i32 @"\01-[RootDeclOnly intProperty]"
244
  return [r intProperty];
245
}
246

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.