[cfe-commits] r127385 - in /cfe/trunk: include/clang/Analysis/AnalysisContext.h include/clang/Analysis/CFG.h lib/Analysis/AnalysisContext.cpp lib/Analysis/CFG.cpp

Ted Kremenek kremenek at apple.com
Wed Mar 9 17:14:05 PST 2011


Author: kremenek
Date: Wed Mar  9 19:14:05 2011
New Revision: 127385

URL: http://llvm.org/viewvc/llvm-project?rev=127385&view=rev
Log:
Rework interaction between AnalysisContext and CFG::BuildOptions to keep a BuildOptions object around instead of keeping a copy of the flags.

Moreover, change AnalysisContext to use an OwningPtr for created analysis objects instead
of directly managing them.

Finally, add a 'forcedBlkExprs' entry to CFG::BuildOptions that will be used by the
CFGBuilder to force specific expressions to be block-level expressions.

Modified:
    cfe/trunk/include/clang/Analysis/AnalysisContext.h
    cfe/trunk/include/clang/Analysis/CFG.h
    cfe/trunk/lib/Analysis/AnalysisContext.cpp
    cfe/trunk/lib/Analysis/CFG.cpp

Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Mar  9 19:14:05 2011
@@ -17,6 +17,7 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
+#include "clang/Analysis/CFG.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerUnion.h"
@@ -27,8 +28,6 @@
 
 class Decl;
 class Stmt;
-class CFG;
-class CFGBlock;
 class CFGReachabilityAnalysis;
 class CFGStmtMap;
 class LiveVariables;
@@ -48,33 +47,32 @@
   // TranslationUnit is NULL if we don't have multiple translation units.
   idx::TranslationUnit *TU;
 
-  // AnalysisContext owns the following data.
-  CFG *cfg, *completeCFG;
-  CFGStmtMap *cfgStmtMap;
+  llvm::OwningPtr<CFG> cfg, completeCFG;
+  llvm::OwningPtr<CFGStmtMap> cfgStmtMap;
+
+  CFG::BuildOptions cfgBuildOptions;
+  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
+  
   bool builtCFG, builtCompleteCFG;
-  LiveVariables *liveness;
-  LiveVariables *relaxedLiveness;
-  ParentMap *PM;
-  PseudoConstantAnalysis *PCA;
-  CFGReachabilityAnalysis *CFA;
-  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+  const bool useUnoptimizedCFG;
+
+  llvm::OwningPtr<LiveVariables> liveness;
+  llvm::OwningPtr<LiveVariables> relaxedLiveness;
+  llvm::OwningPtr<ParentMap> PM;
+  llvm::OwningPtr<PseudoConstantAnalysis> PCA;
+  llvm::OwningPtr<CFGReachabilityAnalysis> CFA;
+
   llvm::BumpPtrAllocator A;
-  bool UseUnoptimizedCFG;  
-  bool AddEHEdges;
-  bool AddImplicitDtors;
-  bool AddInitializers;
+
+  // FIXME: remove.
+  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+
 public:
   AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
                   bool useUnoptimizedCFG = false,
                   bool addehedges = false,
                   bool addImplicitDtors = false,
-                  bool addInitializers = false)
-    : D(d), TU(tu), cfg(0), completeCFG(0), cfgStmtMap(0),
-      builtCFG(false), builtCompleteCFG(false),
-      liveness(0), relaxedLiveness(0), PM(0), PCA(0), CFA(0),
-      ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
-      AddEHEdges(addehedges), AddImplicitDtors(addImplicitDtors),
-      AddInitializers(addInitializers) {}
+                  bool addInitializers = false);
 
   ~AnalysisContext();
 
@@ -87,11 +85,12 @@
   /// callExprs.  If this is false, then try/catch statements and blocks
   /// reachable from them can appear to be dead in the CFG, analysis passes must
   /// cope with that.
