NSAPI.cpp revision 234287
1234287Sdim//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2234287Sdim//
3234287Sdim//                     The LLVM Compiler Infrastructure
4234287Sdim//
5234287Sdim// This file is distributed under the University of Illinois Open Source
6234287Sdim// License. See LICENSE.TXT for details.
7234287Sdim//
8234287Sdim//===----------------------------------------------------------------------===//
9234287Sdim
10234287Sdim#include "clang/AST/NSAPI.h"
11234287Sdim#include "clang/AST/ASTContext.h"
12234287Sdim
13234287Sdimusing namespace clang;
14234287Sdim
15234287SdimNSAPI::NSAPI(ASTContext &ctx)
16234287Sdim  : Ctx(ctx), ClassIds() {
17234287Sdim}
18234287Sdim
19234287SdimIdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
20234287Sdim  static const char *ClassName[NumClassIds] = {
21234287Sdim    "NSObject",
22234287Sdim    "NSString",
23234287Sdim    "NSArray",
24234287Sdim    "NSMutableArray",
25234287Sdim    "NSDictionary",
26234287Sdim    "NSMutableDictionary",
27234287Sdim    "NSNumber"
28234287Sdim  };
29234287Sdim
30234287Sdim  if (!ClassIds[K])
31234287Sdim    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
32234287Sdim
33234287Sdim  return ClassIds[K];
34234287Sdim}
35234287Sdim
36234287SdimSelector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
37234287Sdim  if (NSStringSelectors[MK].isNull()) {
38234287Sdim    Selector Sel;
39234287Sdim    switch (MK) {
40234287Sdim    case NSStr_stringWithString:
41234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
42234287Sdim      break;
43234287Sdim    case NSStr_initWithString:
44234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
45234287Sdim      break;
46234287Sdim    }
47234287Sdim    return (NSStringSelectors[MK] = Sel);
48234287Sdim  }
49234287Sdim
50234287Sdim  return NSStringSelectors[MK];
51234287Sdim}
52234287Sdim
53234287SdimSelector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
54234287Sdim  if (NSArraySelectors[MK].isNull()) {
55234287Sdim    Selector Sel;
56234287Sdim    switch (MK) {
57234287Sdim    case NSArr_array:
58234287Sdim      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
59234287Sdim      break;
60234287Sdim    case NSArr_arrayWithArray:
61234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
62234287Sdim      break;
63234287Sdim    case NSArr_arrayWithObject:
64234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
65234287Sdim      break;
66234287Sdim    case NSArr_arrayWithObjects:
67234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
68234287Sdim      break;
69234287Sdim    case NSArr_arrayWithObjectsCount: {
70234287Sdim      IdentifierInfo *KeyIdents[] = {
71234287Sdim        &Ctx.Idents.get("arrayWithObjects"),
72234287Sdim        &Ctx.Idents.get("count")
73234287Sdim      };
74234287Sdim      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
75234287Sdim      break;
76234287Sdim    }
77234287Sdim    case NSArr_initWithArray:
78234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
79234287Sdim      break;
80234287Sdim    case NSArr_initWithObjects:
81234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
82234287Sdim      break;
83234287Sdim    case NSArr_objectAtIndex:
84234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
85234287Sdim      break;
86234287Sdim    case NSMutableArr_replaceObjectAtIndex: {
87234287Sdim      IdentifierInfo *KeyIdents[] = {
88234287Sdim        &Ctx.Idents.get("replaceObjectAtIndex"),
89234287Sdim        &Ctx.Idents.get("withObject")
90234287Sdim      };
91234287Sdim      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
92234287Sdim      break;
93234287Sdim    }
94234287Sdim    }
95234287Sdim    return (NSArraySelectors[MK] = Sel);
96234287Sdim  }
97234287Sdim
98234287Sdim  return NSArraySelectors[MK];
99234287Sdim}
100234287Sdim
101234287Sdimllvm::Optional<NSAPI::NSArrayMethodKind>
102234287SdimNSAPI::getNSArrayMethodKind(Selector Sel) {
103234287Sdim  for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
104234287Sdim    NSArrayMethodKind MK = NSArrayMethodKind(i);
105234287Sdim    if (Sel == getNSArraySelector(MK))
106234287Sdim      return MK;
107234287Sdim  }
108234287Sdim
109234287Sdim  return llvm::Optional<NSArrayMethodKind>();
110234287Sdim}
111234287Sdim
112234287SdimSelector NSAPI::getNSDictionarySelector(
113234287Sdim                                       NSDictionaryMethodKind MK) const {
114234287Sdim  if (NSDictionarySelectors[MK].isNull()) {
115234287Sdim    Selector Sel;
116234287Sdim    switch (MK) {
117234287Sdim    case NSDict_dictionary:
118234287Sdim      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
119234287Sdim      break;
120234287Sdim    case NSDict_dictionaryWithDictionary:
121234287Sdim      Sel = Ctx.Selectors.getUnarySelector(
122234287Sdim                                   &Ctx.Idents.get("dictionaryWithDictionary"));
123234287Sdim      break;
124234287Sdim    case NSDict_dictionaryWithObjectForKey: {
125234287Sdim      IdentifierInfo *KeyIdents[] = {
126234287Sdim        &Ctx.Idents.get("dictionaryWithObject"),
127234287Sdim        &Ctx.Idents.get("forKey")
128234287Sdim      };
129234287Sdim      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
130234287Sdim      break;
131234287Sdim    }
132234287Sdim    case NSDict_dictionaryWithObjectsForKeys: {
133234287Sdim      IdentifierInfo *KeyIdents[] = {
134234287Sdim        &Ctx.Idents.get("dictionaryWithObjects"),
135234287Sdim        &Ctx.Idents.get("forKeys")
136234287Sdim      };
137234287Sdim      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
138234287Sdim      break;
139234287Sdim    }
140234287Sdim    case NSDict_dictionaryWithObjectsForKeysCount: {
141234287Sdim      IdentifierInfo *KeyIdents[] = {
142234287Sdim        &Ctx.Idents.get("dictionaryWithObjects"),
143234287Sdim        &Ctx.Idents.get("forKeys"),
144234287Sdim        &Ctx.Idents.get("count")
145234287Sdim      };
146234287Sdim      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
147234287Sdim      break;
148234287Sdim    }
149234287Sdim    case NSDict_dictionaryWithObjectsAndKeys:
150234287Sdim      Sel = Ctx.Selectors.getUnarySelector(
151234287Sdim                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
152234287Sdim      break;
153234287Sdim    case NSDict_initWithDictionary:
154234287Sdim      Sel = Ctx.Selectors.getUnarySelector(
155234287Sdim                                         &Ctx.Idents.get("initWithDictionary"));
156234287Sdim      break;
157234287Sdim    case NSDict_initWithObjectsAndKeys:
158234287Sdim      Sel = Ctx.Selectors.getUnarySelector(
159234287Sdim                                     &Ctx.Idents.get("initWithObjectsAndKeys"));
160234287Sdim      break;
161234287Sdim    case NSDict_objectForKey:
162234287Sdim      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
163234287Sdim      break;
164234287Sdim    case NSMutableDict_setObjectForKey: {
165234287Sdim      IdentifierInfo *KeyIdents[] = {
166234287Sdim        &Ctx.Idents.get("setObject"),
167234287Sdim        &Ctx.Idents.get("forKey")
168234287Sdim      };
169234287Sdim      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
170234287Sdim      break;
171234287Sdim    }
172234287Sdim    }
173234287Sdim    return (NSDictionarySelectors[MK] = Sel);
174234287Sdim  }
175234287Sdim
176234287Sdim  return NSDictionarySelectors[MK];
177234287Sdim}
178234287Sdim
179234287Sdimllvm::Optional<NSAPI::NSDictionaryMethodKind>
180234287SdimNSAPI::getNSDictionaryMethodKind(Selector Sel) {
181234287Sdim  for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
182234287Sdim    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
183234287Sdim    if (Sel == getNSDictionarySelector(MK))
184234287Sdim      return MK;
185234287Sdim  }
186234287Sdim
187234287Sdim  return llvm::Optional<NSDictionaryMethodKind>();
188234287Sdim}
189234287Sdim
190234287SdimSelector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
191234287Sdim                                           bool Instance) const {
192234287Sdim  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
193234287Sdim    "numberWithChar",
194234287Sdim    "numberWithUnsignedChar",
195234287Sdim    "numberWithShort",
196234287Sdim    "numberWithUnsignedShort",
197234287Sdim    "numberWithInt",
198234287Sdim    "numberWithUnsignedInt",
199234287Sdim    "numberWithLong",
200234287Sdim    "numberWithUnsignedLong",
201234287Sdim    "numberWithLongLong",
202234287Sdim    "numberWithUnsignedLongLong",
203234287Sdim    "numberWithFloat",
204234287Sdim    "numberWithDouble",
205234287Sdim    "numberWithBool",
206234287Sdim    "numberWithInteger",
207234287Sdim    "numberWithUnsignedInteger"
208234287Sdim  };
209234287Sdim  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
210234287Sdim    "initWithChar",
211234287Sdim    "initWithUnsignedChar",
212234287Sdim    "initWithShort",
213234287Sdim    "initWithUnsignedShort",
214234287Sdim    "initWithInt",
215234287Sdim    "initWithUnsignedInt",
216234287Sdim    "initWithLong",
217234287Sdim    "initWithUnsignedLong",
218234287Sdim    "initWithLongLong",
219234287Sdim    "initWithUnsignedLongLong",
220234287Sdim    "initWithFloat",
221234287Sdim    "initWithDouble",
222234287Sdim    "initWithBool",
223234287Sdim    "initWithInteger",
224234287Sdim    "initWithUnsignedInteger"
225234287Sdim  };
226234287Sdim
227234287Sdim  Selector *Sels;
228234287Sdim  const char **Names;
229234287Sdim  if (Instance) {
230234287Sdim    Sels = NSNumberInstanceSelectors;
231234287Sdim    Names = InstanceSelectorName;
232234287Sdim  } else {
233234287Sdim    Sels = NSNumberClassSelectors;
234234287Sdim    Names = ClassSelectorName;
235234287Sdim  }
236234287Sdim
237234287Sdim  if (Sels[MK].isNull())
238234287Sdim    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
239234287Sdim  return Sels[MK];
240234287Sdim}
241234287Sdim
242234287Sdimllvm::Optional<NSAPI::NSNumberLiteralMethodKind>
243234287SdimNSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
244234287Sdim  for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
245234287Sdim    NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
246234287Sdim    if (isNSNumberLiteralSelector(MK, Sel))
247234287Sdim      return MK;
248234287Sdim  }
249234287Sdim
250234287Sdim  return llvm::Optional<NSNumberLiteralMethodKind>();
251234287Sdim}
252234287Sdim
253234287Sdimllvm::Optional<NSAPI::NSNumberLiteralMethodKind>
254234287SdimNSAPI::getNSNumberFactoryMethodKind(QualType T) {
255234287Sdim  const BuiltinType *BT = T->getAs<BuiltinType>();
256234287Sdim  if (!BT)
257234287Sdim    return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
258234287Sdim
259234287Sdim  switch (BT->getKind()) {
260234287Sdim  case BuiltinType::Char_S:
261234287Sdim  case BuiltinType::SChar:
262234287Sdim    return NSAPI::NSNumberWithChar;
263234287Sdim  case BuiltinType::Char_U:
264234287Sdim  case BuiltinType::UChar:
265234287Sdim    return NSAPI::NSNumberWithUnsignedChar;
266234287Sdim  case BuiltinType::Short:
267234287Sdim    return NSAPI::NSNumberWithShort;
268234287Sdim  case BuiltinType::UShort:
269234287Sdim    return NSAPI::NSNumberWithUnsignedShort;
270234287Sdim  case BuiltinType::Int:
271234287Sdim    return NSAPI::NSNumberWithInt;
272234287Sdim  case BuiltinType::UInt:
273234287Sdim    return NSAPI::NSNumberWithUnsignedInt;
274234287Sdim  case BuiltinType::Long:
275234287Sdim    return NSAPI::NSNumberWithLong;
276234287Sdim  case BuiltinType::ULong:
277234287Sdim    return NSAPI::NSNumberWithUnsignedLong;
278234287Sdim  case BuiltinType::LongLong:
279234287Sdim    return NSAPI::NSNumberWithLongLong;
280234287Sdim  case BuiltinType::ULongLong:
281234287Sdim    return NSAPI::NSNumberWithUnsignedLongLong;
282234287Sdim  case BuiltinType::Float:
283234287Sdim    return NSAPI::NSNumberWithFloat;
284234287Sdim  case BuiltinType::Double:
285234287Sdim    return NSAPI::NSNumberWithDouble;
286234287Sdim  case BuiltinType::Bool:
287234287Sdim    return NSAPI::NSNumberWithBool;
288234287Sdim
289234287Sdim  case BuiltinType::Void:
290234287Sdim  case BuiltinType::WChar_U:
291234287Sdim  case BuiltinType::WChar_S:
292234287Sdim  case BuiltinType::Char16:
293234287Sdim  case BuiltinType::Char32:
294234287Sdim  case BuiltinType::Int128:
295234287Sdim  case BuiltinType::LongDouble:
296234287Sdim  case BuiltinType::UInt128:
297234287Sdim  case BuiltinType::NullPtr:
298234287Sdim  case BuiltinType::ObjCClass:
299234287Sdim  case BuiltinType::ObjCId:
300234287Sdim  case BuiltinType::ObjCSel:
301234287Sdim  case BuiltinType::BoundMember:
302234287Sdim  case BuiltinType::Dependent:
303234287Sdim  case BuiltinType::Overload:
304234287Sdim  case BuiltinType::UnknownAny:
305234287Sdim  case BuiltinType::ARCUnbridgedCast:
306234287Sdim  case BuiltinType::Half:
307234287Sdim  case BuiltinType::PseudoObject:
308234287Sdim    break;
309234287Sdim  }
310234287Sdim
311234287Sdim  return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
312234287Sdim}
313