Remove unused, awkward CFGStmtVisitor and subclasses.
This class is a StmtVisitor that distinguishes between block-level and
non-block-level statements in a CFG. However, it does so using a hard-coded
idea of which statements might be block-level, which probably isn't accurate
anymore. The only implementer of the CFGStmtVisitor hierarchy was the
analyzer's DeadStoresChecker, and the analyzer creates a linearized CFG
anyway (every non-trivial statement is a block-level statement).
This also allows us to remove the block-expr map ("BlkExprMap"), which
mapped statements to positions in the CFG. Apart from having a helper type
that really should have just been Optional<unsigned>, it was only being
used to ask /if/ a particular expression was block-level, for traversal
purposes in CFGStmtVisitor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181945 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 6eb84ce..674c012 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -3400,113 +3400,6 @@
}
//===----------------------------------------------------------------------===//
-// CFG: Queries for BlkExprs.
-//===----------------------------------------------------------------------===//
-
-namespace {
- typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
-}
-
-static void FindSubExprAssignments(const Stmt *S,
- llvm::SmallPtrSet<const Expr*,50>& Set) {
- if (!S)
- return;
-
- for (Stmt::const_child_range I = S->children(); I; ++I) {
- const Stmt *child = *I;
- if (!child)
- continue;
-
- if (const BinaryOperator* B = dyn_cast<BinaryOperator>(child))
- if (B->isAssignmentOp()) Set.insert(B);
-
- FindSubExprAssignments(child, Set);
- }
-}
-
-static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
- BlkExprMapTy* M = new BlkExprMapTy();
-
- // Look for assignments that are used as subexpressions. These are the only
- // assignments that we want to *possibly* register as a block-level
- // expression. Basically, if an assignment occurs both in a subexpression and
- // at the block-level, it is a block-level expression.
- llvm::SmallPtrSet<const Expr*,50> SubExprAssignments;
-
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
- for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI)
- if (Optional<CFGStmt> S = BI->getAs<CFGStmt>())
- FindSubExprAssignments(S->getStmt(), SubExprAssignments);
-
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
-
- // Iterate over the statements again on identify the Expr* and Stmt* at the
- // block-level that are block-level expressions.
-
- for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) {
- Optional<CFGStmt> CS = BI->getAs<CFGStmt>();
- if (!CS)
- continue;
- if (const Expr *Exp = dyn_cast<Expr>(CS->getStmt())) {
- assert((Exp->IgnoreParens() == Exp) && "No parens on block-level exps");
-
- if (const BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
- // Assignment expressions that are not nested within another
- // expression are really "statements" whose value is never used by
- // another expression.
- if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))
- continue;
- } else if (const StmtExpr *SE = dyn_cast<StmtExpr>(Exp)) {
- // Special handling for statement expressions. The last statement in
- // the statement expression is also a block-level expr.
- const CompoundStmt *C = SE->getSubStmt();
- if (!C->body_empty()) {
- const Stmt *Last = C->body_back();
- if (const Expr *LastEx = dyn_cast<Expr>(Last))
- Last = LastEx->IgnoreParens();
- unsigned x = M->size();
- (*M)[Last] = x;
- }
- }
-
- unsigned x = M->size();
- (*M)[Exp] = x;
- }
- }
-
- // Look at terminators. The condition is a block-level expression.
-
- Stmt *S = (*I)->getTerminatorCondition();
-
- if (S && M->find(S) == M->end()) {
- unsigned x = M->size();
- (*M)[S] = x;
- }
- }
-
- return M;
-}
-
-CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt *S) {
- assert(S != NULL);
- if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); }
-
- BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);
- BlkExprMapTy::iterator I = M->find(S);
- return (I == M->end()) ? CFG::BlkExprNumTy() : CFG::BlkExprNumTy(I->second);
-}
-
-unsigned CFG::getNumBlkExprs() {
- if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap))
- return M->size();
-
- // We assume callers interested in the number of BlkExprs will want
- // the map constructed if it doesn't already exist.
- BlkExprMap = (void*) PopulateBlkExprMap(*this);
- return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size();
-}
-
-//===----------------------------------------------------------------------===//
// Filtered walking of the CFG.
//===----------------------------------------------------------------------===//
@@ -3530,14 +3423,6 @@
}
//===----------------------------------------------------------------------===//
-// Cleanup: CFG dstor.
-//===----------------------------------------------------------------------===//
-
-CFG::~CFG() {
- delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
-}
-
-//===----------------------------------------------------------------------===//
// CFG pretty printing
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 730aa6b..3d155c8 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -14,12 +14,12 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/StmtVisitor.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/UninitializedValues.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
-#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PackedVector.h"
diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index f336a6e..7c44c21 100644
--- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -18,7 +18,6 @@
#include "clang/AST/ParentMap.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
@@ -391,26 +390,24 @@
//===----------------------------------------------------------------------===//
namespace {
-class FindEscaped : public CFGRecStmtDeclVisitor<FindEscaped>{
- CFG *cfg;
+class FindEscaped {
public:
- FindEscaped(CFG *c) : cfg(c) {}
-
- CFG& getCFG() { return *cfg; }
-
llvm::SmallPtrSet<const VarDecl*, 20> Escaped;
- void VisitUnaryOperator(UnaryOperator* U) {
- // Check for '&'. Any VarDecl whose value has its address-taken we
- // treat as escaped.
- Expr *E = U->getSubExpr()->IgnoreParenCasts();
- if (U->getOpcode() == UO_AddrOf)
- if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
- if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
- Escaped.insert(VD);
- return;
- }
- Visit(E);
+ void operator()(const Stmt *S) {
+ // Check for '&'. Any VarDecl whose address has been taken we treat as
+ // escaped.
+ // FIXME: What about references?
+ const UnaryOperator *U = dyn_cast<UnaryOperator>(S);
+ if (!U)
+ return;
+ if (U->getOpcode() != UO_AddrOf)
+ return;
+
+ const Expr *E = U->getSubExpr()->IgnoreParenCasts();
+ if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
+ Escaped.insert(VD);
}
};
} // end anonymous namespace
@@ -438,8 +435,8 @@
CFG &cfg = *mgr.getCFG(D);
AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D);
ParentMap &pmap = mgr.getParentMap(D);
- FindEscaped FS(&cfg);
- FS.getCFG().VisitBlockStmts(FS);
+ FindEscaped FS;
+ cfg.VisitBlockStmts(FS);
DeadStoreObs A(cfg, BR.getContext(), BR, AC, pmap, FS.Escaped);
L->runOnAllBlocks(A);
}