diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/AnalysisContext.cpp | 96 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 30 |
2 files changed, 61 insertions, 65 deletions
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 62097ef20d..0085f3af15 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -29,6 +29,24 @@ using namespace clang; +AnalysisContext::AnalysisContext(const Decl *d, + idx::TranslationUnit *tu, + bool useUnoptimizedCFG, + bool addehedges, + bool addImplicitDtors, + bool addInitializers) + : D(d), TU(tu), + forcedBlkExprs(0), + builtCFG(false), builtCompleteCFG(false), + useUnoptimizedCFG(useUnoptimizedCFG), + ReferencedBlockVars(0) +{ + cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; + cfgBuildOptions.AddEHEdges = addehedges; + cfgBuildOptions.AddImplicitDtors = addImplicitDtors; + cfgBuildOptions.AddInitializers = addInitializers; +} + void AnalysisContextManager::clear() { for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) delete I->second; @@ -57,44 +75,38 @@ const ImplicitParamDecl *AnalysisContext::getSelfDecl() const { } CFG *AnalysisContext::getCFG() { - if (UseUnoptimizedCFG) + if (useUnoptimizedCFG) return getUnoptimizedCFG(); if (!builtCFG) { - CFG::BuildOptions B; - B.AddEHEdges = AddEHEdges; - B.AddImplicitDtors = AddImplicitDtors; - B.AddInitializers = AddInitializers; - cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), B); + cfg.reset(CFG::buildCFG(D, getBody(), + &D->getASTContext(), cfgBuildOptions)); // Even when the cfg is not successfully built, we don't // want to try building it again. builtCFG = true; } - return cfg; + return cfg.get(); } CFG *AnalysisContext::getUnoptimizedCFG() { if (!builtCompleteCFG) { - CFG::BuildOptions B; + CFG::BuildOptions B = cfgBuildOptions; B.PruneTriviallyFalseEdges = false; - B.AddEHEdges = AddEHEdges; - B.AddImplicitDtors = AddImplicitDtors; - B.AddInitializers = AddInitializers; - completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(), B); + completeCFG.reset(CFG::buildCFG(D, getBody(), &D->getASTContext(), B)); // Even when the cfg is not successfully built, we don't // want to try building it again. builtCompleteCFG = true; } - return completeCFG; + return completeCFG.get(); } CFGStmtMap *AnalysisContext::getCFGStmtMap() { if (cfgStmtMap) - return cfgStmtMap; + return cfgStmtMap.get(); if (CFG *c = getCFG()) { - cfgStmtMap = CFGStmtMap::Build(c, &getParentMap()); - return cfgStmtMap; + cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap())); + return cfgStmtMap.get(); } return 0; @@ -102,11 +114,11 @@ CFGStmtMap *AnalysisContext::getCFGStmtMap() { CFGReachabilityAnalysis *AnalysisContext::getCFGReachablityAnalysis() { if (CFA) - return CFA; + return CFA.get(); if (CFG *c = getCFG()) { - CFA = new CFGReachabilityAnalysis(*c); - return CFA; + CFA.reset(new CFGReachabilityAnalysis(*c)); + return CFA.get(); } return 0; @@ -118,42 +130,37 @@ void AnalysisContext::dumpCFG() { ParentMap &AnalysisContext::getParentMap() { if (!PM) - PM = new ParentMap(getBody()); + PM.reset(new ParentMap(getBody())); return *PM; } PseudoConstantAnalysis *AnalysisContext::getPseudoConstantAnalysis() { if (!PCA) - PCA = new PseudoConstantAnalysis(getBody()); - return PCA; + PCA.reset(new PseudoConstantAnalysis(getBody())); + return PCA.get(); } LiveVariables *AnalysisContext::getLiveVariables() { if (!liveness) { - CFG *c = getCFG(); - if (!c) - return 0; - - liveness = new LiveVariables(*this); - liveness->runOnCFG(*c); - liveness->runOnAllBlocks(*c, 0, true); + if (CFG *c = getCFG()) { + liveness.reset(new LiveVariables(*this)); + liveness->runOnCFG(*c); + liveness->runOnAllBlocks(*c, 0, true); + } } - return liveness; + return liveness.get(); } LiveVariables *AnalysisContext::getRelaxedLiveVariables() { - if (!relaxedLiveness) { - CFG *c = getCFG(); - if (!c) - return 0; - - relaxedLiveness = new LiveVariables(*this, false); - relaxedLiveness->runOnCFG(*c); - relaxedLiveness->runOnAllBlocks(*c, 0, true); - } + if (!relaxedLiveness) + if (CFG *c = getCFG()) { + relaxedLiveness.reset(new LiveVariables(*this, false)); + relaxedLiveness->runOnCFG(*c); + relaxedLiveness->runOnAllBlocks(*c, 0, true); + } - return relaxedLiveness; + return relaxedLiveness.get(); } AnalysisContext *AnalysisContextManager::getContext(const Decl *D, @@ -370,14 +377,7 @@ AnalysisContext::getReferencedBlockVars(const BlockDecl *BD) { //===----------------------------------------------------------------------===// AnalysisContext::~AnalysisContext() { - delete cfg; - delete completeCFG; - delete cfgStmtMap; - delete liveness; - delete relaxedLiveness; - delete PM; - delete PCA; - delete CFA; + delete forcedBlkExprs; delete ReferencedBlockVars; } diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index fa98f94057..0f5b1fae5c 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -275,22 +275,23 @@ class CFGBuilder { LabelSetTy AddressTakenLabels; bool badCFG; - CFG::BuildOptions BuildOpts; + const CFG::BuildOptions &BuildOpts; // State to track for building switch statements. bool switchExclusivelyCovered; Expr::EvalResult *switchCond; public: - explicit CFGBuilder() : cfg(new CFG()), // crew a new CFG - Block(NULL), Succ(NULL), - SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL), - TryTerminatedBlock(NULL), badCFG(false), - switchExclusivelyCovered(false), switchCond(0) {} + explicit CFGBuilder(ASTContext *astContext, + const CFG::BuildOptions &buildOpts) + : Context(astContext), cfg(new CFG()), // crew a new CFG + Block(NULL), Succ(NULL), + SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL), + TryTerminatedBlock(NULL), badCFG(false), BuildOpts(buildOpts), + switchExclusivelyCovered(false), switchCond(0) {} // buildCFG - Used by external clients to construct the CFG. - CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C, - CFG::BuildOptions BO); + CFG* buildCFG(const Decl *D, Stmt *Statement); private: // Visitors to walk an AST and construct the CFG. @@ -460,16 +461,11 @@ static const VariableArrayType *FindVA(const Type *t) { /// body (compound statement). The ownership of the returned CFG is /// transferred to the caller. If CFG construction fails, this method returns /// NULL. -CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C, - CFG::BuildOptions BO) { - - Context = C; +CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement) { assert(cfg.get()); if (!Statement) return NULL; - BuildOpts = BO; - // Create an empty block that will serve as the exit block for the CFG. Since // this is the first block added to the CFG, it will be implicitly registered // as the exit block. @@ -2768,9 +2764,9 @@ CFGBlock* CFG::createBlock() { /// buildCFG - Constructs a CFG from an AST. Ownership of the returned /// CFG is returned to the caller. CFG* CFG::buildCFG(const Decl *D, Stmt* Statement, ASTContext *C, - BuildOptions BO) { - CFGBuilder Builder; - return Builder.buildCFG(D, Statement, C, BO); + const BuildOptions &BO) { + CFGBuilder Builder(C, BO); + return Builder.buildCFG(D, Statement); } const CXXDestructorDecl * |