blob: ac06d330b3d6e84cc8740111dd1238126fc214f0 [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:
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 break;
490 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000491
David Blaikie7a30dc52013-02-21 01:47:18 +0000492 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000493}
494
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000495/// Returns true if \param T is a typedef of "BOOL" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000496bool NSAPI::isObjCBOOLType(QualType T) const {
497 return isObjCTypedef(T, "BOOL", BOOLId);
498}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000499/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000500bool NSAPI::isObjCNSIntegerType(QualType T) const {
501 return isObjCTypedef(T, "NSInteger", NSIntegerId);
502}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000503/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
Guy Benyei11169dd2012-12-18 14:30:41 +0000504bool NSAPI::isObjCNSUIntegerType(QualType T) const {
505 return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
506}
507
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000508StringRef NSAPI::GetNSIntegralKind(QualType T) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000509 if (!Ctx.getLangOpts().ObjC || T.isNull())
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000510 return StringRef();
Fangrui Song6907ce22018-07-30 19:24:48 +0000511
Fariborz Jahanian35ee87d2014-10-06 23:50:37 +0000512 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
513 StringRef NSIntegralResust =
514 llvm::StringSwitch<StringRef>(
515 TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
516 .Case("int8_t", "int8_t")
517 .Case("int16_t", "int16_t")
518 .Case("int32_t", "int32_t")
519 .Case("NSInteger", "NSInteger")
520 .Case("int64_t", "int64_t")
521 .Case("uint8_t", "uint8_t")
522 .Case("uint16_t", "uint16_t")
523 .Case("uint32_t", "uint32_t")
524 .Case("NSUInteger", "NSUInteger")
525 .Case("uint64_t", "uint64_t")
526 .Default(StringRef());
527 if (!NSIntegralResust.empty())
528 return NSIntegralResust;
529 T = TDT->desugar();
530 }
531 return StringRef();
532}
533
Richard Smith20e883e2015-04-29 23:20:19 +0000534bool NSAPI::isMacroDefined(StringRef Id) const {
535 // FIXME: Check whether the relevant module macros are visible.
536 return Ctx.Idents.get(Id).hasMacroDefinition();
537}
538
Alex Denisov5dfac812015-08-06 04:51:14 +0000539bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
540 NSClassIdKindKind NSClassKind) const {
541 if (!InterfaceDecl) {
542 return false;
543 }
544
545 IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
546
547 bool IsSubclass = false;
548 do {
549 IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
550
551 if (IsSubclass) {
552 break;
553 }
554 } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
555
556 return IsSubclass;
557}
558
Guy Benyei11169dd2012-12-18 14:30:41 +0000559bool NSAPI::isObjCTypedef(QualType T,
560 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000561 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000562 return false;
563 if (T.isNull())
564 return false;
565
566 if (!II)
567 II = &Ctx.Idents.get(name);
568
569 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
570 if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
571 return true;
572 T = TDT->desugar();
573 }
574
575 return false;
576}
577
578bool NSAPI::isObjCEnumerator(const Expr *E,
579 StringRef name, IdentifierInfo *&II) const {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000580 if (!Ctx.getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000581 return false;
582 if (!E)
583 return false;
584
585 if (!II)
586 II = &Ctx.Idents.get(name);
587
588 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
589 if (const EnumConstantDecl *
590 EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
591 return EnumD->getIdentifier() == II;
592
593 return false;
594}
595
596Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
597 Selector &Sel) const {
598 if (Sel.isNull()) {
599 SmallVector<IdentifierInfo *, 4> Idents;
600 for (ArrayRef<StringRef>::const_iterator
601 I = Ids.begin(), E = Ids.end(); I != E; ++I)
602 Idents.push_back(&Ctx.Idents.get(*I));
603 Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
604 }
605 return Sel;
606}
Erik Pilkington42578572018-09-10 22:20:09 +0000607
608Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
609 if (Sel.isNull()) {
610 IdentifierInfo *Ident = &Ctx.Idents.get(Id);
611 Sel = Ctx.Selectors.getSelector(0, &Ident);
612 }
613 return Sel;
614}