Coverage Report

Created: 2020-10-24 06:27

/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
19.3k
    NSUTF8StringEncodingId(nullptr) {}
21
22
65.9k
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
23
65.9k
  static const char *ClassName[NumClassIds] = {
24
65.9k
    "NSObject",
25
65.9k
    "NSString",
26
65.9k
    "NSArray",
27
65.9k
    "NSMutableArray",
28
65.9k
    "NSDictionary",
29
65.9k
    "NSMutableDictionary",
30
65.9k
    "NSNumber",
31
65.9k
    "NSMutableSet",
32
65.9k
    "NSMutableOrderedSet",
33
65.9k
    "NSValue"
34
65.9k
  };
35
36
65.9k
  if (!ClassIds[K])
37
9.01k
    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38
39
56.8k
  return ClassIds[K];
40
56.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
29
}
77
78
3.86k
Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
79
3.86k
  if (NSArraySelectors[MK].isNull()) {
80
2.14k
    Selector Sel;
81
2.14k
    switch (MK) {
82
174
    case NSArr_array:
83
174
      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
84
174
      break;
85
174
    case NSArr_arrayWithArray:
86
174
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
87
174
      break;
88
174
    case NSArr_arrayWithObject:
89
174
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
90
174
      break;
91
174
    case NSArr_arrayWithObjects:
92
174
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
93
174
      break;
94
258
    case NSArr_arrayWithObjectsCount: {
95
258
      IdentifierInfo *KeyIdents[] = {
96
258
        &Ctx.Idents.get("arrayWithObjects"),
97
258
        &Ctx.Idents.get("count")
98
258
      };
99
258
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
100
258
      break;
101
0
    }
102
171
    case NSArr_initWithArray:
103
171
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
104
171
      break;
105
172
    case NSArr_initWithObjects:
106
172
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
107
172
      break;
108
176
    case NSArr_objectAtIndex:
109
176
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
110
176
      break;
111
173
    case NSMutableArr_replaceObjectAtIndex: {
112
173
      IdentifierInfo *KeyIdents[] = {
113
173
        &Ctx.Idents.get("replaceObjectAtIndex"),
114
173
        &Ctx.Idents.get("withObject")
115
173
      };
116
173
      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
117
173
      break;
118
0
    }
119
167
    case NSMutableArr_addObject:
120
167
      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
121
167
      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.14k
    }
138
2.14k
    }
139
2.14k
    return (NSArraySelectors[MK] = Sel);
140
2.14k
  }
141
142
1.71k
  return NSArraySelectors[MK];
143
1.71k
}
144
145
309
Optional<NSAPI::NSArrayMethodKind> NSAPI::getNSArrayMethodKind(Selector Sel) {
146
3.72k
  for (unsigned i = 0; i != NumNSArrayMethods; 
++i3.41k
) {
147
3.52k
    NSArrayMethodKind MK = NSArrayMethodKind(i);
148
3.52k
    if (Sel == getNSArraySelector(MK))
149
115
      return MK;
150
3.52k
  }
151
152
194
  return None;
153
309
}
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
31
  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
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
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
2
  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::IncompleteMatrixIdx:
486
2
  case BuiltinType::OMPArraySection:
487
2
  case BuiltinType::OMPArrayShaping:
488
2
  case BuiltinType::OMPIterator:
489
2
  case BuiltinType::BFloat16:
490
2
    break;
491
2
  }
492
493
2
  return None;
