Coverage Report

Created: 2021-08-24 07:12

/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
32.2k
    NSUTF8StringEncodingId(nullptr) {}
21
22
64.8k
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23
64.8k
  static const char *ClassName[NumClassIds] = {
24
64.8k
    "NSObject",
25
64.8k
    "NSString",
26
64.8k
    "NSArray",
27
64.8k
    "NSMutableArray",
28
64.8k
    "NSDictionary",
29
64.8k
    "NSMutableDictionary",
30
64.8k
    "NSNumber",
31
64.8k
    "NSMutableSet",
32
64.8k
    "NSMutableOrderedSet",
33
64.8k
    "NSValue"
34
64.8k
  };
35
36
64.8k
  if (!ClassIds[K])
37
9.19k
    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38
39
55.6k
  return ClassIds[K];
40
64.8k
}
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
75
29
  return NSStringSelectors[MK];
76
41
}
77
78
3.85k
Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79
3.85k
  if (NSArraySelectors[MK].isNull()) {
80
2.11k
    Selector Sel;
81
2.11k
    switch (MK) {
82
172
    case NSArr_array:
83
172
      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
84
172
      break;
85
172
    case NSArr_arrayWithArray:
86
172
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
87
172
      break;
88
172
    case NSArr_arrayWithObject:
89
172
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
90
172
      break;
91
172
    case NSArr_arrayWithObjects:
92
172
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
93
172
      break;
94
256
    case NSArr_arrayWithObjectsCount: {
95
256
      IdentifierInfo *KeyIdents[] = {
96
256
        &Ctx.Idents.get("arrayWithObjects"),
97
256
        &Ctx.Idents.get("count")
98
256
      };
99
256
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
100
256
      break;
101
0
    }
102
169
    case NSArr_initWithArray:
103
169
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
104
169
      break;
105
170
    case NSArr_initWithObjects:
106
170
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
107
170
      break;
108
174
    case NSArr_objectAtIndex:
109
174
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
110
174
      break;
111
171
    case NSMutableArr_replaceObjectAtIndex: {
112
171
      IdentifierInfo *KeyIdents[] = {
113
171
        &Ctx.Idents.get("replaceObjectAtIndex"),
114
171
        &Ctx.Idents.get("withObject")
115
171
      };
116
171
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
117
171
      break;
118
0
    }
119
165
    case NSMutableArr_addObject:
120
165
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
121
165
      break;
122
162
    case NSMutableArr_insertObjectAtIndex: {
123
162
      IdentifierInfo *KeyIdents[] = {
124
162
        &Ctx.Idents.get("insertObject"),
125
162
        &Ctx.Idents.get("atIndex")
126
162
      };
127
162
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128
162
      break;
129
0
    }
130
162
    case NSMutableArr_setObjectAtIndexedSubscript: {
131
162
      IdentifierInfo *KeyIdents[] = {
132
162
        &Ctx.Idents.get("setObject"),
133
162
        &Ctx.Idents.get("atIndexedSubscript")
134
162
      };
135
162
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
136
162
      break;
137
0
    }
138
2.11k
    }
139
2.11k
    return (NSArraySelectors[MK] = Sel);
140
2.11k
  }
141
142
1.73k
  return NSArraySelectors[MK];
143
3.85k
}
144
145
309
Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
146
3.71k
  for (unsigned i = 0; i != NumNSArrayMethods; 
++i3.40k
) {
147
3.52k
    NSArrayMethodKind MK = NSArrayMethodKind(i);
148
3.52k
    if (Sel == getNSArraySelector(MK))
149
118
      return MK;
150
3.52k
  }
151
152
191
  return None;
