Coverage Report

Created: 2021-02-23 11:24

/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
20.1k
    NSUTF8StringEncodingId(nullptr) {}
21
22
66.2k
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23
66.2k
  static const char *ClassName[NumClassIds] = {
24
66.2k
    "NSObject",
25
66.2k
    "NSString",
26
66.2k
    "NSArray",
27
66.2k
    "NSMutableArray",
28
66.2k
    "NSDictionary",
29
66.2k
    "NSMutableDictionary",
30
66.2k
    "NSNumber",
31
66.2k
    "NSMutableSet",
32
66.2k
    "NSMutableOrderedSet",
33
66.2k
    "NSValue"
34
66.2k
  };
35
36
66.2k
  if (!ClassIds[K])
37
9.14k
    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38
39
57.1k
  return ClassIds[K];
40
57.1k
}
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
29
}
77
78
3.89k
Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79
3.89k
  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
142
1.73k
  return NSArraySelectors[MK];
143
1.73k
}
144
145
312
Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
146
3.75k
  for (unsigned i = 0; i != NumNSArrayMethods; 
++i3.43k
) {
147
3.55k
    NSArrayMethodKind MK = NSArrayMethodKind(i);
148
3.55k
    if (Sel == getNSArraySelector(MK))
149
118
      return MK;
150
3.55k
  }
151
152
194
  return None;
153
312
}
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
180
    case NSDict_dictionaryWithObjectsForKeysCount: {
184
180
      IdentifierInfo *KeyIdents[] = {
185
180
        &Ctx.Idents.get("dictionaryWithObjects"),
186
180
        &Ctx.Idents.get("forKeys"),
187
180
        &Ctx.Idents.get("count")
188
180
      };
189
180
      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
190
180
      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
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
254
129
  return None;
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
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
311
72
  return None;
312
122
}
313
314
Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
315
8.81k
                                           bool Instance) const {
316
8.81k
  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
317
8.81k
    "numberWithChar",
318
8.81k
    "numberWithUnsignedChar",
319
8.81k
    "numberWithShort",
320
8.81k
    "numberWithUnsignedShort",
321
8.81k
    "numberWithInt",
322
8.81k
    "numberWithUnsignedInt",
323
8.81k
    "numberWithLong",
324
8.81k
    "numberWithUnsignedLong",
325
8.81k
    "numberWithLongLong",
326
8.81k
    "numberWithUnsignedLongLong",
327
8.81k
    "numberWithFloat",
328
8.81k
    "numberWithDouble",
329
8.81k
    "numberWithBool",
330
8.81k
    "numberWithInteger",
331
8.81k
    "numberWithUnsignedInteger"
332
8.81k
  };
333
8.81k
  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
334
8.81k
    "initWithChar",
335
8.81k
    "initWithUnsignedChar",
336
8.81k
    "initWithShort",
337
8.81k
    "initWithUnsignedShort",
338
8.81k
    "initWithInt",
339
8.81k
    "initWithUnsignedInt",
340
8.81k
    "initWithLong",
341
8.81k
    "initWithUnsignedLong",
342
8.81k
    "initWithLongLong",
343
8.81k
    "initWithUnsignedLongLong",
344
8.81k
    "initWithFloat",
345
8.81k
    "initWithDouble",
346
8.81k
    "initWithBool",
347
8.81k
    "initWithInteger",
348
8.81k
    "initWithUnsignedInteger"
349
8.81k
  };
350
351
8.81k
  Selector *Sels;
352
8.81k
  const char **Names;
353
8.81k
  if (Instance) {
354
3.94k
    Sels = NSNumberInstanceSelectors;
355
3.94k
    Names = InstanceSelectorName;
356
4.87k
  } else {
357
4.87k
    Sels = NSNumberClassSelectors;
358
4.87k
    Names = ClassSelectorName;
359
4.87k
  }
360
361
8.81k
  if (Sels[MK].isNull())
362
424
    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
363
8.81k
  return Sels[MK];
364
8.81k
}
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
974
NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
379
974
  const BuiltinType *BT = T->getAs<BuiltinType>();
380
974
  if (!BT)
381
0
    return None;
382
383
974
  const TypedefType *TDT = T->getAs<TypedefType>();
384
974
  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
958
  }
393
394
958
  switch (BT->getKind()) {
395
26
  case BuiltinType::Char_S:
396
31
  case BuiltinType::SChar:
397
31
    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
572
  case BuiltinType::Int:
406
572
    return NSAPI::NSNumberWithInt;
407
54
  case BuiltinType::UInt:
408
54
    return NSAPI::NSNumberWithUnsignedInt;
409
25
  case BuiltinType::Long:
410
25
    return NSAPI::NSNumberWithLong;
411
21
  case BuiltinType::ULong:
412
21
    return NSAPI::NSNumberWithUnsignedLong;
413
28
  case BuiltinType::LongLong:
414
28
    return NSAPI::NSNumberWithLongLong;
415
18
  case BuiltinType::ULongLong:
416
18
    return NSAPI::NSNumberWithUnsignedLongLong;
417
31
  case BuiltinType::Float:
418
31
    return NSAPI::NSNumberWithFloat;
419
124
  case BuiltinType::Double:
420
124
    return NSAPI::NSNumberWithDouble;
421
52
  case BuiltinType::Bool:
422
52
    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
24
  case BuiltinType::Id:
468
24
#include 
"clang/Basic/OpenCLExtensionTypes.def"2
469
2
  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
4
  case BuiltinType::Id:
479
4
#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
2
  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
2
  }
497
498
2
  return None;
499
2
}
500
501
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
502
21.4k
bool NSAPI::isObjCBOOLType(QualType T) const {
503
21.4k
  return isObjCTypedef(T, "BOOL", BOOLId);
504
21.4k
}
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
70.9k
                                NSClassIdKindKind NSClassKind) const {
547
70.9k
  if (!InterfaceDecl) {
548
9.98k
    return false;
549
9.98k
  }
550
551
60.9k
  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
552
553
60.9k
  bool IsSubclass = false;
554
111k
  do {
555
111k
    IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
556
557
111k
    if (IsSubclass) {
558
657
      break;
559
657
    }
560
110k
  } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
561
562
60.9k
  return IsSubclass;
563
60.9k
}
564
565
bool NSAPI::isObjCTypedef(QualType T,
566
21.5k
                          StringRef name, IdentifierInfo *&II) const {
567
21.5k
  if (!Ctx.getLangOpts().ObjC)
568
193
    return false;
569
21.3k
  if (T.isNull())
570
0
    return false;
571
572
21.3k
  if (!II)
573
2.21k
    II = &Ctx.Idents.get(name);
574
575
37.0k
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
576
17.2k
    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
577
1.61k
      return true;
578
15.6k
    T = TDT->desugar();
579
15.6k
  }
580
581
19.7k
  return false;
582
21.3k
}
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
2
}
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
13.4k
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
615
13.4k
  if (Sel.isNull()) {
616
1.51k
    IdentifierInfo *Ident = &Ctx.Idents.get(Id);
617
1.51k
    Sel = Ctx.Selectors.getSelector(0, &Ident);
618
1.51k
  }
619
13.4k
  return Sel;
620
13.4k
}