[cfe-commits] r48363 - in /cfe/trunk: Analysis/CFRefCount.cpp Analysis/GRSimpleVals.cpp Driver/ASTConsumers.cpp include/clang/Analysis/Analyses/GRSimpleVals.h include/clang/Analysis/LocalCheckers.h include/clang/Analysis/PathSensitive/ExplodedGraph.h include/clang/Analysis/PathSensitive/GRCoreEngine.h

Ted Kremenek kremenek at apple.com
Fri Mar 14 10:31:00 PDT 2008


Author: kremenek
Date: Fri Mar 14 12:31:00 2008
New Revision: 48363

URL: http://llvm.org/viewvc/llvm-project?rev=48363&view=rev
Log:
Path-sensitive analyses no longer take a FunctionDecl, but any Decl representing
a block of "code".

Patched various ASTConsumers (such as ASTDumper) to have more support for
processing ObjCMethodDecl. CFGVisitor now builds CFGs for ObjCMethodDecls.

Modified:
    cfe/trunk/Analysis/CFRefCount.cpp
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h
    cfe/trunk/include/clang/Analysis/LocalCheckers.h
    cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h

Modified: cfe/trunk/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/CFRefCount.cpp?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/Analysis/CFRefCount.cpp Fri Mar 14 12:31:00 2008
@@ -777,7 +777,7 @@
 
 namespace clang {
   
-  void CheckCFRefCount(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+  void CheckCFRefCount(CFG& cfg, Decl& CD, ASTContext& Ctx,
                        Diagnostic& Diag) {
     
     if (Diag.hasErrorOccurred())
@@ -785,7 +785,7 @@
     
     // FIXME: Refactor some day so this becomes a single function invocation.
     
-    GRCoreEngine<GRExprEngine> Eng(cfg, FD, Ctx);
+    GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
     GRExprEngine* CS = &Eng.getCheckerState();
     CFRefCount TF;
     CS->setTransferFunctions(TF);

Modified: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Fri Mar 14 12:31:00 2008
@@ -89,13 +89,13 @@
   }
 }
   
-unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                          Diagnostic& Diag, bool Visualize, bool TrimGraph) {
   
   if (Diag.hasErrorOccurred())
     return 0;
   
-  GRCoreEngine<GRExprEngine> Eng(cfg, FD, Ctx);
+  GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
   GRExprEngine* CheckerState = &Eng.getCheckerState();
   GRSimpleVals GRSV;
   CheckerState->setTransferFunctions(GRSV);

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Fri Mar 14 12:31:00 2008
@@ -409,7 +409,13 @@
         Out << "Read objc fwd class decl\n";
       } else if (isa<FileScopeAsmDecl>(D)) {
         Out << "Read file scope asm decl\n";
-      } else {
+      } else if (ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
+        Out << "Read objc method decl: '" << MD->getSelector().getName()
+            << "'\n";
+      } else if (isa<ObjCImplementationDecl>(D)) {
+        Out << "Read objc implementation decl\n";
+      }
+      else {
         assert(0 && "Unknown decl type!");
       }
     }
@@ -439,6 +445,15 @@
           llvm::cerr << '\n';
         }
       }
+      else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+        DeclPrinter().PrintObjCMethodDecl(MD);
+        
+        if (MD->getBody()) {
+          llvm::cerr << '\n';
+          MD->getBody()->viewAST();
+          llvm::cerr << '\n';
+        }
+      }
     }
   };
 }
@@ -459,7 +474,7 @@
   CFGVisitor() : FName("") {}
   
   // CFG Visitor interface to be implemented by subclass.
-  virtual void VisitCFG(CFG& C, FunctionDecl& FD) = 0;
+  virtual void VisitCFG(CFG& C, Decl& CD) = 0;
   virtual bool printFuncDeclStart() { return true; }
   
   virtual void HandleTopLevelDecl(Decl *D);
@@ -468,27 +483,41 @@
 } // end anonymous namespace
 
 void CFGVisitor::HandleTopLevelDecl(Decl *D) {
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  
+  CFG *C = NULL;
+  
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
 
-  if (!FD || !FD->getBody())
-    return;
+    if (!FD->getBody())
+      return;
   
-  if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
-    return;
+    if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
+      return;
+      
+    if (printFuncDeclStart()) {
+      DeclPrinter().PrintFunctionDeclStart(FD);
+      llvm::cerr << '\n';
+    }
       
-  if (printFuncDeclStart()) {
-    DeclPrinter().PrintFunctionDeclStart(FD);
-    llvm::cerr << '\n';
+    C = CFG::buildCFG(FD->getBody());
   }
+  else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    
+    if (!MD->getBody())
+      return;
     
-  CFG *C = CFG::buildCFG(FD->getBody());
+    if (printFuncDeclStart()) {
+      DeclPrinter().PrintObjCMethodDecl(MD);
+      llvm::cerr << '\n';
+    }
+    
+    C = CFG::buildCFG(MD->getBody());
+  }
   
   if (C) {  
-    VisitCFG(*C, *FD);
+    VisitCFG(*C, *D);
     delete C;
   }