153
309
}
154
155
Selector NSAPI::getNSDictionarySelector(
156
2.99k
                                       NSDictionaryMethodKind MK) const {
157
2.99k
  if (NSDictionarySelectors[MK].isNull()) {
158
1.46k
    Selector Sel;
159
1.46k
    switch (MK) {
160
110
    case NSDict_dictionary:
161
110
      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
162
110
      break;
163
110
    case NSDict_dictionaryWithDictionary:
164
110
      Sel = Ctx.Selectors.getUnarySelector(
165
110
                                   &Ctx.Idents.get("dictionaryWithDictionary"));
166
110
      break;
167
110
    case NSDict_dictionaryWithObjectForKey: {
168
110
      IdentifierInfo *KeyIdents[] = {
169
110
        &Ctx.Idents.get("dictionaryWithObject"),
170
110
        &Ctx.Idents.get("forKey")
171
110
      };
172
110
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
173
110
      break;
174
0
    }
175
109
    case NSDict_dictionaryWithObjectsForKeys: {
176
109
      IdentifierInfo *KeyIdents[] = {
177
109
        &Ctx.Idents.get("dictionaryWithObjects"),
178
109
        &Ctx.Idents.get("forKeys")
179
109
      };
180
109
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
181
109
      break;
182
0
    }
183
177
    case NSDict_dictionaryWithObjectsForKeysCount: {
184
177
      IdentifierInfo *KeyIdents[] = {
185
177
        &Ctx.Idents.get("dictionaryWithObjects"),
186
177
        &Ctx.Idents.get("forKeys"),
187
177
        &Ctx.Idents.get("count")
188
177
      };
189
177
      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
190
177
      break;
191
0
    }
192
109
    case NSDict_dictionaryWithObjectsAndKeys:
193
109
      Sel = Ctx.Selectors.getUnarySelector(
194
109
                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
195
109
      break;
196
107
    case NSDict_initWithDictionary:
197
107
      Sel = Ctx.Selectors.getUnarySelector(
198
107
                                         &Ctx.Idents.get("initWithDictionary"));
199
107
      break;
200
109
    case NSDict_initWithObjectsAndKeys:
201
109
      Sel = Ctx.Selectors.getUnarySelector(
202
109
                                     &Ctx.Idents.get("initWithObjectsAndKeys"));
203
109
      break;
204
109
    case NSDict_initWithObjectsForKeys: {
205
109
      IdentifierInfo *KeyIdents[] = {
206
109
        &Ctx.Idents.get("initWithObjects"),
207
109
        &Ctx.Idents.get("forKeys")
208
109
      };
209
109
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
210
109
      break;
211
0
    }
212
112
    case NSDict_objectForKey:
213
112
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
214
112
      break;
215
109
    case NSMutableDict_setObjectForKey: {
216
109
      IdentifierInfo *KeyIdents[] = {
217
109
        &Ctx.Idents.get("setObject"),
218
109
        &Ctx.Idents.get("forKey")
219
109
      };
220
109
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221
109
      break;
222
0
    }
223
99
    case NSMutableDict_setObjectForKeyedSubscript: {
224
99
      IdentifierInfo *KeyIdents[] = {
225
99
        &Ctx.Idents.get("setObject"),
226
99
        &Ctx.Idents.get("forKeyedSubscript")
227
99
      };
228
99
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
229
99
      break;
230
0
    }
231
95
    case NSMutableDict_setValueForKey: {
232
95
      IdentifierInfo *KeyIdents[] = {
233
95
        &Ctx.Idents.get("setValue"),
234
95
        &Ctx.Idents.get("forKey")
235
95
      };
236
95
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
237
95
      break;
238
0
    }
239
1.46k
    }
240
1.46k
    return (NSDictionarySelectors[MK] = Sel);
241
1.46k
  }
242
243
1.53k
  return NSDictionarySelectors[MK];
244
2.99k
}
245
246
Optional<NSAPI::NSDictionaryMethodKind>
247
220
NSAPI::getNSDictionaryMethodKind(Selector Sel) {
248
2.84k
  for (unsigned i = 0; i != NumNSDictionaryMethods; 
++i2.62k
) {
249
2.71k
    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
250
2.71k
    if (Sel == getNSDictionarySelector(MK))
251
94
      return MK;
252
2.71k
  }
253
254
126
  return None;
255
220
}
256
257
405
Selector NSAPI::getNSSetSelector(NSSetMethodKind MK) const {
258
405
  if (NSSetSelectors[MK].isNull()) {
259
180
    Selector Sel;
260
180
    switch (MK) {
261
36
    case NSMutableSet_addObject:
262
36
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
263
36
      break;
264
36
    case NSOrderedSet_insertObjectAtIndex: {
265
36
      IdentifierInfo *KeyIdents[] = {
266
36
        &Ctx.Idents.get("insertObject"),
267
36
        &Ctx.Idents.get("atIndex")
268
36
      };
269
36
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
270
36
      break;
271
0
    }
272
36
    case NSOrderedSet_setObjectAtIndex: {
273
36
      IdentifierInfo *KeyIdents[] = {
274
36
        &Ctx.Idents.get("setObject"),
275
36
        &Ctx.Idents.get("atIndex")
276
36
      };
277
36
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
278
36
      break;
279
0
    }
280
36
    case NSOrderedSet_setObjectAtIndexedSubscript: {
281
36
      IdentifierInfo *KeyIdents[] = {
282
36
        &Ctx.Idents.get("setObject"),
283
36
        &Ctx.Idents.get("atIndexedSubscript")
284
36
      };
285
36
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
286
36
      break;
287
0
    }
288
36
    case NSOrderedSet_replaceObjectAtIndexWithObject: {
289
36
      IdentifierInfo *KeyIdents[] = {
290
36
        &Ctx.Idents.get("replaceObjectAtIndex"),
291
36
        &Ctx.Idents.get("withObject")
292
36
      };
293
36
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
294
36
      break;
295
0
    }
296
180
    }
297
180
    return (NSSetSelectors[MK] = Sel);
298
180
  }
299
300
225
  return NSSetSelectors[MK];
301
405
}
302
303
Optional<NSAPI::NSSetMethodKind>
304
119
NSAPI::getNSSetMethodKind(Selector Sel) {
305
474
  for (unsigned i = 0; i != NumNSSetMethods; 
++i355
) {
306
405
    NSSetMethodKind MK = NSSetMethodKind(i);
307
405
    if (Sel == getNSSetSelector(MK))
308
50
      return MK;
309
405
  }
310
311
69
  return None;
312
119
}
313
314
Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
315
8.98k
                                           bool Instance) const {
316
8.98k
  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
317
8.98k
    "numberWithChar",
318
8.98k
    "numberWithUnsignedChar",
319
8.98k
    "numberWithShort",
320
8.98k
    "numberWithUnsignedShort",
321
8.98k
    "numberWithInt",
322
8.98k
    "numberWithUnsignedInt",
323
8.98k
    "numberWithLong",
324
8.98k
    "numberWithUnsignedLong",
325
8.98k
    "numberWithLongLong",
326
8.98k
    "numberWithUnsignedLongLong",
327
8.98k
    "numberWithFloat",
328
8.98k
    "numberWithDouble",
329
8.98k
    "numberWithBool",
330
8.98k
    "numberWithInteger",
331
8.98k
    "numberWithUnsignedInteger"
332
8.98k
  };