494
2
}
495
496
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
497
21.1k
bool NSAPI::isObjCBOOLType(QualType T) const {
498
21.1k
  return isObjCTypedef(T, "BOOL", BOOLId);
499
21.1k
}
500
/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
501
48
bool NSAPI::isObjCNSIntegerType(QualType T) const {
502
48
  return isObjCTypedef(T, "NSInteger", NSIntegerId);
503
48
}
504
/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
505
43
bool NSAPI::isObjCNSUIntegerType(QualType T) const {
506
43
  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
507
43
}
508
509
50
StringRef NSAPI::GetNSIntegralKind(QualType T) const {
510
50
  if (!Ctx.getLangOpts().ObjC || T.isNull())
511
0
    return StringRef();
512
513
50
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
514
22
    StringRef NSIntegralResust =
515
22
      llvm::StringSwitch<StringRef>(
516
22
        TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
517
22
    .Case("int8_t", "int8_t")
518
22
    .Case("int16_t", "int16_t")
519
22
    .Case("int32_t", "int32_t")
520
22
    .Case("NSInteger", "NSInteger")
521
22
    .Case("int64_t", "int64_t")
522
22
    .Case("uint8_t", "uint8_t")
523
22
    .Case("uint16_t", "uint16_t")
524
22
    .Case("uint32_t", "uint32_t")
525
22
    .Case("NSUInteger", "NSUInteger")
526
22
    .Case("uint64_t", "uint64_t")
527
22
    .Default(StringRef());
528
22
    if (!NSIntegralResust.empty())
529
22
      return NSIntegralResust;
530
0
    T = TDT->desugar();
531
0
  }
532
28
  return StringRef();
533
50
}
534
535
122
bool NSAPI::isMacroDefined(StringRef Id) const {
536
  // FIXME: Check whether the relevant module macros are visible.
537
122
  return Ctx.Idents.get(Id).hasMacroDefinition();
538
122
}
539
540
bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
541
70.5k
                                NSClassIdKindKind NSClassKind) const {
542
70.5k
  if (!InterfaceDecl) {
543
9.98k
    return false;
544
9.98k
  }
545
546
60.6k
  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
547
548
60.6k
  bool IsSubclass = false;
549
110k
  do {
550
110k
    IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
551
552
110k
    if (IsSubclass) {
553
654
      break;
554
654
    }
555
109k
  } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
556
557
60.6k
  return IsSubclass;
558
60.6k
}
559
560
bool NSAPI::isObjCTypedef(QualType T,
561
21.2k
                          StringRef name, IdentifierInfo *&II) const {
562
21.2k
  if (!Ctx.getLangOpts().ObjC)
563
203
    return false;
564
21.0k
  if (T.isNull())
565
0
    return false;
566
567
21.0k
  if (!II)
568
2.18k
    II = &Ctx.Idents.get(name);
569
570
36.4k
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
571
17.0k
    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
572
1.60k
      return true;
573
15.4k
    T = TDT->desugar();
574
15.4k
  }
575
576
19.4k
  return false;
577
21.0k
}
578
579
bool NSAPI::isObjCEnumerator(const Expr *E,
580
7
                             StringRef name, IdentifierInfo *&II) const {
581
7
  if (!Ctx.getLangOpts().ObjC)
582
0
    return false;
583
7
  if (!E)
584
0
    return false;
585
586
7
  if (!II)
587
2
    II = &Ctx.Idents.get(name);
588
589
7
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
590
7
    if (const EnumConstantDecl *
591
7
          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
592
5
      return EnumD->getIdentifier() == II;
593
594
2
  return false;
595
2
}
596
597
Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
598
149
                                  Selector &Sel) const {
599
149
  if (Sel.isNull()) {
600
15
    SmallVector<IdentifierInfo *, 4> Idents;
601
15
    for (ArrayRef<StringRef>::const_iterator
602
34
           I = Ids.begin(), E = Ids.end(); I != E; 
++I19
)
603
19
      Idents.push_back(&Ctx.Idents.get(*I));
604
15
    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
605
15
  }
606
149
  return Sel;
607
149
}
608
609
13.4k
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
610
13.4k
  if (Sel.isNull()) {
611
1.51k
    IdentifierInfo *Ident = &Ctx.Idents.get(Id);
612
1.51k
    Sel = Ctx.Selectors.getSelector(0, &Ident);
613
1.51k
  }
614
13.4k
  return Sel;
615
13.4k
}