//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "clang/AST/NSAPI.h" #include "clang/AST/ASTContext.h" using namespace clang; NSAPI::NSAPI(ASTContext &ctx) : Ctx(ctx), ClassIds() { } IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const { static const char *ClassName[NumClassIds] = { "NSObject", "NSString", "NSArray", "NSMutableArray", "NSDictionary", "NSMutableDictionary", "NSNumber" }; if (!ClassIds[K]) return (ClassIds[K] = &Ctx.Idents.get(ClassName[K])); return ClassIds[K]; } Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const { if (NSStringSelectors[MK].isNull()) { Selector Sel; switch (MK) { case NSStr_stringWithString: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString")); break; case NSStr_initWithString: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString")); break; } return (NSStringSelectors[MK] = Sel); } return NSStringSelectors[MK]; } Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const { if (NSArraySelectors[MK].isNull()) { Selector Sel; switch (MK) { case NSArr_array: Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array")); break; case NSArr_arrayWithArray: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray")); break; case NSArr_arrayWithObject: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject")); break; case NSArr_arrayWithObjects: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects")); break; case NSArr_arrayWithObjectsCount: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("arrayWithObjects"), &Ctx.Idents.get("count") }; Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } case NSArr_initWithArray: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray")); break; case NSArr_initWithObjects: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects")); break; case NSArr_objectAtIndex: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex")); break; case NSMutableArr_replaceObjectAtIndex: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("replaceObjectAtIndex"), &Ctx.Idents.get("withObject") }; Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } } return (NSArraySelectors[MK] = Sel); } return NSArraySelectors[MK]; } llvm::Optional NSAPI::getNSArrayMethodKind(Selector Sel) { for (unsigned i = 0; i != NumNSArrayMethods; ++i) { NSArrayMethodKind MK = NSArrayMethodKind(i); if (Sel == getNSArraySelector(MK)) return MK; } return llvm::Optional(); } Selector NSAPI::getNSDictionarySelector( NSDictionaryMethodKind MK) const { if (NSDictionarySelectors[MK].isNull()) { Selector Sel; switch (MK) { case NSDict_dictionary: Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary")); break; case NSDict_dictionaryWithDictionary: Sel = Ctx.Selectors.getUnarySelector( &Ctx.Idents.get("dictionaryWithDictionary")); break; case NSDict_dictionaryWithObjectForKey: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("dictionaryWithObject"), &Ctx.Idents.get("forKey") }; Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } case NSDict_dictionaryWithObjectsForKeys: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("dictionaryWithObjects"), &Ctx.Idents.get("forKeys") }; Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } case NSDict_dictionaryWithObjectsForKeysCount: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("dictionaryWithObjects"), &Ctx.Idents.get("forKeys"), &Ctx.Idents.get("count") }; Sel = Ctx.Selectors.getSelector(3, KeyIdents); break; } case NSDict_dictionaryWithObjectsAndKeys: Sel = Ctx.Selectors.getUnarySelector( &Ctx.Idents.get("dictionaryWithObjectsAndKeys")); break; case NSDict_initWithDictionary: Sel = Ctx.Selectors.getUnarySelector( &Ctx.Idents.get("initWithDictionary")); break; case NSDict_initWithObjectsAndKeys: Sel = Ctx.Selectors.getUnarySelector( &Ctx.Idents.get("initWithObjectsAndKeys")); break; case NSDict_objectForKey: Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey")); break; case NSMutableDict_setObjectForKey: { IdentifierInfo *KeyIdents[] = { &Ctx.Idents.get("setObject"), &Ctx.Idents.get("forKey") }; Sel = Ctx.Selectors.getSelector(2, KeyIdents); break; } } return (NSDictionarySelectors[MK] = Sel); } return NSDictionarySelectors[MK]; } llvm::Optional NSAPI::getNSDictionaryMethodKind(Selector Sel) { for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) { NSDictionaryMethodKind MK = NSDictionaryMethodKind(i); if (Sel == getNSDictionarySelector(MK)) return MK; } return llvm::Optional(); } Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, bool Instance) const { static const char *ClassSelectorName[NumNSNumberLiteralMethods] = { "numberWithChar", "numberWithUnsignedChar", "numberWithShort", "numberWithUnsignedShort", "numberWithInt", "numberWithUnsignedInt", "numberWithLong", "numberWithUnsignedLong", "numberWithLongLong", "numberWithUnsignedLongLong", "numberWithFloat", "numberWithDouble", "numberWithBool", "numberWithInteger", "numberWithUnsignedInteger" }; static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = { "initWithChar", "initWithUnsignedChar", "initWithShort", "initWithUnsignedShort", "initWithInt", "initWithUnsignedInt", "initWithLong", "initWithUnsignedLong", "initWithLongLong", "initWithUnsignedLongLong", "initWithFloat", "initWithDouble", "initWithBool", "initWithInteger", "initWithUnsignedInteger" }; Selector *Sels; const char **Names; if (Instance) { Sels = NSNumberInstanceSelectors; Names = InstanceSelectorName; } else { Sels = NSNumberClassSelectors; Names = ClassSelectorName; } if (Sels[MK].isNull()) Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK])); return Sels[MK]; } llvm::Optional NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const { for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) { NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i); if (isNSNumberLiteralSelector(MK, Sel)) return MK; } return llvm::Optional(); } llvm::Optional NSAPI::getNSNumberFactoryMethodKind(QualType T) { const BuiltinType *BT = T->getAs(); if (!BT) return llvm::Optional(); switch (BT->getKind()) { case BuiltinType::Char_S: case BuiltinType::SChar: return NSAPI::NSNumberWithChar; case BuiltinType::Char_U: case BuiltinType::UChar: return NSAPI::NSNumberWithUnsignedChar; case BuiltinType::Short: return NSAPI::NSNumberWithShort; case BuiltinType::UShort: return NSAPI::NSNumberWithUnsignedShort; case BuiltinType::Int: return NSAPI::NSNumberWithInt; case BuiltinType::UInt: return NSAPI::NSNumberWithUnsignedInt; case BuiltinType::Long: return NSAPI::NSNumberWithLong; case BuiltinType::ULong: return NSAPI::NSNumberWithUnsignedLong; case BuiltinType::LongLong: return NSAPI::NSNumberWithLongLong; case BuiltinType::ULongLong: return NSAPI::NSNumberWithUnsignedLongLong; case BuiltinType::Float: return NSAPI::NSNumberWithFloat; case BuiltinType::Double: return NSAPI::NSNumberWithDouble; case BuiltinType::Bool: return NSAPI::NSNumberWithBool; case BuiltinType::Void: case BuiltinType::WChar_U: case BuiltinType::WChar_S: case BuiltinType::Char16: case BuiltinType::Char32: case BuiltinType::Int128: case BuiltinType::LongDouble: case BuiltinType::UInt128: case BuiltinType::NullPtr: case BuiltinType::ObjCClass: case BuiltinType::ObjCId: case BuiltinType::ObjCSel: case BuiltinType::BoundMember: case BuiltinType::Dependent: case BuiltinType::Overload: case BuiltinType::UnknownAny: case BuiltinType::ARCUnbridgedCast: case BuiltinType::Half: case BuiltinType::PseudoObject: break; } return llvm::Optional(); }