ce_iterator ce_begin() const { return ConstEq.begin(); }
ce_iterator ce_end() const { return ConstEq.end(); }
- class CheckerStatePrinter {
+ class Printer {
public:
- virtual ~CheckerStatePrinter() {}
- virtual void PrintCheckerState(std::ostream& Out, void* State,
- const char* nl, const char* sep) = 0;
+ virtual ~Printer() {}
+ virtual void Print(std::ostream& Out, const GRState* state,
+ const char* nl, const char* sep) = 0;
};
- void print(std::ostream& Out, CheckerStatePrinter* P = NULL,
- const char* nl = "\n", const char* sep = "") const;
+ void print(std::ostream& Out, Printer **Beg = 0, Printer **End = 0,
+ const char* nl = "\n", const char *sep = "") const;
- void printStdErr(CheckerStatePrinter* P = NULL) const;
-
- void printDOT(std::ostream& Out, CheckerStatePrinter*P = NULL) const;
+ void printStdErr(Printer **Beg = 0, Printer **End = 0) const;
+ void printDOT(std::ostream& Out, Printer **Beg = 0, Printer **End = 0) const;
};
template<> struct GRTrait<GRState*> {
#include "clang/Analysis/PathSensitive/RValues.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
+#include <vector>
namespace clang {
GRTransferFuncs() {}
virtual ~GRTransferFuncs() {}
- virtual GRState::CheckerStatePrinter* getCheckerStatePrinter() {
- return NULL;
- }
-
+ virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {}
virtual void RegisterChecks(GRExprEngine& Eng);
// Casts.
typedef llvm::DenseMap<GRExprEngine::NodeTy*, std::vector<SymbolID>*>
LeaksTy;
- class BindingsPrinter : public GRState::CheckerStatePrinter {
+ class BindingsPrinter : public GRState::Printer {
public:
- virtual void PrintCheckerState(std::ostream& Out, void* State,
- const char* nl, const char* sep);
+ virtual void Print(std::ostream& Out, const GRState* state,
+ const char* nl, const char* sep);
};
private:
static RefBindings GetRefBindings(const GRState& StImpl) {
return RefBindings((const RefBindings::TreeTy*) StImpl.CheckerState);
}
+
+ static RefBindings GetRefBindings(const GRState* state) {
+ return RefBindings((const RefBindings::TreeTy*) state->CheckerState);
+ }
private:
virtual void RegisterChecks(GRExprEngine& Eng);
- virtual GRState::CheckerStatePrinter* getCheckerStatePrinter() {
- return &Printer;
+ virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {
+ Printers.push_back(&Printer);
}
bool isGCEnabled() const { return Summaries.isGCEnabled(); }
-void CFRefCount::BindingsPrinter::PrintCheckerState(std::ostream& Out,
- void* State, const char* nl,
- const char* sep) {
- RefBindings B((RefBindings::TreeTy*) State);
+void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
+ const char* nl, const char* sep) {
+
+ RefBindings B = GetRefBindings(state);
- if (State)
+ if (!B.isEmpty())
Out << sep << nl;
for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
#ifndef NDEBUG
static GRExprEngine* GraphPrintCheckerState;
static SourceManager* GraphPrintSourceManager;
-static GRState::CheckerStatePrinter* GraphCheckerStatePrinter;
+static GRState::Printer **GraphStatePrinterBeg, **GraphStatePrinterEnd;
namespace llvm {
template<>
Out << "\\|StateID: " << (void*) N->getState() << "\\|";
- N->getState()->printDOT(Out, GraphCheckerStatePrinter);
+ N->getState()->printDOT(Out, GraphStatePrinterBeg, GraphStatePrinterEnd);
Out << "\\l";
return Out.str();
else {
GraphPrintCheckerState = this;
GraphPrintSourceManager = &getContext().getSourceManager();
- GraphCheckerStatePrinter = getTF().getCheckerStatePrinter();
+
+ // Get the state printers.
+ std::vector<GRState::Printer*> Printers;
+ getTF().getStatePrinters(Printers);
+ GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
+ GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
+
llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
- GraphCheckerStatePrinter = NULL;
+ GraphStatePrinterBeg = NULL;
+ GraphStatePrinterEnd = NULL;
}
#endif
}
#ifndef NDEBUG
GraphPrintCheckerState = this;
GraphPrintSourceManager = &getContext().getSourceManager();
- GraphCheckerStatePrinter = getTF().getCheckerStatePrinter();
+
+ // Get the state printers.
+ std::vector<GRState::Printer*> Printers;
+ getTF().getStatePrinters(Printers);
+ GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
+ GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End);
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
- GraphCheckerStatePrinter = NULL;
+ GraphStatePrinterBeg = NULL;
+ GraphStatePrinterEnd = NULL;
#endif
}
return I;
}
-void GRState::printDOT(std::ostream& Out, CheckerStatePrinter* P) const {
- print(Out, P, "\\l", "\\|");
+void GRState::printDOT(std::ostream& Out,
+ Printer** Beg, Printer** End) const {
+ print(Out, Beg, End, "\\l", "\\|");
}
-void GRState::printStdErr(CheckerStatePrinter* P) const {
- print(*llvm::cerr, P);
+void GRState::printStdErr(Printer** Beg, Printer** End) const {
+ print(*llvm::cerr, Beg, End);
}
-void GRState::print(std::ostream& Out, CheckerStatePrinter* P,
- const char* nl, const char* sep) const {
+void GRState::print(std::ostream& Out, Printer** Beg, Printer** End,
+ const char* nl, const char* sep) const {
// Print Variable Bindings
Out << "Variables:" << nl;
}
// Print equality constraints.
+ // FIXME: Make just another printer do this.
if (!ConstEq.isEmpty()) {
}
// Print != constraints.
+ // FIXME: Make just another printer do this.
if (!ConstNotEq.isEmpty()) {
}
}
- // Print checker-specific data.
-
- if (P && CheckerState)
- P->PrintCheckerState(Out, CheckerState, nl, sep);
+ // Print checker-specific data.
+ for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
}