Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/NSAPI.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "clang/AST/NSAPI.h"
10
#include "clang/AST/ASTContext.h"
11
#include "clang/AST/DeclObjC.h"
12
#include "clang/AST/Expr.h"
13
#include "llvm/ADT/StringSwitch.h"
14
15
using namespace clang;
16
17
NSAPI::NSAPI(ASTContext &ctx)
18
  : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
19
    NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
20
17.4k
    NSUTF8StringEncodingId(nullptr) {}
21
22
65.4k
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23
65.4k
  static const char *ClassName[NumClassIds] = {
24
65.4k
    "NSObject",
25
65.4k
    "NSString",
26
65.4k
    "NSArray",
27
65.4k
    "NSMutableArray",
28
65.4k
    "NSDictionary",
29
65.4k
    "NSMutableDictionary",
30
65.4k
    "NSNumber",
31
65.4k
    "NSMutableSet",
32
65.4k
    "NSMutableOrderedSet",
33
65.4k
    "NSValue"
34
65.4k
  };
35
65.4k
36
65.4k
  if (!ClassIds[K])
37
8.86k
    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38
56.5k
39
56.5k
  return ClassIds[K];
40
56.5k
}
41
42
41
Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
43
41
  if (NSStringSelectors[MK].isNull()) {
44
12
    Selector Sel;
45
12
    switch (MK) {
46
4
    case NSStr_stringWithString:
47
4
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
48
4
      break;
49
1
    case NSStr_stringWithUTF8String:
50
1
      Sel = Ctx.Selectors.getUnarySelector(
51
1
                                       &Ctx.Idents.get("stringWithUTF8String"));
52
1
      break;
53
1
    case NSStr_initWithUTF8String:
54
1
      Sel = Ctx.Selectors.getUnarySelector(
55
1
                                       &Ctx.Idents.get("initWithUTF8String"));
56
1
      break;
57
1
    case NSStr_stringWithCStringEncoding: {
58
1
      IdentifierInfo *KeyIdents[] = {
59
1
        &Ctx.Idents.get("stringWithCString"),
60
1
        &Ctx.Idents.get("encoding")
61
1
      };
62
1
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
63
1
      break;
64
0
    }
65
1
    case NSStr_stringWithCString:
66
1
      Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
67
1
      break;
68
4
    case NSStr_initWithString:
69
4
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
70
4
      break;
71
12
    }
72
12
    return (NSStringSelectors[MK] = Sel);
73
12
  }
74
29
75
29
  return NSStringSelectors[MK];
76
29
}
77
78
3.86k
Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79
3.86k
  if (NSArraySelectors[MK].isNull()) {
80
2.15k
    Selector Sel;
81
2.15k
    switch (MK) {
82
175
    case NSArr_array:
83
175
      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
84
175
      break;
85
175
    case NSArr_arrayWithArray:
86
175
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
87
175
      break;
88
175
    case NSArr_arrayWithObject:
89
175
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
90
175
      break;
91
175
    case NSArr_arrayWithObjects:
92
175
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
93
175
      break;
94
259
    case NSArr_arrayWithObjectsCount: {
95
259
      IdentifierInfo *KeyIdents[] = {
96
259
        &Ctx.Idents.get("arrayWithObjects"),
97
259
        &Ctx.Idents.get("count")
98
259
      };
99
259
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
100
259
      break;
101
0
    }
102
172
    case NSArr_initWithArray:
103
172
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
104
172
      break;
105
173
    case NSArr_initWithObjects:
106
173
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
107
173
      break;
108
177
    case NSArr_objectAtIndex:
109
177
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
110
177
      break;
111
174
    case NSMutableArr_replaceObjectAtIndex: {
112
174
      IdentifierInfo *KeyIdents[] = {
113
174
        &Ctx.Idents.get("replaceObjectAtIndex"),
114
174
        &Ctx.Idents.get("withObject")
115
174
      };
116
174
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
117
174
      break;
118
0
    }
119
168
    case NSMutableArr_addObject:
120
168
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
121
168
      break;
122
165
    case NSMutableArr_insertObjectAtIndex: {
123
165
      IdentifierInfo *KeyIdents[] = {
124
165
        &Ctx.Idents.get("insertObject"),
125
165
        &Ctx.Idents.get("atIndex")
126
165
      };
127
165
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128
165
      break;
129
0
    }
130
165
    case NSMutableArr_setObjectAtIndexedSubscript: {
131
165
      IdentifierInfo *KeyIdents[] = {
132
165
        &Ctx.Idents.get("setObject"),
133
165
        &Ctx.Idents.get("atIndexedSubscript")
134
165
      };
135
165
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
136
165
      break;
137
2.15k
    }
138
2.15k
    }
139
2.15k
    return (NSArraySelectors[MK] = Sel);
140
2.15k
  }
