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