333
8.98k
  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
334
8.98k
    "initWithChar",
335
8.98k
    "initWithUnsignedChar",
336
8.98k
    "initWithShort",
337
8.98k
    "initWithUnsignedShort",
338
8.98k
    "initWithInt",
339
8.98k
    "initWithUnsignedInt",
340
8.98k
    "initWithLong",
341
8.98k
    "initWithUnsignedLong",
342
8.98k
    "initWithLongLong",
343
8.98k
    "initWithUnsignedLongLong",
344
8.98k
    "initWithFloat",
345
8.98k
    "initWithDouble",
346
8.98k
    "initWithBool",
347
8.98k
    "initWithInteger",
348
8.98k
    "initWithUnsignedInteger"
349
8.98k
  };
350
351
8.98k
  Selector *Sels;
352
8.98k
  const char **Names;
353
8.98k
  if (Instance) {
354
3.94k
    Sels = NSNumberInstanceSelectors;
355
3.94k
    Names = InstanceSelectorName;
356
5.04k
  } else {
357
5.04k
    Sels = NSNumberClassSelectors;
358
5.04k
    Names = ClassSelectorName;
359
5.04k
  }
360
361
8.98k
  if (Sels[MK].isNull())
362
598
    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
363
8.98k
  return Sels[MK];
364
8.98k
}
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
374
0
  return None;
375
593
}
376
377
Optional<NSAPI::NSNumberLiteralMethodKind>
378
1.19k
NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
379
1.19k
  const BuiltinType *BT = T->getAs<BuiltinType>();
380
1.19k
  if (!BT)
381
0
    return None;
382
383
1.19k
  const TypedefType *TDT = T->getAs<TypedefType>();
384
1.19k
  if (TDT) {
385
16
    QualType TDTTy = QualType(TDT, 0);
386
16
    if (isObjCBOOLType(TDTTy))
387
10
      return NSAPI::NSNumberWithBool;
388
6
    if (isObjCNSIntegerType(TDTTy))
389
5
      return NSAPI::NSNumberWithInteger;
390
1
    if (isObjCNSUIntegerType(TDTTy))
391
1
      return NSAPI::NSNumberWithUnsignedInteger;
392
1
  }
393
394
1.18k
  switch (BT->getKind()) {
395
56
  case BuiltinType::Char_S:
396
61
  case BuiltinType::SChar:
397
61
    return NSAPI::NSNumberWithChar;
398
0
  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
560
  case BuiltinType::Int:
406
560
    return NSAPI::NSNumberWithInt;
407
54
  case BuiltinType::UInt:
408
54
    return NSAPI::NSNumberWithUnsignedInt;
409
55
  case BuiltinType::Long:
410
55
    return NSAPI::NSNumberWithLong;
411
21
  case BuiltinType::ULong:
412
21
    return NSAPI::NSNumberWithUnsignedLong;
413
58
  case BuiltinType::LongLong:
414
58
    return NSAPI::NSNumberWithLongLong;
415
48
  case BuiltinType::ULongLong:
416
48
    return NSAPI::NSNumberWithUnsignedLongLong;
417
61
  case BuiltinType::Float:
418
61
    return NSAPI::NSNumberWithFloat;
419
148
  case BuiltinType::Double:
420
148
    return NSAPI::NSNumberWithDouble;
421
112
  case BuiltinType::Bool:
422
112
    return NSAPI::NSNumberWithBool;
423
424
0
  case BuiltinType::Void:
425
0
  case BuiltinType::WChar_U:
426
0
  case BuiltinType::WChar_S:
427
0
  case BuiltinType::Char8:
428
0
  case BuiltinType::Char16:
429
0
  case BuiltinType::Char32:
430
0
  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
98
  case BuiltinType::Id:
476
98
#include 
"clang/Basic/AArch64SVEACLETypes.def"2
477
98
#define PPC_VECTOR_TYPE(Name, Id, Size) \
478
98
  
case BuiltinType::Id:4
479
98
#include 
"clang/Basic/PPCTypes.def"2
480
132
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
481
132
#include 
"clang/Basic/RISCVVTypes.def"2
482
132
  case BuiltinType::BoundMember:
483
2
  case BuiltinType::Dependent:
484
2
  case BuiltinType::Overload:
485
2
  case BuiltinType::UnknownAny:
486
2
  case BuiltinType::ARCUnbridgedCast:
487
2
  case BuiltinType::Half:
488
2
  case BuiltinType::PseudoObject:
489
2
  case BuiltinType::BuiltinFn:
490
2
  case BuiltinType::IncompleteMatrixIdx:
491
2
  case BuiltinType::OMPArraySection:
492
2
  case BuiltinType::OMPArrayShaping:
493
2
  case BuiltinType::OMPIterator:
494
2
  case BuiltinType::BFloat16:
495
2
    break;
496
1.18k
  }
497
498
2
  return None;