141
1.71k
142
1.71k
  return NSArraySelectors[MK];
143
1.71k
}
144
145
310
Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
146
3.73k
  for (unsigned i = 0; i != NumNSArrayMethods; 
++i3.42k
) {
147
3.53k
    NSArrayMethodKind MK = NSArrayMethodKind(i);
148
3.53k
    if (Sel == getNSArraySelector(MK))
149
116
      return MK;
150
3.53k
  }
151
310
152
310
  
return None194
;
153
310
}
154
155
Selector NSAPI::getNSDictionarySelector(
156
3.03k
                                       NSDictionaryMethodKind MK) const {
157
3.03k
  if (NSDictionarySelectors[MK].isNull()) {
158
1.50k
    Selector Sel;
159
1.50k
    switch (MK) {
160
113
    case NSDict_dictionary:
161
113
      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
162
113
      break;
163
113
    case NSDict_dictionaryWithDictionary:
164
113
      Sel = Ctx.Selectors.getUnarySelector(
165
113
                                   &Ctx.Idents.get("dictionaryWithDictionary"));
166
113
      break;
167
113
    case NSDict_dictionaryWithObjectForKey: {
168
113
      IdentifierInfo *KeyIdents[] = {
169
113
        &Ctx.Idents.get("dictionaryWithObject"),
170
113
        &Ctx.Idents.get("forKey")
171
113
      };
172
113
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
173
113
      break;
174
0
    }
175
112
    case NSDict_dictionaryWithObjectsForKeys: {
176
112
      IdentifierInfo *KeyIdents[] = {
177
112
        &Ctx.Idents.get("dictionaryWithObjects"),
178
112
        &Ctx.Idents.get("forKeys")
179
112
      };
180
112
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
181
112
      break;
182
0
    }
183
178
    case NSDict_dictionaryWithObjectsForKeysCount: {
184
178
      IdentifierInfo *KeyIdents[] = {
185
178
        &Ctx.Idents.get("dictionaryWithObjects"),
186
178
        &Ctx.Idents.get("forKeys"),
187
178
        &Ctx.Idents.get("count")
188
178
      };
189
178
      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
190
178
      break;
191
0
    }
192
112
    case NSDict_dictionaryWithObjectsAndKeys:
193
112
      Sel = Ctx.Selectors.getUnarySelector(
194
112
                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
195
112
      break;
196
110
    case NSDict_initWithDictionary:
197
110
      Sel = Ctx.Selectors.getUnarySelector(
198
110
                                         &Ctx.Idents.get("initWithDictionary"));
199
110
      break;
200
112
    case NSDict_initWithObjectsAndKeys:
201
112
      Sel = Ctx.Selectors.getUnarySelector(
202
112
                                     &Ctx.Idents.get("initWithObjectsAndKeys"));
203
112
      break;
204
112
    case NSDict_initWithObjectsForKeys: {
205
112
      IdentifierInfo *KeyIdents[] = {
206
112
        &Ctx.Idents.get("initWithObjects"),
207
112
        &Ctx.Idents.get("forKeys")
208
112
      };
209
112
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
210
112
      break;
211
0
    }
212
115
    case NSDict_objectForKey:
213
115
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
214
115
      break;
215
112
    case NSMutableDict_setObjectForKey: {
216
112
      IdentifierInfo *KeyIdents[] = {
217
112
        &Ctx.Idents.get("setObject"),
218
112
        &Ctx.Idents.get("forKey")
219
112
      };
220
112
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221
112
      break;
222
0
    }
223
102
    case NSMutableDict_setObjectForKeyedSubscript: {
224
102
      IdentifierInfo *KeyIdents[] = {
225
102
        &Ctx.Idents.get("setObject"),
226
102
        &Ctx.Idents.get("forKeyedSubscript")
227
102
      };
228
102
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
229
102
      break;
230
0
    }
231
98
    case NSMutableDict_setValueForKey: {
232
98
      IdentifierInfo *KeyIdents[] = {
233
98
        &Ctx.Idents.get("setValue"),
234
98
        &Ctx.Idents.get("forKey")
235
98
      };
236
98
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
237
98
      break;
238
1.50k
    }
239
1.50k
    }
240
1.50k
    return (NSDictionarySelectors[MK] = Sel);
241
1.50k
  }
242
1.53k
243
1.53k
  return NSDictionarySelectors[MK];
244
1.53k
}
245
246
Optional<NSAPI::NSDictionaryMethodKind>
247
223
NSAPI::getNSDictionaryMethodKind(Selector Sel) {
248
2.88k
  for (unsigned i = 0; i != NumNSDictionaryMethods; 
++i2.65k
) {
249
2.75k
    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
250
2.75k
    if (Sel == getNSDictionarySelector(MK))
251
94
      return MK;
252
2.75k
  }
253
223
254
223
  
return None129
;
255
223
}
256
257
420
Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
258
420
  if (NSSetSelectors[MK].isNull()) {
259
195
    Selector Sel;
260
195
    switch (MK) {
261
39
    case NSMutableSet_addObject:
262
39
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
263
39
      break;
264
39
    case NSOrderedSet_insertObjectAtIndex: {
265
39
      IdentifierInfo *KeyIdents[] = {
266
39
        &Ctx.Idents.get("insertObject"),
267
39
        &Ctx.Idents.get("atIndex")
268
39
      };
269
39
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
270
39
      break;
271
0
    }
272
39
    case NSOrderedSet_setObjectAtIndex: {
273
39
      IdentifierInfo *KeyIdents[] = {
274
39
        &Ctx.Idents.get("setObject"),
275
39
        &Ctx.Idents.get("atIndex")
276
39
      };
277
39
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
278
39
      break;
279
0
    }
280
39
    case NSOrderedSet_setObjectAtIndexedSubscript: {
281
39
      IdentifierInfo *KeyIdents[] = {
282
39
        &Ctx.Idents.get("setObject"),
283
39
        &Ctx.Idents.get("atIndexedSubscript")
284
39
      };
285
39
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
286
39
      break;
287
0
    }
288
39
    case NSOrderedSet_replaceObjectAtIndexWithObject: {
289
39
      IdentifierInfo *KeyIdents[] = {
290
39
        &Ctx.Idents.get("replaceObjectAtIndex"),
291
39
        &Ctx.Idents.get("withObject")
292
39
      };
293
39
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
294
39
      break;
295
195
    }
296
195
    }
297
195
    return (NSSetSelectors[MK] = Sel);
298
195
  }
299
225
300
225
  return NSSetSelectors[MK];
301
225
}
302
303
Optional<NSAPI::NSSetMethodKind>
304
122
NSAPI::getNSSetMethodKind(Selector Sel) {
305
492
  for (unsigned i = 0; i != NumNSSetMethods; 
++i370
) {
306
420
    NSSetMethodKind MK = NSSetMethodKind(i);
307
420
    if (Sel == getNSSetSelector(MK))
308
50
      return MK;
309
420
  }
310
122
311
122
  
return None72
;
312
122
}
313
314
Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
315
8.78k
                                           bool Instance) const {
316
8.78k
  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
317
8.78k
    "numberWithChar",
318
8.78k
    "numberWithUnsignedChar",
319
8.78k
    "numberWithShort",
320
8.78k
    "numberWithUnsignedShort",
321
8.78k
    "numberWithInt",
322
8.78k
    "numberWithUnsignedInt",
323
8.78k
    "numberWithLong",
324
8.78k
    "numberWithUnsignedLong",
325
8.78k
    "numberWithLongLong",
326
8.78k
    "numberWithUnsignedLongLong",
327
8.78k
    "numberWithFloat",
328
8.78k
    "numberWithDouble",
329
8.78k
    "numberWithBool",
330
8.78k
    "numberWithInteger",
331
8.78k
    "numberWithUnsignedInteger"
332
8.78k
  };