-  bool getAddEHEdges() const { return AddEHEdges; }
-  
-  bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
-  bool getAddImplicitDtors() const { return AddImplicitDtors; }
-  bool getAddInitializers() const { return AddInitializers; }
+  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }  
+  bool getUseUnoptimizedCFG() const {
+      return cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
+  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
 
   Stmt *getBody();
   CFG *getCFG();

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Mar  9 19:14:05 2011
@@ -19,6 +19,8 @@
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/DenseMap.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/Basic/SourceLocation.h"
 #include <cassert>
@@ -532,13 +534,16 @@
 
   class BuildOptions {
   public:
+    typedef llvm::DenseMap<const Stmt *, const CFGBlock> ForcedBlkExprs;
+    ForcedBlkExprs **forcedBlkExprs;    
+
     bool PruneTriviallyFalseEdges:1;
     bool AddEHEdges:1;
     bool AddInitializers:1;
     bool AddImplicitDtors:1;
 
     BuildOptions()
-        : PruneTriviallyFalseEdges(true)
+        : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
         , AddEHEdges(false)
         , AddInitializers(false)
         , AddImplicitDtors(false) {}
@@ -547,7 +552,7 @@
   /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
   ///   constructed CFG belongs to the caller.
   static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
-      BuildOptions BO = BuildOptions());
+                       const BuildOptions &BO);
 
   /// createBlock - Create a new block in the CFG.  The CFG owns the block;
   ///  the caller should not directly free it.

Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Wed Mar  9 19:14:05 2011
@@ -29,6 +29,24 @@
 
 using namespace clang;
 
+AnalysisContext::AnalysisContext(const Decl *d,
+                                 idx::TranslationUnit *tu,
+                                 bool useUnoptimizedCFG,
+                                 bool addehedges,
+                                 bool addImplicitDtors,
+                                 bool addInitializers)
+  : D(d), TU(tu),
+    forcedBlkExprs(0),
+    builtCFG(false), builtCompleteCFG(false),
+    useUnoptimizedCFG(useUnoptimizedCFG),
+    ReferencedBlockVars(0)
+{
+  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
+  cfgBuildOptions.AddEHEdges = addehedges;
+  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
+  cfgBuildOptions.AddInitializers = addInitializers;
+}
+
 void AnalysisContextManager::clear() {
   for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
     delete I->second;
@@ -57,44 +75,38 @@
 }
 
 CFG *AnalysisContext::getCFG() {
-  if (UseUnoptimizedCFG)
+  if (useUnoptimizedCFG)
     return getUnoptimizedCFG();
 
   if (!builtCFG) {
-    CFG::BuildOptions B;
-    B.AddEHEdges = AddEHEdges;
-    B.AddImplicitDtors = AddImplicitDtors;
-    B.AddInitializers = AddInitializers;
-    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), B);
+    cfg.reset(CFG::buildCFG(D, getBody(),
+                            &D->getASTContext(), cfgBuildOptions));
     // Even when the cfg is not successfully built, we don't
     // want to try building it again.
     builtCFG = true;
   }
-  return cfg;
+  return cfg.get();
 }
 
 CFG *AnalysisContext::getUnoptimizedCFG() {
   if (!builtCompleteCFG) {
-    CFG::BuildOptions B;
+    CFG::BuildOptions B = cfgBuildOptions;
     B.PruneTriviallyFalseEdges = false;
-    B.AddEHEdges = AddEHEdges;
-    B.AddImplicitDtors = AddImplicitDtors;
-    B.AddInitializers = AddInitializers;
-    completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(), B);
+    completeCFG.reset(CFG::buildCFG(D, getBody(), &D->getASTContext(), B));
     // Even when the cfg is not successfully built, we don't
     // want to try building it again.
     builtCompleteCFG = true;
   }
