1 //===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===// 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 #include "clang/AST/NSAPI.h" 11 #include "clang/AST/ASTContext.h" 12 13 using namespace clang; 14 15 NSAPI::NSAPI(ASTContext &ctx) 16 : Ctx(ctx), ClassIds() { 17 } 18 19 IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const { 20 static const char *ClassName[NumClassIds] = { 21 "NSObject", 22 "NSString", 23 "NSArray", 24 "NSMutableArray", 25 "NSDictionary", 26 "NSMutableDictionary", 27 "NSNumber" 28 }; 29 30 if (!ClassIds[K]) 31 return (ClassIds[K] = &Ctx.Idents.get(ClassName[K])); 32 33 return ClassIds[K]; 34 } 35 36 Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const { 37 if (NSStringSelectors[MK].isNull()) { 38 Selector Sel; 39 switch (MK) { 40 case NSStr_stringWithString: 41 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString")); 42 break; 43 case NSStr_initWithString: 44 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString")); 45 break; 46 } 47 return (NSStringSelectors[MK] = Sel); 48 } 49 50 return NSStringSelectors[MK]; 51 } 52 53 Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const { 54 if (NSArraySelectors[MK].isNull()) { 55 Selector Sel; 56 switch (MK) { 57 case NSArr_array: 58 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array")); 59 break; 60 case NSArr_arrayWithArray: 61 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray")); 62 break; 63 case NSArr_arrayWithObject: 64 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject")); 65 break; 66 case NSArr_arrayWithObjects: 67 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects")); 68 break; 69 case NSArr_arrayWithObjectsCount: { 70 IdentifierInfo *KeyIdents[] = { 71 &Ctx.Idents.get("arrayWithObjects"), 72 &Ctx.Idents.get("count") 73 }; 74 Sel = Ctx.Selectors.getSelector(2, KeyIdents); 75 break; 76 } 77 case NSArr_initWithArray: 78 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray")); 79 break; 80 case NSArr_initWithObjects: 81 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects")); 82 break; 83 case NSArr_objectAtIndex: 84 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex")); 85 break; 86 case NSMutableArr_replaceObjectAtIndex: { 87 IdentifierInfo *KeyIdents[] = { 88 &Ctx.Idents.get("replaceObjectAtIndex"), 89 &Ctx.Idents.get("withObject") 90 }; 91 Sel = Ctx.Selectors.getSelector(2, KeyIdents); 92 break; 93 } 94 } 95 return (NSArraySelectors[MK] = Sel); 96 } 97 98 return NSArraySelectors[MK]; 99 } 100 101 llvm::Optional<NSAPI::NSArrayMethodKind> 102 NSAPI::getNSArrayMethodKind(Selector Sel) { 103 for (unsigned i = 0; i != NumNSArrayMethods; ++i) { 104 NSArrayMethodKind MK = NSArrayMethodKind(i); 105 if (Sel == getNSArraySelector(MK)) 106 return MK; 107 } 108 109 return llvm::Optional<NSArrayMethodKind>(); 110 } 111 112 Selector NSAPI::getNSDictionarySelector( 113 NSDictionaryMethodKind MK) const { 114 if (NSDictionarySelectors[MK].isNull()) { 115 Selector Sel; 116 switch (MK) { 117 case NSDict_dictionary: 118 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary")); 119 break; 120 case NSDict_dictionaryWithDictionary: 121 Sel = Ctx.Selectors.getUnarySelector( 122 &Ctx.Idents.get("dictionaryWithDictionary")); 123 break; 124 case NSDict_dictionaryWithObjectForKey: { 125 IdentifierInfo *KeyIdents[] = { 126 &Ctx.Idents.get("dictionaryWithObject"), 127 &Ctx.Idents.get("forKey") 128 }; 129 Sel = Ctx.Selectors.getSelector(2, KeyIdents); 130 break; 131 } 132 case NSDict_dictionaryWithObjectsForKeys: { 133 IdentifierInfo *KeyIdents[] = { 134 &Ctx.Idents.get("dictionaryWithObjects"), 135 &Ctx.Idents.get("forKeys") 136 }; 137 Sel = Ctx.Selectors.getSelector(2, KeyIdents); 138 break; 139 } 140 case NSDict_dictionaryWithObjectsForKeysCount: { 141 IdentifierInfo *KeyIdents[] = { 142 &Ctx.Idents.get("dictionaryWithObjects"), 143 &Ctx.Idents.get("forKeys"), 144 &Ctx.Idents.get("count") 145 }; 146 Sel = Ctx.Selectors.getSelector(3, KeyIdents); 147 break; 148 } 149 case NSDict_dictionaryWithObjectsAndKeys: 150 Sel = Ctx.Selectors.getUnarySelector( 151 &Ctx.Idents.get("dictionaryWithObjectsAndKeys")); 152 break; 153 case NSDict_initWithDictionary: 154 Sel = Ctx.Selectors.getUnarySelector( 155 &Ctx.Idents.get("initWithDictionary")); 156 break; 157 case NSDict_initWithObjectsAndKeys: 158 Sel = Ctx.Selectors.getUnarySelector( 159 &Ctx.Idents.get("initWithObjectsAndKeys")); 160 break; 161 case NSDict_objectForKey: 162 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey")); 163 break; 164 case NSMutableDict_setObjectForKey: { 165 IdentifierInfo *KeyIdents[] = { 166 &Ctx.Idents.get("setObject"), 167 &Ctx.Idents.get("forKey") 168 }; 169 Sel = Ctx.Selectors.getSelector(2, KeyIdents); 170 break; 171 } 172 } 173 return (NSDictionarySelectors[MK] = Sel); 174 } 175 176 return NSDictionarySelectors[MK]; 177 } 178 179 llvm::Optional<NSAPI::NSDictionaryMethodKind> 180 NSAPI::getNSDictionaryMethodKind(Selector Sel) { 181 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) { 182 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i); 183 if (Sel == getNSDictionarySelector(MK)) 184 return MK; 185 } 186 187 return llvm::Optional<NSDictionaryMethodKind>(); 188 } 189 190 Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, 191 bool Instance) const { 192 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = { 193 "numberWithChar", 194 "numberWithUnsignedChar", 195 "numberWithShort", 196 "numberWithUnsignedShort", 197 "numberWithInt", 198 "numberWithUnsignedInt", 199 "numberWithLong", 200 "numberWithUnsignedLong", 201 "numberWithLongLong", 202 "numberWithUnsignedLongLong", 203 "numberWithFloat", 204 "numberWithDouble", 205 "numberWithBool", 206 "numberWithInteger", 207 "numberWithUnsignedInteger" 208 }; 209 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = { 210 "initWithChar", 211 "initWithUnsignedChar", 212 "initWithShort", 213 "initWithUnsignedShort", 214 "initWithInt", 215 "initWithUnsignedInt", 216 "initWithLong", 217 "initWithUnsignedLong", 218 "initWithLongLong", 219 "initWithUnsignedLongLong", 220 "initWithFloat", 221 "initWithDouble", 222 "initWithBool", 223 "initWithInteger", 224 "initWithUnsignedInteger" 225 }; 226 227 Selector *Sels; 228 const char **Names; 229 if (Instance) { 230 Sels = NSNumberInstanceSelectors; 231 Names = InstanceSelectorName; 232 } else { 233 Sels = NSNumberClassSelectors; 234 Names = ClassSelectorName; 235 } 236 237 if (Sels[MK].isNull()) 238 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK])); 239 return Sels[MK]; 240 } 241 242 llvm::Optional<NSAPI::NSNumberLiteralMethodKind> 243 NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const { 244 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) { 245 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i); 246 if (isNSNumberLiteralSelector(MK, Sel)) 247 return MK; 248 } 249 250 return llvm::Optional<NSNumberLiteralMethodKind>(); 251 } 252 253 llvm::Optional<NSAPI::NSNumberLiteralMethodKind> 254 NSAPI::getNSNumberFactoryMethodKind(QualType T) { 255 const BuiltinType *BT = T->getAs<BuiltinType>(); 256 if (!BT) 257 return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>(); 258 259 switch (BT->getKind()) { 260 case BuiltinType::Char_S: 261 case BuiltinType::SChar: 262 return NSAPI::NSNumberWithChar; 263 case BuiltinType::Char_U: 264 case BuiltinType::UChar: 265 return NSAPI::NSNumberWithUnsignedChar; 266 case BuiltinType::Short: 267 return NSAPI::NSNumberWithShort; 268 case BuiltinType::UShort: 269 return NSAPI::NSNumberWithUnsignedShort; 270 case BuiltinType::Int: 271 return NSAPI::NSNumberWithInt; 272 case BuiltinType::UInt: 273 return NSAPI::NSNumberWithUnsignedInt; 274 case BuiltinType::Long: 275 return NSAPI::NSNumberWithLong; 276 case BuiltinType::ULong: 277 return NSAPI::NSNumberWithUnsignedLong; 278 case BuiltinType::LongLong: 279 return NSAPI::NSNumberWithLongLong; 280 case BuiltinType::ULongLong: 281 return NSAPI::NSNumberWithUnsignedLongLong; 282 case BuiltinType::Float: 283 return NSAPI::NSNumberWithFloat; 284 case BuiltinType::Double: 285 return NSAPI::NSNumberWithDouble; 286 case BuiltinType::Bool: 287 return NSAPI::NSNumberWithBool; 288 289 case BuiltinType::Void: 290 case BuiltinType::WChar_U: 291 case BuiltinType::WChar_S: 292 case BuiltinType::Char16: 293 case BuiltinType::Char32: 294 case BuiltinType::Int128: 295 case BuiltinType::LongDouble: 296 case BuiltinType::UInt128: 297 case BuiltinType::NullPtr: 298 case BuiltinType::ObjCClass: 299 case BuiltinType::ObjCId: 300 case BuiltinType::ObjCSel: 301 case BuiltinType::BoundMember: 302 case BuiltinType::Dependent: 303 case BuiltinType::Overload: 304 case BuiltinType::UnknownAny: 305 case BuiltinType::ARCUnbridgedCast: 306 case BuiltinType::Half: 307 case BuiltinType::PseudoObject: 308 break; 309 } 310 311 return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>(); 312 } 313