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