333
8.78k
  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
334
8.78k
    "initWithChar",
335
8.78k
    "initWithUnsignedChar",
336
8.78k
    "initWithShort",
337
8.78k
    "initWithUnsignedShort",
338
8.78k
    "initWithInt",
339
8.78k
    "initWithUnsignedInt",
340
8.78k
    "initWithLong",
341
8.78k
    "initWithUnsignedLong",
342
8.78k
    "initWithLongLong",
343
8.78k
    "initWithUnsignedLongLong",
344
8.78k
    "initWithFloat",
345
8.78k
    "initWithDouble",
346
8.78k
    "initWithBool",
347
8.78k
    "initWithInteger",
348
8.78k
    "initWithUnsignedInteger"
349
8.78k
  };
350
8.78k
351
8.78k
  Selector *Sels;
352
8.78k
  const char **Names;
353
8.78k
  if (Instance) {
354
3.94k
    Sels = NSNumberInstanceSelectors;
355
3.94k
    Names = InstanceSelectorName;
356
4.84k
  } else {
357
4.84k
    Sels = NSNumberClassSelectors;
358
4.84k
    Names = ClassSelectorName;
359
4.84k
  }
360
8.78k
361
8.78k
  if (Sels[MK].isNull())
362
398
    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
363
8.78k
  return Sels[MK];
