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