[cfe-commits] r44246 - in /cfe/trunk: Analysis/LiveVariables.cpp Analysis/UninitializedValues.cpp include/clang/Analysis/Visitors/CFGRecStmtVisitor.h include/clang/Analysis/Visitors/CFGStmtVisitor.h
Ted Kremenek
kremenek at apple.com
Mon Nov 19 19:01:59 PST 2007
Author: kremenek
Date: Mon Nov 19 21:01:58 2007
New Revision: 44246
URL: http://llvm.org/viewvc/llvm-project?rev=44246&view=rev
Log:
Updated CFGStmtVisitor and CFGRecStmtVisitor to have a notion of
"block-expressions" when visiting arbitrary expressions (via calls to
"Visit()"). This results in a refactoring where a dataflow analysis no
longer needs to always special case when handling block-expressions versus
non-block expressions.
Updated LiveVariables and UninitializedValues to conform to the slightly
altered interface of these visitor classes.
Thanks to Nuno Lopes for providing a test case that illustrated some
fundamental problems in the current design of the CFGXXXStmtVisitor classes
and how they were used.
Modified:
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/Analysis/UninitializedValues.cpp
cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h
Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=44246&r1=44245&r2=44246&view=diff
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Mon Nov 19 21:01:58 2007
@@ -35,6 +35,7 @@
public:
RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
+ CFG& getCFG() { return AD.getCFG(); }
};
} // end anonymous namespace
@@ -52,34 +53,25 @@
static const bool Alive = true;
static const bool Dead = false;
-class TransferFuncs : public CFGStmtVisitor<TransferFuncs> {
+class TransferFuncs : public CFGRecStmtVisitor<TransferFuncs> {
LiveVariables::AnalysisDataTy& AD;
LiveVariables::ValTy LiveState;
public:
TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
LiveVariables::ValTy& getVal() { return LiveState; }
+ CFG& getCFG() { return AD.getCFG(); }
void VisitDeclRefExpr(DeclRefExpr* DR);
void VisitBinaryOperator(BinaryOperator* B);
void VisitAssign(BinaryOperator* B);
void VisitDeclStmt(DeclStmt* DS);
void VisitUnaryOperator(UnaryOperator* U);
- void VisitStmt(Stmt* S);
- void VisitExpr(Expr* E);
- void BlockStmt_VisitExpr(Expr *E);
void Visit(Stmt *S);
DeclRefExpr* FindDeclRef(Stmt *S);
};
-
-void TransferFuncs::VisitExpr(Expr * E) {
- if (AD.getCFG().isBlkExpr(E)) return;
- else VisitStmt(E);
-}
-void TransferFuncs::VisitStmt(Stmt* S) { VisitChildren(S); }
-
void TransferFuncs::Visit(Stmt *S) {
if (AD.Observer)
AD.Observer->ObserveStmt(S,AD,LiveState);
@@ -160,11 +152,6 @@
LiveState(D,AD) = Dead;
}
-void TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
- assert (AD.getCFG().isBlkExpr(E));
- VisitChildren(E);
-}
-
} // end anonymous namespace
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/UninitializedValues.cpp?rev=44246&r1=44245&r2=44246&view=diff
==============================================================================
--- cfe/trunk/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/Analysis/UninitializedValues.cpp Mon Nov 19 21:01:58 2007
@@ -34,6 +34,7 @@
RegisterDecls(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
void VisitBlockVarDecl(BlockVarDecl* VD) { AD.Register(VD); }
+ CFG& getCFG() { return AD.getCFG(); }
};
} // end anonymous namespace
@@ -58,6 +59,7 @@
}
UninitializedValues::ValTy& getVal() { return V; }
+ CFG& getCFG() { return AD.getCFG(); }
bool VisitDeclRefExpr(DeclRefExpr* DR);
bool VisitBinaryOperator(BinaryOperator* B);
Modified: cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h?rev=44246&r1=44245&r2=44246&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h (original)
+++ cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h Mon Nov 19 21:01:58 2007
@@ -22,18 +22,10 @@
class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> {
public:
- void Visit(Stmt* S) {
- static_cast< CFGStmtVisitor<ImplClass>* >(this)->Visit(S);
+ void VisitStmt(Stmt* S) {
static_cast< ImplClass* >(this)->VisitChildren(S);
}
-
- void BlockStmt_Visit(Stmt* S) {
- assert (S);
-
- static_cast< CFGStmtVisitor<ImplClass>* >(this)->BlockStmt_Visit(S);
- static_cast< ImplClass* >(this)->VisitChildren(S);
- }
-
+
// Defining operator() allows the visitor to be used as a C++ style functor.
void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
};
Modified: cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h?rev=44246&r1=44245&r2=44246&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h (original)
+++ cfe/trunk/include/clang/Analysis/Visitors/CFGStmtVisitor.h Mon Nov 19 21:01:58 2007
@@ -33,14 +33,36 @@
template <typename ImplClass, typename RetTy=void>
class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
-public:
+ Stmt* CurrentBlkExpr;
+
+ struct NullifyStmt {
+ Stmt*& S;
+
+ NullifyStmt(Stmt*& s) : S(s) {}
+ ~NullifyStmt() { S = NULL; }
+ };
+
+public:
+ CFGStmtVisitor() : CurrentBlkExpr(NULL) {}
+
+ RetTy Visit(Stmt* S) {
+ if (S == CurrentBlkExpr ||
+ !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
+ return StmtVisitor<ImplClass,RetTy>::Visit(S);
+ else
+ return RetTy();
+ }
+
/// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
/// CFGBlocks. Root statements are the statements that appear explicitly in
/// the list of statements in a CFGBlock. For substatements, or when there
/// is no implementation provided for a BlockStmt_XXX method, we default
/// to using StmtVisitor's Visit method.
RetTy BlockStmt_Visit(Stmt* S) {
- switch (S->getStmtClass()) {
+ CurrentBlkExpr = S;
+ NullifyStmt cleanup(CurrentBlkExpr);
+
+ switch (S->getStmtClass()) {
DISPATCH_CASE(CallExpr)
DISPATCH_CASE(StmtExpr)
DISPATCH_CASE(ConditionalOperator)
More information about the cfe-commits
mailing list