364
8.78k
}
365
366
Optional<NSAPI::NSNumberLiteralMethodKind>
367
593
NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
368
4.46k
  for (unsigned i = 0; i != NumNSNumberLiteralMethods; 
++i3.86k
) {
369
4.46k
    NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
370
4.46k
    if (isNSNumberLiteralSelector(MK, Sel))
371
593
      return MK;
372
4.46k
  }
373
593
374
593
  
return None0
;
375
593
}
376
377
Optional<NSAPI::NSNumberLiteralMethodKind>
378
895
NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
379
895
  const BuiltinType *BT = T->getAs<BuiltinType>();
380
895
  if (!BT)
381
0
    return None;
382
895
383
895
  const TypedefType *TDT = T->getAs<TypedefType>();
384
895
  if (TDT) {
385
12
    QualType TDTTy = QualType(TDT, 0);
386
12
    if (isObjCBOOLType(TDTTy))
387
6
      return NSAPI::NSNumberWithBool;
388
6
    if (isObjCNSIntegerType(TDTTy))
389
5
      return NSAPI::NSNumberWithInteger;
390
1
    if (isObjCNSUIntegerType(TDTTy))
391
1
      return NSAPI::NSNumberWithUnsignedInteger;
392
883
  }
393
883
394
883
  switch (BT->getKind()) {
395
25
  case BuiltinType::Char_S:
396
25
  case BuiltinType::SChar:
397
25
    return NSAPI::NSNumberWithChar;
398
25
  case BuiltinType::Char_U:
399
0
  case BuiltinType::UChar:
400
0
    return NSAPI::NSNumberWithUnsignedChar;
401
0
  case BuiltinType::Short:
402
0
    return NSAPI::NSNumberWithShort;
403
0
  case BuiltinType::UShort:
404
0
    return NSAPI::NSNumberWithUnsignedShort;
405
519
  case BuiltinType::Int:
406
519
    return NSAPI::NSNumberWithInt;
407
52
  case BuiltinType::UInt:
408
52
    return NSAPI::NSNumberWithUnsignedInt;
409
25
  case BuiltinType::Long:
410
25
    return NSAPI::NSNumberWithLong;
411
19
  case BuiltinType::ULong:
412
19
    return NSAPI::NSNumberWithUnsignedLong;
413
24
  case BuiltinType::LongLong:
414
24
    return NSAPI::NSNumberWithLongLong;
415
18
  case BuiltinType::ULongLong:
416
18
    return NSAPI::NSNumberWithUnsignedLongLong;
417
31
  case BuiltinType::Float:
418
31
    return NSAPI::NSNumberWithFloat;
419
119
  case BuiltinType::Double:
420
119
    return NSAPI::NSNumberWithDouble;
421
49
  case BuiltinType::Bool:
422
49
    return NSAPI::NSNumberWithBool;
423
0
424
2
  case BuiltinType::Void:
425
2
  case BuiltinType::WChar_U:
426
2
  case BuiltinType::WChar_S:
427
2
  case BuiltinType::Char8:
428
2
  case BuiltinType::Char16:
429
2
  case BuiltinType::Char32:
430
2
  case BuiltinType::Int128:
431
2
  case BuiltinType::LongDouble:
432
2
  case BuiltinType::ShortAccum:
433
2
  case BuiltinType::Accum:
434
2
  case BuiltinType::LongAccum:
435
2
  case BuiltinType::UShortAccum:
436
2
  case BuiltinType::UAccum:
437
2
  case BuiltinType::ULongAccum:
438
2
  case BuiltinType::ShortFract:
439
2
  case BuiltinType::Fract:
440
2
  case BuiltinType::LongFract:
441
2
  case BuiltinType::UShortFract:
442
2
  case BuiltinType::UFract:
443
2
  case BuiltinType::ULongFract:
444
2
  case BuiltinType::SatShortAccum:
445
2
  case BuiltinType::SatAccum:
446
2
  case BuiltinType::SatLongAccum:
447
2
  case BuiltinType::SatUShortAccum:
448
2
  case BuiltinType::SatUAccum:
449
2
  case BuiltinType::SatULongAccum:
450
2
  case BuiltinType::SatShortFract:
451
2
  case BuiltinType::SatFract:
452
2
  case BuiltinType::SatLongFract:
453
2
  case BuiltinType::SatUShortFract:
454
2
  case BuiltinType::SatUFract:
455
2
  case BuiltinType::SatULongFract:
456
2
  case BuiltinType::UInt128:
457
2
  case BuiltinType::Float16:
458
2
  case BuiltinType::Float128:
459
2
  case BuiltinType::NullPtr:
460
2
  case BuiltinType::ObjCClass:
461
2
  case BuiltinType::ObjCId:
462
2
  case BuiltinType::ObjCSel:
463
2
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
464
72
  case BuiltinType::Id:
465
72
#include 
"clang/Basic/OpenCLImageTypes.def"2
466
72
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
467
72
  
case BuiltinType::Id:24
468
72
#include 
"clang/Basic/OpenCLExtensionTypes.def"2
469
24
  case BuiltinType::OCLSampler:
470
2
  case BuiltinType::OCLEvent:
471
2
  case BuiltinType::OCLClkEvent:
472
2
  case BuiltinType::OCLQueue:
473
2
  case BuiltinType::OCLReserveID:
474
2
#define SVE_TYPE(Name, Id, SingletonId) \
475
24
  case BuiltinType::Id:
476
24
#include 
"clang/Basic/AArch64SVEACLETypes.def"2
477
24
  case BuiltinType::BoundMember:
478
2
  case BuiltinType::Dependent:
479
2
  case BuiltinType::Overload:
480
2
  case BuiltinType::UnknownAny:
481
2
  case BuiltinType::ARCUnbridgedCast:
482
2
  case BuiltinType::Half:
483
2
  case BuiltinType::PseudoObject:
484
2
  case BuiltinType::BuiltinFn:
485
2
  case BuiltinType::OMPArraySection:
486
2
    break;
487
2
  }
