From 0ffbfd1a7f80f9a3c07317cb8f44c562f2ba1ba5 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Tue, 10 Jul 2012 23:56:23 +0000 Subject: [PATCH] [analyzer] Add debug.DumpCalls, which prints out any CallEvents it sees. This is probably not so useful yet because it is not path-sensitive, though it does try to show inlining with indentation. This also adds a dump() method to CallEvent, which should be useful for debugging. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160030 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../StaticAnalyzer/Core/PathSensitive/Calls.h | 4 +++ lib/StaticAnalyzer/Checkers/Checkers.td | 4 +++ .../Checkers/TraversalChecker.cpp | 31 +++++++++++++++++-- lib/StaticAnalyzer/Core/Calls.cpp | 18 +++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h index 4d64fd83a6..77eb3bea74 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h @@ -216,6 +216,10 @@ public: return llvm::map_iterator(param_end(), get_type_fun(&ParmVarDecl::getType)); } + // For debugging purposes only + virtual void dump(raw_ostream &Out) const; + LLVM_ATTRIBUTE_USED void dump() const { dump(llvm::errs()); } + static bool classof(const CallEvent *) { return true; } }; diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td index 0969053976..99410def2c 100644 --- a/lib/StaticAnalyzer/Checkers/Checkers.td +++ b/lib/StaticAnalyzer/Checkers/Checkers.td @@ -483,6 +483,10 @@ def TraversalDumper : Checker<"DumpTraversal">, HelpText<"Print branch conditions as they are traversed by the engine">, DescFile<"TraversalChecker.cpp">; +def CallDumper : Checker<"DumpCalls">, + HelpText<"Print calls as they are traversed by the engine">, + DescFile<"TraversalChecker.cpp">; + def AnalyzerStatsChecker : Checker<"Stats">, HelpText<"Emit warnings with analyzer statistics">, DescFile<"AnalyzerStatsChecker.cpp">; diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp index d0479d4519..ed6187de9c 100644 --- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This checker prints branch statements to llvm::outs as they are encountered. -// This lets us see exactly how the ExprEngine is traversing the graph. +// These checkers print various aspects of the ExprEngine's traversal of the CFG +// as it builds the ExplodedGraph. // //===----------------------------------------------------------------------===// #include "ClangSACheckers.h" @@ -16,6 +16,7 @@ #include "clang/AST/StmtObjC.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; @@ -55,3 +56,29 @@ void TraversalDumper::checkEndPath(CheckerContext &C) const { void ento::registerTraversalDumper(CheckerManager &mgr) { mgr.registerChecker(); } + +//------------------------------------------------------------------------------ + +namespace { +class CallDumper : public Checker< check::PreCall > { +public: + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; +}; +} + +void CallDumper::checkPreCall(const CallEvent &Call, CheckerContext &C) const { + unsigned Indentation = 0; + for (const LocationContext *LC = C.getLocationContext()->getParent(); + LC != 0; LC = LC->getParent()) + ++Indentation; + + // It is mildly evil to print directly to llvm::outs() rather than emitting + // warnings, but this ensures things do not get filtered out by the rest of + // the static analyzer machinery. + llvm::outs().indent(Indentation); + Call.dump(llvm::outs()); +} + +void ento::registerCallDumper(CheckerManager &mgr) { + mgr.registerChecker(); +} diff --git a/lib/StaticAnalyzer/Core/Calls.cpp b/lib/StaticAnalyzer/Core/Calls.cpp index ced1154da7..94fc5fc8c0 100644 --- a/lib/StaticAnalyzer/Core/Calls.cpp +++ b/lib/StaticAnalyzer/Core/Calls.cpp @@ -310,6 +310,24 @@ const FunctionDecl *SimpleCall::getDecl() const { return getSVal(CE->getCallee()).getAsFunctionDecl(); } +void CallEvent::dump(raw_ostream &Out) const { + ASTContext &Ctx = State->getStateManager().getContext(); + if (const Expr *E = getOriginExpr()) { + E->printPretty(Out, Ctx, 0, Ctx.getLangOpts()); + Out << "\n"; + return; + } + + if (const Decl *D = getDecl()) { + Out << "Call to "; + D->print(Out, Ctx.getLangOpts()); + return; + } + + // FIXME: a string representation of the kind would be nice. + Out << "Unknown call (type " << getKind() << ")"; +} + SVal CXXMemberCall::getCXXThisVal() const { const Expr *Base = getOriginExpr()->getImplicitObjectArgument(); -- 2.40.0