clang  9.0.0svn
NSAPI.cpp
Go to the documentation of this file.
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 
18  : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
19  NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
20  NSUTF8StringEncodingId(nullptr) {}
21 
23  static const char *ClassName[NumClassIds] = {
24  "NSObject",
25  "NSString",
26  "NSArray",
27  "NSMutableArray",
28  "NSDictionary",
29  "NSMutableDictionary",
30  "NSNumber",
31  "NSMutableSet",
32  "NSMutableOrderedSet",
33  "NSValue"
34  };
35 
36  if (!ClassIds[K])
37  return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
38 
39  return ClassIds[K];
40 }
41 
43  if (NSStringSelectors[MK].isNull()) {
44  Selector Sel;
45  switch (MK) {
47  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
48  break;
50  Sel = Ctx.Selectors.getUnarySelector(
51  &Ctx.Idents.get("stringWithUTF8String"));
52  break;
54  Sel = Ctx.Selectors.getUnarySelector(
55  &Ctx.Idents.get("initWithUTF8String"));
56  break;
58  IdentifierInfo *KeyIdents[] = {
59  &Ctx.Idents.get("stringWithCString"),
60  &Ctx.Idents.get("encoding")
61  };
62  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
63  break;
64  }
66  Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
67  break;
69  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
70  break;
71  }
72  return (NSStringSelectors[MK] = Sel);
73  }
74 
75  return NSStringSelectors[MK];
76 }
77 
80  for (unsigned i = 0; i != NumNSStringMethods; ++i) {
82  if (Sel == getNSStringSelector(MK))
83  return MK;
84  }
85 
86  return None;
87 }
88 
90  if (NSArraySelectors[MK].isNull()) {
91  Selector Sel;
92  switch (MK) {
93  case NSArr_array:
94  Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
95  break;
97  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
98  break;
100  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
101  break;
103  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
104  break;
106  IdentifierInfo *KeyIdents[] = {
107  &Ctx.Idents.get("arrayWithObjects"),
108  &Ctx.Idents.get("count")
109  };
110  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
111  break;
112  }
113  case NSArr_initWithArray:
114  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
115  break;
117  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
118  break;
119  case NSArr_objectAtIndex:
120  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
121  break;
123  IdentifierInfo *KeyIdents[] = {
124  &Ctx.Idents.get("replaceObjectAtIndex"),
125  &Ctx.Idents.get("withObject")
126  };
127  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
128  break;
129  }
131  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
132  break;
134  IdentifierInfo *KeyIdents[] = {
135  &Ctx.Idents.get("insertObject"),
136  &Ctx.Idents.get("atIndex")
137  };
138  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
139  break;
140  }
142  IdentifierInfo *KeyIdents[] = {
143  &Ctx.Idents.get("setObject"),
144  &Ctx.Idents.get("atIndexedSubscript")
145  };
146  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
147  break;
148  }
149  }
150  return (NSArraySelectors[MK] = Sel);
151  }
152 
153  return NSArraySelectors[MK];
154 }
155 
157  for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
159  if (Sel == getNSArraySelector(MK))
160  return MK;
161  }
162 
163  return None;
164 }
165 
167  NSDictionaryMethodKind MK) const {
168  if (NSDictionarySelectors[MK].isNull()) {
169  Selector Sel;
170  switch (MK) {
171  case NSDict_dictionary:
172  Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
173  break;
175  Sel = Ctx.Selectors.getUnarySelector(
176  &Ctx.Idents.get("dictionaryWithDictionary"));
177  break;
179  IdentifierInfo *KeyIdents[] = {
180  &Ctx.Idents.get("dictionaryWithObject"),
181  &Ctx.Idents.get("forKey")
182  };
183  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
184  break;
185  }
187  IdentifierInfo *KeyIdents[] = {
188  &Ctx.Idents.get("dictionaryWithObjects"),
189  &Ctx.Idents.get("forKeys")
190  };
191  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
192  break;
193  }
195  IdentifierInfo *KeyIdents[] = {
196  &Ctx.Idents.get("dictionaryWithObjects"),
197  &Ctx.Idents.get("forKeys"),
198  &Ctx.Idents.get("count")
199  };
200  Sel = Ctx.Selectors.getSelector(3, KeyIdents);
201  break;
202  }
204  Sel = Ctx.Selectors.getUnarySelector(
205  &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
206  break;
208  Sel = Ctx.Selectors.getUnarySelector(
209  &Ctx.Idents.get("initWithDictionary"));
210  break;
212  Sel = Ctx.Selectors.getUnarySelector(
213  &Ctx.Idents.get("initWithObjectsAndKeys"));
214  break;
216  IdentifierInfo *KeyIdents[] = {
217  &Ctx.Idents.get("initWithObjects"),
218  &Ctx.Idents.get("forKeys")
219  };
220  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
221  break;
222  }
223  case NSDict_objectForKey:
224  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
225  break;
227  IdentifierInfo *KeyIdents[] = {
228  &Ctx.Idents.get("setObject"),
229  &Ctx.Idents.get("forKey")
230  };
231  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
232  break;
233  }
235  IdentifierInfo *KeyIdents[] = {
236  &Ctx.Idents.get("setObject"),
237  &Ctx.Idents.get("forKeyedSubscript")
238  };
239  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
240  break;
241  }
243  IdentifierInfo *KeyIdents[] = {
244  &Ctx.Idents.get("setValue"),
245  &Ctx.Idents.get("forKey")
246  };
247  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
248  break;
249  }
250  }
251  return (NSDictionarySelectors[MK] = Sel);
252  }
253 
254  return NSDictionarySelectors[MK];
255 }
256 
259  for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
261  if (Sel == getNSDictionarySelector(MK))
262  return MK;
263  }
264 
265  return None;
266 }
267 
269  if (NSSetSelectors[MK].isNull()) {
270  Selector Sel;
271  switch (MK) {
273  Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("addObject"));
274  break;
276  IdentifierInfo *KeyIdents[] = {
277  &Ctx.Idents.get("insertObject"),
278  &Ctx.Idents.get("atIndex")
279  };
280  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
281  break;
282  }
284  IdentifierInfo *KeyIdents[] = {
285  &Ctx.Idents.get("setObject"),
286  &Ctx.Idents.get("atIndex")
287  };
288  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
289  break;
290  }
292  IdentifierInfo *KeyIdents[] = {
293  &Ctx.Idents.get("setObject"),
294  &Ctx.Idents.get("atIndexedSubscript")
295  };
296  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
297  break;
298  }
300  IdentifierInfo *KeyIdents[] = {
301  &Ctx.Idents.get("replaceObjectAtIndex"),
302  &Ctx.Idents.get("withObject")
303  };
304  Sel = Ctx.Selectors.getSelector(2, KeyIdents);
305  break;
306  }
307  }
308  return (NSSetSelectors[MK] = Sel);
309  }
310 
311  return NSSetSelectors[MK];
312 }
313 
316  for (unsigned i = 0; i != NumNSSetMethods; ++i) {
318  if (Sel == getNSSetSelector(MK))
319  return MK;
320  }
321 
322  return None;
323 }
324 
326  bool Instance) const {
327  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
328  "numberWithChar",
329  "numberWithUnsignedChar",
330  "numberWithShort",
331  "numberWithUnsignedShort",
332  "numberWithInt",
333  "numberWithUnsignedInt",
334  "numberWithLong",
335  "numberWithUnsignedLong",
336  "numberWithLongLong",
337  "numberWithUnsignedLongLong",
338  "numberWithFloat",
339  "numberWithDouble",
340  "numberWithBool",
341  "numberWithInteger",
342  "numberWithUnsignedInteger"
343  };
344  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
345  "initWithChar",
346  "initWithUnsignedChar",
347  "initWithShort",
348  "initWithUnsignedShort",
349  "initWithInt",
350  "initWithUnsignedInt",
351  "initWithLong",
352  "initWithUnsignedLong",
353  "initWithLongLong",
354  "initWithUnsignedLongLong",
355  "initWithFloat",
356  "initWithDouble",
357  "initWithBool",
358  "initWithInteger",
359  "initWithUnsignedInteger"
360  };
361 
362  Selector *Sels;
363  const char **Names;
364  if (Instance) {
365  Sels = NSNumberInstanceSelectors;
366  Names = InstanceSelectorName;
367  } else {
368  Sels = NSNumberClassSelectors;
369  Names = ClassSelectorName;
370  }
371 
372  if (Sels[MK].isNull())
373  Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
374  return Sels[MK];
375 }
376 
379  for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
381  if (isNSNumberLiteralSelector(MK, Sel))
382  return MK;
383  }
384 
385  return None;
386 }
387 
390  const BuiltinType *BT = T->getAs<BuiltinType>();
391  if (!BT)
392  return None;
393 
394  const TypedefType *TDT = T->getAs<TypedefType>();
395  if (TDT) {
396  QualType TDTTy = QualType(TDT, 0);
397  if (isObjCBOOLType(TDTTy))
399  if (isObjCNSIntegerType(TDTTy))
401  if (isObjCNSUIntegerType(TDTTy))
403  }
404 
405  switch (BT->getKind()) {
406  case BuiltinType::Char_S:
407  case BuiltinType::SChar:
409  case BuiltinType::Char_U:
410  case BuiltinType::UChar:
412  case BuiltinType::Short:
414  case BuiltinType::UShort:
416  case BuiltinType::Int:
417  return NSAPI::NSNumberWithInt;
418  case BuiltinType::UInt:
420  case BuiltinType::Long:
422  case BuiltinType::ULong:
424  case BuiltinType::LongLong:
426  case BuiltinType::ULongLong:
428  case BuiltinType::Float:
430  case BuiltinType::Double:
432  case BuiltinType::Bool:
434 
435  case BuiltinType::Void:
436  case BuiltinType::WChar_U:
437  case BuiltinType::WChar_S:
438  case BuiltinType::Char8:
439  case BuiltinType::Char16:
440  case BuiltinType::Char32:
441  case BuiltinType::Int128:
442  case BuiltinType::LongDouble:
443  case BuiltinType::ShortAccum:
444  case BuiltinType::Accum:
445  case BuiltinType::LongAccum:
446  case BuiltinType::UShortAccum:
447  case BuiltinType::UAccum:
448  case BuiltinType::ULongAccum:
449  case BuiltinType::ShortFract:
450  case BuiltinType::Fract:
451  case BuiltinType::LongFract:
452  case BuiltinType::UShortFract:
453  case BuiltinType::UFract:
454  case BuiltinType::ULongFract:
455  case BuiltinType::SatShortAccum:
456  case BuiltinType::SatAccum:
457  case BuiltinType::SatLongAccum:
458  case BuiltinType::SatUShortAccum:
459  case BuiltinType::SatUAccum:
460  case BuiltinType::SatULongAccum:
461  case BuiltinType::SatShortFract:
462  case BuiltinType::SatFract:
463  case BuiltinType::SatLongFract:
464  case BuiltinType::SatUShortFract:
465  case BuiltinType::SatUFract:
466  case BuiltinType::SatULongFract:
467  case BuiltinType::UInt128:
468  case BuiltinType::Float16:
469  case BuiltinType::Float128:
470  case BuiltinType::NullPtr:
471  case BuiltinType::ObjCClass:
472  case BuiltinType::ObjCId:
473  case BuiltinType::ObjCSel:
474 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
475  case BuiltinType::Id:
476 #include "clang/Basic/OpenCLImageTypes.def"
477 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
478  case BuiltinType::Id:
479 #include "clang/Basic/OpenCLExtensionTypes.def"
480  case BuiltinType::OCLSampler:
481  case BuiltinType::OCLEvent:
482  case BuiltinType::OCLClkEvent:
483  case BuiltinType::OCLQueue:
484  case BuiltinType::OCLReserveID:
485  case BuiltinType::BoundMember:
486  case BuiltinType::Dependent:
487  case BuiltinType::Overload:
488  case BuiltinType::UnknownAny:
489  case BuiltinType::ARCUnbridgedCast:
490  case BuiltinType::Half:
491  case BuiltinType::PseudoObject:
492  case BuiltinType::BuiltinFn:
493  case BuiltinType::OMPArraySection:
494  break;
495  }
496 
497  return None;
498 }
499 
500 /// Returns true if \param T is a typedef of "BOOL" in objective-c.
502  return isObjCTypedef(T, "BOOL", BOOLId);
503 }
504 /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
506  return isObjCTypedef(T, "NSInteger", NSIntegerId);
507 }
508 /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
510  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
511 }
512 
513 StringRef NSAPI::GetNSIntegralKind(QualType T) const {
514  if (!Ctx.getLangOpts().ObjC || T.isNull())
515  return StringRef();
516 
517  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
518  StringRef NSIntegralResust =
519  llvm::StringSwitch<StringRef>(
520  TDT->getDecl()->getDeclName().getAsIdentifierInfo()->getName())
521  .Case("int8_t", "int8_t")
522  .Case("int16_t", "int16_t")
523  .Case("int32_t", "int32_t")
524  .Case("NSInteger", "NSInteger")
525  .Case("int64_t", "int64_t")
526  .Case("uint8_t", "uint8_t")
527  .Case("uint16_t", "uint16_t")
528  .Case("uint32_t", "uint32_t")
529  .Case("NSUInteger", "NSUInteger")
530  .Case("uint64_t", "uint64_t")
531  .Default(StringRef());
532  if (!NSIntegralResust.empty())
533  return NSIntegralResust;
534  T = TDT->desugar();
535  }
536  return StringRef();
537 }
538 
539 bool NSAPI::isMacroDefined(StringRef Id) const {
540  // FIXME: Check whether the relevant module macros are visible.
541  return Ctx.Idents.get(Id).hasMacroDefinition();
542 }
543 
545  NSClassIdKindKind NSClassKind) const {
546  if (!InterfaceDecl) {
547  return false;
548  }
549 
550  IdentifierInfo *NSClassID = getNSClassId(NSClassKind);
551 
552  bool IsSubclass = false;
553  do {
554  IsSubclass = NSClassID == InterfaceDecl->getIdentifier();
555 
556  if (IsSubclass) {
557  break;
558  }
559  } while ((InterfaceDecl = InterfaceDecl->getSuperClass()));
560 
561  return IsSubclass;
562 }
563 
564 bool NSAPI::isObjCTypedef(QualType T,
565  StringRef name, IdentifierInfo *&II) const {
566  if (!Ctx.getLangOpts().ObjC)
567  return false;
568  if (T.isNull())
569  return false;
570 
571  if (!II)
572  II = &Ctx.Idents.get(name);
573 
574  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
575  if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
576  return true;
577  T = TDT->desugar();
578  }
579 
580  return false;
581 }
582 
583 bool NSAPI::isObjCEnumerator(const Expr *E,
584  StringRef name, IdentifierInfo *&II) const {
585  if (!Ctx.getLangOpts().ObjC)
586  return false;
587  if (!E)
588  return false;
589 
590  if (!II)
591  II = &Ctx.Idents.get(name);
592 
593  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
594  if (const EnumConstantDecl *
595  EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
596  return EnumD->getIdentifier() == II;
597 
598  return false;
599 }
600 
601 Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
602  Selector &Sel) const {
603  if (Sel.isNull()) {
606  I = Ids.begin(), E = Ids.end(); I != E; ++I)
607  Idents.push_back(&Ctx.Idents.get(*I));
608  Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
609  }
610  return Sel;
611 }
612 
613 Selector NSAPI::getOrInitNullarySelector(StringRef Id, Selector &Sel) const {
614  if (Sel.isNull()) {
615  IdentifierInfo *Ident = &Ctx.Idents.get(Id);
616  Sel = Ctx.Selectors.getSelector(0, &Ident);
617  }
618  return Sel;
619 }
Optional< NSNumberLiteralMethodKind > getNSNumberFactoryMethodKind(QualType T) const
Determine the appropriate NSNumber factory method kind for a literal of the given type...
Definition: NSAPI.cpp:389
Defines the clang::ASTContext interface.
Smart pointer class that efficiently represents Objective-C method names.
A (possibly-)qualified type.
Definition: Type.h:637
Kind getKind() const
Definition: Type.h:2420
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:2785
Optional< NSDictionaryMethodKind > getNSDictionaryMethodKind(Selector Sel)
Return NSDictionaryMethodKind if Sel is such a selector.
Definition: NSAPI.cpp:258
NSNumberLiteralMethodKind
Enumerates the NSNumber methods used to generate literals.
Definition: NSAPI.h:177
NSDictionaryMethodKind
Enumerates the NSDictionary/NSMutableDictionary methods used to generate literals and to apply some c...
Definition: NSAPI.h:99
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6754
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
Selector getUnarySelector(IdentifierInfo *ID)
One of these records is kept for each identifier that is lexed.
Optional< NSSetMethodKind > getNSSetMethodKind(Selector Sel)
Return NSSetMethodKind if Sel is such a selector.
Definition: NSAPI.cpp:315
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
Selector getNSStringSelector(NSStringMethodKind MK) const
The Objective-C NSString selectors.
Definition: NSAPI.cpp:42
Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, bool Instance) const
The Objective-C NSNumber selectors used to create NSNumber literals.
Definition: NSAPI.cpp:325
IdentifierTable & Idents
Definition: ASTContext.h:565
Optional< NSNumberLiteralMethodKind > getNSNumberLiteralMethodKind(Selector Sel) const
Return NSNumberLiteralMethodKind if Sel is such a selector.
Definition: NSAPI.cpp:378
Selector getNullarySelector(IdentifierInfo *ID)
static const unsigned NumClassIds
Definition: NSAPI.h:41
static const unsigned NumNSNumberLiteralMethods
Definition: NSAPI.h:194
NSSetMethodKind
Enumerates the NSMutableSet/NSOrderedSet methods used to apply some checks.
Definition: NSAPI.h:124
NSAPI(ASTContext &Ctx)
Definition: NSAPI.cpp:17
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
static const unsigned NumNSSetMethods
Definition: NSAPI.h:131
NSClassIdKindKind
Definition: NSAPI.h:29
NSArrayMethodKind
Enumerates the NSArray/NSMutableArray methods used to generate literals and to apply some checks...
Definition: NSAPI.h:75
This represents one expression.
Definition: Expr.h:106
Selector getNSArraySelector(NSArrayMethodKind MK) const
The Objective-C NSArray selectors.
Definition: NSAPI.cpp:89
int Id
Definition: ASTDiff.cpp:190
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:337
StringRef GetNSIntegralKind(QualType T) const
Returns one of NSIntegral typedef names if.
Definition: NSAPI.cpp:513
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:702
SelectorTable & Selectors
Definition: ASTContext.h:566
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool isObjCBOOLType(QualType T) const
Returns true if.
Definition: NSAPI.cpp:501
bool isObjCNSUIntegerType(QualType T) const
Returns true if.
Definition: NSAPI.cpp:509
Selector getNSSetSelector(NSSetMethodKind MK) const
The Objective-C NSSet selectors.
Definition: NSAPI.cpp:268
bool isObjCNSIntegerType(QualType T) const
Returns true if.
Definition: NSAPI.cpp:505
bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl, NSClassIdKindKind NSClassKind) const
Returns true if InterfaceDecl is subclass of NSClassKind.
Definition: NSAPI.cpp:544
NSStringMethodKind
Definition: NSAPI.h:43
IdentifierInfo * getNSClassId(NSClassIdKindKind K) const
Definition: NSAPI.cpp:22
Optional< NSStringMethodKind > getNSStringMethodKind(Selector Sel) const
Return NSStringMethodKind if.
Definition: NSAPI.cpp:79
Dataflow Directional Tag Classes.
bool isMacroDefined(StringRef Id) const
Returns true if Id is currently defined as a macro.
Definition: NSAPI.cpp:539
bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, Selector Sel) const
Definition: NSAPI.h:202
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2692
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
static const unsigned NumNSArrayMethods
Definition: NSAPI.h:89
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const
The Objective-C NSDictionary selectors.
Definition: NSAPI.cpp:166
static const unsigned NumNSDictionaryMethods
Definition: NSAPI.h:114
bool isNull() const
Determine whether this is the empty selector.
This class is used for builtin types like &#39;int&#39;.
Definition: Type.h:2393
Optional< NSArrayMethodKind > getNSArrayMethodKind(Selector Sel)
Return NSArrayMethodKind if Sel is such a selector.
Definition: NSAPI.cpp:156
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1047
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:706
static const unsigned NumNSStringMethods
Definition: NSAPI.h:51