aboutsummaryrefslogtreecommitdiff
path: root/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-11 19:44:10 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-11 19:44:10 +0000
commitf39480406d06676a5cc17fab1ef3576427130f31 (patch)
tree14a8de477a6e9228a09885397b494c9edfcd1c39 /Analysis/CFRefCount.cpp
parent75da3e82722cc6a616eaab28b75f9a6973178c49 (diff)
Added pretty-printing support for checker-specific state for the CFRefCount checker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48242 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/CFRefCount.cpp')
-rw-r--r--Analysis/CFRefCount.cpp67
1 files changed, 66 insertions, 1 deletions
diff --git a/Analysis/CFRefCount.cpp b/Analysis/CFRefCount.cpp
index e51353a61d..ea9c8bfd37 100644
--- a/Analysis/CFRefCount.cpp
+++ b/Analysis/CFRefCount.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
+#include <ostream>
using namespace clang;
@@ -193,22 +194,66 @@ public:
bool operator==(const RefVal& X) const { return Data == X.Data; }
void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger(Data); }
+
+ void print(std::ostream& Out) const;
};
-
+
+void RefVal::print(std::ostream& Out) const {
+ switch (getKind()) {
+ default: assert(false);
+ case Owned:
+ Out << "Owned(" << getCount() << ")";
+ break;
+
+ case AcqOwned:
+ Out << "Acquired-Owned(" << getCount() << ")";
+ break;
+
+ case NotOwned:
+ Out << "Not-Owned";
+ break;
+
+ case Released:
+ Out << "Released";
+ break;
+
+ case ErrorUseAfterRelease:
+ Out << "Use-After-Release [ERROR]";
+ break;
+
+ case ErrorReleaseNotOwned:
+ Out << "Release of Not-Owned [ERROR]";
+ break;
+ }
+}
class CFRefCount : public GRSimpleVals {
+
+ // Type definitions.
+
typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
typedef RefBindings::Factory RefBFactoryTy;
typedef llvm::SmallPtrSet<GRExprEngine::NodeTy*,2> UseAfterReleasesTy;
typedef llvm::SmallPtrSet<GRExprEngine::NodeTy*,2> ReleasesNotOwnedTy;
+ class BindingsPrinter : public ValueState::CheckerStatePrinter {
+ public:
+ virtual void PrintCheckerState(std::ostream& Out, void* State,
+ const char* nl, const char* sep);
+ };
+
+ // Instance variables.
+
CFRefSummaryManager Summaries;
RefBFactoryTy RefBFactory;
UseAfterReleasesTy UseAfterReleases;
ReleasesNotOwnedTy ReleasesNotOwned;
+ BindingsPrinter Printer;
+
+ // Private methods.
static RefBindings GetRefBindings(ValueState& StImpl) {
return RefBindings((RefBindings::TreeTy*) StImpl.CheckerState);
@@ -224,10 +269,15 @@ class CFRefCount : public GRSimpleVals {
RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
RefVal::Kind& hasError);
+
public:
CFRefCount() {}
virtual ~CFRefCount() {}
+
+ virtual ValueState::CheckerStatePrinter* getCheckerStatePrinter() {
+ return &Printer;
+ }
// Calls.
@@ -241,6 +291,21 @@ public:
} // end anonymous namespace
+void CFRefCount::BindingsPrinter::PrintCheckerState(std::ostream& Out,
+ void* State, const char* nl,
+ const char* sep) {
+ RefBindings B((RefBindings::TreeTy*) State);
+
+ if (State)
+ Out << sep << nl;
+
+ for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
+ Out << (*I).first << " : ";
+ (*I).second.print(Out);
+ Out << nl;
+ }
+}
+
void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
ValueStateManager& StateMgr,
GRStmtNodeBuilder<ValueState>& Builder,