33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/ADT/StringMap.h" 35 #include "llvm/Support/raw_ostream.h" 37 using namespace clang;
42 class APIMisuse :
public BugType {
44 APIMisuse(
const CheckerBase *checker,
const char *name)
45 : BugType(checker, name,
"API Misuse (Apple)") {}
55 return ID->getIdentifier()->getName();
71 bool IncludeSuperclasses =
true) {
72 static llvm::StringMap<FoundationClass> Classes;
73 if (Classes.empty()) {
85 if (result ==
FC_None && IncludeSuperclasses)
97 class NilArgChecker :
public Checker<check::PreObjCMessage,
98 check::PostStmt<ObjCDictionaryLiteral>,
99 check::PostStmt<ObjCArrayLiteral> > {
100 mutable std::unique_ptr<APIMisuse> BT;
102 mutable llvm::SmallDenseMap<Selector, unsigned, 16> StringSelectors;
103 mutable Selector ArrayWithObjectSel;
105 mutable Selector InsertObjectAtIndexSel;
106 mutable Selector ReplaceObjectAtIndexWithObjectSel;
107 mutable Selector SetObjectAtIndexedSubscriptSel;
108 mutable Selector ArrayByAddingObjectSel;
109 mutable Selector DictionaryWithObjectForKeySel;
110 mutable Selector SetObjectForKeySel;
111 mutable Selector SetObjectForKeyedSubscriptSel;
112 mutable Selector RemoveObjectForKeySel;
114 void warnIfNilExpr(
const Expr *E,
116 CheckerContext &C)
const;
118 void warnIfNilArg(CheckerContext &C,
121 bool CanBeSubscript =
false)
const;
123 void generateBugReport(ExplodedNode *N,
127 CheckerContext &C)
const;
130 void checkPreObjCMessage(
const ObjCMethodCall &M, CheckerContext &C)
const;
132 CheckerContext &C)
const;
134 CheckerContext &C)
const;
138 void NilArgChecker::warnIfNilExpr(
const Expr *E,
140 CheckerContext &C)
const {
142 if (State->isNull(C.getSVal(E)).isConstrainedTrue()) {
144 if (ExplodedNode *N = C.generateErrorNode()) {
150 void NilArgChecker::warnIfNilArg(CheckerContext &C,
154 bool CanBeSubscript)
const {
157 if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
165 if (ExplodedNode *N = C.generateErrorNode()) {
167 llvm::raw_svector_ostream os(sbuf);
172 os <<
"Array element cannot be nil";
175 os <<
"Value stored into '";
182 llvm_unreachable(
"Missing foundation class for the subscript expr");
187 os <<
"Value argument ";
190 os <<
"Key argument ";
194 os <<
"' cannot be nil";
198 os <<
"' cannot be nil";
202 generateBugReport(N, os.str(), msg.getArgSourceRange(Arg),
207 void NilArgChecker::generateBugReport(ExplodedNode *N,
211 CheckerContext &C)
const {
213 BT.reset(
new APIMisuse(
this,
"nil argument"));
215 auto R = llvm::make_unique<BugReport>(*BT, Msg, N);
217 bugreporter::trackExpressionValue(N, E, *R);
218 C.emitReport(std::move(R));
221 void NilArgChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
222 CheckerContext &C)
const {
229 static const unsigned InvalidArgIndex =
UINT_MAX;
230 unsigned Arg = InvalidArgIndex;
231 bool CanBeSubscript =
false;
239 if (StringSelectors.empty()) {
254 StringSelectors[KnownSel] = 0;
256 auto I = StringSelectors.find(S);
257 if (I == StringSelectors.end())
266 if (ArrayWithObjectSel.isNull()) {
270 InsertObjectAtIndexSel =
272 ReplaceObjectAtIndexWithObjectSel =
274 SetObjectAtIndexedSubscriptSel =
279 if (S == ArrayWithObjectSel || S == AddObjectSel ||
280 S == InsertObjectAtIndexSel || S == ArrayByAddingObjectSel) {
282 }
else if (S == SetObjectAtIndexedSubscriptSel) {
284 CanBeSubscript =
true;
285 }
else if (S == ReplaceObjectAtIndexWithObjectSel) {
294 if (DictionaryWithObjectForKeySel.isNull()) {
296 DictionaryWithObjectForKeySel =
299 SetObjectForKeyedSubscriptSel =
304 if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) {
306 warnIfNilArg(C, msg, 1, Class);
307 }
else if (S == SetObjectForKeyedSubscriptSel) {
308 CanBeSubscript =
true;
310 }
else if (S == RemoveObjectForKeySel) {
316 if ((Arg != InvalidArgIndex))
317 warnIfNilArg(C, msg, Arg, Class, CanBeSubscript);
321 CheckerContext &C)
const {
323 for (
unsigned i = 0; i < NumOfElements; ++i) {
324 warnIfNilExpr(AL->
getElement(i),
"Array element cannot be nil", C);
329 CheckerContext &C)
const {
331 for (
unsigned i = 0; i < NumOfElements; ++i) {
333 warnIfNilExpr(Element.
Key,
"Dictionary key cannot be nil", C);
334 warnIfNilExpr(Element.
Value,
"Dictionary value cannot be nil", C);
343 class CFNumberChecker :
public Checker< check::PreStmt<CallExpr> > {
344 mutable std::unique_ptr<APIMisuse> BT;
347 CFNumberChecker() : ICreate(
nullptr), IGetValue(
nullptr) {}
349 void checkPreStmt(
const CallExpr *CE, CheckerContext &C)
const;
352 void EmitError(
const TypedRegion* R,
const Expr *Ex,
353 uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
377 static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };
380 return FixedSize[i-1];
404 static const char* GetCFNumberTypeStr(uint64_t i) {
405 static const char* Names[] = {
406 "kCFNumberSInt8Type",
407 "kCFNumberSInt16Type",
408 "kCFNumberSInt32Type",
409 "kCFNumberSInt64Type",
410 "kCFNumberFloat32Type",
411 "kCFNumberFloat64Type",
413 "kCFNumberShortType",
416 "kCFNumberLongLongType",
417 "kCFNumberFloatType",
418 "kCFNumberDoubleType",
419 "kCFNumberCFIndexType",
420 "kCFNumberNSIntegerType",
421 "kCFNumberCGFloatType" 428 void CFNumberChecker::checkPreStmt(
const CallExpr *CE,
429 CheckerContext &C)
const {
437 ICreate = &Ctx.
Idents.
get(
"CFNumberCreate");
438 IGetValue = &Ctx.
Idents.
get(
"CFNumberGetValue");
445 SVal TheTypeVal = C.getSVal(CE->
getArg(1));
453 uint64_t NumberKind = V->getValue().getLimitedValue();
457 if (!OptCFNumberSize)
460 uint64_t CFNumberSize = *OptCFNumberSize;
465 SVal TheValueExpr = C.getSVal(CE->
getArg(2));
473 const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
487 if (PrimitiveTypeSize == CFNumberSize)
492 ExplodedNode *N = C.generateNonFatalErrorNode();
495 llvm::raw_svector_ostream os(sbuf);
499 os << (PrimitiveTypeSize == 8 ?
"An " :
"A ")
500 << PrimitiveTypeSize <<
"-bit integer is used to initialize a " 501 <<
"CFNumber object that represents " 502 << (CFNumberSize == 8 ?
"an " :
"a ")
503 << CFNumberSize <<
"-bit integer; ";
505 os <<
"A CFNumber object that represents " 506 << (CFNumberSize == 8 ?
"an " :
"a ")
507 << CFNumberSize <<
"-bit integer is used to initialize " 508 << (PrimitiveTypeSize == 8 ?
"an " :
"a ")
509 << PrimitiveTypeSize <<
"-bit integer; ";
512 if (PrimitiveTypeSize < CFNumberSize)
513 os << (CFNumberSize - PrimitiveTypeSize)
514 <<
" bits of the CFNumber value will " 515 << (isCreate ?
"be garbage." :
"overwrite adjacent storage.");
517 os << (PrimitiveTypeSize - CFNumberSize)
518 <<
" bits of the integer value will be " 519 << (isCreate ?
"lost." :
"garbage.");
522 BT.reset(
new APIMisuse(
this,
"Bad use of CFNumber APIs"));
524 auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
526 C.emitReport(std::move(report));
535 class CFRetainReleaseChecker :
public Checker<check::PreCall> {
536 mutable APIMisuse BT{
this,
"null passed to CF memory management function"};
537 CallDescription CFRetain{
"CFRetain", 1},
538 CFRelease{
"CFRelease", 1},
539 CFMakeCollectable{
"CFMakeCollectable", 1},
540 CFAutorelease{
"CFAutorelease", 1};
543 void checkPreCall(
const CallEvent &Call, CheckerContext &C)
const;
547 void CFRetainReleaseChecker::checkPreCall(
const CallEvent &Call,
548 CheckerContext &C)
const {
550 if (!Call.isGlobalCFunction())
554 if (!(Call.isCalled(CFRetain) || Call.isCalled(CFRelease) ||
555 Call.isCalled(CFMakeCollectable) || Call.isCalled(CFAutorelease)))
559 SVal ArgVal = Call.getArgSVal(0);
567 std::tie(stateNonNull, stateNull) = state->assume(*DefArgVal);
570 ExplodedNode *N = C.generateErrorNode(stateNull);
575 raw_svector_ostream
OS(Str);
576 OS <<
"Null pointer argument in call to " 577 << cast<FunctionDecl>(Call.getDecl())->
getName();
579 auto report = llvm::make_unique<BugReport>(BT, OS.str(), N);
580 report->addRange(Call.getArgSourceRange(0));
581 bugreporter::trackExpressionValue(N, Call.getArgExpr(0), *report);
582 C.emitReport(std::move(report));
587 C.addTransition(stateNonNull);
595 class ClassReleaseChecker :
public Checker<check::PreObjCMessage> {
600 mutable std::unique_ptr<BugType> BT;
603 void checkPreObjCMessage(
const ObjCMethodCall &msg, CheckerContext &C)
const;
607 void ClassReleaseChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
608 CheckerContext &C)
const {
610 BT.reset(
new APIMisuse(
611 this,
"message incorrectly sent to class instead of class instance"));
626 if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
629 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
631 llvm::raw_svector_ostream os(buf);
635 os <<
"' message should be sent to instances " 636 "of class '" << Class->
getName()
637 <<
"' and not the class directly";
639 auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
641 C.emitReport(std::move(report));
651 class VariadicMethodTypeChecker :
public Checker<check::PreObjCMessage> {
653 mutable Selector dictionaryWithObjectsAndKeysS;
655 mutable Selector orderedSetWithObjectsS;
657 mutable Selector initWithObjectsAndKeysS;
658 mutable std::unique_ptr<BugType> BT;
663 void checkPreObjCMessage(
const ObjCMethodCall &msg, CheckerContext &C)
const;
670 VariadicMethodTypeChecker::isVariadicMessage(
const ObjCMethodCall &msg)
const {
691 return S == initWithObjectsS;
693 return S == initWithObjectsAndKeysS;
702 return S == arrayWithObjectsS;
704 return S == orderedSetWithObjectsS;
706 return S == setWithObjectsS;
708 return S == dictionaryWithObjectsAndKeysS;
715 void VariadicMethodTypeChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
716 CheckerContext &C)
const {
718 BT.reset(
new APIMisuse(
this,
719 "Arguments passed to variadic method aren't all " 720 "Objective-C pointer types"));
724 dictionaryWithObjectsAndKeysS =
733 if (!isVariadicMessage(msg))
742 unsigned variadicArgsEnd = msg.
getNumArgs() - 1;
744 if (variadicArgsEnd <= variadicArgsBegin)
750 for (
unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
760 if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
764 if (C.getASTContext().isObjCNSObjectType(ArgTy))
772 if (!errorNode.hasValue())
773 errorNode = C.generateNonFatalErrorNode();
775 if (!errorNode.getValue())
779 llvm::raw_svector_ostream os(sbuf);
782 if (!TypeName.empty())
783 os <<
"Argument to '" << TypeName <<
"' method '";
785 os <<
"Argument to method '";
788 os <<
"' should be an Objective-C pointer type, not '";
789 ArgTy.
print(os, C.getLangOpts());
792 auto R = llvm::make_unique<BugReport>(*BT, os.str(), errorNode.getValue());
793 R->addRange(msg.getArgSourceRange(I));
794 C.emitReport(std::move(R));
808 class ObjCLoopChecker
809 :
public Checker<check::PostStmt<ObjCForCollectionStmt>,
810 check::PostObjCMessage,
812 check::PointerEscape > {
816 CheckerContext &C)
const;
819 ObjCLoopChecker() : CountSelectorII(
nullptr) {}
821 void checkPostObjCMessage(
const ObjCMethodCall &M, CheckerContext &C)
const;
822 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C)
const;
863 if (!KnownCollection)
867 std::tie(StNonNil, StNil) = State->assume(*KnownCollection);
868 if (StNil && !StNonNil) {
895 if (
const DeclStmt *DS = dyn_cast<DeclStmt>(Element)) {
896 const VarDecl *ElemDecl = cast<VarDecl>(DS->getSingleDecl());
897 assert(ElemDecl->
getInit() ==
nullptr);
898 ElementLoc = State->getLValue(ElemDecl, LCtx);
900 ElementLoc = State->getSVal(Element, LCtx).getAs<Loc>();
907 SVal Val = State->getSVal(*ElementLoc);
908 return State->assume(Val.castAs<DefinedOrUnknownSVal>(),
true);
915 SymbolRef CollectionS,
bool Assumption) {
916 if (!State || !CollectionS)
919 const SymbolRef *CountS = State->get<ContainerCountMap>(CollectionS);
921 const bool *KnownNonEmpty = State->get<ContainerNonEmptyMap>(CollectionS);
923 return State->set<ContainerNonEmptyMap>(CollectionS, Assumption);
924 return (Assumption == *KnownNonEmpty) ?
State :
nullptr;
927 SValBuilder &SvalBuilder = C.getSValBuilder();
928 SVal CountGreaterThanZeroVal =
929 SvalBuilder.evalBinOp(State, BO_GT,
930 nonloc::SymbolVal(*CountS),
931 SvalBuilder.makeIntVal(0, (*CountS)->getType()),
932 SvalBuilder.getConditionType());
934 CountGreaterThanZeroVal.getAs<DefinedSVal>();
935 if (!CountGreaterThanZero) {
941 return State->assume(*CountGreaterThanZero, Assumption);
963 return BE->getSrc()->getLoopTarget() == FCS;
968 E = N->pred_end(); I != E; ++I) {
977 CheckerContext &C)
const {
981 SVal CollectionSentinel = C.getSVal(FCS);
982 if (CollectionSentinel.isZeroConstant()) {
994 C.generateSink(C.getState(), C.getPredecessor());
995 else if (State != C.getState())
996 C.addTransition(State);
999 bool ObjCLoopChecker::isCollectionCountMethod(
const ObjCMethodCall &M,
1000 CheckerContext &C)
const {
1003 if (!CountSelectorII)
1004 CountSelectorII = &C.getASTContext().Idents.get(
"count");
1011 void ObjCLoopChecker::checkPostObjCMessage(
const ObjCMethodCall &M,
1012 CheckerContext &C)
const {
1033 if (!isCollectionCountMethod(M, C))
1037 SymbolRef CountS = C.getSVal(MsgExpr).getAsSymbol();
1041 C.getSymbolManager().addSymbolDependency(ContainerS, CountS);
1042 State = State->set<ContainerCountMap>(ContainerS, CountS);
1044 if (
const bool *NonEmpty = State->get<ContainerNonEmptyMap>(ContainerS)) {
1045 State = State->remove<ContainerNonEmptyMap>(ContainerS);
1049 C.addTransition(State);
1054 const ObjCMethodCall *Message = dyn_cast_or_null<ObjCMethodCall>(Call);
1099 for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
1108 if (Sym == ImmutableReceiver)
1113 State =
State->remove<ContainerCountMap>(Sym);
1114 State = State->remove<ContainerNonEmptyMap>(Sym);
1119 void ObjCLoopChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1120 CheckerContext &C)
const {
1124 ContainerCountMapTy Tracked = State->get<ContainerCountMap>();
1125 for (ContainerCountMapTy::iterator I = Tracked.begin(),
1126 E = Tracked.end(); I != E; ++I) {
1128 if (SymReaper.isDead(Sym)) {
1129 State = State->remove<ContainerCountMap>(Sym);
1130 State = State->remove<ContainerNonEmptyMap>(Sym);
1134 C.addTransition(State);
1141 class ObjCNonNilReturnValueChecker
1142 :
public Checker<check::PostObjCMessage,
1143 check::PostStmt<ObjCArrayLiteral>,
1144 check::PostStmt<ObjCDictionaryLiteral>,
1145 check::PostStmt<ObjCBoxedExpr> > {
1148 mutable Selector ObjectAtIndexedSubscript;
1152 ObjCNonNilReturnValueChecker() :
Initialized(
false) {}
1156 CheckerContext &C)
const;
1157 void assumeExprIsNonNull(
const Expr *E, CheckerContext &C)
const {
1158 C.addTransition(assumeExprIsNonNull(E, C.getState(), C));
1162 assumeExprIsNonNull(E, C);
1165 assumeExprIsNonNull(E, C);
1167 void checkPostStmt(
const ObjCBoxedExpr *E, CheckerContext &C)
const {
1168 assumeExprIsNonNull(E, C);
1171 void checkPostObjCMessage(
const ObjCMethodCall &M, CheckerContext &C)
const;
1176 ObjCNonNilReturnValueChecker::assumeExprIsNonNull(
const Expr *NonNullExpr,
1178 CheckerContext &C)
const {
1179 SVal Val = C.getSVal(NonNullExpr);
1181 return State->assume(*DV,
true);
1185 void ObjCNonNilReturnValueChecker::checkPostObjCMessage(
const ObjCMethodCall &M,
1193 ObjectAtIndexedSubscript =
GetUnarySelector(
"objectAtIndexedSubscript", Ctx);
1208 if (!C.inTopFrame() && M.
getDecl() &&
1221 if (Sel == ObjectAtIndex || Sel == ObjectAtIndexedSubscript) {
1235 C.addTransition(State);
1242 void ento::registerNilArgChecker(CheckerManager &mgr) {
1243 mgr.registerChecker<NilArgChecker>();
1246 void ento::registerCFNumberChecker(CheckerManager &mgr) {
1247 mgr.registerChecker<CFNumberChecker>();
1250 void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) {
1251 mgr.registerChecker<CFRetainReleaseChecker>();
1254 void ento::registerClassReleaseChecker(CheckerManager &mgr) {
1255 mgr.registerChecker<ClassReleaseChecker>();
1258 void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) {
1259 mgr.registerChecker<VariadicMethodTypeChecker>();
1262 void ento::registerObjCLoopChecker(CheckerManager &mgr) {
1263 mgr.registerChecker<ObjCLoopChecker>();
1267 ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
1268 mgr.registerChecker<ObjCNonNilReturnValueChecker>();
Defines the clang::ASTContext interface.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
Represents a function declaration or definition.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Smart pointer class that efficiently represents Objective-C method names.
A (possibly-)qualified type.
bool isBlockPointerType() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
ObjCInterfaceDecl * getClassInterface()
llvm::DenseSet< SymbolRef > InvalidatedSymbols
static ProgramStateRef assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, SymbolRef CollectionS, bool Assumption)
Returns NULL state if the collection is known to contain elements (or is known not to contain element...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
const SymExpr * SymbolRef
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
static StringRef GetReceiverInterfaceName(const ObjCMethodCall &msg)
SourceRange getSourceRange() const override
static ProgramStateRef checkCollectionNonNil(CheckerContext &C, ProgramStateRef State, const ObjCForCollectionStmt *FCS)
Assumes that the collection is non-nil.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl - Represents an instance or class method declaration.
Defines the Objective-C statement AST node classes.
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
One of these records is kept for each identifier that is lexed.
An element in an Objective-C dictionary literal.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static ProgramStateRef checkElementNonNil(CheckerContext &C, ProgramStateRef State, const ObjCForCollectionStmt *FCS)
Assumes that the collection elements are non-nil.
const ObjCInterfaceDecl * getReceiverInterface() const
Get the interface for the receiver.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isUnarySelector() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Represents any expression that calls an Objective-C method.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
Expr * Key
The key for the dictionary element.
Represents an ObjC class declaration.
static SymbolRef getMethodReceiverIfKnownImmutable(const CallEvent *Call)
static bool isKnownNonNilCollectionType(QualType T)
bool isReceiverSelfOrSuper() const
Checks if the receiver refers to 'self' or 'super'.
The return type of classify().
This represents one expression.
static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID, bool IncludeSuperclasses=true)
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
DeclContext * getDeclContext()
ObjCInterfaceDecl * getSuperClass() const
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
bool isCFObjectRef(QualType T)
unsigned getNumArgs() const
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
static Selector getKeywordSelector(ASTContext &Ctx, IdentifierInfos *... IIs)
bool isObjCObjectPointerType() const
ObjCBoxedExpr - used for generalized expression boxing.
const ObjCMethodDecl * getDecl() const override
Expr * Value
The value of the dictionary element.
StringRef getName() const
Return the actual identifier string.
virtual const ObjCMessageExpr * getOriginExpr() const
Selector getSelector() const
Dataflow Directional Tag Classes.
static bool alreadyExecutedAtLeastOneLoopIteration(const ExplodedNode *N, const ObjCForCollectionStmt *FCS)
If the fist block edge is a back edge, we are reentering the loop.
const Expr * getInit() const
ObjCMessageKind getMessageKind() const
Returns how the message was written in the source (property access, subscript, or explicit message se...
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
Represents a pointer to an Objective C object.
bool isInstanceMessage() const
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's collection statement.
unsigned getNumArgs() const override
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const Expr * getArgExpr(unsigned Index) const override
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
pred_iterator pred_begin()
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
static Optional< uint64_t > GetCFNumberSize(ASTContext &Ctx, uint64_t i)
const ExplodedNode *const * const_pred_iterator
A trivial tuple used to represent a source range.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...