488
2
489
2
  return None;
490
2
}
491
492
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
493
20.1k
bool NSAPI::isObjCBOOLType(QualType T) const {
494
20.1k
  return isObjCTypedef(T, "BOOL", BOOLId);
495
20.1k
}
496
/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
497
48
bool NSAPI::isObjCNSIntegerType(QualType T) const {
498
48
  return isObjCTypedef(T, "NSInteger", NSIntegerId);
499
48
}
500
/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
501
43
bool NSAPI::isObjCNSUIntegerType(QualType T) const {
502
43
  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
503
43
}
504
505
50
StringRef NSAPI::GetNSIntegralKind(QualType T) const {
506
50
  if (!Ctx.getLangOpts().ObjC || T.isNull())
507
0
    return StringRef();
508
50
509
50
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
510
22
    StringRef NSIntegralResust =
511
22
      llvm::StringSwitch<StringRef>(
512
22
        TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
513
22
    .Case("int8_t", "int8_t")
514
22
    .Case("int16_t", "int16_t")
515
22
    .Case("int32_t", "int32_t")
516
22
    .Case("NSInteger", "NSInteger")
517
22
    .Case("int64_t", "int64_t")
518
22
    .Case("uint8_t", "uint8_t")
519
22
    .Case("uint16_t", "uint16_t")
520
22
    .Case("uint32_t", "uint32_t")
521
22
    .Case("NSUInteger", "NSUInteger")
522
22
    .Case("uint64_t", "uint64_t")
523
22
    .Default(StringRef());
524
22
    if (!NSIntegralResust.empty())
525
22
      return NSIntegralResust;
526
0
    T = TDT->desugar();
527
0
  }
528
50
  
return StringRef()28
;
529
50
}
530
531
122
bool NSAPI::isMacroDefined(StringRef Id) const {
532
122
  // FIXME: Check whether the relevant module macros are visible.
533
122
  return Ctx.Idents.get(Id).hasMacroDefinition();
534
122
}
535
536
bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
537
69.9k
                                NSClassIdKindKind NSClassKind) const {
538
69.9k
  if (!InterfaceDecl) {
539
9.68k
    return false;
540
9.68k
  }
541
60.2k
542
60.2k
  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
543
60.2k
544
60.2k
  bool IsSubclass = false;
545
109k
  do {
546
109k
    IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
547
109k
548
109k
    if (IsSubclass) {
549
655
      break;
550
655
    }
551
109k
  } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
552
60.2k
553
60.2k
  return IsSubclass;
554
60.2k
}
555
556
bool NSAPI::isObjCTypedef(QualType T,
557
20.2k
                          StringRef name, IdentifierInfo *&II) const {
558
20.2k
  if (!Ctx.getLangOpts().ObjC)
559
155
    return false;
560
20.0k
  if (T.isNull())
561
0
    return false;
562
20.0k
563
20.0k
  if (!II)
564
2.06k
    II = &Ctx.Idents.get(name);
565
20.0k
566
33.5k
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
567
15.0k
    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
568
1.55k
      return true;
569
13.5k
    T = TDT->desugar();
570
13.5k
  }
