Coverage Report

Created: 2022-01-25 06:29

/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
22.7k
    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.21k
    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::Ibm128:
460
2
  case BuiltinType::NullPtr:
461
2
  case BuiltinType::ObjCClass:
462
2
  case BuiltinType::ObjCId:
463
2
  case BuiltinType::ObjCSel:
464
2
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
465
72
  case BuiltinType::Id:
466
72
#include 
"clang/Basic/OpenCLImageTypes.def"2
467
72
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
468
72
  
case BuiltinType::Id:24
469
72
#include 
"clang/Basic/OpenCLExtensionTypes.def"2
470
24
  case BuiltinType::OCLSampler:
471
2
  case BuiltinType::OCLEvent:
472
2
  case BuiltinType::OCLClkEvent:
473
2
  case BuiltinType::OCLQueue:
474
2
  case BuiltinType::OCLReserveID:
475
2
#define SVE_TYPE(Name, Id, SingletonId) \
476
98
  case BuiltinType::Id:
477
98
#include 
"clang/Basic/AArch64SVEACLETypes.def"2
478
98
#define PPC_VECTOR_TYPE(Name, Id, Size) \
479
98
  
case BuiltinType::Id:4
480
98
#include 
"clang/Basic/PPCTypes.def"2
481
132
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
482
132
#include 
"clang/Basic/RISCVVTypes.def"2
483
132
  case BuiltinType::BoundMember:
484
2
  case BuiltinType::Dependent:
485
2
  case BuiltinType::Overload:
486
2
  case BuiltinType::UnknownAny:
487
2
  case BuiltinType::ARCUnbridgedCast:
488
2
  case BuiltinType::Half:
489
2
  case BuiltinType::PseudoObject:
490
2
  case BuiltinType::BuiltinFn:
491
2
  case BuiltinType::IncompleteMatrixIdx:
492
2
  case BuiltinType::OMPArraySection:
493
2
  case BuiltinType::OMPArrayShaping:
494
2
  case BuiltinType::OMPIterator:
495
2
  case BuiltinType::BFloat16:
496
2
    break;
497
1.18k
  }
498
499
2
  return None;
500
1.18k
}
501
502
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
503
25.7k
bool NSAPI::isObjCBOOLType(QualType T) const {
504
25.7k
  return isObjCTypedef(T, "BOOL", BOOLId);
505
25.7k
}
506
/// Returns true if \param T is a typedef of "NSInteger" in objective-c.
507
48
bool NSAPI::isObjCNSIntegerType(QualType T) const {
508
48
  return isObjCTypedef(T, "NSInteger", NSIntegerId);
509
48
}
510
/// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
511
43
bool NSAPI::isObjCNSUIntegerType(QualType T) const {
512
43
  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
513
43
}
514
515
50
StringRef NSAPI::GetNSIntegralKind(QualType T) const {
516
50
  if (!Ctx.getLangOpts().ObjC || T.isNull())
517
0
    return StringRef();
518
519
50
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
520
22
    StringRef NSIntegralResust =
521
22
      llvm::StringSwitch<StringRef>(
522
22
        TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
523
22
    .Case("int8_t", "int8_t")
524
22
    .Case("int16_t", "int16_t")
525
22
    .Case("int32_t", "int32_t")
526
22
    .Case("NSInteger", "NSInteger")
527
22
    .Case("int64_t", "int64_t")
528
22
    .Case("uint8_t", "uint8_t")
529
22
    .Case("uint16_t", "uint16_t")
530
22
    .Case("uint32_t", "uint32_t")
531
22
    .Case("NSUInteger", "NSUInteger")
532
22
    .Case("uint64_t", "uint64_t")
533
22
    .Default(StringRef());
534
22
    if (!NSIntegralResust.empty())
535
22
      return NSIntegralResust;
536
0
    T = TDT->desugar();
537
0
  }
538
28
  return StringRef();
539
50
}
540
541
122
bool NSAPI::isMacroDefined(StringRef Id) const {
542
  // FIXME: Check whether the relevant module macros are visible.
543
122
  return Ctx.Idents.get(Id).hasMacroDefinition();
544
122
}
545
546
bool NSAPI::isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
547
69.3k
                                NSClassIdKindKind NSClassKind) const {
548
69.3k
  if (!InterfaceDecl) {
549
9.80k
    return false;
550
9.80k
  }
551
552
59.5k
  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
553
554
59.5k
  bool IsSubclass = false;
555
107k
  do {
556
107k
    IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
557
558
107k
    if (IsSubclass) {
559
648
      break;
560
648
    }
561
107k
  } while (
(InterfaceDecl = InterfaceDecl->getSuperClass())107k
);
562
563
0
  return IsSubclass;
564
69.3k
}
565
566
bool NSAPI::isObjCTypedef(QualType T,
567
25.8k
                          StringRef name, IdentifierInfo *&II) const {
568
25.8k
  if (!Ctx.getLangOpts().ObjC)
569
209
    return false;
570
25.6k
  if (T.isNull())
571
0
    return false;
572
573
25.6k
  if (!II)
574
2.31k
    II = &Ctx.Idents.get(name);
575
576
43.1k
  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
577
18.8k
    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
578
1.37k
      return true;
579
17.5k
    T = TDT->desugar();
580
17.5k
  }
581
582
24.2k
  return false;
583
25.6k
}
584
585
bool NSAPI::isObjCEnumerator(const Expr *E,
586
7
                             StringRef name, IdentifierInfo *&II) const {
587
7
  if (!Ctx.getLangOpts().ObjC)
588
0
    return false;
589
7
  if (!E)
590
0
    return false;
591
592
7
  if (!II)
593
2
    II = &Ctx.Idents.get(name);
594
595
7
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
596
7
    if (const EnumConstantDecl *
597
7
          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
598
5
      return EnumD->getIdentifier() == II;
599
600
2
  return false;
601
7
}
602
603
Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
604
149
                                  Selector &Sel) const {
605
149
  if (Sel.isNull()) {
606
15
    SmallVector<IdentifierInfo *, 4> Idents;
607
15
    for (ArrayRef<StringRef>::const_iterator
608
34
           I = Ids.begin(), E = Ids.end(); I != E; 
++I19
)
609
19
      Idents.push_back(&Ctx.Idents.get(*I));
610
15
    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
611
15
  }
612
149
  return Sel;
613
149
}
614
615
12.8k
Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
616
12.8k
  if (Sel.isNull()) {
617
1.52k
    IdentifierInfo *Ident = &Ctx.Idents.get(Id);
618
1.52k
    Sel = Ctx.Selectors.getSelector(0, &Ident);
619
1.52k
  }
620
12.8k
  return Sel;
621
12.8k
}