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