-  else
-    llvm::cerr << "warning: CFG could not be constructed.\n";
 }
 
 //===----------------------------------------------------------------------===//
@@ -501,7 +530,7 @@
     CFGDumper(bool use_graphviz, const std::string& fname) 
      : CFGVisitor(fname), UseGraphviz(use_graphviz) {}
     
-    virtual void VisitCFG(CFG& C, FunctionDecl&) {
+    virtual void VisitCFG(CFG& C, Decl&) {
       if (UseGraphviz)
         C.viewCFG();
       else
@@ -527,7 +556,7 @@
       SM = &Context.getSourceManager();
     }
 
-    virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
+    virtual void VisitCFG(CFG& C, Decl& CD) {
       LiveVariables L(C);
       L.runOnCFG(C);
       L.dumpBlockLiveness(*SM);
@@ -552,7 +581,7 @@
       Ctx = &Context;
     }
     
-    virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
+    virtual void VisitCFG(CFG& C, Decl& CD) {
       CheckDeadStores(C, *Ctx, Diags);
     }
     
@@ -578,7 +607,7 @@
       Ctx = &Context;
     }
     
-    virtual void VisitCFG(CFG& C, FunctionDecl&) { 
+    virtual void VisitCFG(CFG& C, Decl&) { 
       CheckUninitializedValues(C, *Ctx, Diags);
     }
     
@@ -605,7 +634,7 @@
       : CFGVisitor(fname), Diags(diags), Visualize(visualize), TrimGraph(trim){}
     
     virtual void Initialize(ASTContext &Context) { Ctx = &Context; }    
-    virtual void VisitCFG(CFG& C, FunctionDecl&);
+    virtual void VisitCFG(CFG& C, Decl&);
     virtual bool printFuncDeclStart() { return false; }
   };
 } // end anonymous namespace
@@ -617,28 +646,37 @@
   return new GRSimpleValsVisitor(Diags, FunctionName, Visualize, TrimGraph);
 }
 
-void GRSimpleValsVisitor::VisitCFG(CFG& C, FunctionDecl& FD) {
+void GRSimpleValsVisitor::VisitCFG(CFG& C, Decl& CD) {
   
-  SourceLocation Loc = FD.getLocation();
+  SourceLocation Loc = CD.getLocation();
   
   if (!Loc.isFileID() ||
        Loc.getFileID() != Ctx->getSourceManager().getMainFileID())
     return;
   
   if (!Visualize) {
-    llvm::cerr << "ANALYZE: " << FD.getIdentifier()->getName() << ' '
-               << Ctx->getSourceManager().getSourceName(FD.getLocation())
-               << ' ';
+    
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(&CD)) {
+      llvm::cerr << "ANALYZE: " << FD->getIdentifier()->getName() << ' '
+                 << Ctx->getSourceManager().getSourceName(FD->getLocation())
+                 << ' ';
+    }
+    else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(&CD)) {
+      llvm::cerr << "ANALYZE (ObjC Method): "
+        << MD->getSelector().getName() << ' '
+        << Ctx->getSourceManager().getSourceName(MD->getLocation())
+        << ' ';
+    }
 
     llvm::Timer T("GRSimpleVals");
     T.startTimer();
-    unsigned size = RunGRSimpleVals(C, FD, *Ctx, Diags, false, false);
+    unsigned size = RunGRSimpleVals(C, CD, *Ctx, Diags, false, false);
     T.stopTimer();    
     llvm::cerr << size << ' ' << T.getWallTime() << '\n';
   }
   else {  
     llvm::cerr << '\n';    
-    RunGRSimpleVals(C, FD, *Ctx, Diags, Visualize, TrimGraph);
+    RunGRSimpleVals(C, CD, *Ctx, Diags, Visualize, TrimGraph);
   }    
 }
 
@@ -656,7 +694,7 @@
       : CFGVisitor(fname), Diags(diags) {}
     
     virtual void Initialize(ASTContext &Context) { Ctx = &Context; }    
-    virtual void VisitCFG(CFG& C, FunctionDecl&);
+    virtual void VisitCFG(CFG& C, Decl&);
     virtual bool printFuncDeclStart() { return false; }
   };
 } // end anonymous namespace
@@ -668,15 +706,15 @@
   return new CFRefCountCheckerVisitor(Diags, FunctionName);
 }
 
-void CFRefCountCheckerVisitor::VisitCFG(CFG& C, FunctionDecl& FD) {
+void CFRefCountCheckerVisitor::VisitCFG(CFG& C, Decl& CD) {
   
-  SourceLocation Loc = FD.getLocation();
+  SourceLocation Loc = CD.getLocation();
   
   if (!Loc.isFileID() ||
       Loc.getFileID() != Ctx->getSourceManager().getMainFileID())
     return;
      
-  CheckCFRefCount(C, FD, *Ctx, Diags);
+  CheckCFRefCount(C, CD, *Ctx, Diags);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h Fri Mar 14 12:31:00 2008
@@ -24,7 +24,7 @@
   ///  on a provided CFG.  This interface will eventually be replaced with
   ///  something more elaborate as the requirements on the interface become
   ///  clearer.  The value returned is the number of nodes in the ExplodedGraph.
-  unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+  unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                            Diagnostic& Diag, bool Visualize, bool TrimGraph);
   
 } // end clang namespace

