blob: ace7f1ceebe74e68fefa58dcdd48ed8d99900421 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Guy Benyei11169dd2012-12-18 14:30:41 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "clang/AST/NSAPI.h"
10#include "clang/AST/ASTContext.h"
Alex Denisov5dfac812015-08-06 04:51:14 +000011#include "clang/AST/DeclObjC.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000012#include "clang/AST/Expr.h"
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +000013#include "llvm/ADT/StringSwitch.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000014
15using namespace clang;
16
17NSAPI::NSAPI(ASTContext &ctx)
Craig Topper36250ad2014-05-12 05:36:57 +000018 : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
19 NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
20 NSUTF8StringEncodingId(nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +000021
22IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23 static const char *ClassName[NumClassIds] = {
24 "NSObject",
25 "NSString",
26 "NSArray",
27 "NSMutableArray",
28 "NSDictionary",
29 "NSMutableDictionary",
Alex Denisove1d882c2015-03-04 17:55:52 +000030 "NSNumber",
31 "NSMutableSet",
Alex Denisovfde64952015-06-26 05:28:36 +000032 "NSMutableOrderedSet",
33 "NSValue"
Guy Benyei11169dd2012-12-18 14:30:41 +000034 };
35
36 if (!ClassIds[K])
37 return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38
39 return ClassIds[K];
40}
41
42Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
43 if (NSStringSelectors[MK].isNull()) {
44 Selector Sel;
45 switch (MK) {
46 case NSStr_stringWithString:
47 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
48 break;
49 case NSStr_stringWithUTF8String:
50 Sel = Ctx.Selectors.getUnarySelector(
51 &Ctx.Idents.get("stringWithUTF8String"));
52 break;
Fariborz Jahanianbe7bf722014-08-25 20:22:25 +000053 case NSStr_initWithUTF8String:
54 Sel = Ctx.Selectors.getUnarySelector(
55 &Ctx.Idents.get("initWithUTF8String"));
56 break;
Guy Benyei11169dd2012-12-18 14:30:41 +000057 case NSStr_stringWithCStringEncoding: {
58 IdentifierInfo *KeyIdents[] = {
59 &Ctx.Idents.get("stringWithCString"),
60 &Ctx.Idents.get("encoding")
61 };
62 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
63 break;
64 }
65 case NSStr_stringWithCString:
66 Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
67 break;
68 case NSStr_initWithString:
69 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
70 break;
71 }
72 return (NSStringSelectors[MK] = Sel);
73 }
74
75 return NSStringSelectors[MK];
76}
77
Guy Benyei11169dd2012-12-18 14:30:41 +000078Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79 if (NSArraySelectors[MK].isNull()) {
80 Selector Sel;
81 switch (MK) {
82 case NSArr_array:
83 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
84 break;
85 case NSArr_arrayWithArray:
86 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
87 break;
88 case NSArr_arrayWithObject:
89 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
90 break;
91 case NSArr_arrayWithObjects:
92 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
93 break;
94 case NSArr_arrayWithObjectsCount: {
95 IdentifierInfo *KeyIdents[] = {
96 &Ctx.Idents.get("arrayWithObjects"),
97 &Ctx.Idents.get("count")
98 };
99 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
100 break;
101 }
102 case NSArr_initWithArray:
103 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
104 break;
105 case NSArr_initWithObjects:
106 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
107 break;
108 case NSArr_objectAtIndex:
109 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
110 break;
111 case NSMutableArr_replaceObjectAtIndex: {
112 IdentifierInfo *KeyIdents[] = {
113 &Ctx.Idents.get("replaceObjectAtIndex"),
114 &Ctx.Idents.get("withObject")
115 };
116 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
117 break;
118 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000119 case NSMutableArr_addObject:
120 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
121 break;
122 case NSMutableArr_insertObjectAtIndex: {
123 IdentifierInfo *KeyIdents[] = {
124 &Ctx.Idents.get("insertObject"),
125 &Ctx.Idents.get("atIndex")
126 };
127 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128 break;
129 }
130 case NSMutableArr_setObjectAtIndexedSubscript: {
131 IdentifierInfo *KeyIdents[] = {
132 &Ctx.Idents.get("setObject"),
133 &Ctx.Idents.get("atIndexedSubscript")
134 };
135 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
136 break;
137 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000138 }
139 return (NSArraySelectors[MK] = Sel);
140 }
141
142 return NSArraySelectors[MK];
143}
144
David Blaikie05785d12013-02-20 22:23:23 +0000145Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000146 for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
147 NSArrayMethodKind MK = NSArrayMethodKind(i);
148 if (Sel == getNSArraySelector(MK))
149 return MK;
150 }
151
David Blaikie7a30dc52013-02-21 01:47:18 +0000152 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000153}
154
155Selector NSAPI::getNSDictionarySelector(
156 NSDictionaryMethodKind MK) const {
157 if (NSDictionarySelectors[MK].isNull()) {
158 Selector Sel;
159 switch (MK) {
160 case NSDict_dictionary:
161 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
162 break;
163 case NSDict_dictionaryWithDictionary:
164 Sel = Ctx.Selectors.getUnarySelector(
165 &Ctx.Idents.get("dictionaryWithDictionary"));
166 break;
167 case NSDict_dictionaryWithObjectForKey: {
168 IdentifierInfo *KeyIdents[] = {
169 &Ctx.Idents.get("dictionaryWithObject"),
170 &Ctx.Idents.get("forKey")
171 };
172 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
173 break;
174 }
175 case NSDict_dictionaryWithObjectsForKeys: {
176 IdentifierInfo *KeyIdents[] = {
177 &Ctx.Idents.get("dictionaryWithObjects"),
178 &Ctx.Idents.get("forKeys")
179 };
180 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
181 break;
182 }
183 case NSDict_dictionaryWithObjectsForKeysCount: {
184 IdentifierInfo *KeyIdents[] = {
185 &Ctx.Idents.get("dictionaryWithObjects"),
186 &Ctx.Idents.get("forKeys"),
187 &Ctx.Idents.get("count")
188 };
189 Sel = Ctx.Selectors.getSelector(3, KeyIdents);
190 break;
191 }
192 case NSDict_dictionaryWithObjectsAndKeys:
193 Sel = Ctx.Selectors.getUnarySelector(
194 &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
195 break;
196 case NSDict_initWithDictionary:
197 Sel = Ctx.Selectors.getUnarySelector(
198 &Ctx.Idents.get("initWithDictionary"));
199 break;
200 case NSDict_initWithObjectsAndKeys:
201 Sel = Ctx.Selectors.getUnarySelector(
202 &Ctx.Idents.get("initWithObjectsAndKeys"));
203 break;
Argyrios Kyrtzidis6b4f3412013-01-16 23:54:48 +0000204 case NSDict_initWithObjectsForKeys: {
205 IdentifierInfo *KeyIdents[] = {
206 &Ctx.Idents.get("initWithObjects"),
207 &Ctx.Idents.get("forKeys")
208 };
209 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
210 break;
211 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000212 case NSDict_objectForKey:
213 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
214 break;
215 case NSMutableDict_setObjectForKey: {
216 IdentifierInfo *KeyIdents[] = {
217 &Ctx.Idents.get("setObject"),
218 &Ctx.Idents.get("forKey")
219 };
220 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221 break;
222 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000223 case NSMutableDict_setObjectForKeyedSubscript: {
224 IdentifierInfo *KeyIdents[] = {
225 &Ctx.Idents.get("setObject"),
226 &Ctx.Idents.get("forKeyedSubscript")
227 };
228 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
229 break;
230 }
231 case NSMutableDict_setValueForKey: {
232 IdentifierInfo *KeyIdents[] = {
233 &Ctx.Idents.get("setValue"),
234 &Ctx.Idents.get("forKey")
235 };
236 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
237 break;
238 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000239 }
240 return (NSDictionarySelectors[MK] = Sel);
241 }
242
243 return NSDictionarySelectors[MK];
244}
245
David Blaikie05785d12013-02-20 22:23:23 +0000246Optional<NSAPI::NSDictionaryMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000247NSAPI::getNSDictionaryMethodKind(Selector Sel) {
248 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
249 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
250 if (Sel == getNSDictionarySelector(MK))
251 return MK;
252 }
253
David Blaikie7a30dc52013-02-21 01:47:18 +0000254 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000255}
256
Alex Denisove1d882c2015-03-04 17:55:52 +0000257Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
258 if (NSSetSelectors[MK].isNull()) {
259 Selector Sel;
260 switch (MK) {
261 case NSMutableSet_addObject:
262 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
263 break;
264 case NSOrderedSet_insertObjectAtIndex: {
265 IdentifierInfo *KeyIdents[] = {
266 &Ctx.Idents.get("insertObject"),
267 &Ctx.Idents.get("atIndex")
268 };
269 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
270 break;
271 }
272 case NSOrderedSet_setObjectAtIndex: {
273 IdentifierInfo *KeyIdents[] = {
274 &Ctx.Idents.get("setObject"),
275 &Ctx.Idents.get("atIndex")
276 };
277 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
278 break;
279 }
280 case NSOrderedSet_setObjectAtIndexedSubscript: {
281 IdentifierInfo *KeyIdents[] = {
282 &Ctx.Idents.get("setObject"),
283 &Ctx.Idents.get("atIndexedSubscript")
284 };
285 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
286 break;
287 }
288 case NSOrderedSet_replaceObjectAtIndexWithObject: {
289 IdentifierInfo *KeyIdents[] = {
290 &Ctx.Idents.get("replaceObjectAtIndex"),
291 &Ctx.Idents.get("withObject")
292 };
293 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
294 break;
295 }
296 }
297 return (NSSetSelectors[MK] = Sel);
298 }
299
300 return NSSetSelectors[MK];
301}
302
303Optional<NSAPI::NSSetMethodKind>
304NSAPI::getNSSetMethodKind(Selector Sel) {
305 for (unsigned i = 0; i != NumNSSetMethods; ++i) {
306 NSSetMethodKind MK = NSSetMethodKind(i);
307 if (Sel == getNSSetSelector(MK))
308 return MK;
309 }
310
311 return None;
312}
313
Guy Benyei11169dd2012-12-18 14:30:41 +0000314Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
315 bool Instance) const {
316 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
317 "numberWithChar",
318 "numberWithUnsignedChar",
319 "numberWithShort",
320 "numberWithUnsignedShort",
321 "numberWithInt",
322 "numberWithUnsignedInt",
323 "numberWithLong",
324 "numberWithUnsignedLong",
325 "numberWithLongLong",
326 "numberWithUnsignedLongLong",
327 "numberWithFloat",
328 "numberWithDouble",
329 "numberWithBool",
330 "numberWithInteger",
331 "numberWithUnsignedInteger"
332 };
333 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
334 "initWithChar",
335 "initWithUnsignedChar",
336 "initWithShort",
337 "initWithUnsignedShort",
338 "initWithInt",
339 "initWithUnsignedInt",
340 "initWithLong",
341 "initWithUnsignedLong",
342 "initWithLongLong",
343 "initWithUnsignedLongLong",
344 "initWithFloat",
345 "initWithDouble",
346 "initWithBool",
347 "initWithInteger",
348 "initWithUnsignedInteger"
349 };
350
351 Selector *Sels;
352 const char **Names;
353 if (Instance) {
354 Sels = NSNumberInstanceSelectors;
355 Names = InstanceSelectorName;
356 } else {
357 Sels = NSNumberClassSelectors;
358 Names = ClassSelectorName;
359 }
360
361 if (Sels[MK].isNull())
362 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
363 return Sels[MK];
364}
365
David Blaikie05785d12013-02-20 22:23:23 +0000366Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000367NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
368 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
369 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
370 if (isNSNumberLiteralSelector(MK, Sel))
371 return MK;
372 }
373
David Blaikie7a30dc52013-02-21 01:47:18 +0000374 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000375}
376
David Blaikie05785d12013-02-20 22:23:23 +0000377Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000378NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
379 const BuiltinType *BT = T->getAs<BuiltinType>();
380 if (!BT)
David Blaikie7a30dc52013-02-21 01:47:18 +0000381 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000382
383 const TypedefType *TDT = T->getAs<TypedefType>();
384 if (TDT) {
385 QualType TDTTy = QualType(TDT, 0);
386 if (isObjCBOOLType(TDTTy))
387 return NSAPI::NSNumberWithBool;
388 if (isObjCNSIntegerType(TDTTy))
389 return NSAPI::NSNumberWithInteger;
390 if (isObjCNSUIntegerType(TDTTy))
391 return NSAPI::NSNumberWithUnsignedInteger;
392 }
393
394 switch (BT->getKind()) {
395 case BuiltinType::Char_S:
396 case BuiltinType::SChar:
397 return NSAPI::NSNumberWithChar;
398 case BuiltinType::Char_U:
399 case BuiltinType::UChar:
400 return NSAPI::NSNumberWithUnsignedChar;
401 case BuiltinType::Short:
402 return NSAPI::NSNumberWithShort;
403 case BuiltinType::UShort:
404 return NSAPI::NSNumberWithUnsignedShort;
405 case BuiltinType::Int:
406 return NSAPI::NSNumberWithInt;
407 case BuiltinType::UInt:
408 return NSAPI::NSNumberWithUnsignedInt;
409 case BuiltinType::Long:
410 return NSAPI::NSNumberWithLong;
411 case BuiltinType::ULong:
412 return NSAPI::NSNumberWithUnsignedLong;
413 case BuiltinType::LongLong:
414 return NSAPI::NSNumberWithLongLong;
415 case BuiltinType::ULongLong:
416 return NSAPI::NSNumberWithUnsignedLongLong;
417 case BuiltinType::Float:
418 return NSAPI::NSNumberWithFloat;
419 case BuiltinType::Double:
420 return NSAPI::NSNumberWithDouble;
421 case BuiltinType::Bool:
422 return NSAPI::NSNumberWithBool;
Fangrui Song6907ce22018-07-30 19:24:48 +0000423
Guy Benyei11169dd2012-12-18 14:30:41 +0000424 case BuiltinType::Void:
425 case BuiltinType::WChar_U:
426 case BuiltinType::WChar_S:
Richard Smith3a8244d2018-05-01 05:02:45 +0000427 case BuiltinType::Char8:
Guy Benyei11169dd2012-12-18 14:30:41 +0000428 case BuiltinType::Char16:
429 case BuiltinType::Char32:
430 case BuiltinType::Int128:
431 case BuiltinType::LongDouble:
Leonard Chanf921d852018-06-04 16:07:52 +0000432 case BuiltinType::ShortAccum:
433 case BuiltinType::Accum:
434 case BuiltinType::LongAccum:
435 case BuiltinType::UShortAccum:
436 case BuiltinType::UAccum:
437 case BuiltinType::ULongAccum:
Leonard Chanab80f3c2018-06-14 14:53:51 +0000438 case BuiltinType::ShortFract:
439 case BuiltinType::Fract:
440 case BuiltinType::LongFract:
441 case BuiltinType::UShortFract:
442 case BuiltinType::UFract:
443 case BuiltinType::ULongFract:
444 case BuiltinType::SatShortAccum:
445 case BuiltinType::SatAccum:
446 case BuiltinType::SatLongAccum:
447 case BuiltinType::SatUShortAccum:
448 case BuiltinType::SatUAccum:
449 case BuiltinType::SatULongAccum:
450 case BuiltinType::SatShortFract:
451 case BuiltinType::SatFract:
452 case BuiltinType::SatLongFract:
453 case BuiltinType::SatUShortFract:
454 case BuiltinType::SatUFract:
455 case BuiltinType::SatULongFract:
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 case BuiltinType::UInt128:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +0000457 case BuiltinType::Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +0000458 case BuiltinType::Float128:
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 case BuiltinType::NullPtr:
460 case BuiltinType::ObjCClass:
461 case BuiltinType::ObjCId:
462 case BuiltinType::ObjCSel:
Alexey Bader954ba212016-04-08 13:40:33 +0000463#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
464 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +0000465#include "clang/Basic/OpenCLImageTypes.def"
Andrew Savonichev3fee3512018-11-08 11:25:41 +0000466#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
467 case BuiltinType::Id:
468#include "clang/Basic/OpenCLExtensionTypes.def"
Guy Benyei61054192013-02-07 10:55:47 +0000469 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +0000470 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000471 case BuiltinType::OCLClkEvent:
472 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000473 case BuiltinType::OCLReserveID:
Richard Sandifordeb485fb2019-08-09 08:52:54 +0000474#define SVE_TYPE(Name, Id, SingletonId) \
475 case BuiltinType::Id:
476#include "clang/Basic/AArch64SVEACLETypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +0000477 case BuiltinType::BoundMember:
478 case BuiltinType::Dependent:
479 case BuiltinType::Overload:
480 case BuiltinType::UnknownAny:
481 case BuiltinType::ARCUnbridgedCast:
482 case BuiltinType::Half:
483 case BuiltinType::PseudoObject:
484 case BuiltinType::BuiltinFn:
Florian Hahn8f3f88d2020-06-01 19:42:03 +0100485 case BuiltinType::IncompleteMatrixIdx:
Alexey Bataev1a3320e2015-08-25 14:24:04 +0000486 case BuiltinType::OMPArraySection:
Alexey Bataev7ac9efb2020-02-05 09:33:05 -0500487 case BuiltinType::OMPArrayShaping:
Alexey Bataev13a15042020-04-01 15:06:38 -0400488 case BuiltinType::OMPIterator:
Ties Stuijecd682b2020-06-05 00:20:02 +0100489 case BuiltinType::BFloat16:
Guy Benyei11169dd2012-12-18 14:30:41 +0000490 break;
491 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000492
David Blaikie7a30dc52013-02-21 01:47:18 +0000493 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000494}
495
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000496/// Returns true if \param T is a typedef of "BOOL" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000497bool NSAPI::isObjCBOOLType(QualType T) const {
498 return isObjCTypedef(T, "BOOL", BOOLId);
499}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000500/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000501bool NSAPI::isObjCNSIntegerType(QualType T) const {
502 return isObjCTypedef(T, "NSInteger", NSIntegerId);
503}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000504/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000505bool NSAPI::isObjCNSUIntegerType(QualType T) const {
506 return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
507}
508
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000509StringRef NSAPI::GetNSIntegralKind(QualType T) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000510 if (!Ctx.getLangOpts().ObjC || T.isNull())
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000511 return StringRef();
Fangrui Song6907ce22018-07-30 19:24:48 +0000512
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000513 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
514 StringRef NSIntegralResust =
515 llvm::StringSwitch<StringRef>(
516 TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
517 .Case("int8_t", "int8_t")
518 .Case("int16_t", "int16_t")
519 .Case("int32_t", "int32_t")
520 .Case("NSInteger", "NSInteger")
521 .Case("int64_t", "int64_t")
522 .Case("uint8_t", "uint8_t")
523 .Case("uint16_t", "uint16_t")
524 .Case("uint32_t", "uint32_t")
525 .Case("NSUInteger", "NSUInteger")
526 .Case("uint64_t", "uint64_t")
527 .Default(StringRef());
528 if (!NSIntegralResust.empty())
529 return NSIntegralResust;
530 T = TDT->desugar();
531 }
532 return StringRef();
533}
534
Richard Smith20e883e2015-04-29 23:20:19 +0000535bool NSAPI::isMacroDefined(StringRef Id) const {
536 // FIXME: Check whether the relevant module macros are visible.
537 return Ctx.Idents.get(Id).hasMacroDefinition();
538}
539
Alex Denisov5dfac812015-08-06 04:51:14 +0000540bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
541 NSClassIdKindKind NSClassKind) const {
542 if (!InterfaceDecl) {
543 return false;
544 }
545
546 IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
547
548 bool IsSubclass = false;
549 do {
550 IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
551
552 if (IsSubclass) {
553 break;
554 }
555 } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
556
557 return IsSubclass;
558}
559
Guy Benyei11169dd2012-12-18 14:30:41 +0000560bool NSAPI::isObjCTypedef(QualType T,
561 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000562 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000563 return false;
564 if (T.isNull())
565 return false;
566
567 if (!II)
568 II = &Ctx.Idents.get(name);
569
570 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
571 if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
572 return true;
573 T = TDT->desugar();
574 }
575
576 return false;
577}
578
579bool NSAPI::isObjCEnumerator(const Expr *E,
580 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000581 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000582 return false;
583 if (!E)
584 return false;
585
586 if (!II)
587 II = &Ctx.Idents.get(name);
588
589 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
590 if (const EnumConstantDecl *
591 EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
592 return EnumD->getIdentifier() == II;
593
594 return false;
595}
596
597Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
598 Selector &Sel) const {
599 if (Sel.isNull()) {
600 SmallVector<IdentifierInfo *, 4> Idents;
601 for (ArrayRef<StringRef>::const_iterator
602 I = Ids.begin(), E = Ids.end(); I != E; ++I)
603 Idents.push_back(&Ctx.Idents.get(*I));
604 Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
605 }
606 return Sel;
607}
Erik Pilkington42578572018-09-10 22:20:09 +0000608
609Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
610 if (Sel.isNull()) {
611 IdentifierInfo *Ident = &Ctx.Idents.get(Id);
612 Sel = Ctx.Selectors.getSelector(0, &Ident);
613 }
614 return Sel;
615}