The LiveVariables analysis no longer requires a FunctionDecl&; this allows it

to be run on other declarations of blocks of code (e.g., Objective-C methods.)

llvm-svn: 48339
This commit is contained in:
Ted Kremenek 2008-03-13 16:55:07 +00:00
parent 442d708bfb
commit 1fdd0a480e
7 changed files with 43 additions and 26 deletions

View File

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

View File

@ -43,14 +43,9 @@ public:
} // end anonymous namespace } // end anonymous namespace
LiveVariables::LiveVariables(CFG& cfg, FunctionDecl& FD) { LiveVariables::LiveVariables(CFG& cfg) {
// Register all referenced VarDecls.
getAnalysisData().setCFG(&cfg); 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()); RegisterDecls R(getAnalysisData());
cfg.VisitBlockStmts(R); cfg.VisitBlockStmts(R);
} }
@ -201,11 +196,13 @@ void LiveVariables::runOnAllBlocks(const CFG& cfg,
// //
bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const { bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
return getBlockData(B)(D,getAnalysisData()); DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
return i.isValid() ? getBlockData(B).getBit(i) : false;
} }
bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const { bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
return Live(D,getAnalysisData()); DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
return i.isValid() ? Live.getBit(i) : false;
} }
bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const { bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {

View File

@ -528,7 +528,7 @@ namespace {
} }
virtual void VisitCFG(CFG& C, FunctionDecl& FD) { virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
LiveVariables L(C, FD); LiveVariables L(C);
L.runOnCFG(C); L.runOnCFG(C);
L.dumpBlockLiveness(*SM); L.dumpBlockLiveness(*SM);
} }
@ -553,7 +553,7 @@ namespace {
} }
virtual void VisitCFG(CFG& C, FunctionDecl& FD) { virtual void VisitCFG(CFG& C, FunctionDecl& FD) {
CheckDeadStores(C, FD, *Ctx, Diags); CheckDeadStores(C, *Ctx, Diags);
} }
virtual bool printFuncDeclStart() { return false; } virtual bool printFuncDeclStart() { return false; }

View File

@ -64,7 +64,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
public: public:
typedef LiveVariables_ValueTypes::ObserverTy ObserverTy; typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
LiveVariables(CFG& cfg, FunctionDecl& FD); LiveVariables(CFG& cfg);
/// IsLive - Return true if a variable is live at beginning of a /// IsLive - Return true if a variable is live at beginning of a
/// specified block. /// specified block.

View File

@ -22,8 +22,7 @@ class FunctionDecl;
class Diagnostic; class Diagnostic;
class ASTContext; class ASTContext;
void CheckDeadStores(CFG& cfg, FunctionDecl& FD, ASTContext &Ctx, void CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags);
Diagnostic &Diags);
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags, void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false); bool FullUninitTaint=false);

View File

@ -126,7 +126,7 @@ protected:
public: public:
GRExprEngine(GraphTy& g) : GRExprEngine(GraphTy& g) :
G(g), Liveness(G.getCFG(), G.getFunctionDecl()), G(g), Liveness(G.getCFG()),
Builder(NULL), Builder(NULL),
StateMgr(G.getContext(), G.getAllocator()), StateMgr(G.getContext(), G.getAllocator()),
BasicVals(StateMgr.getBasicValueFactory()), BasicVals(StateMgr.getBasicValueFactory()),

View File

@ -28,6 +28,21 @@ namespace clang {
struct DeclBitVector_Types { struct DeclBitVector_Types {
class Idx {
unsigned I;
public:
Idx(unsigned i) : I(i) {}
explicit Idx() : I(~0U) {}
bool isValid() const {
return I != ~0U;
}
operator unsigned() const {
assert (isValid());
return I;
}
};
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// AnalysisDataTy - Whole-function meta data. // AnalysisDataTy - Whole-function meta data.
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -48,10 +63,9 @@ struct DeclBitVector_Types {
bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); } bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); }
unsigned getIdx(const ScopedDecl* SD) const { Idx getIdx(const ScopedDecl* SD) const {
DMapTy::const_iterator I = DMap.find(SD); DMapTy::const_iterator I = DMap.find(SD);
assert (I != DMap.end()); return I == DMap.end() ? Idx() : Idx(I->second);
return I->second;
} }
unsigned getNumDecls() const { return NDecls; } unsigned getNumDecls() const { return NDecls; }
@ -84,13 +98,21 @@ struct DeclBitVector_Types {
void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
llvm::BitVector::reference getBit(unsigned i) {
return DeclBV[i];
}
const bool getBit(unsigned i) const {
return DeclBV[i];
}
llvm::BitVector::reference llvm::BitVector::reference
operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) { operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) {
return DeclBV[AD.getIdx(SD)]; return getBit(AD.getIdx(SD));
} }
const llvm::BitVector::reference
operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) const { bool operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) const {
return const_cast<ValTy&>(*this)(SD,AD); return getBit(AD.getIdx(SD));
} }
llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }