blob: 8f03711f4d70d45d050a038d22a2241df1c94a8b [file] [log] [blame]
Ted Kremenekebcb57a2012-03-06 20:05:56 +00001//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
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#include "clang/AST/NSAPI.h"
11#include "clang/AST/ASTContext.h"
12
13using namespace clang;
14
15NSAPI::NSAPI(ASTContext &ctx)
16 : Ctx(ctx), ClassIds() {
17}
18
19IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
20 static const char *ClassName[NumClassIds] = {
21 "NSString",
22 "NSArray",
23 "NSMutableArray",
24 "NSDictionary",
25 "NSMutableDictionary",
26 "NSNumber"
27 };
28
29 if (!ClassIds[K])
30 return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
31
32 return ClassIds[K];
33}
34
35Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
36 if (NSStringSelectors[MK].isNull()) {
37 Selector Sel;
38 switch (MK) {
39 case NSStr_stringWithString:
40 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
41 break;
42 case NSStr_initWithString:
43 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
44 break;
45 }
46 return (NSStringSelectors[MK] = Sel);
47 }
48
49 return NSStringSelectors[MK];
50}
51
52Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
53 if (NSArraySelectors[MK].isNull()) {
54 Selector Sel;
55 switch (MK) {
56 case NSArr_array:
57 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
58 break;
59 case NSArr_arrayWithArray:
60 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
61 break;
62 case NSArr_arrayWithObject:
63 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
64 break;
65 case NSArr_arrayWithObjects:
66 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
67 break;
68 case NSArr_arrayWithObjectsCount: {
69 IdentifierInfo *KeyIdents[] = {
70 &Ctx.Idents.get("arrayWithObjects"),
71 &Ctx.Idents.get("count")
72 };
73 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
74 break;
75 }
76 case NSArr_initWithArray:
77 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
78 break;
79 case NSArr_initWithObjects:
80 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
81 break;
82 case NSArr_objectAtIndex:
83 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
84 break;
85 case NSMutableArr_replaceObjectAtIndex: {
86 IdentifierInfo *KeyIdents[] = {
87 &Ctx.Idents.get("replaceObjectAtIndex"),
88 &Ctx.Idents.get("withObject")
89 };
90 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
91 break;
92 }
93 }
94 return (NSArraySelectors[MK] = Sel);
95 }
96
97 return NSArraySelectors[MK];
98}
99
100llvm::Optional<NSAPI::NSArrayMethodKind>
101NSAPI::getNSArrayMethodKind(Selector Sel) {
102 for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
103 NSArrayMethodKind MK = NSArrayMethodKind(i);
104 if (Sel == getNSArraySelector(MK))
105 return MK;
106 }
107
108 return llvm::Optional<NSArrayMethodKind>();
109}
110
111Selector NSAPI::getNSDictionarySelector(
112 NSDictionaryMethodKind MK) const {
113 if (NSDictionarySelectors[MK].isNull()) {
114 Selector Sel;
115 switch (MK) {
116 case NSDict_dictionary:
117 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
118 break;
119 case NSDict_dictionaryWithDictionary:
120 Sel = Ctx.Selectors.getUnarySelector(
121 &Ctx.Idents.get("dictionaryWithDictionary"));
122 break;
123 case NSDict_dictionaryWithObjectForKey: {
124 IdentifierInfo *KeyIdents[] = {
125 &Ctx.Idents.get("dictionaryWithObject"),
126 &Ctx.Idents.get("forKey")
127 };
128 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
129 break;
130 }
131 case NSDict_dictionaryWithObjectsForKeys: {
132 IdentifierInfo *KeyIdents[] = {
133 &Ctx.Idents.get("dictionaryWithObjects"),
134 &Ctx.Idents.get("forKeys")
135 };
136 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
137 break;
138 }
139 case NSDict_dictionaryWithObjectsForKeysCount: {
140 IdentifierInfo *KeyIdents[] = {
141 &Ctx.Idents.get("dictionaryWithObjects"),
142 &Ctx.Idents.get("forKeys"),
143 &Ctx.Idents.get("count")
144 };
145 Sel = Ctx.Selectors.getSelector(3, KeyIdents);
146 break;
147 }
148 case NSDict_dictionaryWithObjectsAndKeys:
149 Sel = Ctx.Selectors.getUnarySelector(
150 &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
151 break;
152 case NSDict_initWithDictionary:
153 Sel = Ctx.Selectors.getUnarySelector(
154 &Ctx.Idents.get("initWithDictionary"));
155 break;
156 case NSDict_initWithObjectsAndKeys:
157 Sel = Ctx.Selectors.getUnarySelector(
158 &Ctx.Idents.get("initWithObjectsAndKeys"));
159 break;
160 case NSDict_objectForKey:
161 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
162 break;
163 case NSMutableDict_setObjectForKey: {
164 IdentifierInfo *KeyIdents[] = {
165 &Ctx.Idents.get("setObject"),
166 &Ctx.Idents.get("forKey")
167 };
168 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
169 break;
170 }
171 }
172 return (NSDictionarySelectors[MK] = Sel);
173 }
174
175 return NSDictionarySelectors[MK];
176}
177
178llvm::Optional<NSAPI::NSDictionaryMethodKind>
179NSAPI::getNSDictionaryMethodKind(Selector Sel) {
180 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
181 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
182 if (Sel == getNSDictionarySelector(MK))
183 return MK;
184 }
185
186 return llvm::Optional<NSDictionaryMethodKind>();
187}
188
189Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
190 bool Instance) const {
191 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
192 "numberWithChar",
193 "numberWithUnsignedChar",
194 "numberWithShort",
195 "numberWithUnsignedShort",
196 "numberWithInt",
197 "numberWithUnsignedInt",
198 "numberWithLong",
199 "numberWithUnsignedLong",
200 "numberWithLongLong",
201 "numberWithUnsignedLongLong",
202 "numberWithFloat",
203 "numberWithDouble",
204 "numberWithBool",
205 "numberWithInteger",
206 "numberWithUnsignedInteger"
207 };
208 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
209 "initWithChar",
210 "initWithUnsignedChar",
211 "initWithShort",
212 "initWithUnsignedShort",
213 "initWithInt",
214 "initWithUnsignedInt",
215 "initWithLong",
216 "initWithUnsignedLong",
217 "initWithLongLong",
218 "initWithUnsignedLongLong",
219 "initWithFloat",
220 "initWithDouble",
221 "initWithBool",
222 "initWithInteger",
223 "initWithUnsignedInteger"
224 };
225
226 Selector *Sels;
227 const char **Names;
228 if (Instance) {
229 Sels = NSNumberInstanceSelectors;
230 Names = InstanceSelectorName;
231 } else {
232 Sels = NSNumberClassSelectors;
233 Names = ClassSelectorName;
234 }
235
236 if (Sels[MK].isNull())
237 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
238 return Sels[MK];
239}
240
241llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
242NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
243 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
244 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
245 if (isNSNumberLiteralSelector(MK, Sel))
246 return MK;
247 }
248
249 return llvm::Optional<NSNumberLiteralMethodKind>();
250}
251
252llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
253NSAPI::getNSNumberFactoryMethodKind(QualType T) {
254 const BuiltinType *BT = T->getAs<BuiltinType>();
255 if (!BT)
256 return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
257
258 switch (BT->getKind()) {
259 case BuiltinType::Char_S:
260 case BuiltinType::SChar:
261 return NSAPI::NSNumberWithChar;
262 case BuiltinType::Char_U:
263 case BuiltinType::UChar:
264 return NSAPI::NSNumberWithUnsignedChar;
265 case BuiltinType::Short:
266 return NSAPI::NSNumberWithShort;
267 case BuiltinType::UShort:
268 return NSAPI::NSNumberWithUnsignedShort;
269 case BuiltinType::Int:
270 return NSAPI::NSNumberWithInt;
271 case BuiltinType::UInt:
272 return NSAPI::NSNumberWithUnsignedInt;
273 case BuiltinType::Long:
274 return NSAPI::NSNumberWithLong;
275 case BuiltinType::ULong:
276 return NSAPI::NSNumberWithUnsignedLong;
277 case BuiltinType::LongLong:
278 return NSAPI::NSNumberWithLongLong;
279 case BuiltinType::ULongLong:
280 return NSAPI::NSNumberWithUnsignedLongLong;
281 case BuiltinType::Float:
282 return NSAPI::NSNumberWithFloat;
283 case BuiltinType::Double:
284 return NSAPI::NSNumberWithDouble;
285 case BuiltinType::Bool:
286 return NSAPI::NSNumberWithBool;
287
288 case BuiltinType::Void:
289 case BuiltinType::WChar_U:
290 case BuiltinType::WChar_S:
291 case BuiltinType::Char16:
292 case BuiltinType::Char32:
293 case BuiltinType::Int128:
294 case BuiltinType::LongDouble:
295 case BuiltinType::UInt128:
296 case BuiltinType::NullPtr:
297 case BuiltinType::ObjCClass:
298 case BuiltinType::ObjCId:
299 case BuiltinType::ObjCSel:
300 case BuiltinType::BoundMember:
301 case BuiltinType::Dependent:
302 case BuiltinType::Overload:
303 case BuiltinType::UnknownAny:
304 case BuiltinType::ARCUnbridgedCast:
305 case BuiltinType::Half:
306 case BuiltinType::PseudoObject:
307 break;
308 }
309
310 return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
311}