diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 19:28:04 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 19:28:04 +0000 |
commit | de507eaf3cb54d3cb234dc14499c10ab3373d15f (patch) | |
tree | d6f5328cba078ef92f7825cdb3b2f7053a90e854 /include/clang/StaticAnalyzer | |
parent | cde8cdbd6a662c636164465ad309b5f17ff01064 (diff) |
[analyzer] Finish replacing ObjCMessage with ObjCMethodDecl and friends.
The preObjCMessage and postObjCMessage callbacks now take an ObjCMethodCall
argument, which can represent an explicit message send (ObjCMessageSend) or an
implicit message generated by a property access (ObjCPropertyAccess).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159559 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer')
4 files changed, 29 insertions, 183 deletions
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index fb224ef158..07a1ccff6c 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -122,7 +122,7 @@ public: class PreObjCMessage { template <typename CHECKER> - static void _checkObjCMessage(void *checker, const ObjCMessage &msg, + static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, CheckerContext &C) { ((const CHECKER *)checker)->checkPreObjCMessage(msg, C); } @@ -137,7 +137,7 @@ public: class PostObjCMessage { template <typename CHECKER> - static void _checkObjCMessage(void *checker, const ObjCMessage &msg, + static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, CheckerContext &C) { ((const CHECKER *)checker)->checkPostObjCMessage(msg, C); } diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 3202fbe6b8..eef82fe848 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -33,7 +33,7 @@ namespace ento { class AnalysisManager; class BugReporter; class CheckerContext; - class ObjCMessage; + class ObjCMethodCall; class SVal; class ExplodedNode; class ExplodedNodeSet; @@ -207,7 +207,7 @@ public: /// \brief Run checkers for pre-visiting obj-c messages. void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const ObjCMessage &msg, + const ObjCMethodCall &msg, ExprEngine &Eng) { runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); } @@ -215,7 +215,7 @@ public: /// \brief Run checkers for post-visiting obj-c messages. void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const ObjCMessage &msg, + const ObjCMethodCall &msg, ExprEngine &Eng) { runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); } @@ -224,7 +224,7 @@ public: void runCheckersForObjCMessage(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const ObjCMessage &msg, ExprEngine &Eng); + const ObjCMethodCall &msg, ExprEngine &Eng); /// \brief Run checkers for load/store of a location. void runCheckersForLocation(ExplodedNodeSet &Dst, @@ -343,7 +343,7 @@ public: typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; - typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)> + typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)> CheckObjCMessageFunc; typedef CheckerFn<void (const SVal &location, bool isLoad, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h index fdfb485a52..a16eb4afef 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h @@ -20,8 +20,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" namespace clang { @@ -114,6 +113,10 @@ public: /// \brief Returns the kind of call this is. Kind getKind() const { return K; } + /// \brief Returns a source range for the entire call, suitable for + /// outputting in diagnostics. + virtual SourceRange getSourceRange() const = 0; + /// \brief Returns the value of a given argument at the time of the call. virtual SVal getArgSVal(unsigned Index) const; @@ -213,6 +216,7 @@ public: const FunctionDecl *getDecl() const; unsigned getNumArgs() const { return CE->getNumArgs(); } + SourceRange getSourceRange() const { return CE->getSourceRange(); } const Expr *getArgExpr(unsigned Index) const { return CE->getArg(Index); @@ -305,6 +309,7 @@ public: : AnyFunctionCall(St, LCtx, CE_CXXConstructor), CE(ce), Target(target) {} const CXXConstructExpr *getOriginExpr() const { return CE; } + SourceRange getSourceRange() const { return CE->getSourceRange(); } const CXXConstructorDecl *getDecl() const { return CE->getConstructor(); @@ -341,7 +346,9 @@ public: Selector getSelector() const { return Msg->getSelector(); } bool isInstanceMessage() const { return Msg->isInstanceMessage(); } ObjCMethodFamily getMethodFamily() const { return Msg->getMethodFamily(); } + const ObjCMethodDecl *getDecl() const { return Msg->getMethodDecl(); } + SourceRange getSourceRange() const { return Msg->getSourceRange(); } unsigned getNumArgs() const { return Msg->getNumArgs(); } const Expr *getArgExpr(unsigned Index) const { return Msg->getArg(Index); @@ -351,6 +358,10 @@ public: SVal getReceiverSVal() const; + const Expr *getInstanceReceiverExpr() const { + return Msg->getInstanceReceiver(); + } + const ObjCInterfaceDecl *getReceiverInterface() const { return Msg->getReceiverInterface(); } @@ -359,11 +370,6 @@ public: return Msg->getReceiverRange(); } - // FIXME: Remove this once everything is converted to use ObjCMethodCall. - virtual operator ObjCMessage() const { - return ObjCMessage(Msg); - } - static bool classof(const CallEvent *CA) { return CA->getKind() >= CE_BEG_OBJC_CALLS && CA->getKind() <= CE_END_OBJC_CALLS; @@ -389,20 +395,23 @@ public: /// Example: obj.prop += 1; class ObjCPropertyAccess : public ObjCMethodCall { const ObjCPropertyRefExpr *PropE; + SourceRange EntireRange; public: - ObjCPropertyAccess(const ObjCPropertyRefExpr *pe, const ObjCMessageExpr *Msg, - const ProgramStateRef St, const LocationContext *LCtx) - : ObjCMethodCall(Msg, St, LCtx, CE_ObjCPropertyAccess), PropE(pe) {} + ObjCPropertyAccess(const ObjCPropertyRefExpr *pe, SourceRange range, + const ObjCMessageExpr *Msg, const ProgramStateRef St, + const LocationContext *LCtx) + : ObjCMethodCall(Msg, St, LCtx, CE_ObjCPropertyAccess), PropE(pe), + EntireRange(range) + {} /// \brief Returns true if this property access is calling the setter method. bool isSetter() const { return getNumArgs() > 0; } - // FIXME: Remove this once everything is converted to use ObjCMethodCall. - operator ObjCMessage() const { - return ObjCMessage(getOriginExpr(), PropE, isSetter()); + SourceRange getSourceRange() const { + return EntireRange; } static bool classof(const CallEvent *CA) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h deleted file mode 100644 index f64326d2c6..0000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h +++ /dev/null @@ -1,163 +0,0 @@ -//===- ObjCMessage.h - Wrapper for ObjC messages and dot syntax ---*- C++ -*--// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines ObjCMessage which serves as a common wrapper for ObjC -// message expressions or implicit messages for loading/storing ObjC properties. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE -#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE - -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/ExprCXX.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Compiler.h" - -namespace clang { -namespace ento { -using llvm::StrInStrNoCase; - -/// \brief Represents both explicit ObjC message expressions and implicit -/// messages that are sent for handling properties in dot syntax. -class ObjCMessage { - const ObjCMessageExpr *Msg; - const ObjCPropertyRefExpr *PE; - const bool IsPropSetter; -public: - ObjCMessage() : Msg(0), PE(0), IsPropSetter(false) {} - - ObjCMessage(const ObjCMessageExpr *E, const ObjCPropertyRefExpr *pe = 0, - bool isSetter = false) - : Msg(E), PE(pe), IsPropSetter(isSetter) { - assert(E && "should not be initialized with null expression"); - } - - bool isValid() const { return Msg; } - - bool isPureMessageExpr() const { return !PE; } - - bool isPropertyGetter() const { return PE && !IsPropSetter; } - - bool isPropertySetter() const { - return IsPropSetter; - } - - const ObjCMessageExpr *getMessageExpr() const { - return Msg; - } - - QualType getType(ASTContext &ctx) const { - return Msg->getType(); - } - - QualType getResultType(ASTContext &ctx) const { - if (const ObjCMethodDecl *MD = Msg->getMethodDecl()) - return MD->getResultType(); - return getType(ctx); - } - - ObjCMethodFamily getMethodFamily() const { - return Msg->getMethodFamily(); - } - - Selector getSelector() const { - return Msg->getSelector(); - } - - const Expr *getInstanceReceiver() const { - return Msg->getInstanceReceiver(); - } - - SVal getInstanceReceiverSVal(ProgramStateRef State, - const LocationContext *LC) const { - if (!isInstanceMessage()) - return UndefinedVal(); - if (const Expr *Ex = getInstanceReceiver()) - return State->getSValAsScalarOrLoc(Ex, LC); - - // An instance message with no expression means we are sending to super. - // In this case the object reference is the same as 'self'. - const ImplicitParamDecl *SelfDecl = LC->getSelfDecl(); - assert(SelfDecl && "No message receiver Expr, but not in an ObjC method"); - return State->getSVal(State->getRegion(SelfDecl, LC)); - } - - bool isInstanceMessage() const { - return Msg->isInstanceMessage(); - } - - const ObjCMethodDecl *getMethodDecl() const { - return Msg->getMethodDecl(); - } - - const ObjCInterfaceDecl *getReceiverInterface() const { - return Msg->getReceiverInterface(); - } - - SourceLocation getSuperLoc() const { - if (PE) - return PE->getReceiverLocation(); - return Msg->getSuperLoc(); - } - - SourceRange getSourceRange() const LLVM_READONLY { - if (PE) - return PE->getSourceRange(); - return Msg->getSourceRange(); - } - - unsigned getNumArgs() const { - return Msg->getNumArgs(); - } - - SVal getArgSVal(unsigned i, - const LocationContext *LCtx, - ProgramStateRef state) const { - assert(i < getNumArgs() && "Invalid index for argument"); - return state->getSVal(Msg->getArg(i), LCtx); - } - - QualType getArgType(unsigned i) const { - assert(i < getNumArgs() && "Invalid index for argument"); - return Msg->getArg(i)->getType(); - } - - const Expr *getArgExpr(unsigned i) const { - assert(i < getNumArgs() && "Invalid index for argument"); - return Msg->getArg(i); - } - - SourceRange getArgSourceRange(unsigned i) const { - const Expr *argE = getArgExpr(i); - return argE->getSourceRange(); - } - - SourceRange getReceiverSourceRange() const { - if (PE) { - if (PE->isObjectReceiver()) - return PE->getBase()->getSourceRange(); - } - else { - return Msg->getReceiverRange(); - } - - // FIXME: This isn't a range. - return PE->getReceiverLocation(); - } -}; - -} -} - -#endif |