571
20.0k
572
20.0k
  
return false18.5k
;
573
20.0k
}
574
575
bool NSAPI::isObjCEnumerator(const Expr *E,
576
7
                             StringRef name, IdentifierInfo *&II) const {
577
7
  if (!Ctx.getLangOpts().ObjC)
578
0
    return false;
579
7
  if (!E)
580
0
    return false;
581
7
582
7
  if (!II)
583
2
    II = &Ctx.Idents.get(name);
584
7
585
7
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
586
7
    if (const EnumConstantDecl *
587
7
          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
588
5
      return EnumD->getIdentifier() == II;
589
2
590
2
  return false;
591
2
}
592
593
Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
594
149
                                  Selector &Sel) const {
595
149
  if (Sel.isNull()) {
596
15
    SmallVector<IdentifierInfo *, 4> Idents;
597
15
    for (ArrayRef<StringRef>::const_iterator
598
34
           I = Ids.begin(), E = Ids.end(); I != E; 
++I19
)
599
19
      Idents.push_back(&Ctx.Idents.get(*I));
600
15
    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
601
15
  }
602
149
  return Sel;
603
149
}
604
605
12.8k
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
606
12.8k
  if (Sel.isNull()) {
607
1.50k
    IdentifierInfo *Ident = &Ctx.Idents.get(Id);
608
1.50k
    Sel = Ctx.Selectors.getSelector(0, &Ident);
609
1.50k
  }
610
12.8k
  return Sel;
611
12.8k
}