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