diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/AnalysisDeclContext.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 137 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 4 |
3 files changed, 95 insertions, 50 deletions
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp index 96a92b4b5b..5740e64d26 100644 --- a/lib/Analysis/AnalysisDeclContext.cpp +++ b/lib/Analysis/AnalysisDeclContext.cpp @@ -179,8 +179,8 @@ CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnaly return 0; } -void AnalysisDeclContext::dumpCFG() { - getCFG()->dump(getASTContext().getLangOptions()); +void AnalysisDeclContext::dumpCFG(bool ShowColors) { + getCFG()->dump(getASTContext().getLangOptions(), ShowColors); } ParentMap &AnalysisDeclContext::getParentMap() { diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 8d7aff19ca..5bbccf53c5 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -3554,27 +3554,35 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, static void print_block(raw_ostream &OS, const CFG* cfg, const CFGBlock &B, - StmtPrinterHelper* Helper, bool print_edges) { + StmtPrinterHelper* Helper, bool print_edges, + bool ShowColors) { - if (Helper) Helper->setBlockID(B.getBlockID()); + if (Helper) + Helper->setBlockID(B.getBlockID()); // Print the header. - OS << "\n [ B" << B.getBlockID(); + if (ShowColors) + OS.changeColor(raw_ostream::YELLOW, true); + + OS << "\n [B" << B.getBlockID(); if (&B == &cfg->getEntry()) - OS << " (ENTRY) ]\n"; + OS << " (ENTRY)]\n"; else if (&B == &cfg->getExit()) - OS << " (EXIT) ]\n"; + OS << " (EXIT)]\n"; else if (&B == cfg->getIndirectGotoBlock()) - OS << " (INDIRECT GOTO DISPATCH) ]\n"; + OS << " (INDIRECT GOTO DISPATCH)]\n"; else - OS << " ]\n"; + OS << "]\n"; + + if (ShowColors) + OS.resetColor(); // Print the label of this block. if (Stmt *Label = const_cast<Stmt*>(B.getLabel())) { if (print_edges) - OS << " "; + OS << " "; if (LabelStmt *L = dyn_cast<LabelStmt>(Label)) OS << L->getName(); @@ -3612,22 +3620,22 @@ static void print_block(raw_ostream &OS, const CFG* cfg, // Print the statement # in the basic block and the statement itself. if (print_edges) - OS << " "; + OS << " "; OS << llvm::format("%3d", j) << ": "; if (Helper) Helper->setStmtID(j); - print_elem(OS,Helper,*I); + print_elem(OS, Helper, *I); } // Print the terminator of this block. if (B.getTerminator()) { - if (print_edges) - OS << " "; + if (ShowColors) + OS.changeColor(raw_ostream::GREEN); - OS << " T: "; + OS << " T: "; if (Helper) Helper->setBlockID(-1); @@ -3635,54 +3643,86 @@ static void print_block(raw_ostream &OS, const CFG* cfg, PrintingPolicy(Helper->getLangOpts())); TPrinter.Visit(const_cast<Stmt*>(B.getTerminator().getStmt())); OS << '\n'; + + if (ShowColors) + OS.resetColor(); } if (print_edges) { // Print the predecessors of this block. - OS << " Predecessors (" << B.pred_size() << "):"; - unsigned i = 0; + if (!B.pred_empty()) { + const raw_ostream::Colors Color = raw_ostream::BLUE; + if (ShowColors) + OS.changeColor(Color); + OS << " Preds " ; + if (ShowColors) + OS.resetColor(); + OS << '(' << B.pred_size() << "):"; + unsigned i = 0; + + if (ShowColors) + OS.changeColor(Color); + + for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end(); + I != E; ++I, ++i) { - for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end(); - I != E; ++I, ++i) { + if (i == 8 || (i-8) == 0) + OS << "\n "; - if (i == 8 || (i-8) == 0) - OS << "\n "; + OS << " B" << (*I)->getBlockID(); + } + + if (ShowColors) + OS.resetColor(); - OS << " B" << (*I)->getBlockID(); + OS << '\n'; } - OS << '\n'; - // Print the successors of this block. - OS << " Successors (" << B.succ_size() << "):"; - i = 0; - - for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end(); - I != E; ++I, ++i) { - - if (i == 8 || (i-8) % 10 == 0) - OS << "\n "; - - if (*I) - OS << " B" << (*I)->getBlockID(); - else - OS << " NULL"; + if (!B.succ_empty()) { + const raw_ostream::Colors Color = raw_ostream::MAGENTA; + if (ShowColors) + OS.changeColor(Color); + OS << " Succs "; + if (ShowColors) + OS.resetColor(); + OS << '(' << B.succ_size() << "):"; + unsigned i = 0; + + if (ShowColors) + OS.changeColor(Color); + + for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end(); + I != E; ++I, ++i) { + + if (i == 8 || (i-8) % 10 == 0) + OS << "\n "; + + if (*I) + OS << " B" << (*I)->getBlockID(); + else + OS << " NULL"; + } + + if (ShowColors) + OS.resetColor(); + OS << '\n'; } - - OS << '\n'; } } /// dump - A simple pretty printer of a CFG that outputs to stderr. -void CFG::dump(const LangOptions &LO) const { print(llvm::errs(), LO); } +void CFG::dump(const LangOptions &LO, bool ShowColors) const { + print(llvm::errs(), LO, ShowColors); +} /// print - A simple pretty printer of a CFG that outputs to an ostream. -void CFG::print(raw_ostream &OS, const LangOptions &LO) const { +void CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const { StmtPrinterHelper Helper(this, LO); // Print the entry block. - print_block(OS, this, getEntry(), &Helper, true); + print_block(OS, this, getEntry(), &Helper, true, ShowColors); // Iterate through the CFGBlocks and print them one by one. for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) { @@ -3690,25 +3730,28 @@ void CFG::print(raw_ostream &OS, const LangOptions &LO) const { if (&(**I) == &getEntry() || &(**I) == &getExit()) continue; - print_block(OS, this, **I, &Helper, true); + print_block(OS, this, **I, &Helper, true, ShowColors); } // Print the exit block. - print_block(OS, this, getExit(), &Helper, true); + print_block(OS, this, getExit(), &Helper, true, ShowColors); + OS << '\n'; OS.flush(); } /// dump - A simply pretty printer of a CFGBlock that outputs to stderr. -void CFGBlock::dump(const CFG* cfg, const LangOptions &LO) const { - print(llvm::errs(), cfg, LO); +void CFGBlock::dump(const CFG* cfg, const LangOptions &LO, + bool ShowColors) const { + print(llvm::errs(), cfg, LO, ShowColors); } /// print - A simple pretty printer of a CFGBlock that outputs to an ostream. /// Generally this will only be called from CFG::print. void CFGBlock::print(raw_ostream &OS, const CFG* cfg, - const LangOptions &LO) const { + const LangOptions &LO, bool ShowColors) const { StmtPrinterHelper Helper(cfg, LO); - print_block(OS, cfg, *this, &Helper, true); + print_block(OS, cfg, *this, &Helper, true, ShowColors); + OS << '\n'; } /// printTerminator - A simple pretty printer of the terminator of a CFGBlock. @@ -3805,7 +3848,7 @@ struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits { #ifndef NDEBUG std::string OutSStr; llvm::raw_string_ostream Out(OutSStr); - print_block(Out,Graph, *Node, GraphHelper, false); + print_block(Out,Graph, *Node, GraphHelper, false, false); std::string& OutStr = Out.str(); if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index bd1b8542f6..d7e7af1c8e 100644 --- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -16,6 +16,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/Analyses/Dominators.h" +#include "llvm/Support/Process.h" using namespace clang; using namespace ento; @@ -92,7 +93,8 @@ public: void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, BugReporter &BR) const { if (CFG *cfg = mgr.getCFG(D)) { - cfg->dump(mgr.getLangOptions()); + cfg->dump(mgr.getLangOptions(), + llvm::sys::Process::StandardErrHasColors()); } } }; |