32 #include "llvm/ADT/SmallString.h" 33 #include "llvm/ADT/StringMap.h" 34 #include "llvm/Support/raw_ostream.h" 36 using namespace clang;
41 class APIMisuse :
public BugType {
43 APIMisuse(
const CheckerBase *checker,
const char *
name)
44 : BugType(checker, name,
"API Misuse (Apple)") {}
54 return ID->getIdentifier()->getName();
70 bool IncludeSuperclasses =
true) {
71 static llvm::StringMap<FoundationClass> Classes;
72 if (Classes.empty()) {
84 if (result ==
FC_None && IncludeSuperclasses)
96 class NilArgChecker :
public Checker<check::PreObjCMessage,
97 check::PostStmt<ObjCDictionaryLiteral>,
98 check::PostStmt<ObjCArrayLiteral> > {
99 mutable std::unique_ptr<APIMisuse> BT;
101 mutable llvm::SmallDenseMap<Selector, unsigned, 16> StringSelectors;
102 mutable Selector ArrayWithObjectSel;
104 mutable Selector InsertObjectAtIndexSel;
105 mutable Selector ReplaceObjectAtIndexWithObjectSel;
106 mutable Selector SetObjectAtIndexedSubscriptSel;
107 mutable Selector ArrayByAddingObjectSel;
108 mutable Selector DictionaryWithObjectForKeySel;
109 mutable Selector SetObjectForKeySel;
110 mutable Selector SetObjectForKeyedSubscriptSel;
111 mutable Selector RemoveObjectForKeySel;
113 void warnIfNilExpr(
const Expr *E,
115 CheckerContext &C)
const;
117 void warnIfNilArg(CheckerContext &C,
120 bool CanBeSubscript =
false)
const;
122 void generateBugReport(ExplodedNode *N,
126 CheckerContext &C)
const;
129 void checkPreObjCMessage(
const ObjCMethodCall &M, CheckerContext &C)
const;
131 CheckerContext &C)
const;
133 CheckerContext &C)
const;
137 void NilArgChecker::warnIfNilExpr(
const Expr *E,
139 CheckerContext &C)
const {
141 if (State->isNull(C.getSVal(E)).isConstrainedTrue()) {
143 if (ExplodedNode *N = C.generateErrorNode()) {
149 void NilArgChecker::warnIfNilArg(CheckerContext &C,
153 bool CanBeSubscript)
const {
156 if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
164 if (ExplodedNode *N = C.generateErrorNode()) {
166 llvm::raw_svector_ostream os(sbuf);
171 os <<
"Array element cannot be nil";
174 os <<
"Value stored into '";
181 llvm_unreachable(
"Missing foundation class for the subscript expr");
186 os <<
"Value argument ";
189 os <<
"Key argument ";
193 os <<
"' cannot be nil";
197 os <<
"' cannot be nil";
201 generateBugReport(N, os.str(), msg.getArgSourceRange(Arg),
206 void NilArgChecker::generateBugReport(ExplodedNode *N,
210 CheckerContext &C)
const {
212 BT.reset(
new APIMisuse(
this,
"nil argument"));
214 auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
216 bugreporter::trackExpressionValue(N, E, *R);
217 C.emitReport(std::move(R));
220 void NilArgChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
221 CheckerContext &C)
const {
228 static const unsigned InvalidArgIndex =
UINT_MAX;
229 unsigned Arg = InvalidArgIndex;
230 bool CanBeSubscript =
false;
238 if (StringSelectors.empty()) {
253 StringSelectors[KnownSel] = 0;
255 auto I = StringSelectors.find(S);
256 if (I == StringSelectors.end())
265 if (ArrayWithObjectSel.isNull()) {
269 InsertObjectAtIndexSel =
271 ReplaceObjectAtIndexWithObjectSel =
273 SetObjectAtIndexedSubscriptSel =
278 if (S == ArrayWithObjectSel || S == AddObjectSel ||
279 S == InsertObjectAtIndexSel || S == ArrayByAddingObjectSel) {
281 }
else if (S == SetObjectAtIndexedSubscriptSel) {
283 CanBeSubscript =
true;
284 }
else if (S == ReplaceObjectAtIndexWithObjectSel) {
293 if (DictionaryWithObjectForKeySel.isNull()) {
295 DictionaryWithObjectForKeySel =
298 SetObjectForKeyedSubscriptSel =
303 if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) {
305 warnIfNilArg(C, msg, 1, Class);
306 }
else if (S == SetObjectForKeyedSubscriptSel) {
307 CanBeSubscript =
true;
309 }
else if (S == RemoveObjectForKeySel) {
315 if ((Arg != InvalidArgIndex))
316 warnIfNilArg(C, msg, Arg, Class, CanBeSubscript);
320 CheckerContext &C)
const {
322 for (
unsigned i = 0; i < NumOfElements; ++i) {
323 warnIfNilExpr(AL->
getElement(i),
"Array element cannot be nil", C);
328 CheckerContext &C)
const {
330 for (
unsigned i = 0; i < NumOfElements; ++i) {
332 warnIfNilExpr(Element.
Key,
"Dictionary key cannot be nil", C);
333 warnIfNilExpr(Element.
Value,
"Dictionary value cannot be nil", C);
342 class CFNumberChecker :
public Checker< check::PreStmt<CallExpr> > {
343 mutable std::unique_ptr<APIMisuse> BT;
346 CFNumberChecker() : ICreate(
nullptr), IGetValue(
nullptr) {}
348 void checkPreStmt(
const CallExpr *CE, CheckerContext &C)
const;
351 void EmitError(
const TypedRegion* R,
const Expr *Ex,
352 uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
376 static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };
379 return FixedSize[i-1];
403 static const char* GetCFNumberTypeStr(uint64_t i) {
404 static const char* Names[] = {
405 "kCFNumberSInt8Type",
406 "kCFNumberSInt16Type",
407 "kCFNumberSInt32Type",
408 "kCFNumberSInt64Type",
409 "kCFNumberFloat32Type",
410 "kCFNumberFloat64Type",
412 "kCFNumberShortType",
415 "kCFNumberLongLongType",
416 "kCFNumberFloatType",
417 "kCFNumberDoubleType",
418 "kCFNumberCFIndexType",
419 "kCFNumberNSIntegerType",
420 "kCFNumberCGFloatType" 427 void CFNumberChecker::checkPreStmt(
const CallExpr *CE,
428 CheckerContext &C)
const {
436 ICreate = &Ctx.
Idents.
get(
"CFNumberCreate");
437 IGetValue = &Ctx.
Idents.
get(
"CFNumberGetValue");
444 SVal TheTypeVal = C.getSVal(CE->
getArg(1));
452 uint64_t NumberKind = V->getValue().getLimitedValue();
456 if (!OptCFNumberSize)
459 uint64_t CFNumberSize = *OptCFNumberSize;
464 SVal TheValueExpr = C.getSVal(CE->
getArg(2));
472 const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
486 if (PrimitiveTypeSize == CFNumberSize)
491 ExplodedNode *N = C.generateNonFatalErrorNode();
494 llvm::raw_svector_ostream os(sbuf);
498 os << (PrimitiveTypeSize == 8 ?
"An " :
"A ")
499 << PrimitiveTypeSize <<
"-bit integer is used to initialize a " 500 <<
"CFNumber object that represents " 501 << (CFNumberSize == 8 ?
"an " :
"a ")
502 << CFNumberSize <<
"-bit integer; ";
504 os <<
"A CFNumber object that represents " 505 << (CFNumberSize == 8 ?
"an " :
"a ")
506 << CFNumberSize <<
"-bit integer is used to initialize " 507 << (PrimitiveTypeSize == 8 ?
"an " :
"a ")
508 << PrimitiveTypeSize <<
"-bit integer; ";
511 if (PrimitiveTypeSize < CFNumberSize)
512 os << (CFNumberSize - PrimitiveTypeSize)
513 <<
" bits of the CFNumber value will " 514 << (isCreate ?
"be garbage." :
"overwrite adjacent storage.");
516 os << (PrimitiveTypeSize - CFNumberSize)
517 <<
" bits of the integer value will be " 518 << (isCreate ?
"lost." :
"garbage.");
521 BT.reset(
new APIMisuse(
this,
"Bad use of CFNumber APIs"));
523 auto report = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
525 C.emitReport(std::move(report));
534 class CFRetainReleaseChecker :
public Checker<check::PreCall> {
535 mutable APIMisuse BT{
this,
"null passed to CF memory management function"};
537 CFRelease{
"CFRelease", 1},
538 CFMakeCollectable{
"CFMakeCollectable", 1},
539 CFAutorelease{
"CFAutorelease", 1};
542 void checkPreCall(
const CallEvent &Call, CheckerContext &C)
const;
546 void CFRetainReleaseChecker::checkPreCall(
const CallEvent &Call,
547 CheckerContext &C)
const {
549 if (!Call.isGlobalCFunction())
553 if (!(Call.isCalled(CFRetain) || Call.isCalled(CFRelease) ||
554 Call.isCalled(CFMakeCollectable) || Call.isCalled(CFAutorelease)))
558 SVal ArgVal = Call.getArgSVal(0);
566 std::tie(stateNonNull, stateNull) = state->assume(*DefArgVal);
569 ExplodedNode *N = C.generateErrorNode(stateNull);
574 raw_svector_ostream
OS(Str);
575 OS <<
"Null pointer argument in call to " 576 << cast<FunctionDecl>(Call.getDecl())->
getName();
578 auto report = std::make_unique<PathSensitiveBugReport>(BT, OS.str(), N);
579 report->addRange(Call.getArgSourceRange(0));
580 bugreporter::trackExpressionValue(N, Call.getArgExpr(0), *report);
581 C.emitReport(std::move(report));
586 C.addTransition(stateNonNull);
594 class ClassReleaseChecker :
public Checker<check::PreObjCMessage> {
599 mutable std::unique_ptr<BugType> BT;
602 void checkPreObjCMessage(
const ObjCMethodCall &msg, CheckerContext &C)
const;
606 void ClassReleaseChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
607 CheckerContext &C)
const {
609 BT.reset(
new APIMisuse(
610 this,
"message incorrectly sent to class instead of class instance"));
625 if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
628 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
630 llvm::raw_svector_ostream os(buf);
634 os <<
"' message should be sent to instances " 635 "of class '" << Class->
getName()
636 <<
"' and not the class directly";
638 auto report = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
640 C.emitReport(std::move(report));
650 class VariadicMethodTypeChecker :
public Checker<check::PreObjCMessage> {
652 mutable Selector dictionaryWithObjectsAndKeysS;
654 mutable Selector orderedSetWithObjectsS;
656 mutable Selector initWithObjectsAndKeysS;
657 mutable std::unique_ptr<BugType> BT;
662 void checkPreObjCMessage(
const ObjCMethodCall &msg, CheckerContext &C)
const;
669 VariadicMethodTypeChecker::isVariadicMessage(
const ObjCMethodCall &msg)
const {
690 return S == initWithObjectsS;
692 return S == initWithObjectsAndKeysS;
701 return S == arrayWithObjectsS;
703 return S == orderedSetWithObjectsS;
705 return S == setWithObjectsS;
707 return S == dictionaryWithObjectsAndKeysS;
714 void VariadicMethodTypeChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
715 CheckerContext &C)
const {
717 BT.reset(
new APIMisuse(
this,
718 "Arguments passed to variadic method aren't all " 719 "Objective-C pointer types"));
723 dictionaryWithObjectsAndKeysS =
732 if (!isVariadicMessage(msg))
741 unsigned variadicArgsEnd = msg.
getNumArgs() - 1;
743 if (variadicArgsEnd <= variadicArgsBegin)
749 for (
unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
759 if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
763 if (C.getASTContext().isObjCNSObjectType(ArgTy))
771 if (!errorNode.hasValue())
772 errorNode = C.generateNonFatalErrorNode();
774 if (!errorNode.getValue())
778 llvm::raw_svector_ostream os(sbuf);
781 if (!TypeName.empty())
782 os <<
"Argument to '" << TypeName <<
"' method '";
784 os <<
"Argument to method '";
787 os <<
"' should be an Objective-C pointer type, not '";
788 ArgTy.
print(os, C.getLangOpts());
791 auto R = std::make_unique<PathSensitiveBugReport>(*BT, os.str(),
792 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 bool ento::shouldRegisterNilArgChecker(
const LangOptions &LO) {
1250 void ento::registerCFNumberChecker(CheckerManager &mgr) {
1251 mgr.registerChecker<CFNumberChecker>();
1254 bool ento::shouldRegisterCFNumberChecker(
const LangOptions &LO) {
1258 void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) {
1259 mgr.registerChecker<CFRetainReleaseChecker>();
1262 bool ento::shouldRegisterCFRetainReleaseChecker(
const LangOptions &LO) {
1266 void ento::registerClassReleaseChecker(CheckerManager &mgr) {
1267 mgr.registerChecker<ClassReleaseChecker>();
1270 bool ento::shouldRegisterClassReleaseChecker(
const LangOptions &LO) {
1274 void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) {
1275 mgr.registerChecker<VariadicMethodTypeChecker>();
1278 bool ento::shouldRegisterVariadicMethodTypeChecker(
const LangOptions &LO) {
1282 void ento::registerObjCLoopChecker(CheckerManager &mgr) {
1283 mgr.registerChecker<ObjCLoopChecker>();
1286 bool ento::shouldRegisterObjCLoopChecker(
const LangOptions &LO) {
1290 void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
1291 mgr.registerChecker<ObjCNonNilReturnValueChecker>();
1294 bool ento::shouldRegisterObjCNonNilReturnValueChecker(
const LangOptions &LO) {
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...
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
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.
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.
const SymExpr * SymbolRef
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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
This class represents a description of a function call using the number of arguments and the name of ...
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 std::string getName(const CallEvent &Call)
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...