1e5dd7070Spatrick //===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===// 2e5dd7070Spatrick // 3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e5dd7070Spatrick // 7e5dd7070Spatrick //===----------------------------------------------------------------------===// 8e5dd7070Spatrick 9e5dd7070Spatrick #ifndef LLVM_CLANG_AST_NSAPI_H 10e5dd7070Spatrick #define LLVM_CLANG_AST_NSAPI_H 11e5dd7070Spatrick 12e5dd7070Spatrick #include "clang/Basic/IdentifierTable.h" 13e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h" 14*12c85518Srobert #include <optional> 15e5dd7070Spatrick 16e5dd7070Spatrick namespace clang { 17e5dd7070Spatrick class ASTContext; 18e5dd7070Spatrick class ObjCInterfaceDecl; 19e5dd7070Spatrick class QualType; 20e5dd7070Spatrick class Expr; 21e5dd7070Spatrick 22e5dd7070Spatrick // Provides info and caches identifiers/selectors for NSFoundation API. 23e5dd7070Spatrick class NSAPI { 24e5dd7070Spatrick public: 25e5dd7070Spatrick explicit NSAPI(ASTContext &Ctx); 26e5dd7070Spatrick getASTContext()27e5dd7070Spatrick ASTContext &getASTContext() const { return Ctx; } 28e5dd7070Spatrick 29e5dd7070Spatrick enum NSClassIdKindKind { 30e5dd7070Spatrick ClassId_NSObject, 31e5dd7070Spatrick ClassId_NSString, 32e5dd7070Spatrick ClassId_NSArray, 33e5dd7070Spatrick ClassId_NSMutableArray, 34e5dd7070Spatrick ClassId_NSDictionary, 35e5dd7070Spatrick ClassId_NSMutableDictionary, 36e5dd7070Spatrick ClassId_NSNumber, 37e5dd7070Spatrick ClassId_NSMutableSet, 38e5dd7070Spatrick ClassId_NSMutableOrderedSet, 39e5dd7070Spatrick ClassId_NSValue 40e5dd7070Spatrick }; 41e5dd7070Spatrick static const unsigned NumClassIds = 10; 42e5dd7070Spatrick 43e5dd7070Spatrick enum NSStringMethodKind { 44e5dd7070Spatrick NSStr_stringWithString, 45e5dd7070Spatrick NSStr_stringWithUTF8String, 46e5dd7070Spatrick NSStr_stringWithCStringEncoding, 47e5dd7070Spatrick NSStr_stringWithCString, 48e5dd7070Spatrick NSStr_initWithString, 49e5dd7070Spatrick NSStr_initWithUTF8String 50e5dd7070Spatrick }; 51e5dd7070Spatrick static const unsigned NumNSStringMethods = 6; 52e5dd7070Spatrick 53e5dd7070Spatrick IdentifierInfo *getNSClassId(NSClassIdKindKind K) const; 54e5dd7070Spatrick 55e5dd7070Spatrick /// The Objective-C NSString selectors. 56e5dd7070Spatrick Selector getNSStringSelector(NSStringMethodKind MK) const; 57e5dd7070Spatrick 58e5dd7070Spatrick /// Returns true if the expression \param E is a reference of 59e5dd7070Spatrick /// "NSUTF8StringEncoding" enum constant. isNSUTF8StringEncodingConstant(const Expr * E)60e5dd7070Spatrick bool isNSUTF8StringEncodingConstant(const Expr *E) const { 61e5dd7070Spatrick return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId); 62e5dd7070Spatrick } 63e5dd7070Spatrick 64e5dd7070Spatrick /// Returns true if the expression \param E is a reference of 65e5dd7070Spatrick /// "NSASCIIStringEncoding" enum constant. isNSASCIIStringEncodingConstant(const Expr * E)66e5dd7070Spatrick bool isNSASCIIStringEncodingConstant(const Expr *E) const { 67e5dd7070Spatrick return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId); 68e5dd7070Spatrick } 69e5dd7070Spatrick 70e5dd7070Spatrick /// Enumerates the NSArray/NSMutableArray methods used to generate 71e5dd7070Spatrick /// literals and to apply some checks. 72e5dd7070Spatrick enum NSArrayMethodKind { 73e5dd7070Spatrick NSArr_array, 74e5dd7070Spatrick NSArr_arrayWithArray, 75e5dd7070Spatrick NSArr_arrayWithObject, 76e5dd7070Spatrick NSArr_arrayWithObjects, 77e5dd7070Spatrick NSArr_arrayWithObjectsCount, 78e5dd7070Spatrick NSArr_initWithArray, 79e5dd7070Spatrick NSArr_initWithObjects, 80e5dd7070Spatrick NSArr_objectAtIndex, 81e5dd7070Spatrick NSMutableArr_replaceObjectAtIndex, 82e5dd7070Spatrick NSMutableArr_addObject, 83e5dd7070Spatrick NSMutableArr_insertObjectAtIndex, 84e5dd7070Spatrick NSMutableArr_setObjectAtIndexedSubscript 85e5dd7070Spatrick }; 86e5dd7070Spatrick static const unsigned NumNSArrayMethods = 12; 87e5dd7070Spatrick 88e5dd7070Spatrick /// The Objective-C NSArray selectors. 89e5dd7070Spatrick Selector getNSArraySelector(NSArrayMethodKind MK) const; 90e5dd7070Spatrick 91e5dd7070Spatrick /// Return NSArrayMethodKind if \p Sel is such a selector. 92*12c85518Srobert std::optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); 93e5dd7070Spatrick 94e5dd7070Spatrick /// Enumerates the NSDictionary/NSMutableDictionary methods used 95e5dd7070Spatrick /// to generate literals and to apply some checks. 96e5dd7070Spatrick enum NSDictionaryMethodKind { 97e5dd7070Spatrick NSDict_dictionary, 98e5dd7070Spatrick NSDict_dictionaryWithDictionary, 99e5dd7070Spatrick NSDict_dictionaryWithObjectForKey, 100e5dd7070Spatrick NSDict_dictionaryWithObjectsForKeys, 101e5dd7070Spatrick NSDict_dictionaryWithObjectsForKeysCount, 102e5dd7070Spatrick NSDict_dictionaryWithObjectsAndKeys, 103e5dd7070Spatrick NSDict_initWithDictionary, 104e5dd7070Spatrick NSDict_initWithObjectsAndKeys, 105e5dd7070Spatrick NSDict_initWithObjectsForKeys, 106e5dd7070Spatrick NSDict_objectForKey, 107e5dd7070Spatrick NSMutableDict_setObjectForKey, 108e5dd7070Spatrick NSMutableDict_setObjectForKeyedSubscript, 109e5dd7070Spatrick NSMutableDict_setValueForKey 110e5dd7070Spatrick }; 111e5dd7070Spatrick static const unsigned NumNSDictionaryMethods = 13; 112e5dd7070Spatrick 113e5dd7070Spatrick /// The Objective-C NSDictionary selectors. 114e5dd7070Spatrick Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; 115e5dd7070Spatrick 116e5dd7070Spatrick /// Return NSDictionaryMethodKind if \p Sel is such a selector. 117*12c85518Srobert std::optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); 118e5dd7070Spatrick 119e5dd7070Spatrick /// Enumerates the NSMutableSet/NSOrderedSet methods used 120e5dd7070Spatrick /// to apply some checks. 121e5dd7070Spatrick enum NSSetMethodKind { 122e5dd7070Spatrick NSMutableSet_addObject, 123e5dd7070Spatrick NSOrderedSet_insertObjectAtIndex, 124e5dd7070Spatrick NSOrderedSet_setObjectAtIndex, 125e5dd7070Spatrick NSOrderedSet_setObjectAtIndexedSubscript, 126e5dd7070Spatrick NSOrderedSet_replaceObjectAtIndexWithObject 127e5dd7070Spatrick }; 128e5dd7070Spatrick static const unsigned NumNSSetMethods = 5; 129e5dd7070Spatrick 130e5dd7070Spatrick /// The Objective-C NSSet selectors. 131e5dd7070Spatrick Selector getNSSetSelector(NSSetMethodKind MK) const; 132e5dd7070Spatrick 133e5dd7070Spatrick /// Return NSSetMethodKind if \p Sel is such a selector. 134*12c85518Srobert std::optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel); 135e5dd7070Spatrick 136e5dd7070Spatrick /// Returns selector for "objectForKeyedSubscript:". getObjectForKeyedSubscriptSelector()137e5dd7070Spatrick Selector getObjectForKeyedSubscriptSelector() const { 138e5dd7070Spatrick return getOrInitSelector(StringRef("objectForKeyedSubscript"), 139e5dd7070Spatrick objectForKeyedSubscriptSel); 140e5dd7070Spatrick } 141e5dd7070Spatrick 142e5dd7070Spatrick /// Returns selector for "objectAtIndexedSubscript:". getObjectAtIndexedSubscriptSelector()143e5dd7070Spatrick Selector getObjectAtIndexedSubscriptSelector() const { 144e5dd7070Spatrick return getOrInitSelector(StringRef("objectAtIndexedSubscript"), 145e5dd7070Spatrick objectAtIndexedSubscriptSel); 146e5dd7070Spatrick } 147e5dd7070Spatrick 148e5dd7070Spatrick /// Returns selector for "setObject:forKeyedSubscript". getSetObjectForKeyedSubscriptSelector()149e5dd7070Spatrick Selector getSetObjectForKeyedSubscriptSelector() const { 150e5dd7070Spatrick StringRef Ids[] = { "setObject", "forKeyedSubscript" }; 151e5dd7070Spatrick return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel); 152e5dd7070Spatrick } 153e5dd7070Spatrick 154e5dd7070Spatrick /// Returns selector for "setObject:atIndexedSubscript". getSetObjectAtIndexedSubscriptSelector()155e5dd7070Spatrick Selector getSetObjectAtIndexedSubscriptSelector() const { 156e5dd7070Spatrick StringRef Ids[] = { "setObject", "atIndexedSubscript" }; 157e5dd7070Spatrick return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel); 158e5dd7070Spatrick } 159e5dd7070Spatrick 160e5dd7070Spatrick /// Returns selector for "isEqual:". getIsEqualSelector()161e5dd7070Spatrick Selector getIsEqualSelector() const { 162e5dd7070Spatrick return getOrInitSelector(StringRef("isEqual"), isEqualSel); 163e5dd7070Spatrick } 164e5dd7070Spatrick getNewSelector()165e5dd7070Spatrick Selector getNewSelector() const { 166e5dd7070Spatrick return getOrInitNullarySelector("new", NewSel); 167e5dd7070Spatrick } 168e5dd7070Spatrick getInitSelector()169e5dd7070Spatrick Selector getInitSelector() const { 170e5dd7070Spatrick return getOrInitNullarySelector("init", InitSel); 171e5dd7070Spatrick } 172e5dd7070Spatrick 173e5dd7070Spatrick /// Enumerates the NSNumber methods used to generate literals. 174e5dd7070Spatrick enum NSNumberLiteralMethodKind { 175e5dd7070Spatrick NSNumberWithChar, 176e5dd7070Spatrick NSNumberWithUnsignedChar, 177e5dd7070Spatrick NSNumberWithShort, 178e5dd7070Spatrick NSNumberWithUnsignedShort, 179e5dd7070Spatrick NSNumberWithInt, 180e5dd7070Spatrick NSNumberWithUnsignedInt, 181e5dd7070Spatrick NSNumberWithLong, 182e5dd7070Spatrick NSNumberWithUnsignedLong, 183e5dd7070Spatrick NSNumberWithLongLong, 184e5dd7070Spatrick NSNumberWithUnsignedLongLong, 185e5dd7070Spatrick NSNumberWithFloat, 186e5dd7070Spatrick NSNumberWithDouble, 187e5dd7070Spatrick NSNumberWithBool, 188e5dd7070Spatrick NSNumberWithInteger, 189e5dd7070Spatrick NSNumberWithUnsignedInteger 190e5dd7070Spatrick }; 191e5dd7070Spatrick static const unsigned NumNSNumberLiteralMethods = 15; 192e5dd7070Spatrick 193e5dd7070Spatrick /// The Objective-C NSNumber selectors used to create NSNumber literals. 194e5dd7070Spatrick /// \param Instance if true it will return the selector for the init* method 195e5dd7070Spatrick /// otherwise it will return the selector for the number* method. 196e5dd7070Spatrick Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, 197e5dd7070Spatrick bool Instance) const; 198e5dd7070Spatrick isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,Selector Sel)199e5dd7070Spatrick bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, 200e5dd7070Spatrick Selector Sel) const { 201e5dd7070Spatrick return Sel == getNSNumberLiteralSelector(MK, false) || 202e5dd7070Spatrick Sel == getNSNumberLiteralSelector(MK, true); 203e5dd7070Spatrick } 204e5dd7070Spatrick 205e5dd7070Spatrick /// Return NSNumberLiteralMethodKind if \p Sel is such a selector. 206*12c85518Srobert std::optional<NSNumberLiteralMethodKind> 207e5dd7070Spatrick getNSNumberLiteralMethodKind(Selector Sel) const; 208e5dd7070Spatrick 209e5dd7070Spatrick /// Determine the appropriate NSNumber factory method kind for a 210e5dd7070Spatrick /// literal of the given type. 211*12c85518Srobert std::optional<NSNumberLiteralMethodKind> 212e5dd7070Spatrick getNSNumberFactoryMethodKind(QualType T) const; 213e5dd7070Spatrick 214e5dd7070Spatrick /// Returns true if \param T is a typedef of "BOOL" in objective-c. 215e5dd7070Spatrick bool isObjCBOOLType(QualType T) const; 216e5dd7070Spatrick /// Returns true if \param T is a typedef of "NSInteger" in objective-c. 217e5dd7070Spatrick bool isObjCNSIntegerType(QualType T) const; 218e5dd7070Spatrick /// Returns true if \param T is a typedef of "NSUInteger" in objective-c. 219e5dd7070Spatrick bool isObjCNSUIntegerType(QualType T) const; 220e5dd7070Spatrick /// Returns one of NSIntegral typedef names if \param T is a typedef 221e5dd7070Spatrick /// of that name in objective-c. 222e5dd7070Spatrick StringRef GetNSIntegralKind(QualType T) const; 223e5dd7070Spatrick 224e5dd7070Spatrick /// Returns \c true if \p Id is currently defined as a macro. 225e5dd7070Spatrick bool isMacroDefined(StringRef Id) const; 226e5dd7070Spatrick 227e5dd7070Spatrick /// Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind 228e5dd7070Spatrick bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, 229e5dd7070Spatrick NSClassIdKindKind NSClassKind) const; 230e5dd7070Spatrick 231e5dd7070Spatrick private: 232e5dd7070Spatrick bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const; 233e5dd7070Spatrick bool isObjCEnumerator(const Expr *E, 234e5dd7070Spatrick StringRef name, IdentifierInfo *&II) const; 235e5dd7070Spatrick Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const; 236e5dd7070Spatrick Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const; 237e5dd7070Spatrick 238e5dd7070Spatrick ASTContext &Ctx; 239e5dd7070Spatrick 240e5dd7070Spatrick mutable IdentifierInfo *ClassIds[NumClassIds]; 241e5dd7070Spatrick 242e5dd7070Spatrick mutable Selector NSStringSelectors[NumNSStringMethods]; 243e5dd7070Spatrick 244e5dd7070Spatrick /// The selectors for Objective-C NSArray methods. 245e5dd7070Spatrick mutable Selector NSArraySelectors[NumNSArrayMethods]; 246e5dd7070Spatrick 247e5dd7070Spatrick /// The selectors for Objective-C NSDictionary methods. 248e5dd7070Spatrick mutable Selector NSDictionarySelectors[NumNSDictionaryMethods]; 249e5dd7070Spatrick 250e5dd7070Spatrick /// The selectors for Objective-C NSSet methods. 251e5dd7070Spatrick mutable Selector NSSetSelectors[NumNSSetMethods]; 252e5dd7070Spatrick 253e5dd7070Spatrick /// The Objective-C NSNumber selectors used to create NSNumber literals. 254e5dd7070Spatrick mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods]; 255e5dd7070Spatrick mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods]; 256e5dd7070Spatrick 257e5dd7070Spatrick mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel, 258e5dd7070Spatrick setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel, 259e5dd7070Spatrick isEqualSel, InitSel, NewSel; 260e5dd7070Spatrick 261e5dd7070Spatrick mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId; 262e5dd7070Spatrick mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId; 263e5dd7070Spatrick }; 264e5dd7070Spatrick 265e5dd7070Spatrick } // end namespace clang 266e5dd7070Spatrick 267e5dd7070Spatrick #endif // LLVM_CLANG_AST_NSAPI_H 268