• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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