Enhance LiveVariables to understand that blocks can extend the liveness of a variable by "capturing" them in a BlockExpr.
This required two changes:
1) Added 'getReferencedgetReferencedBlockVars()' to AnalysisContext so
that clients can iterate over the "captured" variables in a block.
2) Modified LiveVariables to take an AnalysisContext& in its
constructor and to call getReferencedgetReferencedBlockVars() when it
processes a BlockExpr*.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89924 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 2510445..e61f27b 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -19,6 +19,7 @@
#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@@ -77,10 +78,12 @@
};
} // end anonymous namespace
-LiveVariables::LiveVariables(ASTContext& Ctx, CFG& cfg) {
+LiveVariables::LiveVariables(AnalysisContext &AC) {
// Register all referenced VarDecls.
+ CFG &cfg = *AC.getCFG();
getAnalysisData().setCFG(cfg);
- getAnalysisData().setContext(Ctx);
+ getAnalysisData().setContext(AC.getASTContext());
+ getAnalysisData().AC = ∾
RegisterDecls R(getAnalysisData());
cfg.VisitBlockStmts(R);
@@ -103,6 +106,7 @@
void VisitDeclRefExpr(DeclRefExpr* DR);
void VisitBinaryOperator(BinaryOperator* B);
+ void VisitBlockExpr(BlockExpr *B);
void VisitAssign(BinaryOperator* B);
void VisitDeclStmt(DeclStmt* DS);
void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S);
@@ -153,7 +157,17 @@
void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
- LiveState(V,AD) = Alive;
+ LiveState(V, AD) = Alive;
+}
+
+void TransferFuncs::VisitBlockExpr(BlockExpr *BE) {
+ AnalysisContext::referenced_decls_iterator I, E;
+ llvm::tie(I, E) = AD.AC->getReferencedBlockVars(BE->getBlockDecl());
+ for ( ; I != E ; ++I) {
+ DeclBitVector_Types::Idx i = AD.getIdx(*I);
+ if (i.isValid())
+ LiveState.getBit(i) = Alive;
+ }
}
void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {