[cfe-commits] r110085 - 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
Mon Aug 2 16:46:59 PDT 2010


Author: kremenek
Date: Mon Aug  2 18:46:59 2010
New Revision: 110085

URL: http://llvm.org/viewvc/llvm-project?rev=110085&view=rev
Log:
Add 'AnalysisContext::getUnoptimizedCFG()' to allow clients to get access to the original
CFG without any edges pruned out because of trivially solvable conditions (e.g., 'if (0)').

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=110085&r1=110084&r2=110085&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Mon Aug  2 18:46:59 2010
@@ -45,8 +45,8 @@
   idx::TranslationUnit *TU;
 
   // AnalysisContext owns the following data.
-  CFG *cfg;
-  bool builtCFG;
+  CFG *cfg, *completeCFG;
+  bool builtCFG, builtCompleteCFG;
   LiveVariables *liveness;
   ParentMap *PM;
   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
@@ -55,7 +55,9 @@
 public:
   AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
                   bool addehedges = false)
-    : D(d), TU(tu), cfg(0), builtCFG(false), liveness(0), PM(0),
+    : D(d), TU(tu), cfg(0), completeCFG(0),
+      builtCFG(false), builtCompleteCFG(false),
+      liveness(0), PM(0),
       ReferencedBlockVars(0), AddEHEdges(addehedges) {}
 
   ~AnalysisContext();
@@ -72,6 +74,10 @@
   bool getAddEHEdges() const { return AddEHEdges; }
   Stmt *getBody();
   CFG *getCFG();
+  
+  /// Return a version of the CFG without any edges pruned.
+  CFG *getUnoptimizedCFG();
+
   ParentMap &getParentMap();
   LiveVariables *getLiveVariables();
 

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=110085&r1=110084&r2=110085&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Mon Aug  2 18:46:59 2010
@@ -285,6 +285,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,
+                       bool pruneTriviallyFalseEdges = true,
                        bool AddEHEdges = false,
                        bool AddScopes = false /* NOT FULLY IMPLEMENTED.
                                                  NOT READY FOR GENERAL USE. */);

Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=110085&r1=110084&r2=110085&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Mon Aug  2 18:46:59 2010
@@ -55,7 +55,7 @@
 
 CFG *AnalysisContext::getCFG() {
   if (!builtCFG) {
-    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), AddEHEdges);
+    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), true, AddEHEdges);
     // Even when the cfg is not successfully built, we don't
     // want to try building it again.
     builtCFG = true;
@@ -63,6 +63,17 @@
   return cfg;
 }
 
+CFG *AnalysisContext::getUnoptimizedCFG() {
+  if (!builtCompleteCFG) {
+    completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(),
+                                false, AddEHEdges);
+    // Even when the cfg is not successfully built, we don't
+    // want to try building it again.
+    builtCompleteCFG = true;
+  }
+  return completeCFG;
+}
+
 ParentMap &AnalysisContext::getParentMap() {
   if (!PM)
     PM = new ParentMap(getBody());
@@ -297,6 +308,7 @@
 
 AnalysisContext::~AnalysisContext() {
   delete cfg;
+  delete completeCFG;
   delete liveness;
   delete PM;
   delete ReferencedBlockVars;

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=110085&r1=110084&r2=110085&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Mon Aug  2 18:46:59 2010
@@ -35,7 +35,7 @@
 
   return D->getLocation();
 }
-  
+
 class AddStmtChoice {
 public:
   enum Kind { NotAlwaysAdd = 0,
@@ -99,7 +99,8 @@
                           TryTerminatedBlock(NULL) {}
 
   // buildCFG - Used by external clients to construct the CFG.
-  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C, bool AddEHEdges,
+  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C,
+                bool pruneTriviallyFalseEdges, bool AddEHEdges,
                 bool AddScopes);
 
 private:
@@ -174,12 +175,12 @@
   CFGBlock *addStmt(Stmt *S) {
     return Visit(S, AddStmtChoice::AlwaysAdd);
   }
-  
+
   void AppendStmt(CFGBlock *B, Stmt *S,
                   AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
     B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
   }
-  
+
   void AddSuccessor(CFGBlock *B, CFGBlock *S) {
     B->addSuccessor(S, cfg->getBumpVectorContext());
   }
@@ -206,6 +207,9 @@
   /// TryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
   /// if we can evaluate to a known value, otherwise return -1.
   TryResult TryEvaluateBool(Expr *S) {
+    if (!PruneTriviallyFalseEdges)
+      return TryResult();
+
     Expr::EvalResult Result;
     if (!S->isTypeDependent() && !S->isValueDependent() &&
         S->Evaluate(Result, *Context) && Result.Val.isInt())
@@ -216,6 +220,9 @@
 
   bool badCFG;
 
+  // True iff trivially false edges should be pruned from the CFG.
+  bool PruneTriviallyFalseEdges;
+
   // True iff EH edges on CallExprs should be added to the CFG.
   bool AddEHEdges;
 
@@ -243,8 +250,12 @@
 ///  transferred to the caller.  If CFG construction fails, this method returns
 ///  NULL.
 CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
+                          bool pruneTriviallyFalseEdges,
                           bool addehedges, bool AddScopes) {
+
   AddEHEdges = addehedges;
+  PruneTriviallyFalseEdges = pruneTriviallyFalseEdges;
+
   Context = C;
   assert(cfg.get());
   if (!Statement)
@@ -384,10 +395,10 @@
 
     case Stmt::CXXThrowExprClass:
       return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
-      
+
     case Stmt::CXXTryStmtClass:
       return VisitCXXTryStmt(cast<CXXTryStmt>(S));
-      
+
     case Stmt::DeclStmtClass:
       return VisitDeclStmt(cast<DeclStmt>(S));
 
@@ -543,7 +554,7 @@
       autoCreateBlock();
       AppendStmt(Block, B, asc);
     }
-    
+
     Visit(B->getRHS());
     return Visit(B->getLHS(), AddStmtChoice::AsLValueNotAlwaysAdd);
   }
@@ -586,7 +597,7 @@
     Ty = Ty->getAs<PointerType>()->getPointeeType();
   else if (Ty->isBlockPointerType())
     Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
-    
+
   const FunctionType *FT = Ty->getAs<FunctionType>();
   if (FT) {
     if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT))
