[cfe-commits] r41779 - /cfe/trunk/Driver/ASTStreamers.cpp

Ted Kremenek kremenek at apple.com
Fri Sep 7 16:47:56 PDT 2007


Author: kremenek
Date: Fri Sep  7 18:47:56 2007
New Revision: 41779

URL: http://llvm.org/viewvc/llvm-project?rev=41779&view=rev
Log:
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.


Modified:
    cfe/trunk/Driver/ASTStreamers.cpp

Modified: cfe/trunk/Driver/ASTStreamers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.cpp?rev=41779&r1=41778&r2=41779&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTStreamers.cpp (original)
+++ cfe/trunk/Driver/ASTStreamers.cpp Fri Sep  7 18:47:56 2007
@@ -157,24 +157,44 @@
   ASTStreamer_Terminate(Streamer);
 }
 
-void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
-                     bool Stats, bool use_graphviz) 
-{
+//===----------------------------------------------------------------------===//
+// 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 (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
       if (FD->getBody()) {
-        PrintFunctionDeclStart(FD);
-        fprintf(stderr,"\n");
+        
+        if (printFDecl) {
+          PrintFunctionDeclStart(FD);          
+          fprintf(stderr,"\n");
+        }
+        
         if (CFG* C = CFG::buildCFG(FD->getBody())) {
-          if (use_graphviz) C->viewCFG(); else C->dump();
+          Visitor.VisitCFG(*C);
+          delete C;
         }
         else
-          fprintf(stderr," Error processing CFG.\n");
+          fprintf(stderr," Error processing CFG.\n");          
       }
-    }
   }
   
   if (Stats) {
@@ -186,54 +206,63 @@
   ASTStreamer_Terminate(Streamer);
 }
 
-void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID)
-{
-  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
-  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
+//===----------------------------------------------------------------------===//
+// 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 
   
-  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");
-      }
-    }
-  }
-      
-  ASTStreamer_Terminate(Streamer);
+void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
+                     bool Stats, bool use_graphviz) {
+  CFGDumper Visitor(use_graphviz);
+  VisitCFGs(Visitor,PP,MainFileID,Stats);
 }
 
-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");
-      }
+//===----------------------------------------------------------------------===//
+// 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());
     }
-  }
-  
-  if (Stats) {
-    fprintf(stderr, "\nSTATISTICS:\n");
-    ASTStreamer_PrintStats(Streamer);
-    Context.PrintStats();
-  }
+  };
+} // end anonymous namespace
   
-  ASTStreamer_Terminate(Streamer);
+void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID) {
+  LivenessVisitor Visitor(PP);
+  VisitCFGs(Visitor,PP,MainFileID,false);
 }
 
+//===----------------------------------------------------------------------===//
+// 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);
+}





More information about the cfe-commits mailing list