[cfe-commits] r127385 - in /cfe/trunk: include/clang/Analysis/AnalysisContext.h include/clang/Analysis/CFG.h lib/Analysis/AnalysisContext.cpp lib/Analysis/CFG.cpp
Ted Kremenek
kremenek at apple.com
Wed Mar 9 17:14:05 PST 2011
Author: kremenek
Date: Wed Mar 9 19:14:05 2011
New Revision: 127385
URL: http://llvm.org/viewvc/llvm-project?rev=127385&view=rev
Log:
Rework interaction between AnalysisContext and CFG::BuildOptions to keep a BuildOptions object around instead of keeping a copy of the flags.
Moreover, change AnalysisContext to use an OwningPtr for created analysis objects instead
of directly managing them.
Finally, add a 'forcedBlkExprs' entry to CFG::BuildOptions that will be used by the
CFGBuilder to force specific expressions to be block-level expressions.
Modified:
cfe/trunk/include/clang/Analysis/AnalysisContext.h
cfe/trunk/include/clang/Analysis/CFG.h
cfe/trunk/lib/Analysis/AnalysisContext.cpp
cfe/trunk/lib/Analysis/CFG.cpp
Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Mar 9 19:14:05 2011
@@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/Analysis/CFG.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
@@ -27,8 +28,6 @@
class Decl;
class Stmt;
-class CFG;
-class CFGBlock;
class CFGReachabilityAnalysis;
class CFGStmtMap;
class LiveVariables;
@@ -48,33 +47,32 @@
// TranslationUnit is NULL if we don't have multiple translation units.
idx::TranslationUnit *TU;
- // AnalysisContext owns the following data.
- CFG *cfg, *completeCFG;
- CFGStmtMap *cfgStmtMap;
+ llvm::OwningPtr<CFG> cfg, completeCFG;
+ llvm::OwningPtr<CFGStmtMap> cfgStmtMap;
+
+ CFG::BuildOptions cfgBuildOptions;
+ CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
+
bool builtCFG, builtCompleteCFG;
- LiveVariables *liveness;
- LiveVariables *relaxedLiveness;
- ParentMap *PM;
- PseudoConstantAnalysis *PCA;
- CFGReachabilityAnalysis *CFA;
- llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ const bool useUnoptimizedCFG;
+
+ llvm::OwningPtr<LiveVariables> liveness;
+ llvm::OwningPtr<LiveVariables> relaxedLiveness;
+ llvm::OwningPtr<ParentMap> PM;
+ llvm::OwningPtr<PseudoConstantAnalysis> PCA;
+ llvm::OwningPtr<CFGReachabilityAnalysis> CFA;
+
llvm::BumpPtrAllocator A;
- bool UseUnoptimizedCFG;
- bool AddEHEdges;
- bool AddImplicitDtors;
- bool AddInitializers;
+
+ // FIXME: remove.
+ llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+
public:
AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
bool useUnoptimizedCFG = false,
bool addehedges = false,
bool addImplicitDtors = false,
- bool addInitializers = false)
- : D(d), TU(tu), cfg(0), completeCFG(0), cfgStmtMap(0),
- builtCFG(false), builtCompleteCFG(false),
- liveness(0), relaxedLiveness(0), PM(0), PCA(0), CFA(0),
- ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
- AddEHEdges(addehedges), AddImplicitDtors(addImplicitDtors),
- AddInitializers(addInitializers) {}
+ bool addInitializers = false);
~AnalysisContext();
@@ -87,11 +85,12 @@
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must
/// cope with that.
- bool getAddEHEdges() const { return AddEHEdges; }
-
- bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
- bool getAddImplicitDtors() const { return AddImplicitDtors; }
- bool getAddInitializers() const { return AddInitializers; }
+ bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
+ bool getUseUnoptimizedCFG() const {
+ return cfgBuildOptions.PruneTriviallyFalseEdges;
+ }
+ bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
+ bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
Stmt *getBody();
CFG *getCFG();
Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Mar 9 19:14:05 2011
@@ -19,6 +19,8 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/DenseMap.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/SourceLocation.h"
#include <cassert>
@@ -532,13 +534,16 @@
class BuildOptions {
public:
+ typedef llvm::DenseMap<const Stmt *, const CFGBlock> ForcedBlkExprs;
+ ForcedBlkExprs **forcedBlkExprs;
+
bool PruneTriviallyFalseEdges:1;
bool AddEHEdges:1;
bool AddInitializers:1;
bool AddImplicitDtors:1;
BuildOptions()
- : PruneTriviallyFalseEdges(true)
+ : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
, AddEHEdges(false)
, AddInitializers(false)
, AddImplicitDtors(false) {}
@@ -547,7 +552,7 @@
/// buildCFG - Builds a CFG from an AST. The responsibility to free the
/// constructed CFG belongs to the caller.
static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
- BuildOptions BO = BuildOptions());
+ const BuildOptions &BO);
/// createBlock - Create a new block in the CFG. The CFG owns the block;
/// the caller should not directly free it.
Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Wed Mar 9 19:14:05 2011
@@ -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 @@
}
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 @@
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 @@
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::~AnalysisContext() {
- delete cfg;
- delete completeCFG;
- delete cfgStmtMap;
- delete liveness;
- delete relaxedLiveness;
- delete PM;
- delete PCA;
- delete CFA;
+ delete forcedBlkExprs;
delete ReferencedBlockVars;
}
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=127385&r1=127384&r2=127385&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Mar 9 19:14:05 2011
@@ -275,22 +275,23 @@
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 @@
/// 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 @@
/// 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 *
More information about the cfe-commits
mailing list