• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
getASTContext()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.
isNSUTF8StringEncodingConstant(const Expr * E)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.
isNSASCIIStringEncodingConstant(const Expr * E)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:".
getObjectForKeyedSubscriptSelector()141    Selector getObjectForKeyedSubscriptSelector() const {
142      return getOrInitSelector(StringRef("objectForKeyedSubscript"),
143                               objectForKeyedSubscriptSel);
144    }
145  
146    /// \brief Returns selector for "objectAtIndexedSubscript:".
getObjectAtIndexedSubscriptSelector()147    Selector getObjectAtIndexedSubscriptSelector() const {
148      return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
149                               objectAtIndexedSubscriptSel);
150    }
151  
152    /// \brief Returns selector for "setObject:forKeyedSubscript".
getSetObjectForKeyedSubscriptSelector()153    Selector getSetObjectForKeyedSubscriptSelector() const {
154      StringRef Ids[] = { "setObject", "forKeyedSubscript" };
155      return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
156    }
157  
158    /// \brief Returns selector for "setObject:atIndexedSubscript".
getSetObjectAtIndexedSubscriptSelector()159    Selector getSetObjectAtIndexedSubscriptSelector() const {
160      StringRef Ids[] = { "setObject", "atIndexedSubscript" };
161      return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
162    }
163  
164    /// \brief Returns selector for "isEqual:".
getIsEqualSelector()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  
isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,Selector Sel)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