@@ -901,7 +912,7 @@
   // new blocks as the condition may contain control-flow.  Any newly created
   // blocks will be pointed to be "Block".
   Block = addStmt(I->getCond());
-  
+
   // Finally, if the IfStmt contains a condition variable, add both the IfStmt
   // and the condition variable initialization to the CFG.
   if (VarDecl *VD = I->getConditionVariable()) {
@@ -911,7 +922,7 @@
       addStmt(Init);
     }
   }
-  
+
   return Block;
 }
 
@@ -1029,7 +1040,7 @@
         assert(Block == EntryConditionBlock);
       }
     }
-    
+
     if (Block) {
       if (!FinishBlock(EntryConditionBlock))
         return 0;
@@ -1277,7 +1288,7 @@
     Block = ExitConditionBlock;
     EntryConditionBlock = addStmt(C);
     assert(Block == EntryConditionBlock);
-    
+
     // If this block contains a condition variable, add both the condition
     // variable and initializer to the CFG.
     if (VarDecl *VD = W->getConditionVariable()) {
@@ -1389,7 +1400,7 @@
   if (TryTerminatedBlock)
     // The current try statement is the only successor.
     AddSuccessor(Block, TryTerminatedBlock);
-  else 
+  else
     // otherwise the Exit block is the only successor.
     AddSuccessor(Block, &cfg->getExit());
 
@@ -1589,7 +1600,7 @@
   assert(Terminator->getCond() && "switch condition must be non-NULL");
   Block = SwitchTerminatedBlock;
   Block = addStmt(Terminator->getCond());
-  
+
   // Finally, if the SwitchStmt contains a condition variable, add both the
   // SwitchStmt and the condition variable initialization to the CFG.
   if (VarDecl *VD = Terminator->getConditionVariable()) {
@@ -1599,7 +1610,7 @@
       addStmt(Init);
     }
   }
-  
+
   return Block;
 }
 
@@ -1742,9 +1753,9 @@
   return CatchBlock;
 }
 
-CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C, 
+CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C,
                                              AddStmtChoice asc) {
-  AddStmtChoice::Kind K = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue 
+  AddStmtChoice::Kind K = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue
                                          : AddStmtChoice::AlwaysAdd;
   autoCreateBlock();
   AppendStmt(Block, C, AddStmtChoice(K));
@@ -1795,9 +1806,11 @@
 /// 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,
+                   bool PruneTriviallyFalse,
                    bool AddEHEdges, bool AddScopes) {
   CFGBuilder Builder;
-  return Builder.buildCFG(D, Statement, C, AddEHEdges, AddScopes);
+  return Builder.buildCFG(D, Statement, C, PruneTriviallyFalse,
+                          AddEHEdges, AddScopes);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1814,10 +1827,10 @@
     return;
 
   for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) {
-    Stmt *child = *I;    
+    Stmt *child = *I;
     if (!child)
       continue;
-    
+
     if (BinaryOperator* B = dyn_cast<BinaryOperator>(child))
       if (B->isAssignmentOp()) Set.insert(B);
 





More information about the cfe-commits mailing list