diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-11-26 02:31:33 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-11-26 02:31:33 +0000 |
commit | b1a7b65231e86f7da6aacbf00bcdc16c56350e65 (patch) | |
tree | a72b34bb5372c1f89a4841fac28fd2250132342f /lib/Analysis/AnalysisContext.cpp | |
parent | f21bf9b87a5edefb3f10a96ac036f92f538b8d32 (diff) |
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
Diffstat (limited to 'lib/Analysis/AnalysisContext.cpp')
-rw-r--r-- | lib/Analysis/AnalysisContext.cpp | 87 |
1 files changed, 75 insertions, 12 deletions
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 640912ad6b..339e2c93ce 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -18,21 +18,12 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Analysis/Support/BumpVector.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; -AnalysisContext::~AnalysisContext() { - delete cfg; - delete liveness; - delete PM; -} - -AnalysisContextManager::~AnalysisContextManager() { - for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) - delete I->second; -} - void AnalysisContextManager::clear() { for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) delete I->second; @@ -73,7 +64,7 @@ LiveVariables *AnalysisContext::getLiveVariables() { if (!c) return 0; - liveness = new LiveVariables(D->getASTContext(), *c); + liveness = new LiveVariables(*this); liveness->runOnCFG(*c); liveness->runOnAllBlocks(*c, 0, true); } @@ -157,3 +148,75 @@ ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx, } return scope; } + +//===----------------------------------------------------------------------===// +// Lazily generated map to query the external variables referenced by a Block. +//===----------------------------------------------------------------------===// + +namespace { +class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{ + BumpVector<const VarDecl*> &BEVals; + BumpVectorContext &BC; +public: + FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals, + BumpVectorContext &bc) + : BEVals(bevals), BC(bc) {} + + void VisitStmt(Stmt *S) { + for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();I!=E;++I) + if (Stmt *child = *I) + Visit(child); + } + + void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) { + if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) + BEVals.push_back(VD, BC); + } +}; +} // end anonymous namespace + +typedef BumpVector<const VarDecl*> DeclVec; + +static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD, + void *&Vec, + llvm::BumpPtrAllocator &A) { + if (Vec) + return (DeclVec*) Vec; + + BumpVectorContext BC(A); + DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>(); + new (BV) DeclVec(BC, 10); + + // Find the referenced variables. + FindBlockDeclRefExprsVals F(*BV, BC); + F.Visit(BD->getBody()); + + Vec = BV; + return BV; +} + +std::pair<AnalysisContext::referenced_decls_iterator, + AnalysisContext::referenced_decls_iterator> +AnalysisContext::getReferencedBlockVars(const BlockDecl *BD) { + if (!ReferencedBlockVars) + ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>(); + + DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A); + return std::make_pair(V->begin(), V->end()); +} + +//===----------------------------------------------------------------------===// +// Cleanup. +//===----------------------------------------------------------------------===// + +AnalysisContext::~AnalysisContext() { + delete cfg; + delete liveness; + delete PM; + delete ReferencedBlockVars; +} + +AnalysisContextManager::~AnalysisContextManager() { + for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) + delete I->second; +} |