Added "PrinterHelper" interface (include/AST/PrinterHelper) that can
be passed as an (optional) argument to StmtPrinter to customize
printing of AST nodes.

Used new PrinterHelper interface to enhance printing and visualization
of CFGs.  The CFGs now illustrate the semantic connectives between
statements and terminators, wheras in the previous printing certain
expressions would (visible) be printed multiple times to reflect which
expressions used the results of other expressions.

The end result is that the CFG is easier to read for flow of
expression values (following principles similar to the LLVM IR).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41651 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index 6903080..28bf446 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/Lex/IdentifierTable.h"
 #include "llvm/Support/Compiler.h"
 #include <iostream>
@@ -29,8 +30,10 @@
   class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
     std::ostream &OS;
     unsigned IndentLevel;
+    clang::PrinterHelper* Helper;
   public:
-    StmtPrinter(std::ostream &os) : OS(os), IndentLevel(0) {}
+    StmtPrinter(std::ostream &os, PrinterHelper* helper) : 
+      OS(os), IndentLevel(0), Helper(helper) {}
     
     void PrintStmt(Stmt *S, int SubIndent = 1) {
       IndentLevel += SubIndent;
@@ -67,6 +70,12 @@
     bool PrintOffsetOfDesignator(Expr *E);
     void VisitUnaryOffsetOf(UnaryOperator *Node);
     
+    void Visit(Stmt* S) {    
+      if (Helper && Helper->handledStmt(S,OS))
+          return;
+      else StmtVisitor<StmtPrinter>::Visit(S);
+    }
+    
     void VisitStmt(Stmt *Node);
 #define STMT(N, CLASS, PARENT) \
     void Visit##CLASS(CLASS *Node);
@@ -593,12 +602,19 @@
   printPretty(std::cerr);
 }
 
-void Stmt::printPretty(std::ostream &OS) const {
+void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
   if (this == 0) {
     OS << "<NULL>";
     return;
   }
 
-  StmtPrinter P(OS);
+  StmtPrinter P(OS, Helper);
   P.Visit(const_cast<Stmt*>(this));
 }
+
+//===----------------------------------------------------------------------===//
+// PrinterHelper
+//===----------------------------------------------------------------------===//
+
+// Implement virtual destructor.
+PrinterHelper::~PrinterHelper() {}
\ No newline at end of file