499
1.18k
}
500
501
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
502
25.8k
bool NSAPI::isObjCBOOLType(QualType T) const {
503
25.8k
  return isObjCTypedef(T, "BOOL", BOOLId);
504
25.8k
}
505
/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
506
48
bool NSAPI::isObjCNSIntegerType(QualType T) const {
507
48
  return isObjCTypedef(T, "NSInteger", NSIntegerId);
508
48
}
509
/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
510
43
bool NSAPI::isObjCNSUIntegerType(QualType T) const {
511
43
  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
512
43
}
513
514
50
StringRef NSAPI::GetNSIntegralKind(QualType T) const {
515
50
  if (!Ctx.getLangOpts().ObjC || T.isNull())
516
0
    return StringRef();
517
518
50
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
519
22
    StringRef NSIntegralResust =
520
22
      llvm::StringSwitch<StringRef>(
521
22
        TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
522
22
    .Case("int8_t", "int8_t")
523
22
    .Case("int16_t", "int16_t")
524
22
    .Case("int32_t", "int32_t")
525
22
    .Case("NSInteger", "NSInteger")
526
22
    .Case("int64_t", "int64_t")
527
22
    .Case("uint8_t", "uint8_t")
528
22
    .Case("uint16_t", "uint16_t")
529
22
    .Case("uint32_t", "uint32_t")
530
22
    .Case("NSUInteger", "NSUInteger")
531
22
    .Case("uint64_t", "uint64_t")
532
22
    .Default(StringRef());
533
22
    if (!NSIntegralResust.empty())
534
22
      return NSIntegralResust;
535
0
    T = TDT->desugar();
536
0
  }
537
28
  return StringRef();
538
50
}
539
540
122
bool NSAPI::isMacroDefined(StringRef Id) const {
541
  // FIXME: Check whether the relevant module macros are visible.
542
122
  return Ctx.Idents.get(Id).hasMacroDefinition();
543
122
}
544
545
bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
546
69.2k
                                NSClassIdKindKind NSClassKind) const {
547
69.2k
  if (!InterfaceDecl) {
548
9.77k
    return false;
549
9.77k
  }
550
551
59.5k
  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
552
553
59.5k
  bool IsSubclass = false;
554
107k
  do {
555
107k
    IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
556
557
107k
    if (IsSubclass) {
558
648
      break;
559
648
    }
560
107k
  } while (
(InterfaceDecl = InterfaceDecl->getSuperClass())107k
);
561
562
0
  return IsSubclass;
563
69.2k
}
564
565
bool NSAPI::isObjCTypedef(QualType T,
566
25.9k
                          StringRef name, IdentifierInfo *&II) const {
567
25.9k
  if (!Ctx.getLangOpts().ObjC)
568
199
    return false;
569
25.7k
  if (T.isNull())
570
0
    return false;
571
572
25.7k
  if (!II)
573
2.32k
    II = &Ctx.Idents.get(name);
574
575
43.3k
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
576
18.9k
    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
577
1.37k
      return true;
578
17.6k
    T = TDT->desugar();
579
17.6k
  }
580
581
24.4k
  return false;
582
25.7k
}
583
584
bool NSAPI::isObjCEnumerator(const Expr *E,
585
7
                             StringRef name, IdentifierInfo *&II) const {
586
7
  if (!Ctx.getLangOpts().ObjC)
587
0
    return false;
588
7
  if (!E)
589
0
    return false;
590
591
7
  if (!II)
592
2
    II = &Ctx.Idents.get(name);
593
594
7
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
595
7
    if (const EnumConstantDecl *
596
7
          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
597
5
      return EnumD->getIdentifier() == II;
598
599
2
  return false;
600
7
}
601
602
Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
603
149
                                  Selector &Sel) const {
604
149
  if (Sel.isNull()) {
605
15
    SmallVector<IdentifierInfo *, 4> Idents;
606
15
    for (ArrayRef<StringRef>::const_iterator
607
34
           I = Ids.begin(), E = Ids.end(); I != E; 
++I19
)
608
19
      Idents.push_back(&Ctx.Idents.get(*I));
609
15
    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
610
15
  }
611
149
  return Sel;
612
149
}
613
614
12.9k
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
615
12.9k
  if (Sel.isNull()) {
616
1.52k
    IdentifierInfo *Ident = &Ctx.Idents.get(Id);
617
1.52k
    Sel = Ctx.Selectors.getSelector(0, &Ident);
618
1.52k
  }
619
12.9k
  return Sel;
620
12.9k
}