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
17namespace clang {
18  class ASTContext;
19  class QualType;
20  class Expr;
21
22// \brief Provides info and caches identifiers/selectors for NSFoundation API.
23class NSAPI {
24public:
25  explicit NSAPI(ASTContext &Ctx);
26
27  ASTContext &getASTContext() const { return Ctx; }
28
29  enum NSClassIdKindKind {
30    ClassId_NSObject,
31    ClassId_NSString,
32    ClassId_NSArray,
33    ClassId_NSMutableArray,
34    ClassId_NSDictionary,
35    ClassId_NSMutableDictionary,
36    ClassId_NSNumber,
37    ClassId_NSMutableSet,
38    ClassId_NSCountedSet,
39    ClassId_NSMutableOrderedSet,
40  };
41  static const unsigned NumClassIds = 10;
42
43  enum NSStringMethodKind {
44    NSStr_stringWithString,
45    NSStr_stringWithUTF8String,
46    NSStr_stringWithCStringEncoding,
47    NSStr_stringWithCString,
48    NSStr_initWithString,
49    NSStr_initWithUTF8String
50  };
51  static const unsigned NumNSStringMethods = 5;
52
53  IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
54
55  /// \brief The Objective-C NSString selectors.
56  Selector getNSStringSelector(NSStringMethodKind MK) const;
57
58  /// \brief Return NSStringMethodKind if \param Sel is such a selector.
59  Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
60
61  /// \brief Returns true if the expression \param E is a reference of
62  /// "NSUTF8StringEncoding" enum constant.
63  bool isNSUTF8StringEncodingConstant(const Expr *E) const {
64    return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
65  }
66
67  /// \brief Returns true if the expression \param E is a reference of
68  /// "NSASCIIStringEncoding" enum constant.
69  bool isNSASCIIStringEncodingConstant(const Expr *E) const {
70    return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
71  }
72
73  /// \brief Enumerates the NSArray/NSMutableArray methods used to generate
74  /// literals and to apply some checks.
75  enum NSArrayMethodKind {
76    NSArr_array,
77    NSArr_arrayWithArray,
78    NSArr_arrayWithObject,
79    NSArr_arrayWithObjects,
80    NSArr_arrayWithObjectsCount,
81    NSArr_initWithArray,
82    NSArr_initWithObjects,
83    NSArr_objectAtIndex,
84    NSMutableArr_replaceObjectAtIndex,
85    NSMutableArr_addObject,
86    NSMutableArr_insertObjectAtIndex,
87    NSMutableArr_setObjectAtIndexedSubscript
88  };
89  static const unsigned NumNSArrayMethods = 12;
90
91  /// \brief The Objective-C NSArray selectors.
92  Selector getNSArraySelector(NSArrayMethodKind MK) const;
93
94  /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
95  Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
96
97  /// \brief Enumerates the NSDictionary/NSMutableDictionary methods used
98  /// to generate literals and to apply some checks.
99  enum NSDictionaryMethodKind {
100    NSDict_dictionary,
101    NSDict_dictionaryWithDictionary,
102    NSDict_dictionaryWithObjectForKey,
103    NSDict_dictionaryWithObjectsForKeys,
104    NSDict_dictionaryWithObjectsForKeysCount,
105    NSDict_dictionaryWithObjectsAndKeys,
106    NSDict_initWithDictionary,
107    NSDict_initWithObjectsAndKeys,
108    NSDict_initWithObjectsForKeys,
109    NSDict_objectForKey,
110    NSMutableDict_setObjectForKey,
111    NSMutableDict_setObjectForKeyedSubscript,
112    NSMutableDict_setValueForKey
113  };
114  static const unsigned NumNSDictionaryMethods = 14;
115
116  /// \brief The Objective-C NSDictionary selectors.
117  Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
118
119  /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
120  Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
121
122  /// \brief Enumerates the NSMutableSet/NSOrderedSet methods used
123  /// to apply some checks.
124  enum NSSetMethodKind {
125    NSMutableSet_addObject,
126    NSOrderedSet_insertObjectAtIndex,
127    NSOrderedSet_setObjectAtIndex,
128    NSOrderedSet_setObjectAtIndexedSubscript,
129    NSOrderedSet_replaceObjectAtIndexWithObject
130  };
131  static const unsigned NumNSSetMethods = 5;
132
133  /// \brief The Objective-C NSSet selectors.
134  Selector getNSSetSelector(NSSetMethodKind MK) const;
135
136  /// \brief Return NSSetMethodKind if \p Sel is such a selector.
137  Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
138
139  /// \brief Returns selector for "objectForKeyedSubscript:".
140  Selector getObjectForKeyedSubscriptSelector() const {
141    return getOrInitSelector(StringRef("objectForKeyedSubscript"),
142                             objectForKeyedSubscriptSel);
143  }
144
145  /// \brief Returns selector for "objectAtIndexedSubscript:".
146  Selector getObjectAtIndexedSubscriptSelector() const {
147    return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
148                             objectAtIndexedSubscriptSel);
149  }
150
151  /// \brief Returns selector for "setObject:forKeyedSubscript".
152  Selector getSetObjectForKeyedSubscriptSelector() const {
153    StringRef Ids[] = { "setObject", "forKeyedSubscript" };
154    return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
155  }
156
157  /// \brief Returns selector for "setObject:atIndexedSubscript".
158  Selector getSetObjectAtIndexedSubscriptSelector() const {
159    StringRef Ids[] = { "setObject", "atIndexedSubscript" };
160    return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
161  }
162
163  /// \brief Returns selector for "isEqual:".
164  Selector getIsEqualSelector() const {
165    return getOrInitSelector(StringRef("isEqual"), isEqualSel);
166  }
167
168  /// \brief Enumerates the NSNumber methods used to generate literals.
169  enum NSNumberLiteralMethodKind {
170    NSNumberWithChar,
171    NSNumberWithUnsignedChar,
172    NSNumberWithShort,
173    NSNumberWithUnsignedShort,
174    NSNumberWithInt,
175    NSNumberWithUnsignedInt,
176    NSNumberWithLong,
177    NSNumberWithUnsignedLong,
178    NSNumberWithLongLong,
179    NSNumberWithUnsignedLongLong,
180    NSNumberWithFloat,
181    NSNumberWithDouble,
182    NSNumberWithBool,
183    NSNumberWithInteger,
184    NSNumberWithUnsignedInteger
185  };
186  static const unsigned NumNSNumberLiteralMethods = 15;
187
188  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
189  /// \param Instance if true it will return the selector for the init* method
190  /// otherwise it will return the selector for the number* method.
191  Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
192                                      bool Instance) const;
193
194  bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
195                                 Selector Sel) const {
196    return Sel == getNSNumberLiteralSelector(MK, false) ||
197           Sel == getNSNumberLiteralSelector(MK, true);
198  }
199
200  /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
201  Optional<NSNumberLiteralMethodKind>
202      getNSNumberLiteralMethodKind(Selector Sel) const;
203
204  /// \brief Determine the appropriate NSNumber factory method kind for a
205  /// literal of the given type.
206  Optional<NSNumberLiteralMethodKind>
207      getNSNumberFactoryMethodKind(QualType T) const;
208
209  /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
210  bool isObjCBOOLType(QualType T) const;
211  /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
212  bool isObjCNSIntegerType(QualType T) const;
213  /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
214  bool isObjCNSUIntegerType(QualType T) const;
215  /// \brief Returns one of NSIntegral typedef names if \param T is a typedef
216  /// of that name in objective-c.
217  StringRef GetNSIntegralKind(QualType T) const;
218
219private:
220  bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
221  bool isObjCEnumerator(const Expr *E,
222                        StringRef name, IdentifierInfo *&II) const;
223  Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
224
225  ASTContext &Ctx;
226
227  mutable IdentifierInfo *ClassIds[NumClassIds];
228
229  mutable Selector NSStringSelectors[NumNSStringMethods];
230
231  /// \brief The selectors for Objective-C NSArray methods.
232  mutable Selector NSArraySelectors[NumNSArrayMethods];
233
234  /// \brief The selectors for Objective-C NSDictionary methods.
235  mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
236
237  /// \brief The selectors for Objective-C NSSet methods.
238  mutable Selector NSSetSelectors[NumNSSetMethods];
239
240  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
241  mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
242  mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
243
244  mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
245                   setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
246                   isEqualSel;
247
248  mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
249  mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
250};
251
252}  // end namespace clang
253
254#endif // LLVM_CLANG_AST_NSAPI_H
255