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