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 // 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 = 6; 53 54 IdentifierInfo *getNSClassId(NSClassIdKindKind K) const; 55 56 /// The Objective-C NSString selectors. 57 Selector getNSStringSelector(NSStringMethodKind MK) const; 58 59 /// Return NSStringMethodKind if \param Sel is such a selector. 60 Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const; 61 62 /// 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 /// 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 /// 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 /// The Objective-C NSArray selectors. 93 Selector getNSArraySelector(NSArrayMethodKind MK) const; 94 95 /// Return NSArrayMethodKind if \p Sel is such a selector. 96 Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); 97 98 /// 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 = 13; 116 117 /// The Objective-C NSDictionary selectors. 118 Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; 119 120 /// Return NSDictionaryMethodKind if \p Sel is such a selector. 121 Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); 122 123 /// 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 /// The Objective-C NSSet selectors. 135 Selector getNSSetSelector(NSSetMethodKind MK) const; 136 137 /// Return NSSetMethodKind if \p Sel is such a selector. 138 Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel); 139 140 /// Returns selector for "objectForKeyedSubscript:". getObjectForKeyedSubscriptSelector()141 Selector getObjectForKeyedSubscriptSelector() const { 142 return getOrInitSelector(StringRef("objectForKeyedSubscript"), 143 objectForKeyedSubscriptSel); 144 } 145 146 /// Returns selector for "objectAtIndexedSubscript:". getObjectAtIndexedSubscriptSelector()147 Selector getObjectAtIndexedSubscriptSelector() const { 148 return getOrInitSelector(StringRef("objectAtIndexedSubscript"), 149 objectAtIndexedSubscriptSel); 150 } 151 152 /// Returns selector for "setObject:forKeyedSubscript". getSetObjectForKeyedSubscriptSelector()153 Selector getSetObjectForKeyedSubscriptSelector() const { 154 StringRef Ids[] = { "setObject", "forKeyedSubscript" }; 155 return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel); 156 } 157 158 /// Returns selector for "setObject:atIndexedSubscript". getSetObjectAtIndexedSubscriptSelector()159 Selector getSetObjectAtIndexedSubscriptSelector() const { 160 StringRef Ids[] = { "setObject", "atIndexedSubscript" }; 161 return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel); 162 } 163 164 /// Returns selector for "isEqual:". getIsEqualSelector()165 Selector getIsEqualSelector() const { 166 return getOrInitSelector(StringRef("isEqual"), isEqualSel); 167 } 168 getNewSelector()169 Selector getNewSelector() const { 170 return getOrInitNullarySelector("new", NewSel); 171 } 172 getInitSelector()173 Selector getInitSelector() const { 174 return getOrInitNullarySelector("init", InitSel); 175 } 176 177 /// Enumerates the NSNumber methods used to generate literals. 178 enum NSNumberLiteralMethodKind { 179 NSNumberWithChar, 180 NSNumberWithUnsignedChar, 181 NSNumberWithShort, 182 NSNumberWithUnsignedShort, 183 NSNumberWithInt, 184 NSNumberWithUnsignedInt, 185 NSNumberWithLong, 186 NSNumberWithUnsignedLong, 187 NSNumberWithLongLong, 188 NSNumberWithUnsignedLongLong, 189 NSNumberWithFloat, 190 NSNumberWithDouble, 191 NSNumberWithBool, 192 NSNumberWithInteger, 193 NSNumberWithUnsignedInteger 194 }; 195 static const unsigned NumNSNumberLiteralMethods = 15; 196 197 /// The Objective-C NSNumber selectors used to create NSNumber literals. 198 /// \param Instance if true it will return the selector for the init* method 199 /// otherwise it will return the selector for the number* method. 200 Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, 201 bool Instance) const; 202 isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,Selector Sel)203 bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, 204 Selector Sel) const { 205 return Sel == getNSNumberLiteralSelector(MK, false) || 206 Sel == getNSNumberLiteralSelector(MK, true); 207 } 208 209 /// Return NSNumberLiteralMethodKind if \p Sel is such a selector. 210 Optional<NSNumberLiteralMethodKind> 211 getNSNumberLiteralMethodKind(Selector Sel) const; 212 213 /// Determine the appropriate NSNumber factory method kind for a 214 /// literal of the given type. 215 Optional<NSNumberLiteralMethodKind> 216 getNSNumberFactoryMethodKind(QualType T) const; 217 218 /// Returns true if \param T is a typedef of "BOOL" in objective-c. 219 bool isObjCBOOLType(QualType T) const; 220 /// Returns true if \param T is a typedef of "NSInteger" in objective-c. 221 bool isObjCNSIntegerType(QualType T) const; 222 /// Returns true if \param T is a typedef of "NSUInteger" in objective-c. 223 bool isObjCNSUIntegerType(QualType T) const; 224 /// Returns one of NSIntegral typedef names if \param T is a typedef 225 /// of that name in objective-c. 226 StringRef GetNSIntegralKind(QualType T) const; 227 228 /// Returns \c true if \p Id is currently defined as a macro. 229 bool isMacroDefined(StringRef Id) const; 230 231 /// Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind 232 bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, 233 NSClassIdKindKind NSClassKind) const; 234 235 private: 236 bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const; 237 bool isObjCEnumerator(const Expr *E, 238 StringRef name, IdentifierInfo *&II) const; 239 Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const; 240 Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const; 241 242 ASTContext &Ctx; 243 244 mutable IdentifierInfo *ClassIds[NumClassIds]; 245 246 mutable Selector NSStringSelectors[NumNSStringMethods]; 247 248 /// The selectors for Objective-C NSArray methods. 249 mutable Selector NSArraySelectors[NumNSArrayMethods]; 250 251 /// The selectors for Objective-C NSDictionary methods. 252 mutable Selector NSDictionarySelectors[NumNSDictionaryMethods]; 253 254 /// The selectors for Objective-C NSSet methods. 255 mutable Selector NSSetSelectors[NumNSSetMethods]; 256 257 /// The Objective-C NSNumber selectors used to create NSNumber literals. 258 mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods]; 259 mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods]; 260 261 mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel, 262 setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel, 263 isEqualSel, InitSel, NewSel; 264 265 mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId; 266 mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId; 267 }; 268 269 } // end namespace clang 270 271 #endif // LLVM_CLANG_AST_NSAPI_H 272