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