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

Ted Kremenek kremenek at apple.com
Wed Sep 8 17:06:04 PDT 2010


Author: kremenek
Date: Wed Sep  8 19:06:04 2010
New Revision: 113449

URL: http://llvm.org/viewvc/llvm-project?rev=113449&view=rev
Log:
Add 'filtered_pred_iterator' and 'filtered_succ_iterator' to CFGBlock.  This allows a client
to selectively walk successors/predecessors based on commonly used filters.  For starters, add
a filter to ignore 'default:' cases for SwitchStmts when all enum values are covered by CaseStmts.

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

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=113449&r1=113448&r2=113449&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Sep  8 19:06:04 2010
@@ -205,6 +205,59 @@
   unsigned                     pred_size()   const { return Preds.size();    }
   bool                         pred_empty()  const { return Preds.empty();   }
 
+
+  class FilterOptions {
+  public:
+    FilterOptions() {
+      IgnoreDefaultsWithCoveredEnums = 0;
+    };
+
+    unsigned IgnoreDefaultsWithCoveredEnums : 1;
+  };
+
+  static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
+			 const CFGBlock *Dst);
+
+  template <typename IMPL, bool IsPred>
+  class FilteredCFGBlockIterator {
+  private:
+    IMPL I, E;
+    const FilterOptions F;
+    const CFGBlock *From;
+   public:
+    explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
+				      const CFGBlock *from,
+				      const FilterOptions &f)
+      : I(i), E(e), F(f), From(from) {}
+
+    bool hasMore() const { return I != E; }
+
+    FilteredCFGBlockIterator &operator++() {
+      do { ++I; } while (hasMore() && Filter(*I));
+      return *this;
+    }
+
+    const CFGBlock *operator*() const { return *I; }
+  private:
+    bool Filter(const CFGBlock *To) {
+      return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
+    }
+  };
+
+  typedef FilteredCFGBlockIterator<const_pred_iterator, true>
+          filtered_pred_iterator;
+
+  typedef FilteredCFGBlockIterator<const_succ_iterator, false>
+          filtered_succ_iterator;
+
+  filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
+    return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
+  }
+
+  filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const {
+    return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
+  }
+
   // Manipulation of block contents
 
   void setTerminator(Stmt* Statement) { Terminator = Statement; }

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=113449&r1=113448&r2=113449&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Sep  8 19:06:04 2010
@@ -1937,6 +1937,29 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Filtered walking of the CFG.
+//===----------------------------------------------------------------------===//
+
+bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F,
+			  const CFGBlock *From, const CFGBlock *To) {
+
+  if (F.IgnoreDefaultsWithCoveredEnums) {
+    // If the 'To' has no label or is labeled but the label isn't a
+    // CaseStmt then filter this edge.
+    if (const SwitchStmt *S =
+	dyn_cast_or_null<SwitchStmt>(From->getTerminator())) {
+      if (S->isAllEnumCasesCovered()) {
+	const Stmt *L = To->getLabel();
+	if (!L || !isa<CaseStmt>(L))
+	  return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
 // Cleanup: CFG dstor.
 //===----------------------------------------------------------------------===//
 





More information about the cfe-commits mailing list