xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/NSAPI.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg 
97330f729Sjoerg #include "clang/AST/NSAPI.h"
107330f729Sjoerg #include "clang/AST/ASTContext.h"
117330f729Sjoerg #include "clang/AST/DeclObjC.h"
127330f729Sjoerg #include "clang/AST/Expr.h"
137330f729Sjoerg #include "llvm/ADT/StringSwitch.h"
147330f729Sjoerg 
157330f729Sjoerg using namespace clang;
167330f729Sjoerg 
NSAPI(ASTContext & ctx)177330f729Sjoerg NSAPI::NSAPI(ASTContext &ctx)
187330f729Sjoerg   : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
197330f729Sjoerg     NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
207330f729Sjoerg     NSUTF8StringEncodingId(nullptr) {}
217330f729Sjoerg 
getNSClassId(NSClassIdKindKind K) const227330f729Sjoerg IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
237330f729Sjoerg   static const char *ClassName[NumClassIds] = {
247330f729Sjoerg     "NSObject",
257330f729Sjoerg     "NSString",
267330f729Sjoerg     "NSArray",
277330f729Sjoerg     "NSMutableArray",
287330f729Sjoerg     "NSDictionary",
297330f729Sjoerg     "NSMutableDictionary",
307330f729Sjoerg     "NSNumber",
317330f729Sjoerg     "NSMutableSet",
327330f729Sjoerg     "NSMutableOrderedSet",
337330f729Sjoerg     "NSValue"
347330f729Sjoerg   };
357330f729Sjoerg 
367330f729Sjoerg   if (!ClassIds[K])
377330f729Sjoerg     return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
387330f729Sjoerg 
397330f729Sjoerg   return ClassIds[K];
407330f729Sjoerg }
417330f729Sjoerg 
getNSStringSelector(NSStringMethodKind MK) const427330f729Sjoerg Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
437330f729Sjoerg   if (NSStringSelectors[MK].isNull()) {
447330f729Sjoerg     Selector Sel;
457330f729Sjoerg     switch (MK) {
467330f729Sjoerg     case NSStr_stringWithString:
477330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
487330f729Sjoerg       break;
497330f729Sjoerg     case NSStr_stringWithUTF8String:
507330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
517330f729Sjoerg                                        &Ctx.Idents.get("stringWithUTF8String"));
527330f729Sjoerg       break;
537330f729Sjoerg     case NSStr_initWithUTF8String:
547330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
557330f729Sjoerg                                        &Ctx.Idents.get("initWithUTF8String"));
567330f729Sjoerg       break;
577330f729Sjoerg     case NSStr_stringWithCStringEncoding: {
587330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
597330f729Sjoerg         &Ctx.Idents.get("stringWithCString"),
607330f729Sjoerg         &Ctx.Idents.get("encoding")
617330f729Sjoerg       };
627330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
637330f729Sjoerg       break;
647330f729Sjoerg     }
657330f729Sjoerg     case NSStr_stringWithCString:
667330f729Sjoerg       Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
677330f729Sjoerg       break;
687330f729Sjoerg     case NSStr_initWithString:
697330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
707330f729Sjoerg       break;
717330f729Sjoerg     }
727330f729Sjoerg     return (NSStringSelectors[MK] = Sel);
737330f729Sjoerg   }
747330f729Sjoerg 
757330f729Sjoerg   return NSStringSelectors[MK];
767330f729Sjoerg }
777330f729Sjoerg 
getNSArraySelector(NSArrayMethodKind MK) const787330f729Sjoerg Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
797330f729Sjoerg   if (NSArraySelectors[MK].isNull()) {
807330f729Sjoerg     Selector Sel;
817330f729Sjoerg     switch (MK) {
827330f729Sjoerg     case NSArr_array:
837330f729Sjoerg       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
847330f729Sjoerg       break;
857330f729Sjoerg     case NSArr_arrayWithArray:
867330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
877330f729Sjoerg       break;
887330f729Sjoerg     case NSArr_arrayWithObject:
897330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
907330f729Sjoerg       break;
917330f729Sjoerg     case NSArr_arrayWithObjects:
927330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
937330f729Sjoerg       break;
947330f729Sjoerg     case NSArr_arrayWithObjectsCount: {
957330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
967330f729Sjoerg         &Ctx.Idents.get("arrayWithObjects"),
977330f729Sjoerg         &Ctx.Idents.get("count")
987330f729Sjoerg       };
997330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1007330f729Sjoerg       break;
1017330f729Sjoerg     }
1027330f729Sjoerg     case NSArr_initWithArray:
1037330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
1047330f729Sjoerg       break;
1057330f729Sjoerg     case NSArr_initWithObjects:
1067330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
1077330f729Sjoerg       break;
1087330f729Sjoerg     case NSArr_objectAtIndex:
1097330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
1107330f729Sjoerg       break;
1117330f729Sjoerg     case NSMutableArr_replaceObjectAtIndex: {
1127330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1137330f729Sjoerg         &Ctx.Idents.get("replaceObjectAtIndex"),
1147330f729Sjoerg         &Ctx.Idents.get("withObject")
1157330f729Sjoerg       };
1167330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1177330f729Sjoerg       break;
1187330f729Sjoerg     }
1197330f729Sjoerg     case NSMutableArr_addObject:
1207330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
1217330f729Sjoerg       break;
1227330f729Sjoerg     case NSMutableArr_insertObjectAtIndex: {
1237330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1247330f729Sjoerg         &Ctx.Idents.get("insertObject"),
1257330f729Sjoerg         &Ctx.Idents.get("atIndex")
1267330f729Sjoerg       };
1277330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1287330f729Sjoerg       break;
1297330f729Sjoerg     }
1307330f729Sjoerg     case NSMutableArr_setObjectAtIndexedSubscript: {
1317330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1327330f729Sjoerg         &Ctx.Idents.get("setObject"),
1337330f729Sjoerg         &Ctx.Idents.get("atIndexedSubscript")
1347330f729Sjoerg       };
1357330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1367330f729Sjoerg       break;
1377330f729Sjoerg     }
1387330f729Sjoerg     }
1397330f729Sjoerg     return (NSArraySelectors[MK] = Sel);
1407330f729Sjoerg   }
1417330f729Sjoerg 
1427330f729Sjoerg   return NSArraySelectors[MK];
1437330f729Sjoerg }
1447330f729Sjoerg 
getNSArrayMethodKind(Selector Sel)1457330f729Sjoerg Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
1467330f729Sjoerg   for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
1477330f729Sjoerg     NSArrayMethodKind MK = NSArrayMethodKind(i);
1487330f729Sjoerg     if (Sel == getNSArraySelector(MK))
1497330f729Sjoerg       return MK;
1507330f729Sjoerg   }
1517330f729Sjoerg 
1527330f729Sjoerg   return None;
1537330f729Sjoerg }
1547330f729Sjoerg 
getNSDictionarySelector(NSDictionaryMethodKind MK) const1557330f729Sjoerg Selector NSAPI::getNSDictionarySelector(
1567330f729Sjoerg                                        NSDictionaryMethodKind MK) const {
1577330f729Sjoerg   if (NSDictionarySelectors[MK].isNull()) {
1587330f729Sjoerg     Selector Sel;
1597330f729Sjoerg     switch (MK) {
1607330f729Sjoerg     case NSDict_dictionary:
1617330f729Sjoerg       Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
1627330f729Sjoerg       break;
1637330f729Sjoerg     case NSDict_dictionaryWithDictionary:
1647330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
1657330f729Sjoerg                                    &Ctx.Idents.get("dictionaryWithDictionary"));
1667330f729Sjoerg       break;
1677330f729Sjoerg     case NSDict_dictionaryWithObjectForKey: {
1687330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1697330f729Sjoerg         &Ctx.Idents.get("dictionaryWithObject"),
1707330f729Sjoerg         &Ctx.Idents.get("forKey")
1717330f729Sjoerg       };
1727330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1737330f729Sjoerg       break;
1747330f729Sjoerg     }
1757330f729Sjoerg     case NSDict_dictionaryWithObjectsForKeys: {
1767330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1777330f729Sjoerg         &Ctx.Idents.get("dictionaryWithObjects"),
1787330f729Sjoerg         &Ctx.Idents.get("forKeys")
1797330f729Sjoerg       };
1807330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
1817330f729Sjoerg       break;
1827330f729Sjoerg     }
1837330f729Sjoerg     case NSDict_dictionaryWithObjectsForKeysCount: {
1847330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
1857330f729Sjoerg         &Ctx.Idents.get("dictionaryWithObjects"),
1867330f729Sjoerg         &Ctx.Idents.get("forKeys"),
1877330f729Sjoerg         &Ctx.Idents.get("count")
1887330f729Sjoerg       };
1897330f729Sjoerg       Sel = Ctx.Selectors.getSelector(3, KeyIdents);
1907330f729Sjoerg       break;
1917330f729Sjoerg     }
1927330f729Sjoerg     case NSDict_dictionaryWithObjectsAndKeys:
1937330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
1947330f729Sjoerg                                &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
1957330f729Sjoerg       break;
1967330f729Sjoerg     case NSDict_initWithDictionary:
1977330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
1987330f729Sjoerg                                          &Ctx.Idents.get("initWithDictionary"));
1997330f729Sjoerg       break;
2007330f729Sjoerg     case NSDict_initWithObjectsAndKeys:
2017330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(
2027330f729Sjoerg                                      &Ctx.Idents.get("initWithObjectsAndKeys"));
2037330f729Sjoerg       break;
2047330f729Sjoerg     case NSDict_initWithObjectsForKeys: {
2057330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2067330f729Sjoerg         &Ctx.Idents.get("initWithObjects"),
2077330f729Sjoerg         &Ctx.Idents.get("forKeys")
2087330f729Sjoerg       };
2097330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2107330f729Sjoerg       break;
2117330f729Sjoerg     }
2127330f729Sjoerg     case NSDict_objectForKey:
2137330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
2147330f729Sjoerg       break;
2157330f729Sjoerg     case NSMutableDict_setObjectForKey: {
2167330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2177330f729Sjoerg         &Ctx.Idents.get("setObject"),
2187330f729Sjoerg         &Ctx.Idents.get("forKey")
2197330f729Sjoerg       };
2207330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2217330f729Sjoerg       break;
2227330f729Sjoerg     }
2237330f729Sjoerg     case NSMutableDict_setObjectForKeyedSubscript: {
2247330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2257330f729Sjoerg         &Ctx.Idents.get("setObject"),
2267330f729Sjoerg         &Ctx.Idents.get("forKeyedSubscript")
2277330f729Sjoerg       };
2287330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2297330f729Sjoerg       break;
2307330f729Sjoerg     }
2317330f729Sjoerg     case NSMutableDict_setValueForKey: {
2327330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2337330f729Sjoerg         &Ctx.Idents.get("setValue"),
2347330f729Sjoerg         &Ctx.Idents.get("forKey")
2357330f729Sjoerg       };
2367330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2377330f729Sjoerg       break;
2387330f729Sjoerg     }
2397330f729Sjoerg     }
2407330f729Sjoerg     return (NSDictionarySelectors[MK] = Sel);
2417330f729Sjoerg   }
2427330f729Sjoerg 
2437330f729Sjoerg   return NSDictionarySelectors[MK];
2447330f729Sjoerg }
2457330f729Sjoerg 
2467330f729Sjoerg Optional<NSAPI::NSDictionaryMethodKind>
getNSDictionaryMethodKind(Selector Sel)2477330f729Sjoerg NSAPI::getNSDictionaryMethodKind(Selector Sel) {
2487330f729Sjoerg   for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
2497330f729Sjoerg     NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
2507330f729Sjoerg     if (Sel == getNSDictionarySelector(MK))
2517330f729Sjoerg       return MK;
2527330f729Sjoerg   }
2537330f729Sjoerg 
2547330f729Sjoerg   return None;
2557330f729Sjoerg }
2567330f729Sjoerg 
getNSSetSelector(NSSetMethodKind MK) const2577330f729Sjoerg Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
2587330f729Sjoerg   if (NSSetSelectors[MK].isNull()) {
2597330f729Sjoerg     Selector Sel;
2607330f729Sjoerg     switch (MK) {
2617330f729Sjoerg     case NSMutableSet_addObject:
2627330f729Sjoerg       Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
2637330f729Sjoerg       break;
2647330f729Sjoerg     case NSOrderedSet_insertObjectAtIndex: {
2657330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2667330f729Sjoerg         &Ctx.Idents.get("insertObject"),
2677330f729Sjoerg         &Ctx.Idents.get("atIndex")
2687330f729Sjoerg       };
2697330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2707330f729Sjoerg       break;
2717330f729Sjoerg     }
2727330f729Sjoerg     case NSOrderedSet_setObjectAtIndex: {
2737330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2747330f729Sjoerg         &Ctx.Idents.get("setObject"),
2757330f729Sjoerg         &Ctx.Idents.get("atIndex")
2767330f729Sjoerg       };
2777330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2787330f729Sjoerg       break;
2797330f729Sjoerg     }
2807330f729Sjoerg     case NSOrderedSet_setObjectAtIndexedSubscript: {
2817330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2827330f729Sjoerg         &Ctx.Idents.get("setObject"),
2837330f729Sjoerg         &Ctx.Idents.get("atIndexedSubscript")
2847330f729Sjoerg       };
2857330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2867330f729Sjoerg       break;
2877330f729Sjoerg     }
2887330f729Sjoerg     case NSOrderedSet_replaceObjectAtIndexWithObject: {
2897330f729Sjoerg       IdentifierInfo *KeyIdents[] = {
2907330f729Sjoerg         &Ctx.Idents.get("replaceObjectAtIndex"),
2917330f729Sjoerg         &Ctx.Idents.get("withObject")
2927330f729Sjoerg       };
2937330f729Sjoerg       Sel = Ctx.Selectors.getSelector(2, KeyIdents);
2947330f729Sjoerg       break;
2957330f729Sjoerg     }
2967330f729Sjoerg     }
2977330f729Sjoerg     return (NSSetSelectors[MK] = Sel);
2987330f729Sjoerg   }
2997330f729Sjoerg 
3007330f729Sjoerg   return NSSetSelectors[MK];
3017330f729Sjoerg }
3027330f729Sjoerg 
3037330f729Sjoerg Optional<NSAPI::NSSetMethodKind>
getNSSetMethodKind(Selector Sel)3047330f729Sjoerg NSAPI::getNSSetMethodKind(Selector Sel) {
3057330f729Sjoerg   for (unsigned i = 0; i != NumNSSetMethods; ++i) {
3067330f729Sjoerg     NSSetMethodKind MK = NSSetMethodKind(i);
3077330f729Sjoerg     if (Sel == getNSSetSelector(MK))
3087330f729Sjoerg       return MK;
3097330f729Sjoerg   }
3107330f729Sjoerg 
3117330f729Sjoerg   return None;
3127330f729Sjoerg }
3137330f729Sjoerg 
getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,bool Instance) const3147330f729Sjoerg Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
3157330f729Sjoerg                                            bool Instance) const {
3167330f729Sjoerg   static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
3177330f729Sjoerg     "numberWithChar",
3187330f729Sjoerg     "numberWithUnsignedChar",
3197330f729Sjoerg     "numberWithShort",
3207330f729Sjoerg     "numberWithUnsignedShort",
3217330f729Sjoerg     "numberWithInt",
3227330f729Sjoerg     "numberWithUnsignedInt",
3237330f729Sjoerg     "numberWithLong",
3247330f729Sjoerg     "numberWithUnsignedLong",
3257330f729Sjoerg     "numberWithLongLong",
3267330f729Sjoerg     "numberWithUnsignedLongLong",
3277330f729Sjoerg     "numberWithFloat",
3287330f729Sjoerg     "numberWithDouble",
3297330f729Sjoerg     "numberWithBool",
3307330f729Sjoerg     "numberWithInteger",
3317330f729Sjoerg     "numberWithUnsignedInteger"
3327330f729Sjoerg   };
3337330f729Sjoerg   static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
3347330f729Sjoerg     "initWithChar",
3357330f729Sjoerg     "initWithUnsignedChar",
3367330f729Sjoerg     "initWithShort",
3377330f729Sjoerg     "initWithUnsignedShort",
3387330f729Sjoerg     "initWithInt",
3397330f729Sjoerg     "initWithUnsignedInt",
3407330f729Sjoerg     "initWithLong",
3417330f729Sjoerg     "initWithUnsignedLong",
3427330f729Sjoerg     "initWithLongLong",
3437330f729Sjoerg     "initWithUnsignedLongLong",
3447330f729Sjoerg     "initWithFloat",
3457330f729Sjoerg     "initWithDouble",
3467330f729Sjoerg     "initWithBool",
3477330f729Sjoerg     "initWithInteger",
3487330f729Sjoerg     "initWithUnsignedInteger"
3497330f729Sjoerg   };
3507330f729Sjoerg 
3517330f729Sjoerg   Selector *Sels;
3527330f729Sjoerg   const char **Names;
3537330f729Sjoerg   if (Instance) {
3547330f729Sjoerg     Sels = NSNumberInstanceSelectors;
3557330f729Sjoerg     Names = InstanceSelectorName;
3567330f729Sjoerg   } else {
3577330f729Sjoerg     Sels = NSNumberClassSelectors;
3587330f729Sjoerg     Names = ClassSelectorName;
3597330f729Sjoerg   }
3607330f729Sjoerg 
3617330f729Sjoerg   if (Sels[MK].isNull())
3627330f729Sjoerg     Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
3637330f729Sjoerg   return Sels[MK];
3647330f729Sjoerg }
3657330f729Sjoerg 
3667330f729Sjoerg Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const3677330f729Sjoerg NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
3687330f729Sjoerg   for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
3697330f729Sjoerg     NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
3707330f729Sjoerg     if (isNSNumberLiteralSelector(MK, Sel))
3717330f729Sjoerg       return MK;
3727330f729Sjoerg   }
3737330f729Sjoerg 
3747330f729Sjoerg   return None;
3757330f729Sjoerg }
3767330f729Sjoerg 
3777330f729Sjoerg Optional<NSAPI::NSNumberLiteralMethodKind>
getNSNumberFactoryMethodKind(QualType T) const3787330f729Sjoerg NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
3797330f729Sjoerg   const BuiltinType *BT = T->getAs<BuiltinType>();
3807330f729Sjoerg   if (!BT)
3817330f729Sjoerg     return None;
3827330f729Sjoerg 
3837330f729Sjoerg   const TypedefType *TDT = T->getAs<TypedefType>();
3847330f729Sjoerg   if (TDT) {
3857330f729Sjoerg     QualType TDTTy = QualType(TDT, 0);
3867330f729Sjoerg     if (isObjCBOOLType(TDTTy))
3877330f729Sjoerg       return NSAPI::NSNumberWithBool;
3887330f729Sjoerg     if (isObjCNSIntegerType(TDTTy))
3897330f729Sjoerg       return NSAPI::NSNumberWithInteger;
3907330f729Sjoerg     if (isObjCNSUIntegerType(TDTTy))
3917330f729Sjoerg       return NSAPI::NSNumberWithUnsignedInteger;
3927330f729Sjoerg   }
3937330f729Sjoerg 
3947330f729Sjoerg   switch (BT->getKind()) {
3957330f729Sjoerg   case BuiltinType::Char_S:
3967330f729Sjoerg   case BuiltinType::SChar:
3977330f729Sjoerg     return NSAPI::NSNumberWithChar;
3987330f729Sjoerg   case BuiltinType::Char_U:
3997330f729Sjoerg   case BuiltinType::UChar:
4007330f729Sjoerg     return NSAPI::NSNumberWithUnsignedChar;
4017330f729Sjoerg   case BuiltinType::Short:
4027330f729Sjoerg     return NSAPI::NSNumberWithShort;
4037330f729Sjoerg   case BuiltinType::UShort:
4047330f729Sjoerg     return NSAPI::NSNumberWithUnsignedShort;
4057330f729Sjoerg   case BuiltinType::Int:
4067330f729Sjoerg     return NSAPI::NSNumberWithInt;
4077330f729Sjoerg   case BuiltinType::UInt:
4087330f729Sjoerg     return NSAPI::NSNumberWithUnsignedInt;
4097330f729Sjoerg   case BuiltinType::Long:
4107330f729Sjoerg     return NSAPI::NSNumberWithLong;
4117330f729Sjoerg   case BuiltinType::ULong:
4127330f729Sjoerg     return NSAPI::NSNumberWithUnsignedLong;
4137330f729Sjoerg   case BuiltinType::LongLong:
4147330f729Sjoerg     return NSAPI::NSNumberWithLongLong;
4157330f729Sjoerg   case BuiltinType::ULongLong:
4167330f729Sjoerg     return NSAPI::NSNumberWithUnsignedLongLong;
4177330f729Sjoerg   case BuiltinType::Float:
4187330f729Sjoerg     return NSAPI::NSNumberWithFloat;
4197330f729Sjoerg   case BuiltinType::Double:
4207330f729Sjoerg     return NSAPI::NSNumberWithDouble;
4217330f729Sjoerg   case BuiltinType::Bool:
4227330f729Sjoerg     return NSAPI::NSNumberWithBool;
4237330f729Sjoerg 
4247330f729Sjoerg   case BuiltinType::Void:
4257330f729Sjoerg   case BuiltinType::WChar_U:
4267330f729Sjoerg   case BuiltinType::WChar_S:
4277330f729Sjoerg   case BuiltinType::Char8:
4287330f729Sjoerg   case BuiltinType::Char16:
4297330f729Sjoerg   case BuiltinType::Char32:
4307330f729Sjoerg   case BuiltinType::Int128:
4317330f729Sjoerg   case BuiltinType::LongDouble:
4327330f729Sjoerg   case BuiltinType::ShortAccum:
4337330f729Sjoerg   case BuiltinType::Accum:
4347330f729Sjoerg   case BuiltinType::LongAccum:
4357330f729Sjoerg   case BuiltinType::UShortAccum:
4367330f729Sjoerg   case BuiltinType::UAccum:
4377330f729Sjoerg   case BuiltinType::ULongAccum:
4387330f729Sjoerg   case BuiltinType::ShortFract:
4397330f729Sjoerg   case BuiltinType::Fract:
4407330f729Sjoerg   case BuiltinType::LongFract:
4417330f729Sjoerg   case BuiltinType::UShortFract:
4427330f729Sjoerg   case BuiltinType::UFract:
4437330f729Sjoerg   case BuiltinType::ULongFract:
4447330f729Sjoerg   case BuiltinType::SatShortAccum:
4457330f729Sjoerg   case BuiltinType::SatAccum:
4467330f729Sjoerg   case BuiltinType::SatLongAccum:
4477330f729Sjoerg   case BuiltinType::SatUShortAccum:
4487330f729Sjoerg   case BuiltinType::SatUAccum:
4497330f729Sjoerg   case BuiltinType::SatULongAccum:
4507330f729Sjoerg   case BuiltinType::SatShortFract:
4517330f729Sjoerg   case BuiltinType::SatFract:
4527330f729Sjoerg   case BuiltinType::SatLongFract:
4537330f729Sjoerg   case BuiltinType::SatUShortFract:
4547330f729Sjoerg   case BuiltinType::SatUFract:
4557330f729Sjoerg   case BuiltinType::SatULongFract:
4567330f729Sjoerg   case BuiltinType::UInt128:
4577330f729Sjoerg   case BuiltinType::Float16:
4587330f729Sjoerg   case BuiltinType::Float128:
4597330f729Sjoerg   case BuiltinType::NullPtr:
4607330f729Sjoerg   case BuiltinType::ObjCClass:
4617330f729Sjoerg   case BuiltinType::ObjCId:
4627330f729Sjoerg   case BuiltinType::ObjCSel:
4637330f729Sjoerg #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
4647330f729Sjoerg   case BuiltinType::Id:
4657330f729Sjoerg #include "clang/Basic/OpenCLImageTypes.def"
4667330f729Sjoerg #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
4677330f729Sjoerg   case BuiltinType::Id:
4687330f729Sjoerg #include "clang/Basic/OpenCLExtensionTypes.def"
4697330f729Sjoerg   case BuiltinType::OCLSampler:
4707330f729Sjoerg   case BuiltinType::OCLEvent:
4717330f729Sjoerg   case BuiltinType::OCLClkEvent:
4727330f729Sjoerg   case BuiltinType::OCLQueue:
4737330f729Sjoerg   case BuiltinType::OCLReserveID:
4747330f729Sjoerg #define SVE_TYPE(Name, Id, SingletonId) \
4757330f729Sjoerg   case BuiltinType::Id:
4767330f729Sjoerg #include "clang/Basic/AArch64SVEACLETypes.def"
477*e038c9c4Sjoerg #define PPC_VECTOR_TYPE(Name, Id, Size) \
478*e038c9c4Sjoerg   case BuiltinType::Id:
479*e038c9c4Sjoerg #include "clang/Basic/PPCTypes.def"
480*e038c9c4Sjoerg #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
481*e038c9c4Sjoerg #include "clang/Basic/RISCVVTypes.def"
4827330f729Sjoerg   case BuiltinType::BoundMember:
4837330f729Sjoerg   case BuiltinType::Dependent:
4847330f729Sjoerg   case BuiltinType::Overload:
4857330f729Sjoerg   case BuiltinType::UnknownAny:
4867330f729Sjoerg   case BuiltinType::ARCUnbridgedCast:
4877330f729Sjoerg   case BuiltinType::Half:
4887330f729Sjoerg   case BuiltinType::PseudoObject:
4897330f729Sjoerg   case BuiltinType::BuiltinFn:
490*e038c9c4Sjoerg   case BuiltinType::IncompleteMatrixIdx:
4917330f729Sjoerg   case BuiltinType::OMPArraySection:
492*e038c9c4Sjoerg   case BuiltinType::OMPArrayShaping:
493*e038c9c4Sjoerg   case BuiltinType::OMPIterator:
494*e038c9c4Sjoerg   case BuiltinType::BFloat16:
4957330f729Sjoerg     break;
4967330f729Sjoerg   }
4977330f729Sjoerg 
4987330f729Sjoerg   return None;
4997330f729Sjoerg }
5007330f729Sjoerg 
5017330f729Sjoerg /// Returns true if \param T is a typedef of "BOOL" in objective-c.
isObjCBOOLType(QualType T) const5027330f729Sjoerg bool NSAPI::isObjCBOOLType(QualType T) const {
5037330f729Sjoerg   return isObjCTypedef(T, "BOOL", BOOLId);
5047330f729Sjoerg }
5057330f729Sjoerg /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
isObjCNSIntegerType(QualType T) const5067330f729Sjoerg bool NSAPI::isObjCNSIntegerType(QualType T) const {
5077330f729Sjoerg   return isObjCTypedef(T, "NSInteger", NSIntegerId);
5087330f729Sjoerg }
5097330f729Sjoerg /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
isObjCNSUIntegerType(QualType T) const5107330f729Sjoerg bool NSAPI::isObjCNSUIntegerType(QualType T) const {
5117330f729Sjoerg   return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
5127330f729Sjoerg }
5137330f729Sjoerg 
GetNSIntegralKind(QualType T) const5147330f729Sjoerg StringRef NSAPI::GetNSIntegralKind(QualType T) const {
5157330f729Sjoerg   if (!Ctx.getLangOpts().ObjC || T.isNull())
5167330f729Sjoerg     return StringRef();
5177330f729Sjoerg 
5187330f729Sjoerg   while (const TypedefType *TDT = T->getAs<TypedefType>()) {
5197330f729Sjoerg     StringRef NSIntegralResust =
5207330f729Sjoerg       llvm::StringSwitch<StringRef>(
5217330f729Sjoerg         TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
5227330f729Sjoerg     .Case("int8_t", "int8_t")
5237330f729Sjoerg     .Case("int16_t", "int16_t")
5247330f729Sjoerg     .Case("int32_t", "int32_t")
5257330f729Sjoerg     .Case("NSInteger", "NSInteger")
5267330f729Sjoerg     .Case("int64_t", "int64_t")
5277330f729Sjoerg     .Case("uint8_t", "uint8_t")
5287330f729Sjoerg     .Case("uint16_t", "uint16_t")
5297330f729Sjoerg     .Case("uint32_t", "uint32_t")
5307330f729Sjoerg     .Case("NSUInteger", "NSUInteger")
5317330f729Sjoerg     .Case("uint64_t", "uint64_t")
5327330f729Sjoerg     .Default(StringRef());
5337330f729Sjoerg     if (!NSIntegralResust.empty())
5347330f729Sjoerg       return NSIntegralResust;
5357330f729Sjoerg     T = TDT->desugar();
5367330f729Sjoerg   }
5377330f729Sjoerg   return StringRef();
5387330f729Sjoerg }
5397330f729Sjoerg 
isMacroDefined(StringRef Id) const5407330f729Sjoerg bool NSAPI::isMacroDefined(StringRef Id) const {
5417330f729Sjoerg   // FIXME: Check whether the relevant module macros are visible.
5427330f729Sjoerg   return Ctx.Idents.get(Id).hasMacroDefinition();
5437330f729Sjoerg }
5447330f729Sjoerg 
isSubclassOfNSClass(ObjCInterfaceDecl * InterfaceDecl,NSClassIdKindKind NSClassKind) const5457330f729Sjoerg bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
5467330f729Sjoerg                                 NSClassIdKindKind NSClassKind) const {
5477330f729Sjoerg   if (!InterfaceDecl) {
5487330f729Sjoerg     return false;
5497330f729Sjoerg   }
5507330f729Sjoerg 
5517330f729Sjoerg   IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
5527330f729Sjoerg 
5537330f729Sjoerg   bool IsSubclass = false;
5547330f729Sjoerg   do {
5557330f729Sjoerg     IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
5567330f729Sjoerg 
5577330f729Sjoerg     if (IsSubclass) {
5587330f729Sjoerg       break;
5597330f729Sjoerg     }
5607330f729Sjoerg   } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
5617330f729Sjoerg 
5627330f729Sjoerg   return IsSubclass;
5637330f729Sjoerg }
5647330f729Sjoerg 
isObjCTypedef(QualType T,StringRef name,IdentifierInfo * & II) const5657330f729Sjoerg bool NSAPI::isObjCTypedef(QualType T,
5667330f729Sjoerg                           StringRef name, IdentifierInfo *&II) const {
5677330f729Sjoerg   if (!Ctx.getLangOpts().ObjC)
5687330f729Sjoerg     return false;
5697330f729Sjoerg   if (T.isNull())
5707330f729Sjoerg     return false;
5717330f729Sjoerg 
5727330f729Sjoerg   if (!II)
5737330f729Sjoerg     II = &Ctx.Idents.get(name);
5747330f729Sjoerg 
5757330f729Sjoerg   while (const TypedefType *TDT = T->getAs<TypedefType>()) {
5767330f729Sjoerg     if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
5777330f729Sjoerg       return true;
5787330f729Sjoerg     T = TDT->desugar();
5797330f729Sjoerg   }
5807330f729Sjoerg 
5817330f729Sjoerg   return false;
5827330f729Sjoerg }
5837330f729Sjoerg 
isObjCEnumerator(const Expr * E,StringRef name,IdentifierInfo * & II) const5847330f729Sjoerg bool NSAPI::isObjCEnumerator(const Expr *E,
5857330f729Sjoerg                              StringRef name, IdentifierInfo *&II) const {
5867330f729Sjoerg   if (!Ctx.getLangOpts().ObjC)
5877330f729Sjoerg     return false;
5887330f729Sjoerg   if (!E)
5897330f729Sjoerg     return false;
5907330f729Sjoerg 
5917330f729Sjoerg   if (!II)
5927330f729Sjoerg     II = &Ctx.Idents.get(name);
5937330f729Sjoerg 
5947330f729Sjoerg   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
5957330f729Sjoerg     if (const EnumConstantDecl *
5967330f729Sjoerg           EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
5977330f729Sjoerg       return EnumD->getIdentifier() == II;
5987330f729Sjoerg 
5997330f729Sjoerg   return false;
6007330f729Sjoerg }
6017330f729Sjoerg 
getOrInitSelector(ArrayRef<StringRef> Ids,Selector & Sel) const6027330f729Sjoerg Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
6037330f729Sjoerg                                   Selector &Sel) const {
6047330f729Sjoerg   if (Sel.isNull()) {
6057330f729Sjoerg     SmallVector<IdentifierInfo *, 4> Idents;
6067330f729Sjoerg     for (ArrayRef<StringRef>::const_iterator
6077330f729Sjoerg            I = Ids.begin(), E = Ids.end(); I != E; ++I)
6087330f729Sjoerg       Idents.push_back(&Ctx.Idents.get(*I));
6097330f729Sjoerg     Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
6107330f729Sjoerg   }
6117330f729Sjoerg   return Sel;
6127330f729Sjoerg }
6137330f729Sjoerg 
getOrInitNullarySelector(StringRef Id,Selector & Sel) const6147330f729Sjoerg Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
6157330f729Sjoerg   if (Sel.isNull()) {
6167330f729Sjoerg     IdentifierInfo *Ident = &Ctx.Idents.get(Id);
6177330f729Sjoerg     Sel = Ctx.Selectors.getSelector(0, &Ident);
6187330f729Sjoerg   }
6197330f729Sjoerg   return Sel;
6207330f729Sjoerg }
621