blob: 5b8300893e2d5c5b76447feabd9a3fb4f07d7188 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/AST/NSAPI.h"
11#include "clang/AST/ASTContext.h"
Alex Denisov5dfac812015-08-06 04:51:14 +000012#include "clang/AST/DeclObjC.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000013#include "clang/AST/Expr.h"
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +000014#include "llvm/ADT/StringSwitch.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000015
16using namespace clang;
17
18NSAPI::NSAPI(ASTContext &ctx)
Craig Topper36250ad2014-05-12 05:36:57 +000019 : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
20 NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
21 NSUTF8StringEncodingId(nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +000022
23IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
24 static const char *ClassName[NumClassIds] = {
25 "NSObject",
26 "NSString",
27 "NSArray",
28 "NSMutableArray",
29 "NSDictionary",
30 "NSMutableDictionary",
Alex Denisove1d882c2015-03-04 17:55:52 +000031 "NSNumber",
32 "NSMutableSet",
Alex Denisovfde64952015-06-26 05:28:36 +000033 "NSMutableOrderedSet",
34 "NSValue"
Guy Benyei11169dd2012-12-18 14:30:41 +000035 };
36
37 if (!ClassIds[K])
38 return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
39
40 return ClassIds[K];
41}
42
43Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
44 if (NSStringSelectors[MK].isNull()) {
45 Selector Sel;
46 switch (MK) {
47 case NSStr_stringWithString:
48 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
49 break;
50 case NSStr_stringWithUTF8String:
51 Sel = Ctx.Selectors.getUnarySelector(
52 &Ctx.Idents.get("stringWithUTF8String"));
53 break;
Fariborz Jahanianbe7bf722014-08-25 20:22:25 +000054 case NSStr_initWithUTF8String:
55 Sel = Ctx.Selectors.getUnarySelector(
56 &Ctx.Idents.get("initWithUTF8String"));
57 break;
Guy Benyei11169dd2012-12-18 14:30:41 +000058 case NSStr_stringWithCStringEncoding: {
59 IdentifierInfo *KeyIdents[] = {
60 &Ctx.Idents.get("stringWithCString"),
61 &Ctx.Idents.get("encoding")
62 };
63 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
64 break;
65 }
66 case NSStr_stringWithCString:
67 Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
68 break;
69 case NSStr_initWithString:
70 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
71 break;
72 }
73 return (NSStringSelectors[MK] = Sel);
74 }
75
76 return NSStringSelectors[MK];
77}
78
David Blaikie05785d12013-02-20 22:23:23 +000079Optional<NSAPI::NSStringMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +000080NSAPI::getNSStringMethodKind(Selector Sel) const {
81 for (unsigned i = 0; i != NumNSStringMethods; ++i) {
82 NSStringMethodKind MK = NSStringMethodKind(i);
83 if (Sel == getNSStringSelector(MK))
84 return MK;
85 }
86
David Blaikie7a30dc52013-02-21 01:47:18 +000087 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +000088}
89
90Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
91 if (NSArraySelectors[MK].isNull()) {
92 Selector Sel;
93 switch (MK) {
94 case NSArr_array:
95 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
96 break;
97 case NSArr_arrayWithArray:
98 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
99 break;
100 case NSArr_arrayWithObject:
101 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
102 break;
103 case NSArr_arrayWithObjects:
104 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
105 break;
106 case NSArr_arrayWithObjectsCount: {
107 IdentifierInfo *KeyIdents[] = {
108 &Ctx.Idents.get("arrayWithObjects"),
109 &Ctx.Idents.get("count")
110 };
111 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
112 break;
113 }
114 case NSArr_initWithArray:
115 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
116 break;
117 case NSArr_initWithObjects:
118 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
119 break;
120 case NSArr_objectAtIndex:
121 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
122 break;
123 case NSMutableArr_replaceObjectAtIndex: {
124 IdentifierInfo *KeyIdents[] = {
125 &Ctx.Idents.get("replaceObjectAtIndex"),
126 &Ctx.Idents.get("withObject")
127 };
128 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
129 break;
130 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000131 case NSMutableArr_addObject:
132 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
133 break;
134 case NSMutableArr_insertObjectAtIndex: {
135 IdentifierInfo *KeyIdents[] = {
136 &Ctx.Idents.get("insertObject"),
137 &Ctx.Idents.get("atIndex")
138 };
139 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
140 break;
141 }
142 case NSMutableArr_setObjectAtIndexedSubscript: {
143 IdentifierInfo *KeyIdents[] = {
144 &Ctx.Idents.get("setObject"),
145 &Ctx.Idents.get("atIndexedSubscript")
146 };
147 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
148 break;
149 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000150 }
151 return (NSArraySelectors[MK] = Sel);
152 }
153
154 return NSArraySelectors[MK];
155}
156
David Blaikie05785d12013-02-20 22:23:23 +0000157Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
159 NSArrayMethodKind MK = NSArrayMethodKind(i);
160 if (Sel == getNSArraySelector(MK))
161 return MK;
162 }
163
David Blaikie7a30dc52013-02-21 01:47:18 +0000164 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000165}
166
167Selector NSAPI::getNSDictionarySelector(
168 NSDictionaryMethodKind MK) const {
169 if (NSDictionarySelectors[MK].isNull()) {
170 Selector Sel;
171 switch (MK) {
172 case NSDict_dictionary:
173 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
174 break;
175 case NSDict_dictionaryWithDictionary:
176 Sel = Ctx.Selectors.getUnarySelector(
177 &Ctx.Idents.get("dictionaryWithDictionary"));
178 break;
179 case NSDict_dictionaryWithObjectForKey: {
180 IdentifierInfo *KeyIdents[] = {
181 &Ctx.Idents.get("dictionaryWithObject"),
182 &Ctx.Idents.get("forKey")
183 };
184 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
185 break;
186 }
187 case NSDict_dictionaryWithObjectsForKeys: {
188 IdentifierInfo *KeyIdents[] = {
189 &Ctx.Idents.get("dictionaryWithObjects"),
190 &Ctx.Idents.get("forKeys")
191 };
192 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
193 break;
194 }
195 case NSDict_dictionaryWithObjectsForKeysCount: {
196 IdentifierInfo *KeyIdents[] = {
197 &Ctx.Idents.get("dictionaryWithObjects"),
198 &Ctx.Idents.get("forKeys"),
199 &Ctx.Idents.get("count")
200 };
201 Sel = Ctx.Selectors.getSelector(3, KeyIdents);
202 break;
203 }
204 case NSDict_dictionaryWithObjectsAndKeys:
205 Sel = Ctx.Selectors.getUnarySelector(
206 &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
207 break;
208 case NSDict_initWithDictionary:
209 Sel = Ctx.Selectors.getUnarySelector(
210 &Ctx.Idents.get("initWithDictionary"));
211 break;
212 case NSDict_initWithObjectsAndKeys:
213 Sel = Ctx.Selectors.getUnarySelector(
214 &Ctx.Idents.get("initWithObjectsAndKeys"));
215 break;
Argyrios Kyrtzidis6b4f3412013-01-16 23:54:48 +0000216 case NSDict_initWithObjectsForKeys: {
217 IdentifierInfo *KeyIdents[] = {
218 &Ctx.Idents.get("initWithObjects"),
219 &Ctx.Idents.get("forKeys")
220 };
221 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
222 break;
223 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000224 case NSDict_objectForKey:
225 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
226 break;
227 case NSMutableDict_setObjectForKey: {
228 IdentifierInfo *KeyIdents[] = {
229 &Ctx.Idents.get("setObject"),
230 &Ctx.Idents.get("forKey")
231 };
232 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
233 break;
234 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000235 case NSMutableDict_setObjectForKeyedSubscript: {
236 IdentifierInfo *KeyIdents[] = {
237 &Ctx.Idents.get("setObject"),
238 &Ctx.Idents.get("forKeyedSubscript")
239 };
240 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
241 break;
242 }
243 case NSMutableDict_setValueForKey: {
244 IdentifierInfo *KeyIdents[] = {
245 &Ctx.Idents.get("setValue"),
246 &Ctx.Idents.get("forKey")
247 };
248 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
249 break;
250 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 }
252 return (NSDictionarySelectors[MK] = Sel);
253 }
254
255 return NSDictionarySelectors[MK];
256}
257
David Blaikie05785d12013-02-20 22:23:23 +0000258Optional<NSAPI::NSDictionaryMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000259NSAPI::getNSDictionaryMethodKind(Selector Sel) {
260 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
261 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
262 if (Sel == getNSDictionarySelector(MK))
263 return MK;
264 }
265
David Blaikie7a30dc52013-02-21 01:47:18 +0000266 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000267}
268
Alex Denisove1d882c2015-03-04 17:55:52 +0000269Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
270 if (NSSetSelectors[MK].isNull()) {
271 Selector Sel;
272 switch (MK) {
273 case NSMutableSet_addObject:
274 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
275 break;
276 case NSOrderedSet_insertObjectAtIndex: {
277 IdentifierInfo *KeyIdents[] = {
278 &Ctx.Idents.get("insertObject"),
279 &Ctx.Idents.get("atIndex")
280 };
281 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
282 break;
283 }
284 case NSOrderedSet_setObjectAtIndex: {
285 IdentifierInfo *KeyIdents[] = {
286 &Ctx.Idents.get("setObject"),
287 &Ctx.Idents.get("atIndex")
288 };
289 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
290 break;
291 }
292 case NSOrderedSet_setObjectAtIndexedSubscript: {
293 IdentifierInfo *KeyIdents[] = {
294 &Ctx.Idents.get("setObject"),
295 &Ctx.Idents.get("atIndexedSubscript")
296 };
297 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
298 break;
299 }
300 case NSOrderedSet_replaceObjectAtIndexWithObject: {
301 IdentifierInfo *KeyIdents[] = {
302 &Ctx.Idents.get("replaceObjectAtIndex"),
303 &Ctx.Idents.get("withObject")
304 };
305 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
306 break;
307 }
308 }
309 return (NSSetSelectors[MK] = Sel);
310 }
311
312 return NSSetSelectors[MK];
313}
314
315Optional<NSAPI::NSSetMethodKind>
316NSAPI::getNSSetMethodKind(Selector Sel) {
317 for (unsigned i = 0; i != NumNSSetMethods; ++i) {
318 NSSetMethodKind MK = NSSetMethodKind(i);
319 if (Sel == getNSSetSelector(MK))
320 return MK;
321 }
322
323 return None;
324}
325
Guy Benyei11169dd2012-12-18 14:30:41 +0000326Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
327 bool Instance) const {
328 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
329 "numberWithChar",
330 "numberWithUnsignedChar",
331 "numberWithShort",
332 "numberWithUnsignedShort",
333 "numberWithInt",
334 "numberWithUnsignedInt",
335 "numberWithLong",
336 "numberWithUnsignedLong",
337 "numberWithLongLong",
338 "numberWithUnsignedLongLong",
339 "numberWithFloat",
340 "numberWithDouble",
341 "numberWithBool",
342 "numberWithInteger",
343 "numberWithUnsignedInteger"
344 };
345 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
346 "initWithChar",
347 "initWithUnsignedChar",
348 "initWithShort",
349 "initWithUnsignedShort",
350 "initWithInt",
351 "initWithUnsignedInt",
352 "initWithLong",
353 "initWithUnsignedLong",
354 "initWithLongLong",
355 "initWithUnsignedLongLong",
356 "initWithFloat",
357 "initWithDouble",
358 "initWithBool",
359 "initWithInteger",
360 "initWithUnsignedInteger"
361 };
362
363 Selector *Sels;
364 const char **Names;
365 if (Instance) {
366 Sels = NSNumberInstanceSelectors;
367 Names = InstanceSelectorName;
368 } else {
369 Sels = NSNumberClassSelectors;
370 Names = ClassSelectorName;
371 }
372
373 if (Sels[MK].isNull())
374 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
375 return Sels[MK];
376}
377
David Blaikie05785d12013-02-20 22:23:23 +0000378Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000379NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
380 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
381 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
382 if (isNSNumberLiteralSelector(MK, Sel))
383 return MK;
384 }
385
David Blaikie7a30dc52013-02-21 01:47:18 +0000386 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000387}
388
David Blaikie05785d12013-02-20 22:23:23 +0000389Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000390NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
391 const BuiltinType *BT = T->getAs<BuiltinType>();
392 if (!BT)
David Blaikie7a30dc52013-02-21 01:47:18 +0000393 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000394
395 const TypedefType *TDT = T->getAs<TypedefType>();
396 if (TDT) {
397 QualType TDTTy = QualType(TDT, 0);
398 if (isObjCBOOLType(TDTTy))
399 return NSAPI::NSNumberWithBool;
400 if (isObjCNSIntegerType(TDTTy))
401 return NSAPI::NSNumberWithInteger;
402 if (isObjCNSUIntegerType(TDTTy))
403 return NSAPI::NSNumberWithUnsignedInteger;
404 }
405
406 switch (BT->getKind()) {
407 case BuiltinType::Char_S:
408 case BuiltinType::SChar:
409 return NSAPI::NSNumberWithChar;
410 case BuiltinType::Char_U:
411 case BuiltinType::UChar:
412 return NSAPI::NSNumberWithUnsignedChar;
413 case BuiltinType::Short:
414 return NSAPI::NSNumberWithShort;
415 case BuiltinType::UShort:
416 return NSAPI::NSNumberWithUnsignedShort;
417 case BuiltinType::Int:
418 return NSAPI::NSNumberWithInt;
419 case BuiltinType::UInt:
420 return NSAPI::NSNumberWithUnsignedInt;
421 case BuiltinType::Long:
422 return NSAPI::NSNumberWithLong;
423 case BuiltinType::ULong:
424 return NSAPI::NSNumberWithUnsignedLong;
425 case BuiltinType::LongLong:
426 return NSAPI::NSNumberWithLongLong;
427 case BuiltinType::ULongLong:
428 return NSAPI::NSNumberWithUnsignedLongLong;
429 case BuiltinType::Float:
430 return NSAPI::NSNumberWithFloat;
431 case BuiltinType::Double:
432 return NSAPI::NSNumberWithDouble;
433 case BuiltinType::Bool:
434 return NSAPI::NSNumberWithBool;
Fangrui Song6907ce22018-07-30 19:24:48 +0000435
Guy Benyei11169dd2012-12-18 14:30:41 +0000436 case BuiltinType::Void:
437 case BuiltinType::WChar_U:
438 case BuiltinType::WChar_S:
Richard Smith3a8244d2018-05-01 05:02:45 +0000439 case BuiltinType::Char8:
Guy Benyei11169dd2012-12-18 14:30:41 +0000440 case BuiltinType::Char16:
441 case BuiltinType::Char32:
442 case BuiltinType::Int128:
443 case BuiltinType::LongDouble:
Leonard Chanf921d852018-06-04 16:07:52 +0000444 case BuiltinType::ShortAccum:
445 case BuiltinType::Accum:
446 case BuiltinType::LongAccum:
447 case BuiltinType::UShortAccum:
448 case BuiltinType::UAccum:
449 case BuiltinType::ULongAccum:
Leonard Chanab80f3c2018-06-14 14:53:51 +0000450 case BuiltinType::ShortFract:
451 case BuiltinType::Fract:
452 case BuiltinType::LongFract:
453 case BuiltinType::UShortFract:
454 case BuiltinType::UFract:
455 case BuiltinType::ULongFract:
456 case BuiltinType::SatShortAccum:
457 case BuiltinType::SatAccum:
458 case BuiltinType::SatLongAccum:
459 case BuiltinType::SatUShortAccum:
460 case BuiltinType::SatUAccum:
461 case BuiltinType::SatULongAccum:
462 case BuiltinType::SatShortFract:
463 case BuiltinType::SatFract:
464 case BuiltinType::SatLongFract:
465 case BuiltinType::SatUShortFract:
466 case BuiltinType::SatUFract:
467 case BuiltinType::SatULongFract:
Guy Benyei11169dd2012-12-18 14:30:41 +0000468 case BuiltinType::UInt128:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +0000469 case BuiltinType::Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +0000470 case BuiltinType::Float128:
Guy Benyei11169dd2012-12-18 14:30:41 +0000471 case BuiltinType::NullPtr:
472 case BuiltinType::ObjCClass:
473 case BuiltinType::ObjCId:
474 case BuiltinType::ObjCSel:
Alexey Bader954ba212016-04-08 13:40:33 +0000475#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
476 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +0000477#include "clang/Basic/OpenCLImageTypes.def"
Andrew Savonichev3fee3512018-11-08 11:25:41 +0000478#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
479 case BuiltinType::Id:
480#include "clang/Basic/OpenCLExtensionTypes.def"
Guy Benyei61054192013-02-07 10:55:47 +0000481 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +0000482 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000483 case BuiltinType::OCLClkEvent:
484 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000485 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +0000486 case BuiltinType::BoundMember:
487 case BuiltinType::Dependent:
488 case BuiltinType::Overload:
489 case BuiltinType::UnknownAny:
490 case BuiltinType::ARCUnbridgedCast:
491 case BuiltinType::Half:
492 case BuiltinType::PseudoObject:
493 case BuiltinType::BuiltinFn:
Alexey Bataev1a3320e2015-08-25 14:24:04 +0000494 case BuiltinType::OMPArraySection:
Guy Benyei11169dd2012-12-18 14:30:41 +0000495 break;
496 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000497
David Blaikie7a30dc52013-02-21 01:47:18 +0000498 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000499}
500
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000501/// Returns true if \param T is a typedef of "BOOL" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000502bool NSAPI::isObjCBOOLType(QualType T) const {
503 return isObjCTypedef(T, "BOOL", BOOLId);
504}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000505/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000506bool NSAPI::isObjCNSIntegerType(QualType T) const {
507 return isObjCTypedef(T, "NSInteger", NSIntegerId);
508}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000509/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000510bool NSAPI::isObjCNSUIntegerType(QualType T) const {
511 return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
512}
513
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000514StringRef NSAPI::GetNSIntegralKind(QualType T) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000515 if (!Ctx.getLangOpts().ObjC || T.isNull())
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000516 return StringRef();
Fangrui Song6907ce22018-07-30 19:24:48 +0000517
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000518 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
519 StringRef NSIntegralResust =
520 llvm::StringSwitch<StringRef>(
521 TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
522 .Case("int8_t", "int8_t")
523 .Case("int16_t", "int16_t")
524 .Case("int32_t", "int32_t")
525 .Case("NSInteger", "NSInteger")
526 .Case("int64_t", "int64_t")
527 .Case("uint8_t", "uint8_t")
528 .Case("uint16_t", "uint16_t")
529 .Case("uint32_t", "uint32_t")
530 .Case("NSUInteger", "NSUInteger")
531 .Case("uint64_t", "uint64_t")
532 .Default(StringRef());
533 if (!NSIntegralResust.empty())
534 return NSIntegralResust;
535 T = TDT->desugar();
536 }
537 return StringRef();
538}
539
Richard Smith20e883e2015-04-29 23:20:19 +0000540bool NSAPI::isMacroDefined(StringRef Id) const {
541 // FIXME: Check whether the relevant module macros are visible.
542 return Ctx.Idents.get(Id).hasMacroDefinition();
543}
544
Alex Denisov5dfac812015-08-06 04:51:14 +0000545bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
546 NSClassIdKindKind NSClassKind) const {
547 if (!InterfaceDecl) {
548 return false;
549 }
550
551 IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
552
553 bool IsSubclass = false;
554 do {
555 IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
556
557 if (IsSubclass) {
558 break;
559 }
560 } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
561
562 return IsSubclass;
563}
564
Guy Benyei11169dd2012-12-18 14:30:41 +0000565bool NSAPI::isObjCTypedef(QualType T,
566 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000567 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000568 return false;
569 if (T.isNull())
570 return false;
571
572 if (!II)
573 II = &Ctx.Idents.get(name);
574
575 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
576 if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
577 return true;
578 T = TDT->desugar();
579 }
580
581 return false;
582}
583
584bool NSAPI::isObjCEnumerator(const Expr *E,
585 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000586 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000587 return false;
588 if (!E)
589 return false;
590
591 if (!II)
592 II = &Ctx.Idents.get(name);
593
594 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
595 if (const EnumConstantDecl *
596 EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
597 return EnumD->getIdentifier() == II;
598
599 return false;
600}
601
602Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
603 Selector &Sel) const {
604 if (Sel.isNull()) {
605 SmallVector<IdentifierInfo *, 4> Idents;
606 for (ArrayRef<StringRef>::const_iterator
607 I = Ids.begin(), E = Ids.end(); I != E; ++I)
608 Idents.push_back(&Ctx.Idents.get(*I));
609 Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
610 }
611 return Sel;
612}
Erik Pilkington42578572018-09-10 22:20:09 +0000613
614Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
615 if (Sel.isNull()) {
616 IdentifierInfo *Ident = &Ctx.Idents.get(Id);
617 Sel = Ctx.Selectors.getSelector(0, &Ident);
618 }
619 return Sel;
620}