Modified: cfe/trunk/include/clang/Analysis/LocalCheckers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/LocalCheckers.h?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/LocalCheckers.h (original)
+++ cfe/trunk/include/clang/Analysis/LocalCheckers.h Fri Mar 14 12:31:00 2008
@@ -18,7 +18,7 @@
 namespace clang {
 
 class CFG;
-class FunctionDecl;
+class Decl;
 class Diagnostic;
 class ASTContext;
 
@@ -27,7 +27,7 @@
 void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
                               bool FullUninitTaint=false);
   
-void CheckCFRefCount(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+void CheckCFRefCount(CFG& cfg, Decl& CodeDecl, ASTContext& Ctx,
                      Diagnostic& Diag);
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Fri Mar 14 12:31:00 2008
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
 
 #include "clang/Analysis/ProgramPoint.h"
+#include "clang/AST/Decl.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -23,6 +24,7 @@
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/Support/Casting.h"
 
 namespace clang {
 
@@ -34,9 +36,7 @@
 class GRSwitchNodeBuilderImpl;
 class CFG;
 class ASTContext;
-class FunctionDecl;
 
-  
 class ExplodedNodeImpl : public llvm::FoldingSetNode {
 protected:
   friend class ExplodedGraphImpl;
@@ -220,10 +220,11 @@
   /// cfg - The CFG associated with this analysis graph.
   CFG& cfg;
   
-  /// FD - The function declaration of the function being analyzed.
-  FunctionDecl& FD;
+  /// CodeDecl - The declaration containing the code being analyzed.  This
+  ///  can be a FunctionDecl or and ObjCMethodDecl.
+  Decl& CodeDecl;
   
-  /// Ctx - The ASTContext used to "interpret" FD.
+  /// Ctx - The ASTContext used to "interpret" CodeDecl.
   ASTContext& Ctx;
   
   /// NumNodes - The number of nodes in the graph.
@@ -250,8 +251,8 @@
   }
   
   // ctor.
-  ExplodedGraphImpl(CFG& c, FunctionDecl& f, ASTContext& ctx)
-    : cfg(c), FD(f), Ctx(ctx), NumNodes(0) {}
+  ExplodedGraphImpl(CFG& c, Decl& cd, ASTContext& ctx)
+    : cfg(c), CodeDecl(cd), Ctx(ctx), NumNodes(0) {}
 
 public:
   virtual ~ExplodedGraphImpl() {}
@@ -265,7 +266,12 @@
   llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
   CFG& getCFG() { return cfg; }
   ASTContext& getContext() { return Ctx; }
-  FunctionDecl& getFunctionDecl() { return FD; }
+  
+  const Decl& getCodeDecl() const { return CodeDecl; }
+
+  const FunctionDecl* getFunctionDecl() const {
+    return llvm::dyn_cast<FunctionDecl>(&CodeDecl);
+  }
   
   ExplodedGraphImpl* Trim(ExplodedNodeImpl** NBeg,
                           ExplodedNodeImpl** NEnd) const;
@@ -294,12 +300,12 @@
   }
   
   virtual ExplodedGraphImpl* MakeEmptyGraph() const {
-    return new ExplodedGraph(cfg, FD, Ctx);
+    return new ExplodedGraph(cfg, CodeDecl, Ctx);
   }  
     
 public:
-  ExplodedGraph(CFG& c, FunctionDecl& fd, ASTContext& ctx)
-    : ExplodedGraphImpl(c, fd, ctx), CheckerState(new CheckerTy(*this)) {}
+  ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx)
+    : ExplodedGraphImpl(c, cd, ctx), CheckerState(new CheckerTy(*this)) {}
   
   /// getCheckerState - Returns the internal checker state associated
   ///  with the exploded graph.  Ownership remains with the ExplodedGraph

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h?rev=48363&r1=48362&r2=48363&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Fri Mar 14 12:31:00 2008
@@ -505,15 +505,15 @@
 public:  
   /// Construct a GRCoreEngine object to analyze the provided CFG using
   ///  a DFS exploration of the exploded graph.
-  GRCoreEngine(CFG& cfg, FunctionDecl& fd, ASTContext& ctx)
-    : GRCoreEngineImpl(new GraphTy(cfg, fd, ctx), GRWorkList::MakeDFS()),
+  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx)
+    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), GRWorkList::MakeDFS()),
       Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {}
   
   /// Construct a GRCoreEngine object to analyze the provided CFG and to
   ///  use the provided worklist object to execute the worklist algorithm.
   ///  The GRCoreEngine object assumes ownership of 'wlist'.
-  GRCoreEngine(CFG& cfg, FunctionDecl& fd, ASTContext& ctx, GRWorkList* wlist)
-    : GRCoreEngineImpl(new GraphTy(cfg, fd, ctx), wlist),
+  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRWorkList* wlist)
+    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), wlist),
       Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {}
   
   virtual ~GRCoreEngine() {}





More information about the cfe-commits mailing list