Refactored driver options that perform analyses/work over CFGs to use
"CFGVisitor", which now handles all the boilerplate for iterating over
the function definitions in a translation unit and building the CFGs.
This logic was previously replicated for each driver option that used
CFGs.

The options -dump-cfg, -view-cfg, -check-dead-stores, and
-dump-live-variables now use this refactored code.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41779 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp
index 95d39fa..d6db959 100644
--- a/Driver/ASTStreamers.cpp
+++ b/Driver/ASTStreamers.cpp
@@ -157,83 +157,112 @@
   ASTStreamer_Terminate(Streamer);
 }
 
+//===----------------------------------------------------------------------===//
+// CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
+//   the CFGs for all function definitions.
+
+namespace {
+
+class CFGVisitor {
+public:
+  virtual ~CFGVisitor() {}
+  virtual void VisitCFG(CFG& C) = 0;
+  virtual bool printFuncDeclStart() { return true; }
+};
+
+} // end anonymous namespace
+
+static void VisitCFGs(CFGVisitor& Visitor, Preprocessor& PP, 
+                      unsigned MainFileID, bool Stats) {
+
+  bool printFDecl = Visitor.printFuncDeclStart();
+  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
+  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
+  
+  while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      if (FD->getBody()) {
+        
+        if (printFDecl) {
+          PrintFunctionDeclStart(FD);          
+          fprintf(stderr,"\n");
+        }
+        
+        if (CFG* C = CFG::buildCFG(FD->getBody())) {
+          Visitor.VisitCFG(*C);
+          delete C;
+        }
+        else
+          fprintf(stderr," Error processing CFG.\n");          
+      }
+  }
+  
+  if (Stats) {
+    fprintf(stderr, "\nSTATISTICS:\n");
+    ASTStreamer_PrintStats(Streamer);
+    Context.PrintStats();
+  }
+  
+  ASTStreamer_Terminate(Streamer);
+}
+
+//===----------------------------------------------------------------------===//
+// DumpCFGs - Dump CFGs to stderr or visualize with Graphviz
+
+namespace {
+  class CFGDumper : public CFGVisitor {
+    const bool UseGraphviz;
+  public:
+    CFGDumper(bool use_graphviz) : UseGraphviz(use_graphviz) {}
+    
+    virtual void VisitCFG(CFG& C) {
+      if (UseGraphviz) C.viewCFG();
+      else C.dump();
+    }    
+  }; 
+} // end anonymous namespace 
+  
 void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
-                     bool Stats, bool use_graphviz) 
-{
-  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
-  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
-  
-  while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {      
-      if (FD->getBody()) {
-        PrintFunctionDeclStart(FD);
-        fprintf(stderr,"\n");
-        if (CFG* C = CFG::buildCFG(FD->getBody())) {
-          if (use_graphviz) C->viewCFG(); else C->dump();
-        }
-        else
-          fprintf(stderr," Error processing CFG.\n");
-      }
-    }
-  }
-  
-  if (Stats) {
-    fprintf(stderr, "\nSTATISTICS:\n");
-    ASTStreamer_PrintStats(Streamer);
-    Context.PrintStats();
-  }
-  
-  ASTStreamer_Terminate(Streamer);
+                     bool Stats, bool use_graphviz) {
+  CFGDumper Visitor(use_graphviz);
+  VisitCFGs(Visitor,PP,MainFileID,Stats);
 }
 
-void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID)
-{
-  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
-  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
-  
-  while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {      
-      if (FD->getBody()) {
-        PrintFunctionDeclStart(FD);
-        fprintf(stderr,"\n");
-        if (CFG* C = CFG::buildCFG(FD->getBody())) {
-          LiveVariables L;
-          L.runOnCFG(*C);
-          L.dumpBlockLiveness(PP.getSourceManager());
-        }
-        else
-          fprintf(stderr," Error processing CFG.\n");
-      }
+//===----------------------------------------------------------------------===//
+// AnalyzeLiveVariables - perform live variable analysis and dump results
+
+namespace {
+  class LivenessVisitor : public CFGVisitor {
+    Preprocessor& PP;
+  public:
+    LivenessVisitor(Preprocessor& pp) : PP(pp) {}
+    
+    virtual void VisitCFG(CFG& C) {
+      LiveVariables L;
+      L.runOnCFG(C);
+      L.dumpBlockLiveness(PP.getSourceManager());
     }
-  }
-      
-  ASTStreamer_Terminate(Streamer);
+  };
+} // end anonymous namespace
+  
+void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID) {
+  LivenessVisitor Visitor(PP);
+  VisitCFGs(Visitor,PP,MainFileID,false);
 }
 
-void clang::RunDeadStoresCheck(Preprocessor &PP, unsigned MainFileID,bool Stats)
-{
-  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
-  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
-  
-  while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {      
-      if (FD->getBody()) {
-        if (CFG* C = CFG::buildCFG(FD->getBody())) {
-          clang::CheckDeadStores(*C,PP);
-        }
-        else
-          fprintf(stderr," Error processing CFG.\n");
-      }
-    }
-  }
-  
-  if (Stats) {
-    fprintf(stderr, "\nSTATISTICS:\n");
-    ASTStreamer_PrintStats(Streamer);
-    Context.PrintStats();
-  }
-  
-  ASTStreamer_Terminate(Streamer);
+//===----------------------------------------------------------------------===//
+// RunDeadStores - run checker to locate dead stores in a function
+
+namespace {
+  class DeadStoreVisitor : public CFGVisitor {
+    Preprocessor& PP;
+  public:
+    DeadStoreVisitor(Preprocessor& pp) : PP(pp) {}
+    virtual void VisitCFG(CFG& C) { CheckDeadStores(C,PP); }
+  }; 
+} // end anonymous namespace
+
+void clang::RunDeadStoresCheck(Preprocessor &PP,unsigned MainFileID,bool Stats){
+  DeadStoreVisitor Visitor(PP);
+  VisitCFGs(Visitor,PP,MainFileID,Stats);
 }
-
-