123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- //===--- 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"
- #include "clang/AST/Expr.h"
- using namespace clang;
- NSAPI::NSAPI(ASTContext &ctx)
- : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),
- NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {
- }
- 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_stringWithUTF8String:
- Sel = Ctx.Selectors.getUnarySelector(
- &Ctx.Idents.get("stringWithUTF8String"));
- break;
- case NSStr_stringWithCStringEncoding: {
- IdentifierInfo *KeyIdents[] = {
- &Ctx.Idents.get("stringWithCString"),
- &Ctx.Idents.get("encoding")
- };
- Sel = Ctx.Selectors.getSelector(2, KeyIdents);
- break;
- }
- case NSStr_stringWithCString:
- Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
- break;
- case NSStr_initWithString:
- Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
- break;
- }
- return (NSStringSelectors[MK] = Sel);
- }
- return NSStringSelectors[MK];
- }
- llvm::Optional<NSAPI::NSStringMethodKind>
- NSAPI::getNSStringMethodKind(Selector Sel) const {
- for (unsigned i = 0; i != NumNSStringMethods; ++i) {
- NSStringMethodKind MK = NSStringMethodKind(i);
- if (Sel == getNSStringSelector(MK))
- return MK;
- }
- return llvm::Optional<NSStringMethodKind>();
- }
- 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::NSArrayMethodKind>
- NSAPI::getNSArrayMethodKind(Selector Sel) {
- for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
- NSArrayMethodKind MK = NSArrayMethodKind(i);
- if (Sel == getNSArraySelector(MK))
- return MK;
- }
- return llvm::Optional<NSArrayMethodKind>();
- }
- 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_initWithObjectsForKeys: {
- IdentifierInfo *KeyIdents[] = {
- &Ctx.Idents.get("initWithObjects"),
- &Ctx.Idents.get("forKeys")
- };
- Sel = Ctx.Selectors.getSelector(2, KeyIdents);
- 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::NSDictionaryMethodKind>
- NSAPI::getNSDictionaryMethodKind(Selector Sel) {
- for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
- NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
- if (Sel == getNSDictionarySelector(MK))
- return MK;
- }
- return llvm::Optional<NSDictionaryMethodKind>();
- }
- 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::NSNumberLiteralMethodKind>
- 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<NSNumberLiteralMethodKind>();
- }
- llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
- NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
- const BuiltinType *BT = T->getAs<BuiltinType>();
- if (!BT)
- return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
- const TypedefType *TDT = T->getAs<TypedefType>();
- if (TDT) {
- QualType TDTTy = QualType(TDT, 0);
- if (isObjCBOOLType(TDTTy))
- return NSAPI::NSNumberWithBool;
- if (isObjCNSIntegerType(TDTTy))
- return NSAPI::NSNumberWithInteger;
- if (isObjCNSUIntegerType(TDTTy))
- return NSAPI::NSNumberWithUnsignedInteger;
- }
- 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::OCLImage1d:
- case BuiltinType::OCLImage1dArray:
- case BuiltinType::OCLImage1dBuffer:
- case BuiltinType::OCLImage2d:
- case BuiltinType::OCLImage2dArray:
- case BuiltinType::OCLImage3d:
- case BuiltinType::OCLSampler:
- case BuiltinType::OCLEvent:
- case BuiltinType::BoundMember:
- case BuiltinType::Dependent:
- case BuiltinType::Overload:
- case BuiltinType::UnknownAny:
- case BuiltinType::ARCUnbridgedCast:
- case BuiltinType::Half:
- case BuiltinType::PseudoObject:
- case BuiltinType::BuiltinFn:
- break;
- }
-
- return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
- }
- /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
- bool NSAPI::isObjCBOOLType(QualType T) const {
- return isObjCTypedef(T, "BOOL", BOOLId);
- }
- /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
- bool NSAPI::isObjCNSIntegerType(QualType T) const {
- return isObjCTypedef(T, "NSInteger", NSIntegerId);
- }
- /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
- bool NSAPI::isObjCNSUIntegerType(QualType T) const {
- return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
- }
- bool NSAPI::isObjCTypedef(QualType T,
- StringRef name, IdentifierInfo *&II) const {
- if (!Ctx.getLangOpts().ObjC1)
- return false;
- if (T.isNull())
- return false;
- if (!II)
- II = &Ctx.Idents.get(name);
- while (const TypedefType *TDT = T->getAs<TypedefType>()) {
- if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
- return true;
- T = TDT->desugar();
- }
- return false;
- }
- bool NSAPI::isObjCEnumerator(const Expr *E,
- StringRef name, IdentifierInfo *&II) const {
- if (!Ctx.getLangOpts().ObjC1)
- return false;
- if (!E)
- return false;
- if (!II)
- II = &Ctx.Idents.get(name);
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
- if (const EnumConstantDecl *
- EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
- return EnumD->getIdentifier() == II;
- return false;
- }
- Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
- Selector &Sel) const {
- if (Sel.isNull()) {
- SmallVector<IdentifierInfo *, 4> Idents;
- for (ArrayRef<StringRef>::const_iterator
- I = Ids.begin(), E = Ids.end(); I != E; ++I)
- Idents.push_back(&Ctx.Idents.get(*I));
- Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
- }
- return Sel;
- }
|