/src/llvm-project/clang/lib/AST/NSAPI.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "clang/AST/NSAPI.h" |
10 | | #include "clang/AST/ASTContext.h" |
11 | | #include "clang/AST/DeclObjC.h" |
12 | | #include "clang/AST/Expr.h" |
13 | | #include "llvm/ADT/StringSwitch.h" |
14 | | #include <optional> |
15 | | |
16 | | using namespace clang; |
17 | | |
18 | | NSAPI::NSAPI(ASTContext &ctx) |
19 | | : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr), |
20 | | NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr), |
21 | 23 | NSUTF8StringEncodingId(nullptr) {} |
22 | | |
23 | 0 | IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const { |
24 | 0 | static const char *ClassName[NumClassIds] = { |
25 | 0 | "NSObject", |
26 | 0 | "NSString", |
27 | 0 | "NSArray", |
28 | 0 | "NSMutableArray", |
29 | 0 | "NSDictionary", |
30 | 0 | "NSMutableDictionary", |
31 | 0 | "NSNumber", |
32 | 0 | "NSMutableSet", |
33 | 0 | "NSMutableOrderedSet", |
34 | 0 | "NSValue" |
35 | 0 | }; |
36 | |
|
37 | 0 | if (!ClassIds[K]) |
38 | 0 | return (ClassIds[K] = &Ctx.Idents.get(ClassName[K])); |
39 | | |
40 | 0 | return ClassIds[K]; |
41 | 0 | } |
42 | | |
43 | 0 | Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const { |
44 | 0 | if (NSStringSelectors[MK].isNull()) { |
45 | 0 | Selector Sel; |
46 | 0 | switch (MK) { |
47 | 0 | case NSStr_stringWithString: |
48 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString")); |
49 | 0 | break; |
50 | 0 | case NSStr_stringWithUTF8String: |
51 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
52 | 0 | &Ctx.Idents.get("stringWithUTF8String")); |
53 | 0 | break; |
54 | 0 | case NSStr_initWithUTF8String: |
55 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
56 | 0 | &Ctx.Idents.get("initWithUTF8String")); |
57 | 0 | break; |
58 | 0 | case NSStr_stringWithCStringEncoding: { |
59 | 0 | IdentifierInfo *KeyIdents[] = { |
60 | 0 | &Ctx.Idents.get("stringWithCString"), |
61 | 0 | &Ctx.Idents.get("encoding") |
62 | 0 | }; |
63 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
64 | 0 | break; |
65 | 0 | } |
66 | 0 | case NSStr_stringWithCString: |
67 | 0 | Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString")); |
68 | 0 | break; |
69 | 0 | case NSStr_initWithString: |
70 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString")); |
71 | 0 | break; |
72 | 0 | } |
73 | 0 | return (NSStringSelectors[MK] = Sel); |
74 | 0 | } |
75 | | |
76 | 0 | return NSStringSelectors[MK]; |
77 | 0 | } |
78 | | |
79 | 0 | Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const { |
80 | 0 | if (NSArraySelectors[MK].isNull()) { |
81 | 0 | Selector Sel; |
82 | 0 | switch (MK) { |
83 | 0 | case NSArr_array: |
84 | 0 | Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array")); |
85 | 0 | break; |
86 | 0 | case NSArr_arrayWithArray: |
87 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray")); |
88 | 0 | break; |
89 | 0 | case NSArr_arrayWithObject: |
90 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject")); |
91 | 0 | break; |
92 | 0 | case NSArr_arrayWithObjects: |
93 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects")); |
94 | 0 | break; |
95 | 0 | case NSArr_arrayWithObjectsCount: { |
96 | 0 | IdentifierInfo *KeyIdents[] = { |
97 | 0 | &Ctx.Idents.get("arrayWithObjects"), |
98 | 0 | &Ctx.Idents.get("count") |
99 | 0 | }; |
100 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
101 | 0 | break; |
102 | 0 | } |
103 | 0 | case NSArr_initWithArray: |
104 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray")); |
105 | 0 | break; |
106 | 0 | case NSArr_initWithObjects: |
107 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects")); |
108 | 0 | break; |
109 | 0 | case NSArr_objectAtIndex: |
110 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex")); |
111 | 0 | break; |
112 | 0 | case NSMutableArr_replaceObjectAtIndex: { |
113 | 0 | IdentifierInfo *KeyIdents[] = { |
114 | 0 | &Ctx.Idents.get("replaceObjectAtIndex"), |
115 | 0 | &Ctx.Idents.get("withObject") |
116 | 0 | }; |
117 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
118 | 0 | break; |
119 | 0 | } |
120 | 0 | case NSMutableArr_addObject: |
121 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject")); |
122 | 0 | break; |
123 | 0 | case NSMutableArr_insertObjectAtIndex: { |
124 | 0 | IdentifierInfo *KeyIdents[] = { |
125 | 0 | &Ctx.Idents.get("insertObject"), |
126 | 0 | &Ctx.Idents.get("atIndex") |
127 | 0 | }; |
128 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
129 | 0 | break; |
130 | 0 | } |
131 | 0 | case NSMutableArr_setObjectAtIndexedSubscript: { |
132 | 0 | IdentifierInfo *KeyIdents[] = { |
133 | 0 | &Ctx.Idents.get("setObject"), |
134 | 0 | &Ctx.Idents.get("atIndexedSubscript") |
135 | 0 | }; |
136 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
137 | 0 | break; |
138 | 0 | } |
139 | 0 | } |
140 | 0 | return (NSArraySelectors[MK] = Sel); |
141 | 0 | } |
142 | | |
143 | 0 | return NSArraySelectors[MK]; |
144 | 0 | } |
145 | | |
146 | | std::optional<NSAPI::NSArrayMethodKind> |
147 | 0 | NSAPI::getNSArrayMethodKind(Selector Sel) { |
148 | 0 | for (unsigned i = 0; i != NumNSArrayMethods; ++i) { |
149 | 0 | NSArrayMethodKind MK = NSArrayMethodKind(i); |
150 | 0 | if (Sel == getNSArraySelector(MK)) |
151 | 0 | return MK; |
152 | 0 | } |
153 | | |
154 | 0 | return std::nullopt; |
155 | 0 | } |
156 | | |
157 | | Selector NSAPI::getNSDictionarySelector( |
158 | 0 | NSDictionaryMethodKind MK) const { |
159 | 0 | if (NSDictionarySelectors[MK].isNull()) { |
160 | 0 | Selector Sel; |
161 | 0 | switch (MK) { |
162 | 0 | case NSDict_dictionary: |
163 | 0 | Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary")); |
164 | 0 | break; |
165 | 0 | case NSDict_dictionaryWithDictionary: |
166 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
167 | 0 | &Ctx.Idents.get("dictionaryWithDictionary")); |
168 | 0 | break; |
169 | 0 | case NSDict_dictionaryWithObjectForKey: { |
170 | 0 | IdentifierInfo *KeyIdents[] = { |
171 | 0 | &Ctx.Idents.get("dictionaryWithObject"), |
172 | 0 | &Ctx.Idents.get("forKey") |
173 | 0 | }; |
174 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
175 | 0 | break; |
176 | 0 | } |
177 | 0 | case NSDict_dictionaryWithObjectsForKeys: { |
178 | 0 | IdentifierInfo *KeyIdents[] = { |
179 | 0 | &Ctx.Idents.get("dictionaryWithObjects"), |
180 | 0 | &Ctx.Idents.get("forKeys") |
181 | 0 | }; |
182 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
183 | 0 | break; |
184 | 0 | } |
185 | 0 | case NSDict_dictionaryWithObjectsForKeysCount: { |
186 | 0 | IdentifierInfo *KeyIdents[] = { |
187 | 0 | &Ctx.Idents.get("dictionaryWithObjects"), |
188 | 0 | &Ctx.Idents.get("forKeys"), |
189 | 0 | &Ctx.Idents.get("count") |
190 | 0 | }; |
191 | 0 | Sel = Ctx.Selectors.getSelector(3, KeyIdents); |
192 | 0 | break; |
193 | 0 | } |
194 | 0 | case NSDict_dictionaryWithObjectsAndKeys: |
195 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
196 | 0 | &Ctx.Idents.get("dictionaryWithObjectsAndKeys")); |
197 | 0 | break; |
198 | 0 | case NSDict_initWithDictionary: |
199 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
200 | 0 | &Ctx.Idents.get("initWithDictionary")); |
201 | 0 | break; |
202 | 0 | case NSDict_initWithObjectsAndKeys: |
203 | 0 | Sel = Ctx.Selectors.getUnarySelector( |
204 | 0 | &Ctx.Idents.get("initWithObjectsAndKeys")); |
205 | 0 | break; |
206 | 0 | case NSDict_initWithObjectsForKeys: { |
207 | 0 | IdentifierInfo *KeyIdents[] = { |
208 | 0 | &Ctx.Idents.get("initWithObjects"), |
209 | 0 | &Ctx.Idents.get("forKeys") |
210 | 0 | }; |
211 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
212 | 0 | break; |
213 | 0 | } |
214 | 0 | case NSDict_objectForKey: |
215 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey")); |
216 | 0 | break; |
217 | 0 | case NSMutableDict_setObjectForKey: { |
218 | 0 | IdentifierInfo *KeyIdents[] = { |
219 | 0 | &Ctx.Idents.get("setObject"), |
220 | 0 | &Ctx.Idents.get("forKey") |
221 | 0 | }; |
222 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
223 | 0 | break; |
224 | 0 | } |
225 | 0 | case NSMutableDict_setObjectForKeyedSubscript: { |
226 | 0 | IdentifierInfo *KeyIdents[] = { |
227 | 0 | &Ctx.Idents.get("setObject"), |
228 | 0 | &Ctx.Idents.get("forKeyedSubscript") |
229 | 0 | }; |
230 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
231 | 0 | break; |
232 | 0 | } |
233 | 0 | case NSMutableDict_setValueForKey: { |
234 | 0 | IdentifierInfo *KeyIdents[] = { |
235 | 0 | &Ctx.Idents.get("setValue"), |
236 | 0 | &Ctx.Idents.get("forKey") |
237 | 0 | }; |
238 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
239 | 0 | break; |
240 | 0 | } |
241 | 0 | } |
242 | 0 | return (NSDictionarySelectors[MK] = Sel); |
243 | 0 | } |
244 | | |
245 | 0 | return NSDictionarySelectors[MK]; |
246 | 0 | } |
247 | | |
248 | | std::optional<NSAPI::NSDictionaryMethodKind> |
249 | 0 | NSAPI::getNSDictionaryMethodKind(Selector Sel) { |
250 | 0 | for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) { |
251 | 0 | NSDictionaryMethodKind MK = NSDictionaryMethodKind(i); |
252 | 0 | if (Sel == getNSDictionarySelector(MK)) |
253 | 0 | return MK; |
254 | 0 | } |
255 | | |
256 | 0 | return std::nullopt; |
257 | 0 | } |
258 | | |
259 | 0 | Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const { |
260 | 0 | if (NSSetSelectors[MK].isNull()) { |
261 | 0 | Selector Sel; |
262 | 0 | switch (MK) { |
263 | 0 | case NSMutableSet_addObject: |
264 | 0 | Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject")); |
265 | 0 | break; |
266 | 0 | case NSOrderedSet_insertObjectAtIndex: { |
267 | 0 | IdentifierInfo *KeyIdents[] = { |
268 | 0 | &Ctx.Idents.get("insertObject"), |
269 | 0 | &Ctx.Idents.get("atIndex") |
270 | 0 | }; |
271 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
272 | 0 | break; |
273 | 0 | } |
274 | 0 | case NSOrderedSet_setObjectAtIndex: { |
275 | 0 | IdentifierInfo *KeyIdents[] = { |
276 | 0 | &Ctx.Idents.get("setObject"), |
277 | 0 | &Ctx.Idents.get("atIndex") |
278 | 0 | }; |
279 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
280 | 0 | break; |
281 | 0 | } |
282 | 0 | case NSOrderedSet_setObjectAtIndexedSubscript: { |
283 | 0 | IdentifierInfo *KeyIdents[] = { |
284 | 0 | &Ctx.Idents.get("setObject"), |
285 | 0 | &Ctx.Idents.get("atIndexedSubscript") |
286 | 0 | }; |
287 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
288 | 0 | break; |
289 | 0 | } |
290 | 0 | case NSOrderedSet_replaceObjectAtIndexWithObject: { |
291 | 0 | IdentifierInfo *KeyIdents[] = { |
292 | 0 | &Ctx.Idents.get("replaceObjectAtIndex"), |
293 | 0 | &Ctx.Idents.get("withObject") |
294 | 0 | }; |
295 | 0 | Sel = Ctx.Selectors.getSelector(2, KeyIdents); |
296 | 0 | break; |
297 | 0 | } |
298 | 0 | } |
299 | 0 | return (NSSetSelectors[MK] = Sel); |
300 | 0 | } |
301 | | |
302 | 0 | return NSSetSelectors[MK]; |
303 | 0 | } |
304 | | |
305 | 0 | std::optional<NSAPI::NSSetMethodKind> NSAPI::getNSSetMethodKind(Selector Sel) { |
306 | 0 | for (unsigned i = 0; i != NumNSSetMethods; ++i) { |
307 | 0 | NSSetMethodKind MK = NSSetMethodKind(i); |
308 | 0 | if (Sel == getNSSetSelector(MK)) |
309 | 0 | return MK; |
310 | 0 | } |
311 | | |
312 | 0 | return std::nullopt; |
313 | 0 | } |
314 | | |
315 | | Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, |
316 | 0 | bool Instance) const { |
317 | 0 | static const char *ClassSelectorName[NumNSNumberLiteralMethods] = { |
318 | 0 | "numberWithChar", |
319 | 0 | "numberWithUnsignedChar", |
320 | 0 | "numberWithShort", |
321 | 0 | "numberWithUnsignedShort", |
322 | 0 | "numberWithInt", |
323 | 0 | "numberWithUnsignedInt", |
324 | 0 | "numberWithLong", |
325 | 0 | "numberWithUnsignedLong", |
326 | 0 | "numberWithLongLong", |
327 | 0 | "numberWithUnsignedLongLong", |
328 | 0 | "numberWithFloat", |
329 | 0 | "numberWithDouble", |
330 | 0 | "numberWithBool", |
331 | 0 | "numberWithInteger", |
332 | 0 | "numberWithUnsignedInteger" |
333 | 0 | }; |
334 | 0 | static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = { |
335 | 0 | "initWithChar", |
336 | 0 | "initWithUnsignedChar", |
337 | 0 | "initWithShort", |
338 | 0 | "initWithUnsignedShort", |
339 | 0 | "initWithInt", |
340 | 0 | "initWithUnsignedInt", |
341 | 0 | "initWithLong", |
342 | 0 | "initWithUnsignedLong", |
343 | 0 | "initWithLongLong", |
344 | 0 | "initWithUnsignedLongLong", |
345 | 0 | "initWithFloat", |
346 | 0 | "initWithDouble", |
347 | 0 | "initWithBool", |
348 | 0 | "initWithInteger", |
349 | 0 | "initWithUnsignedInteger" |
350 | 0 | }; |
351 | |
|
352 | 0 | Selector *Sels; |
353 | 0 | const char **Names; |
354 | 0 | if (Instance) { |
355 | 0 | Sels = NSNumberInstanceSelectors; |
356 | 0 | Names = InstanceSelectorName; |
357 | 0 | } else { |
358 | 0 | Sels = NSNumberClassSelectors; |
359 | 0 | Names = ClassSelectorName; |
360 | 0 | } |
361 | |
|
362 | 0 | if (Sels[MK].isNull()) |
363 | 0 | Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK])); |
364 | 0 | return Sels[MK]; |
365 | 0 | } |
366 | | |
367 | | std::optional<NSAPI::NSNumberLiteralMethodKind> |
368 | 0 | NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const { |
369 | 0 | for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) { |
370 | 0 | NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i); |
371 | 0 | if (isNSNumberLiteralSelector(MK, Sel)) |
372 | 0 | return MK; |
373 | 0 | } |
374 | | |
375 | 0 | return std::nullopt; |
376 | 0 | } |
377 | | |
378 | | std::optional<NSAPI::NSNumberLiteralMethodKind> |
379 | 0 | NSAPI::getNSNumberFactoryMethodKind(QualType T) const { |
380 | 0 | const BuiltinType *BT = T->getAs<BuiltinType>(); |
381 | 0 | if (!BT) |
382 | 0 | return std::nullopt; |
383 | | |
384 | 0 | const TypedefType *TDT = T->getAs<TypedefType>(); |
385 | 0 | if (TDT) { |
386 | 0 | QualType TDTTy = QualType(TDT, 0); |
387 | 0 | if (isObjCBOOLType(TDTTy)) |
388 | 0 | return NSAPI::NSNumberWithBool; |
389 | 0 | if (isObjCNSIntegerType(TDTTy)) |
390 | 0 | return NSAPI::NSNumberWithInteger; |
391 | 0 | if (isObjCNSUIntegerType(TDTTy)) |
392 | 0 | return NSAPI::NSNumberWithUnsignedInteger; |
393 | 0 | } |
394 | | |
395 | 0 | switch (BT->getKind()) { |
396 | 0 | case BuiltinType::Char_S: |
397 | 0 | case BuiltinType::SChar: |
398 | 0 | return NSAPI::NSNumberWithChar; |
399 | 0 | case BuiltinType::Char_U: |
400 | 0 | case BuiltinType::UChar: |
401 | 0 | return NSAPI::NSNumberWithUnsignedChar; |
402 | 0 | case BuiltinType::Short: |
403 | 0 | return NSAPI::NSNumberWithShort; |
404 | 0 | case BuiltinType::UShort: |
405 | 0 | return NSAPI::NSNumberWithUnsignedShort; |
406 | 0 | case BuiltinType::Int: |
407 | 0 | return NSAPI::NSNumberWithInt; |
408 | 0 | case BuiltinType::UInt: |
409 | 0 | return NSAPI::NSNumberWithUnsignedInt; |
410 | 0 | case BuiltinType::Long: |
411 | 0 | return NSAPI::NSNumberWithLong; |
412 | 0 | case BuiltinType::ULong: |
413 | 0 | return NSAPI::NSNumberWithUnsignedLong; |
414 | 0 | case BuiltinType::LongLong: |
415 | 0 | return NSAPI::NSNumberWithLongLong; |
416 | 0 | case BuiltinType::ULongLong: |
417 | 0 | return NSAPI::NSNumberWithUnsignedLongLong; |
418 | 0 | case BuiltinType::Float: |
419 | 0 | return NSAPI::NSNumberWithFloat; |
420 | 0 | case BuiltinType::Double: |
421 | 0 | return NSAPI::NSNumberWithDouble; |
422 | 0 | case BuiltinType::Bool: |
423 | 0 | return NSAPI::NSNumberWithBool; |
424 | | |
425 | 0 | case BuiltinType::Void: |
426 | 0 | case BuiltinType::WChar_U: |
427 | 0 | case BuiltinType::WChar_S: |
428 | 0 | case BuiltinType::Char8: |
429 | 0 | case BuiltinType::Char16: |
430 | 0 | case BuiltinType::Char32: |
431 | 0 | case BuiltinType::Int128: |
432 | 0 | case BuiltinType::LongDouble: |
433 | 0 | case BuiltinType::ShortAccum: |
434 | 0 | case BuiltinType::Accum: |
435 | 0 | case BuiltinType::LongAccum: |
436 | 0 | case BuiltinType::UShortAccum: |
437 | 0 | case BuiltinType::UAccum: |
438 | 0 | case BuiltinType::ULongAccum: |
439 | 0 | case BuiltinType::ShortFract: |
440 | 0 | case BuiltinType::Fract: |
441 | 0 | case BuiltinType::LongFract: |
442 | 0 | case BuiltinType::UShortFract: |
443 | 0 | case BuiltinType::UFract: |
444 | 0 | case BuiltinType::ULongFract: |
445 | 0 | case BuiltinType::SatShortAccum: |
446 | 0 | case BuiltinType::SatAccum: |
447 | 0 | case BuiltinType::SatLongAccum: |
448 | 0 | case BuiltinType::SatUShortAccum: |
449 | 0 | case BuiltinType::SatUAccum: |
450 | 0 | case BuiltinType::SatULongAccum: |
451 | 0 | case BuiltinType::SatShortFract: |
452 | 0 | case BuiltinType::SatFract: |
453 | 0 | case BuiltinType::SatLongFract: |
454 | 0 | case BuiltinType::SatUShortFract: |
455 | 0 | case BuiltinType::SatUFract: |
456 | 0 | case BuiltinType::SatULongFract: |
457 | 0 | case BuiltinType::UInt128: |
458 | 0 | case BuiltinType::Float16: |
459 | 0 | case BuiltinType::Float128: |
460 | 0 | case BuiltinType::Ibm128: |
461 | 0 | case BuiltinType::NullPtr: |
462 | 0 | case BuiltinType::ObjCClass: |
463 | 0 | case BuiltinType::ObjCId: |
464 | 0 | case BuiltinType::ObjCSel: |
465 | 0 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
466 | 0 | case BuiltinType::Id: |
467 | 0 | #include "clang/Basic/OpenCLImageTypes.def" |
468 | 0 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
469 | 0 | case BuiltinType::Id: |
470 | 0 | #include "clang/Basic/OpenCLExtensionTypes.def" |
471 | 0 | case BuiltinType::OCLSampler: |
472 | 0 | case BuiltinType::OCLEvent: |
473 | 0 | case BuiltinType::OCLClkEvent: |
474 | 0 | case BuiltinType::OCLQueue: |
475 | 0 | case BuiltinType::OCLReserveID: |
476 | 0 | #define SVE_TYPE(Name, Id, SingletonId) \ |
477 | 0 | case BuiltinType::Id: |
478 | 0 | #include "clang/Basic/AArch64SVEACLETypes.def" |
479 | 0 | #define PPC_VECTOR_TYPE(Name, Id, Size) \ |
480 | 0 | case BuiltinType::Id: |
481 | 0 | #include "clang/Basic/PPCTypes.def" |
482 | 0 | #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: |
483 | 0 | #include "clang/Basic/RISCVVTypes.def" |
484 | 0 | #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id: |
485 | 0 | #include "clang/Basic/WebAssemblyReferenceTypes.def" |
486 | 0 | case BuiltinType::BoundMember: |
487 | 0 | case BuiltinType::Dependent: |
488 | 0 | case BuiltinType::Overload: |
489 | 0 | case BuiltinType::UnknownAny: |
490 | 0 | case BuiltinType::ARCUnbridgedCast: |
491 | 0 | case BuiltinType::Half: |
492 | 0 | case BuiltinType::PseudoObject: |
493 | 0 | case BuiltinType::BuiltinFn: |
494 | 0 | case BuiltinType::IncompleteMatrixIdx: |
495 | 0 | case BuiltinType::OMPArraySection: |
496 | 0 | case BuiltinType::OMPArrayShaping: |
497 | 0 | case BuiltinType::OMPIterator: |
498 | 0 | case BuiltinType::BFloat16: |
499 | 0 | break; |
500 | 0 | } |
501 | | |
502 | 0 | return std::nullopt; |
503 | 0 | } |
504 | | |
505 | | /// Returns true if \param T is a typedef of "BOOL" in objective-c. |
506 | 0 | bool NSAPI::isObjCBOOLType(QualType T) const { |
507 | 0 | return isObjCTypedef(T, "BOOL", BOOLId); |
508 | 0 | } |
509 | | /// Returns true if \param T is a typedef of "NSInteger" in objective-c. |
510 | 0 | bool NSAPI::isObjCNSIntegerType(QualType T) const { |
511 | 0 | return isObjCTypedef(T, "NSInteger", NSIntegerId); |
512 | 0 | } |
513 | | /// Returns true if \param T is a typedef of "NSUInteger" in objective-c. |
514 | 0 | bool NSAPI::isObjCNSUIntegerType(QualType T) const { |
515 | 0 | return isObjCTypedef(T, "NSUInteger", NSUIntegerId); |
516 | 0 | } |
517 | | |
518 | 0 | StringRef NSAPI::GetNSIntegralKind(QualType T) const { |
519 | 0 | if (!Ctx.getLangOpts().ObjC || T.isNull()) |
520 | 0 | return StringRef(); |
521 | | |
522 | 0 | while (const TypedefType *TDT = T->getAs<TypedefType>()) { |
523 | 0 | StringRef NSIntegralResust = |
524 | 0 | llvm::StringSwitch<StringRef>( |
525 | 0 | TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName()) |
526 | 0 | .Case("int8_t", "int8_t") |
527 | 0 | .Case("int16_t", "int16_t") |
528 | 0 | .Case("int32_t", "int32_t") |
529 | 0 | .Case("NSInteger", "NSInteger") |
530 | 0 | .Case("int64_t", "int64_t") |
531 | 0 | .Case("uint8_t", "uint8_t") |
532 | 0 | .Case("uint16_t", "uint16_t") |
533 | 0 | .Case("uint32_t", "uint32_t") |
534 | 0 | .Case("NSUInteger", "NSUInteger") |
535 | 0 | .Case("uint64_t", "uint64_t") |
536 | 0 | .Default(StringRef()); |
537 | 0 | if (!NSIntegralResust.empty()) |
538 | 0 | return NSIntegralResust; |
539 | 0 | T = TDT->desugar(); |
540 | 0 | } |
541 | 0 | return StringRef(); |
542 | 0 | } |
543 | | |
544 | 0 | bool NSAPI::isMacroDefined(StringRef Id) const { |
545 | | // FIXME: Check whether the relevant module macros are visible. |
546 | 0 | return Ctx.Idents.get(Id).hasMacroDefinition(); |
547 | 0 | } |
548 | | |
549 | | bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, |
550 | 0 | NSClassIdKindKind NSClassKind) const { |
551 | 0 | if (!InterfaceDecl) { |
552 | 0 | return false; |
553 | 0 | } |
554 | | |
555 | 0 | IdentifierInfo *NSClassID = getNSClassId(NSClassKind); |
556 | |
|
557 | 0 | bool IsSubclass = false; |
558 | 0 | do { |
559 | 0 | IsSubclass = NSClassID == InterfaceDecl->getIdentifier(); |
560 | |
|
561 | 0 | if (IsSubclass) { |
562 | 0 | break; |
563 | 0 | } |
564 | 0 | } while ((InterfaceDecl = InterfaceDecl->getSuperClass())); |
565 | | |
566 | 0 | return IsSubclass; |
567 | 0 | } |
568 | | |
569 | | bool NSAPI::isObjCTypedef(QualType T, |
570 | 0 | StringRef name, IdentifierInfo *&II) const { |
571 | 0 | if (!Ctx.getLangOpts().ObjC) |
572 | 0 | return false; |
573 | 0 | if (T.isNull()) |
574 | 0 | return false; |
575 | | |
576 | 0 | if (!II) |
577 | 0 | II = &Ctx.Idents.get(name); |
578 | |
|
579 | 0 | while (const TypedefType *TDT = T->getAs<TypedefType>()) { |
580 | 0 | if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II) |
581 | 0 | return true; |
582 | 0 | T = TDT->desugar(); |
583 | 0 | } |
584 | | |
585 | 0 | return false; |
586 | 0 | } |
587 | | |
588 | | bool NSAPI::isObjCEnumerator(const Expr *E, |
589 | 0 | StringRef name, IdentifierInfo *&II) const { |
590 | 0 | if (!Ctx.getLangOpts().ObjC) |
591 | 0 | return false; |
592 | 0 | if (!E) |
593 | 0 | return false; |
594 | | |
595 | 0 | if (!II) |
596 | 0 | II = &Ctx.Idents.get(name); |
597 | |
|
598 | 0 | if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) |
599 | 0 | if (const EnumConstantDecl * |
600 | 0 | EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl())) |
601 | 0 | return EnumD->getIdentifier() == II; |
602 | | |
603 | 0 | return false; |
604 | 0 | } |
605 | | |
606 | | Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids, |
607 | 0 | Selector &Sel) const { |
608 | 0 | if (Sel.isNull()) { |
609 | 0 | SmallVector<IdentifierInfo *, 4> Idents; |
610 | 0 | for (ArrayRef<StringRef>::const_iterator |
611 | 0 | I = Ids.begin(), E = Ids.end(); I != E; ++I) |
612 | 0 | Idents.push_back(&Ctx.Idents.get(*I)); |
613 | 0 | Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data()); |
614 | 0 | } |
615 | 0 | return Sel; |
616 | 0 | } |
617 | | |
618 | 0 | Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const { |
619 | 0 | if (Sel.isNull()) { |
620 | 0 | IdentifierInfo *Ident = &Ctx.Idents.get(Id); |
621 | 0 | Sel = Ctx.Selectors.getSelector(0, &Ident); |
622 | 0 | } |
623 | 0 | return Sel; |
624 | 0 | } |