Modified LiveVariables to perform all of its base initialization in the ctor,

and now we require a FunctionDecl* object so that we can also keep track of
all of the ParmDecls.

Modified clients of LiveVariables to conform to the new interface.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46490 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-01-29 05:13:23 +00:00
Родитель b3c2b88de6
Коммит bffaa83147
6 изменённых файлов: 47 добавлений и 40 удалений

Просмотреть файл

@ -76,8 +76,10 @@ public:
namespace clang {
void CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags) {
LiveVariables L(cfg);
void CheckDeadStores(CFG& cfg, FunctionDecl& FD, ASTContext &Ctx,
Diagnostic &Diags) {
LiveVariables L(cfg, FD);
L.runOnCFG(cfg);
DeadStoreObs A(Ctx, Diags);
L.runOnAllBlocks(cfg,&A);

Просмотреть файл

@ -577,7 +577,7 @@ protected:
/// Liveness - live-variables information the ValueDecl* and block-level
/// Expr* in the CFG. Used to prune out dead state.
LiveVariables* Liveness;
LiveVariables Liveness;
/// Builder - The current GRNodeBuilder which is used when building the nodes
/// for a given statement.
@ -600,17 +600,14 @@ protected:
ASTContext& getContext() const { return G.getContext(); }
public:
GRConstants(GraphTy& g) : G(g), Liveness(NULL), Builder(NULL),
ValMgr(G.getContext()), StmtEntryNode(NULL), CurrentStmt(NULL) {
GRConstants(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
Builder(NULL), ValMgr(G.getContext()), StmtEntryNode(NULL),
CurrentStmt(NULL) {
// Compute liveness information.
CFG& c = G.getCFG();
Liveness = new LiveVariables(c);
Liveness->runOnCFG(c);
Liveness->runOnAllBlocks(c, NULL, true);
Liveness.runOnCFG(G.getCFG());
Liveness.runOnAllBlocks(G.getCFG(), NULL, true);
}
~GRConstants() { delete Liveness; }
/// getCFG - Returns the CFG associated with this analysis.
CFG& getCFG() { return G.getCFG(); }
@ -843,14 +840,14 @@ GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
// Remove old bindings for subexpressions and "dead" block-level expressions.
for (; I!=E && !I.getKey().isDecl(); ++I) {
if (I.getKey().isSubExpr() || !Liveness->isLive(Loc,cast<Stmt>(I.getKey())))
if (I.getKey().isSubExpr() || !Liveness.isLive(Loc,cast<Stmt>(I.getKey())))
M = StateMgr.Remove(M, I.getKey());
}
// Remove bindings for "dead" decls.
for (; I!=E && I.getKey().isDecl(); ++I)
if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
if (!Liveness->isLive(Loc, V))
if (!Liveness.isLive(Loc, V))
M = StateMgr.Remove(M, I.getKey());
return M;

Просмотреть файл

@ -42,7 +42,15 @@ public:
};
} // end anonymous namespace
void LiveVariables::InitializeValues(const CFG& cfg) {
LiveVariables::LiveVariables(CFG& cfg, FunctionDecl& FD) {
getAnalysisData().setCFG(&cfg);
for (FunctionDecl::param_iterator I=FD.param_begin(), E=FD.param_end();
I !=E; ++I)
getAnalysisData().Register(*I);
// Now register all the other VarDecls;
RegisterDecls R(getAnalysisData());
cfg.VisitBlockStmts(R);
}

Просмотреть файл

@ -449,7 +449,7 @@ namespace {
class CFGVisitor : public ASTConsumer {
public:
// CFG Visitor interface to be implemented by subclass.
virtual void VisitCFG(CFG& C) = 0;
virtual void VisitCFG(CFG& C, FunctionDecl& FD) = 0;
virtual bool printFuncDeclStart() { return true; }
virtual void HandleTopLevelDecl(Decl *D);
@ -468,7 +468,7 @@ void CFGVisitor::HandleTopLevelDecl(Decl *D) {
}
CFG *C = CFG::buildCFG(FD->getBody());
VisitCFG(*C);
VisitCFG(*C, *FD);
delete C;
}
@ -481,7 +481,7 @@ namespace {
public:
CFGDumper(bool use_graphviz) : UseGraphviz(use_graphviz) {}
virtual void VisitCFG(CFG &C) {
virtual void VisitCFG(CFG& C, FunctionDecl&) {
if (UseGraphviz)
C.viewCFG();
else
@ -505,8 +505,8 @@ namespace {
SM = &Context.getSourceManager();
}
virtual void VisitCFG(CFG& C) {
LiveVariables L(C);
virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
LiveVariables L(C, FD);
L.runOnCFG(C);
L.dumpBlockLiveness(*SM);
}
@ -530,7 +530,10 @@ namespace {
Ctx = &Context;
}
virtual void VisitCFG(CFG& C) { CheckDeadStores(C, *Ctx, Diags); }
virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
CheckDeadStores(C, FD, *Ctx, Diags);
}
virtual bool printFuncDeclStart() { return false; }
};
} // end anonymous namespace
@ -553,7 +556,10 @@ namespace {
Ctx = &Context;
}
virtual void VisitCFG(CFG& C) { CheckUninitializedValues(C, *Ctx, Diags); }
virtual void VisitCFG(CFG& C, FunctionDecl&) {
CheckUninitializedValues(C, *Ctx, Diags);
}
virtual bool printFuncDeclStart() { return false; }
};
} // end anonymous namespace
@ -566,12 +572,12 @@ ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
// GRConstants - Perform intra-procedural, path-sensitive constant propagation.
namespace {
class GRConstantsVisitor : public ASTConsumer {
class GRConstantsVisitor : public CFGVisitor {
ASTContext* Ctx;
public:
virtual void Initialize(ASTContext &Context) { Ctx = &Context; }
virtual void HandleTopLevelDecl(Decl *D);
virtual void VisitCFG(CFG& C, FunctionDecl&);
};
} // end anonymous namespace
@ -579,18 +585,8 @@ ASTConsumer* clang::CreateGRConstants() {
return new GRConstantsVisitor();
}
void GRConstantsVisitor::HandleTopLevelDecl(Decl *D) {
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
if (!FD || !FD->getBody())
return;
DeclPrinter().PrintFunctionDeclStart(FD);
llvm::cerr << '\n';
CFG *C = CFG::buildCFG(FD->getBody());
RunGRConstants(*C, *FD, *Ctx);
delete C;
void GRConstantsVisitor::VisitCFG(CFG& C, FunctionDecl& FD) {
RunGRConstants(C, FD, *Ctx);
}
//===----------------------------------------------------------------------===//

Просмотреть файл

@ -64,7 +64,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
public:
typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
LiveVariables(CFG& cfg) { getAnalysisData().setCFG(&cfg); }
LiveVariables(CFG& cfg, FunctionDecl& FD);
/// IsLive - Return true if a variable is live at beginning of a
/// specified block.
@ -97,9 +97,10 @@ public:
/// analysis.
unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); }
/// IntializeValues - Create initial dataflow values and meta data for
/// a given CFG. This is intended to be called by the dataflow solver.
void InitializeValues(const CFG& cfg);
/// IntializeValues - This routine can perform extra initialization, but
/// for LiveVariables this does nothing since all that logic is in
/// the constructor.
void InitializeValues(const CFG& cfg) {}
void runOnCFG(CFG& cfg);

Просмотреть файл

@ -18,10 +18,13 @@
namespace clang {
class CFG;
class FunctionDecl;
class Diagnostic;
class ASTContext;
void CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags);
void CheckDeadStores(CFG& cfg, FunctionDecl& FD, ASTContext &Ctx,
Diagnostic &Diags);
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false);