-  return completeCFG;
+  return completeCFG.get();
 }
 
 CFGStmtMap *AnalysisContext::getCFGStmtMap() {
   if (cfgStmtMap)
-    return cfgStmtMap;
+    return cfgStmtMap.get();
   
   if (CFG *c = getCFG()) {
-    cfgStmtMap = CFGStmtMap::Build(c, &getParentMap());
-    return cfgStmtMap;
+    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
+    return cfgStmtMap.get();
   }
     
   return 0;
@@ -102,11 +114,11 @@
 
 CFGReachabilityAnalysis *AnalysisContext::getCFGReachablityAnalysis() {
   if (CFA)
-    return CFA;
+    return CFA.get();
   
   if (CFG *c = getCFG()) {
-    CFA = new CFGReachabilityAnalysis(*c);
-    return CFA;
+    CFA.reset(new CFGReachabilityAnalysis(*c));
+    return CFA.get();
   }
   
   return 0;
@@ -118,42 +130,37 @@
 
 ParentMap &AnalysisContext::getParentMap() {
   if (!PM)
-    PM = new ParentMap(getBody());
+    PM.reset(new ParentMap(getBody()));
   return *PM;
 }
 
 PseudoConstantAnalysis *AnalysisContext::getPseudoConstantAnalysis() {
   if (!PCA)
-    PCA = new PseudoConstantAnalysis(getBody());
-  return PCA;
+    PCA.reset(new PseudoConstantAnalysis(getBody()));
+  return PCA.get();
 }
 
 LiveVariables *AnalysisContext::getLiveVariables() {
   if (!liveness) {
-    CFG *c = getCFG();
-    if (!c)
-      return 0;
-
-    liveness = new LiveVariables(*this);
-    liveness->runOnCFG(*c);
-    liveness->runOnAllBlocks(*c, 0, true);
+    if (CFG *c = getCFG()) {
+      liveness.reset(new LiveVariables(*this));
+      liveness->runOnCFG(*c);
+      liveness->runOnAllBlocks(*c, 0, true);
+    }
   }
 
-  return liveness;
+  return liveness.get();
 }
 
 LiveVariables *AnalysisContext::getRelaxedLiveVariables() {
-  if (!relaxedLiveness) {
-    CFG *c = getCFG();
-    if (!c)
-      return 0;
-
-    relaxedLiveness = new LiveVariables(*this, false);
-    relaxedLiveness->runOnCFG(*c);
-    relaxedLiveness->runOnAllBlocks(*c, 0, true);
-  }
+  if (!relaxedLiveness)
+    if (CFG *c = getCFG()) {
+      relaxedLiveness.reset(new LiveVariables(*this, false));
+      relaxedLiveness->runOnCFG(*c);
+      relaxedLiveness->runOnAllBlocks(*c, 0, true);
+    }
 
-  return relaxedLiveness;
+  return relaxedLiveness.get();
 }
 
 AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
@@ -370,14 +377,7 @@
 //===----------------------------------------------------------------------===//
 
 AnalysisContext::~AnalysisContext() {
-  delete cfg;
-  delete completeCFG;
-  delete cfgStmtMap;
-  delete liveness;
-  delete relaxedLiveness;
-  delete PM;
-  delete PCA;
-  delete CFA;
+  delete forcedBlkExprs;
   delete ReferencedBlockVars;
 }
 

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Mar  9 19:14:05 2011
@@ -275,22 +275,23 @@
   LabelSetTy AddressTakenLabels;
 
   bool badCFG;
-  CFG::BuildOptions BuildOpts;
+  const CFG::BuildOptions &BuildOpts;
   
   // State to track for building switch statements.
   bool switchExclusivelyCovered;
   Expr::EvalResult *switchCond;
 
 public:
-  explicit CFGBuilder() : cfg(new CFG()), // crew a new CFG
-                          Block(NULL), Succ(NULL),
-                          SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
-                          TryTerminatedBlock(NULL), badCFG(false),
-                          switchExclusivelyCovered(false), switchCond(0) {}
+  explicit CFGBuilder(ASTContext *astContext,
+                      const CFG::BuildOptions &buildOpts) 
+    : Context(astContext), cfg(new CFG()), // crew a new CFG
+      Block(NULL), Succ(NULL),
+      SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
+      TryTerminatedBlock(NULL), badCFG(false), BuildOpts(buildOpts), 
+      switchExclusivelyCovered(false), switchCond(0) {}
 
   // buildCFG - Used by external clients to construct the CFG.
-  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C,
-      CFG::BuildOptions BO);
+  CFG* buildCFG(const Decl *D, Stmt *Statement);
 
 private:
   // Visitors to walk an AST and construct the CFG.
@@ -460,16 +461,11 @@
 ///  body (compound statement).  The ownership of the returned CFG is
 ///  transferred to the caller.  If CFG construction fails, this method returns
 ///  NULL.
-CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
-    CFG::BuildOptions BO) {
-
-  Context = C;
+CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement) {
   assert(cfg.get());
   if (!Statement)
     return NULL;
 
-  BuildOpts = BO;
-
   // Create an empty block that will serve as the exit block for the CFG.  Since
   // this is the first block added to the CFG, it will be implicitly registered
   // as the exit block.
@@ -2768,9 +2764,9 @@
 /// buildCFG - Constructs a CFG from an AST.  Ownership of the returned
 ///  CFG is returned to the caller.
 CFG* CFG::buildCFG(const Decl *D, Stmt* Statement, ASTContext *C,
-    BuildOptions BO) {
-  CFGBuilder Builder;
-  return Builder.buildCFG(D, Statement, C, BO);
+    const BuildOptions &BO) {
+  CFGBuilder Builder(C, BO);
+  return Builder.buildCFG(D, Statement);
 }
 
 const CXXDestructorDecl *





More information about the cfe-commits mailing list