blob: 5104dc59d621e600b30a5309a7d2de06b3f5bb66 [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
David Blaikie05785d12013-02-20 22:23:23 +000078Optional<NSAPI::NSStringMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +000079NSAPI::getNSStringMethodKind(Selector Sel) const {
80 for (unsigned i = 0; i != NumNSStringMethods; ++i) {
81 NSStringMethodKind MK = NSStringMethodKind(i);
82 if (Sel == getNSStringSelector(MK))
83 return MK;
84 }
85
David Blaikie7a30dc52013-02-21 01:47:18 +000086 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +000087}
88
89Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
90 if (NSArraySelectors[MK].isNull()) {
91 Selector Sel;
92 switch (MK) {
93 case NSArr_array:
94 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
95 break;
96 case NSArr_arrayWithArray:
97 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
98 break;
99 case NSArr_arrayWithObject:
100 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
101 break;
102 case NSArr_arrayWithObjects:
103 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
104 break;
105 case NSArr_arrayWithObjectsCount: {
106 IdentifierInfo *KeyIdents[] = {
107 &Ctx.Idents.get("arrayWithObjects"),
108 &Ctx.Idents.get("count")
109 };
110 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
111 break;
112 }
113 case NSArr_initWithArray:
114 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
115 break;
116 case NSArr_initWithObjects:
117 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
118 break;
119 case NSArr_objectAtIndex:
120 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
121 break;
122 case NSMutableArr_replaceObjectAtIndex: {
123 IdentifierInfo *KeyIdents[] = {
124 &Ctx.Idents.get("replaceObjectAtIndex"),
125 &Ctx.Idents.get("withObject")
126 };
127 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128 break;
129 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000130 case NSMutableArr_addObject:
131 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
132 break;
133 case NSMutableArr_insertObjectAtIndex: {
134 IdentifierInfo *KeyIdents[] = {
135 &Ctx.Idents.get("insertObject"),
136 &Ctx.Idents.get("atIndex")
137 };
138 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
139 break;
140 }
141 case NSMutableArr_setObjectAtIndexedSubscript: {
142 IdentifierInfo *KeyIdents[] = {
143 &Ctx.Idents.get("setObject"),
144 &Ctx.Idents.get("atIndexedSubscript")
145 };
146 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
147 break;
148 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000149 }
150 return (NSArraySelectors[MK] = Sel);
151 }
152
153 return NSArraySelectors[MK];
154}
155
David Blaikie05785d12013-02-20 22:23:23 +0000156Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000157 for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
158 NSArrayMethodKind MK = NSArrayMethodKind(i);
159 if (Sel == getNSArraySelector(MK))
160 return MK;
161 }
162
David Blaikie7a30dc52013-02-21 01:47:18 +0000163 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000164}
165
166Selector NSAPI::getNSDictionarySelector(
167 NSDictionaryMethodKind MK) const {
168 if (NSDictionarySelectors[MK].isNull()) {
169 Selector Sel;
170 switch (MK) {
171 case NSDict_dictionary:
172 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
173 break;
174 case NSDict_dictionaryWithDictionary:
175 Sel = Ctx.Selectors.getUnarySelector(
176 &Ctx.Idents.get("dictionaryWithDictionary"));
177 break;
178 case NSDict_dictionaryWithObjectForKey: {
179 IdentifierInfo *KeyIdents[] = {
180 &Ctx.Idents.get("dictionaryWithObject"),
181 &Ctx.Idents.get("forKey")
182 };
183 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
184 break;
185 }
186 case NSDict_dictionaryWithObjectsForKeys: {
187 IdentifierInfo *KeyIdents[] = {
188 &Ctx.Idents.get("dictionaryWithObjects"),
189 &Ctx.Idents.get("forKeys")
190 };
191 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
192 break;
193 }
194 case NSDict_dictionaryWithObjectsForKeysCount: {
195 IdentifierInfo *KeyIdents[] = {
196 &Ctx.Idents.get("dictionaryWithObjects"),
197 &Ctx.Idents.get("forKeys"),
198 &Ctx.Idents.get("count")
199 };
200 Sel = Ctx.Selectors.getSelector(3, KeyIdents);
201 break;
202 }
203 case NSDict_dictionaryWithObjectsAndKeys:
204 Sel = Ctx.Selectors.getUnarySelector(
205 &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
206 break;
207 case NSDict_initWithDictionary:
208 Sel = Ctx.Selectors.getUnarySelector(
209 &Ctx.Idents.get("initWithDictionary"));
210 break;
211 case NSDict_initWithObjectsAndKeys:
212 Sel = Ctx.Selectors.getUnarySelector(
213 &Ctx.Idents.get("initWithObjectsAndKeys"));
214 break;
Argyrios Kyrtzidis6b4f3412013-01-16 23:54:48 +0000215 case NSDict_initWithObjectsForKeys: {
216 IdentifierInfo *KeyIdents[] = {
217 &Ctx.Idents.get("initWithObjects"),
218 &Ctx.Idents.get("forKeys")
219 };
220 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221 break;
222 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000223 case NSDict_objectForKey:
224 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
225 break;
226 case NSMutableDict_setObjectForKey: {
227 IdentifierInfo *KeyIdents[] = {
228 &Ctx.Idents.get("setObject"),
229 &Ctx.Idents.get("forKey")
230 };
231 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
232 break;
233 }
Alex Denisove1d882c2015-03-04 17:55:52 +0000234 case NSMutableDict_setObjectForKeyedSubscript: {
235 IdentifierInfo *KeyIdents[] = {
236 &Ctx.Idents.get("setObject"),
237 &Ctx.Idents.get("forKeyedSubscript")
238 };
239 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
240 break;
241 }
242 case NSMutableDict_setValueForKey: {
243 IdentifierInfo *KeyIdents[] = {
244 &Ctx.Idents.get("setValue"),
245 &Ctx.Idents.get("forKey")
246 };
247 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
248 break;
249 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 }
251 return (NSDictionarySelectors[MK] = Sel);
252 }
253
254 return NSDictionarySelectors[MK];
255}
256
David Blaikie05785d12013-02-20 22:23:23 +0000257Optional<NSAPI::NSDictionaryMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000258NSAPI::getNSDictionaryMethodKind(Selector Sel) {
259 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
260 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
261 if (Sel == getNSDictionarySelector(MK))
262 return MK;
263 }
264
David Blaikie7a30dc52013-02-21 01:47:18 +0000265 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266}
267
Alex Denisove1d882c2015-03-04 17:55:52 +0000268Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
269 if (NSSetSelectors[MK].isNull()) {
270 Selector Sel;
271 switch (MK) {
272 case NSMutableSet_addObject:
273 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
274 break;
275 case NSOrderedSet_insertObjectAtIndex: {
276 IdentifierInfo *KeyIdents[] = {
277 &Ctx.Idents.get("insertObject"),
278 &Ctx.Idents.get("atIndex")
279 };
280 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
281 break;
282 }
283 case NSOrderedSet_setObjectAtIndex: {
284 IdentifierInfo *KeyIdents[] = {
285 &Ctx.Idents.get("setObject"),
286 &Ctx.Idents.get("atIndex")
287 };
288 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
289 break;
290 }
291 case NSOrderedSet_setObjectAtIndexedSubscript: {
292 IdentifierInfo *KeyIdents[] = {
293 &Ctx.Idents.get("setObject"),
294 &Ctx.Idents.get("atIndexedSubscript")
295 };
296 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
297 break;
298 }
299 case NSOrderedSet_replaceObjectAtIndexWithObject: {
300 IdentifierInfo *KeyIdents[] = {
301 &Ctx.Idents.get("replaceObjectAtIndex"),
302 &Ctx.Idents.get("withObject")
303 };
304 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
305 break;
306 }
307 }
308 return (NSSetSelectors[MK] = Sel);
309 }
310
311 return NSSetSelectors[MK];
312}
313
314Optional<NSAPI::NSSetMethodKind>
315NSAPI::getNSSetMethodKind(Selector Sel) {
316 for (unsigned i = 0; i != NumNSSetMethods; ++i) {
317 NSSetMethodKind MK = NSSetMethodKind(i);
318 if (Sel == getNSSetSelector(MK))
319 return MK;
320 }
321
322 return None;
323}
324
Guy Benyei11169dd2012-12-18 14:30:41 +0000325Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
326 bool Instance) const {
327 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
328 "numberWithChar",
329 "numberWithUnsignedChar",
330 "numberWithShort",
331 "numberWithUnsignedShort",
332 "numberWithInt",
333 "numberWithUnsignedInt",
334 "numberWithLong",
335 "numberWithUnsignedLong",
336 "numberWithLongLong",
337 "numberWithUnsignedLongLong",
338 "numberWithFloat",
339 "numberWithDouble",
340 "numberWithBool",
341 "numberWithInteger",
342 "numberWithUnsignedInteger"
343 };
344 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
345 "initWithChar",
346 "initWithUnsignedChar",
347 "initWithShort",
348 "initWithUnsignedShort",
349 "initWithInt",
350 "initWithUnsignedInt",
351 "initWithLong",
352 "initWithUnsignedLong",
353 "initWithLongLong",
354 "initWithUnsignedLongLong",
355 "initWithFloat",
356 "initWithDouble",
357 "initWithBool",
358 "initWithInteger",
359 "initWithUnsignedInteger"
360 };
361
362 Selector *Sels;
363 const char **Names;
364 if (Instance) {
365 Sels = NSNumberInstanceSelectors;
366 Names = InstanceSelectorName;
367 } else {
368 Sels = NSNumberClassSelectors;
369 Names = ClassSelectorName;
370 }
371
372 if (Sels[MK].isNull())
373 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
374 return Sels[MK];
375}
376
David Blaikie05785d12013-02-20 22:23:23 +0000377Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000378NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
379 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
380 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
381 if (isNSNumberLiteralSelector(MK, Sel))
382 return MK;
383 }
384
David Blaikie7a30dc52013-02-21 01:47:18 +0000385 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000386}
387
David Blaikie05785d12013-02-20 22:23:23 +0000388Optional<NSAPI::NSNumberLiteralMethodKind>
Guy Benyei11169dd2012-12-18 14:30:41 +0000389NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
390 const BuiltinType *BT = T->getAs<BuiltinType>();
391 if (!BT)
David Blaikie7a30dc52013-02-21 01:47:18 +0000392 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393
394 const TypedefType *TDT = T->getAs<TypedefType>();
395 if (TDT) {
396 QualType TDTTy = QualType(TDT, 0);
397 if (isObjCBOOLType(TDTTy))
398 return NSAPI::NSNumberWithBool;
399 if (isObjCNSIntegerType(TDTTy))
400 return NSAPI::NSNumberWithInteger;
401 if (isObjCNSUIntegerType(TDTTy))
402 return NSAPI::NSNumberWithUnsignedInteger;
403 }
404
405 switch (BT->getKind()) {
406 case BuiltinType::Char_S:
407 case BuiltinType::SChar:
408 return NSAPI::NSNumberWithChar;
409 case BuiltinType::Char_U:
410 case BuiltinType::UChar:
411 return NSAPI::NSNumberWithUnsignedChar;
412 case BuiltinType::Short:
413 return NSAPI::NSNumberWithShort;
414 case BuiltinType::UShort:
415 return NSAPI::NSNumberWithUnsignedShort;
416 case BuiltinType::Int:
417 return NSAPI::NSNumberWithInt;
418 case BuiltinType::UInt:
419 return NSAPI::NSNumberWithUnsignedInt;
420 case BuiltinType::Long:
421 return NSAPI::NSNumberWithLong;
422 case BuiltinType::ULong:
423 return NSAPI::NSNumberWithUnsignedLong;
424 case BuiltinType::LongLong:
425 return NSAPI::NSNumberWithLongLong;
426 case BuiltinType::ULongLong:
427 return NSAPI::NSNumberWithUnsignedLongLong;
428 case BuiltinType::Float:
429 return NSAPI::NSNumberWithFloat;
430 case BuiltinType::Double:
431 return NSAPI::NSNumberWithDouble;
432 case BuiltinType::Bool:
433 return NSAPI::NSNumberWithBool;
Fangrui Song6907ce22018-07-30 19:24:48 +0000434
Guy Benyei11169dd2012-12-18 14:30:41 +0000435 case BuiltinType::Void:
436 case BuiltinType::WChar_U:
437 case BuiltinType::WChar_S:
Richard Smith3a8244d2018-05-01 05:02:45 +0000438 case BuiltinType::Char8:
Guy Benyei11169dd2012-12-18 14:30:41 +0000439 case BuiltinType::Char16:
440 case BuiltinType::Char32:
441 case BuiltinType::Int128:
442 case BuiltinType::LongDouble:
Leonard Chanf921d852018-06-04 16:07:52 +0000443 case BuiltinType::ShortAccum:
444 case BuiltinType::Accum:
445 case BuiltinType::LongAccum:
446 case BuiltinType::UShortAccum:
447 case BuiltinType::UAccum:
448 case BuiltinType::ULongAccum:
Leonard Chanab80f3c2018-06-14 14:53:51 +0000449 case BuiltinType::ShortFract:
450 case BuiltinType::Fract:
451 case BuiltinType::LongFract:
452 case BuiltinType::UShortFract:
453 case BuiltinType::UFract:
454 case BuiltinType::ULongFract:
455 case BuiltinType::SatShortAccum:
456 case BuiltinType::SatAccum:
457 case BuiltinType::SatLongAccum:
458 case BuiltinType::SatUShortAccum:
459 case BuiltinType::SatUAccum:
460 case BuiltinType::SatULongAccum:
461 case BuiltinType::SatShortFract:
462 case BuiltinType::SatFract:
463 case BuiltinType::SatLongFract:
464 case BuiltinType::SatUShortFract:
465 case BuiltinType::SatUFract:
466 case BuiltinType::SatULongFract:
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 case BuiltinType::UInt128:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +0000468 case BuiltinType::Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +0000469 case BuiltinType::Float128:
Guy Benyei11169dd2012-12-18 14:30:41 +0000470 case BuiltinType::NullPtr:
471 case BuiltinType::ObjCClass:
472 case BuiltinType::ObjCId:
473 case BuiltinType::ObjCSel:
Alexey Bader954ba212016-04-08 13:40:33 +0000474#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
475 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +0000476#include "clang/Basic/OpenCLImageTypes.def"
Andrew Savonichev3fee3512018-11-08 11:25:41 +0000477#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
478 case BuiltinType::Id:
479#include "clang/Basic/OpenCLExtensionTypes.def"
Guy Benyei61054192013-02-07 10:55:47 +0000480 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +0000481 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000482 case BuiltinType::OCLClkEvent:
483 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +0000484 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +0000485 case BuiltinType::BoundMember:
486 case BuiltinType::Dependent:
487 case BuiltinType::Overload:
488 case BuiltinType::UnknownAny:
489 case BuiltinType::ARCUnbridgedCast:
490 case BuiltinType::Half:
491 case BuiltinType::PseudoObject:
492 case BuiltinType::BuiltinFn:
Alexey Bataev1a3320e2015-08-25 14:24:04 +0000493 case BuiltinType::OMPArraySection:
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 break;
495 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000496
David Blaikie7a30dc52013-02-21 01:47:18 +0000497 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000498}
499
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000500/// Returns true if \param T is a typedef of "BOOL" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000501bool NSAPI::isObjCBOOLType(QualType T) const {
502 return isObjCTypedef(T, "BOOL", BOOLId);
503}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000504/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000505bool NSAPI::isObjCNSIntegerType(QualType T) const {
506 return isObjCTypedef(T, "NSInteger", NSIntegerId);
507}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000508/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000509bool NSAPI::isObjCNSUIntegerType(QualType T) const {
510 return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
511}
512
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000513StringRef NSAPI::GetNSIntegralKind(QualType T) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000514 if (!Ctx.getLangOpts().ObjC || T.isNull())
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000515 return StringRef();
Fangrui Song6907ce22018-07-30 19:24:48 +0000516
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000517 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
518 StringRef NSIntegralResust =
519 llvm::StringSwitch<StringRef>(
520 TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
521 .Case("int8_t", "int8_t")
522 .Case("int16_t", "int16_t")
523 .Case("int32_t", "int32_t")
524 .Case("NSInteger", "NSInteger")
525 .Case("int64_t", "int64_t")
526 .Case("uint8_t", "uint8_t")
527 .Case("uint16_t", "uint16_t")
528 .Case("uint32_t", "uint32_t")
529 .Case("NSUInteger", "NSUInteger")
530 .Case("uint64_t", "uint64_t")
531 .Default(StringRef());
532 if (!NSIntegralResust.empty())
533 return NSIntegralResust;
534 T = TDT->desugar();
535 }
536 return StringRef();
537}
538
Richard Smith20e883e2015-04-29 23:20:19 +0000539bool NSAPI::isMacroDefined(StringRef Id) const {
540 // FIXME: Check whether the relevant module macros are visible.
541 return Ctx.Idents.get(Id).hasMacroDefinition();
542}
543
Alex Denisov5dfac812015-08-06 04:51:14 +0000544bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
545 NSClassIdKindKind NSClassKind) const {
546 if (!InterfaceDecl) {
547 return false;
548 }
549
550 IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
551
552 bool IsSubclass = false;
553 do {
554 IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
555
556 if (IsSubclass) {
557 break;
558 }
559 } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
560
561 return IsSubclass;
562}
563
Guy Benyei11169dd2012-12-18 14:30:41 +0000564bool NSAPI::isObjCTypedef(QualType T,
565 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000566 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000567 return false;
568 if (T.isNull())
569 return false;
570
571 if (!II)
572 II = &Ctx.Idents.get(name);
573
574 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
575 if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
576 return true;
577 T = TDT->desugar();
578 }
579
580 return false;
581}
582
583bool NSAPI::isObjCEnumerator(const Expr *E,
584 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000585 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000586 return false;
587 if (!E)
588 return false;
589
590 if (!II)
591 II = &Ctx.Idents.get(name);
592
593 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
594 if (const EnumConstantDecl *
595 EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
596 return EnumD->getIdentifier() == II;
597
598 return false;
599}
600
601Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
602 Selector &Sel) const {
603 if (Sel.isNull()) {
604 SmallVector<IdentifierInfo *, 4> Idents;
605 for (ArrayRef<StringRef>::const_iterator
606 I = Ids.begin(), E = Ids.end(); I != E; ++I)
607 Idents.push_back(&Ctx.Idents.get(*I));
608 Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
609 }
610 return Sel;
611}
Erik Pilkington42578572018-09-10 22:20:09 +0000612
613Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
614 if (Sel.isNull()) {
615 IdentifierInfo *Ident = &Ctx.Idents.get(Id);
616 Sel = Ctx.Selectors.getSelector(0, &Ident);
617 }
618 return Sel;
619}