etc/services - sync with NetBSD-8
[minix.git] / external / bsd / llvm / dist / clang / lib / AST / NSAPI.cpp
blob3dc750a81787e275ba859f9a7c5b5703e27c9614
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 //===----------------------------------------------------------------------===//
10 #include "clang/AST/NSAPI.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/Expr.h"
13 #include "llvm/ADT/StringSwitch.h"
15 using namespace clang;
17 NSAPI::NSAPI(ASTContext &ctx)
18 : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
19 NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
20 NSUTF8StringEncodingId(nullptr) {}
22 IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23 static const char *ClassName[NumClassIds] = {
24 "NSObject",
25 "NSString",
26 "NSArray",
27 "NSMutableArray",
28 "NSDictionary",
29 "NSMutableDictionary",
30 "NSNumber"
33 if (!ClassIds[K])
34 return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
36 return ClassIds[K];
39 Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
40 if (NSStringSelectors[MK].isNull()) {
41 Selector Sel;
42 switch (MK) {
43 case NSStr_stringWithString:
44 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
45 break;
46 case NSStr_stringWithUTF8String:
47 Sel = Ctx.Selectors.getUnarySelector(
48 &Ctx.Idents.get("stringWithUTF8String"));
49 break;
50 case NSStr_initWithUTF8String:
51 Sel = Ctx.Selectors.getUnarySelector(
52 &Ctx.Idents.get("initWithUTF8String"));
53 break;
54 case NSStr_stringWithCStringEncoding: {
55 IdentifierInfo *KeyIdents[] = {
56 &Ctx.Idents.get("stringWithCString"),
57 &Ctx.Idents.get("encoding")
59 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
60 break;
62 case NSStr_stringWithCString:
63 Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
64 break;
65 case NSStr_initWithString:
66 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
67 break;
69 return (NSStringSelectors[MK] = Sel);
72 return NSStringSelectors[MK];
75 Optional<NSAPI::NSStringMethodKind>
76 NSAPI::getNSStringMethodKind(Selector Sel) const {
77 for (unsigned i = 0; i != NumNSStringMethods; ++i) {
78 NSStringMethodKind MK = NSStringMethodKind(i);
79 if (Sel == getNSStringSelector(MK))
80 return MK;
83 return None;
86 Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
87 if (NSArraySelectors[MK].isNull()) {
88 Selector Sel;
89 switch (MK) {
90 case NSArr_array:
91 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
92 break;
93 case NSArr_arrayWithArray:
94 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
95 break;
96 case NSArr_arrayWithObject:
97 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
98 break;
99 case NSArr_arrayWithObjects:
100 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
101 break;
102 case NSArr_arrayWithObjectsCount: {
103 IdentifierInfo *KeyIdents[] = {
104 &Ctx.Idents.get("arrayWithObjects"),
105 &Ctx.Idents.get("count")
107 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
108 break;
110 case NSArr_initWithArray:
111 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
112 break;
113 case NSArr_initWithObjects:
114 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
115 break;
116 case NSArr_objectAtIndex:
117 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
118 break;
119 case NSMutableArr_replaceObjectAtIndex: {
120 IdentifierInfo *KeyIdents[] = {
121 &Ctx.Idents.get("replaceObjectAtIndex"),
122 &Ctx.Idents.get("withObject")
124 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
125 break;
128 return (NSArraySelectors[MK] = Sel);
131 return NSArraySelectors[MK];
134 Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
135 for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
136 NSArrayMethodKind MK = NSArrayMethodKind(i);
137 if (Sel == getNSArraySelector(MK))
138 return MK;
141 return None;
144 Selector NSAPI::getNSDictionarySelector(
145 NSDictionaryMethodKind MK) const {
146 if (NSDictionarySelectors[MK].isNull()) {
147 Selector Sel;
148 switch (MK) {
149 case NSDict_dictionary:
150 Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
151 break;
152 case NSDict_dictionaryWithDictionary:
153 Sel = Ctx.Selectors.getUnarySelector(
154 &Ctx.Idents.get("dictionaryWithDictionary"));
155 break;
156 case NSDict_dictionaryWithObjectForKey: {
157 IdentifierInfo *KeyIdents[] = {
158 &Ctx.Idents.get("dictionaryWithObject"),
159 &Ctx.Idents.get("forKey")
161 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
162 break;
164 case NSDict_dictionaryWithObjectsForKeys: {
165 IdentifierInfo *KeyIdents[] = {
166 &Ctx.Idents.get("dictionaryWithObjects"),
167 &Ctx.Idents.get("forKeys")
169 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
170 break;
172 case NSDict_dictionaryWithObjectsForKeysCount: {
173 IdentifierInfo *KeyIdents[] = {
174 &Ctx.Idents.get("dictionaryWithObjects"),
175 &Ctx.Idents.get("forKeys"),
176 &Ctx.Idents.get("count")
178 Sel = Ctx.Selectors.getSelector(3, KeyIdents);
179 break;
181 case NSDict_dictionaryWithObjectsAndKeys:
182 Sel = Ctx.Selectors.getUnarySelector(
183 &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
184 break;
185 case NSDict_initWithDictionary:
186 Sel = Ctx.Selectors.getUnarySelector(
187 &Ctx.Idents.get("initWithDictionary"));
188 break;
189 case NSDict_initWithObjectsAndKeys:
190 Sel = Ctx.Selectors.getUnarySelector(
191 &Ctx.Idents.get("initWithObjectsAndKeys"));
192 break;
193 case NSDict_initWithObjectsForKeys: {
194 IdentifierInfo *KeyIdents[] = {
195 &Ctx.Idents.get("initWithObjects"),
196 &Ctx.Idents.get("forKeys")
198 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
199 break;
201 case NSDict_objectForKey:
202 Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
203 break;
204 case NSMutableDict_setObjectForKey: {
205 IdentifierInfo *KeyIdents[] = {
206 &Ctx.Idents.get("setObject"),
207 &Ctx.Idents.get("forKey")
209 Sel = Ctx.Selectors.getSelector(2, KeyIdents);
210 break;
213 return (NSDictionarySelectors[MK] = Sel);
216 return NSDictionarySelectors[MK];
219 Optional<NSAPI::NSDictionaryMethodKind>
220 NSAPI::getNSDictionaryMethodKind(Selector Sel) {
221 for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
222 NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
223 if (Sel == getNSDictionarySelector(MK))
224 return MK;
227 return None;
230 Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
231 bool Instance) const {
232 static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
233 "numberWithChar",
234 "numberWithUnsignedChar",
235 "numberWithShort",
236 "numberWithUnsignedShort",
237 "numberWithInt",
238 "numberWithUnsignedInt",
239 "numberWithLong",
240 "numberWithUnsignedLong",
241 "numberWithLongLong",
242 "numberWithUnsignedLongLong",
243 "numberWithFloat",
244 "numberWithDouble",
245 "numberWithBool",
246 "numberWithInteger",
247 "numberWithUnsignedInteger"
249 static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
250 "initWithChar",
251 "initWithUnsignedChar",
252 "initWithShort",
253 "initWithUnsignedShort",
254 "initWithInt",
255 "initWithUnsignedInt",
256 "initWithLong",
257 "initWithUnsignedLong",
258 "initWithLongLong",
259 "initWithUnsignedLongLong",
260 "initWithFloat",
261 "initWithDouble",
262 "initWithBool",
263 "initWithInteger",
264 "initWithUnsignedInteger"
267 Selector *Sels;
268 const char **Names;
269 if (Instance) {
270 Sels = NSNumberInstanceSelectors;
271 Names = InstanceSelectorName;
272 } else {
273 Sels = NSNumberClassSelectors;
274 Names = ClassSelectorName;
277 if (Sels[MK].isNull())
278 Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
279 return Sels[MK];
282 Optional<NSAPI::NSNumberLiteralMethodKind>
283 NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
284 for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
285 NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
286 if (isNSNumberLiteralSelector(MK, Sel))
287 return MK;
290 return None;
293 Optional<NSAPI::NSNumberLiteralMethodKind>
294 NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
295 const BuiltinType *BT = T->getAs<BuiltinType>();
296 if (!BT)
297 return None;
299 const TypedefType *TDT = T->getAs<TypedefType>();
300 if (TDT) {
301 QualType TDTTy = QualType(TDT, 0);
302 if (isObjCBOOLType(TDTTy))
303 return NSAPI::NSNumberWithBool;
304 if (isObjCNSIntegerType(TDTTy))
305 return NSAPI::NSNumberWithInteger;
306 if (isObjCNSUIntegerType(TDTTy))
307 return NSAPI::NSNumberWithUnsignedInteger;
310 switch (BT->getKind()) {
311 case BuiltinType::Char_S:
312 case BuiltinType::SChar:
313 return NSAPI::NSNumberWithChar;
314 case BuiltinType::Char_U:
315 case BuiltinType::UChar:
316 return NSAPI::NSNumberWithUnsignedChar;
317 case BuiltinType::Short:
318 return NSAPI::NSNumberWithShort;
319 case BuiltinType::UShort:
320 return NSAPI::NSNumberWithUnsignedShort;
321 case BuiltinType::Int:
322 return NSAPI::NSNumberWithInt;
323 case BuiltinType::UInt:
324 return NSAPI::NSNumberWithUnsignedInt;
325 case BuiltinType::Long:
326 return NSAPI::NSNumberWithLong;
327 case BuiltinType::ULong:
328 return NSAPI::NSNumberWithUnsignedLong;
329 case BuiltinType::LongLong:
330 return NSAPI::NSNumberWithLongLong;
331 case BuiltinType::ULongLong:
332 return NSAPI::NSNumberWithUnsignedLongLong;
333 case BuiltinType::Float:
334 return NSAPI::NSNumberWithFloat;
335 case BuiltinType::Double:
336 return NSAPI::NSNumberWithDouble;
337 case BuiltinType::Bool:
338 return NSAPI::NSNumberWithBool;
340 case BuiltinType::Void:
341 case BuiltinType::WChar_U:
342 case BuiltinType::WChar_S:
343 case BuiltinType::Char16:
344 case BuiltinType::Char32:
345 case BuiltinType::Int128:
346 case BuiltinType::LongDouble:
347 case BuiltinType::UInt128:
348 case BuiltinType::NullPtr:
349 case BuiltinType::ObjCClass:
350 case BuiltinType::ObjCId:
351 case BuiltinType::ObjCSel:
352 case BuiltinType::OCLImage1d:
353 case BuiltinType::OCLImage1dArray:
354 case BuiltinType::OCLImage1dBuffer:
355 case BuiltinType::OCLImage2d:
356 case BuiltinType::OCLImage2dArray:
357 case BuiltinType::OCLImage3d:
358 case BuiltinType::OCLSampler:
359 case BuiltinType::OCLEvent:
360 case BuiltinType::BoundMember:
361 case BuiltinType::Dependent:
362 case BuiltinType::Overload:
363 case BuiltinType::UnknownAny:
364 case BuiltinType::ARCUnbridgedCast:
365 case BuiltinType::Half:
366 case BuiltinType::PseudoObject:
367 case BuiltinType::BuiltinFn:
368 break;
371 return None;
374 /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
375 bool NSAPI::isObjCBOOLType(QualType T) const {
376 return isObjCTypedef(T, "BOOL", BOOLId);
378 /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
379 bool NSAPI::isObjCNSIntegerType(QualType T) const {
380 return isObjCTypedef(T, "NSInteger", NSIntegerId);
382 /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
383 bool NSAPI::isObjCNSUIntegerType(QualType T) const {
384 return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
387 StringRef NSAPI::GetNSIntegralKind(QualType T) const {
388 if (!Ctx.getLangOpts().ObjC1 || T.isNull())
389 return StringRef();
391 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
392 StringRef NSIntegralResust =
393 llvm::StringSwitch<StringRef>(
394 TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
395 .Case("int8_t", "int8_t")
396 .Case("int16_t", "int16_t")
397 .Case("int32_t", "int32_t")
398 .Case("NSInteger", "NSInteger")
399 .Case("int64_t", "int64_t")
400 .Case("uint8_t", "uint8_t")
401 .Case("uint16_t", "uint16_t")
402 .Case("uint32_t", "uint32_t")
403 .Case("NSUInteger", "NSUInteger")
404 .Case("uint64_t", "uint64_t")
405 .Default(StringRef());
406 if (!NSIntegralResust.empty())
407 return NSIntegralResust;
408 T = TDT->desugar();
410 return StringRef();
413 bool NSAPI::isObjCTypedef(QualType T,
414 StringRef name, IdentifierInfo *&II) const {
415 if (!Ctx.getLangOpts().ObjC1)
416 return false;
417 if (T.isNull())
418 return false;
420 if (!II)
421 II = &Ctx.Idents.get(name);
423 while (const TypedefType *TDT = T->getAs<TypedefType>()) {
424 if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
425 return true;
426 T = TDT->desugar();
429 return false;
432 bool NSAPI::isObjCEnumerator(const Expr *E,
433 StringRef name, IdentifierInfo *&II) const {
434 if (!Ctx.getLangOpts().ObjC1)
435 return false;
436 if (!E)
437 return false;
439 if (!II)
440 II = &Ctx.Idents.get(name);
442 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
443 if (const EnumConstantDecl *
444 EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
445 return EnumD->getIdentifier() == II;
447 return false;
450 Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
451 Selector &Sel) const {
452 if (Sel.isNull()) {
453 SmallVector<IdentifierInfo *, 4> Idents;
454 for (ArrayRef<StringRef>::const_iterator
455 I = Ids.begin(), E = Ids.end(); I != E; ++I)
456 Idents.push_back(&Ctx.Idents.get(*I));
457 Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
459 return Sel;