forked from OSchip/llvm-project
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:
parent
442d708bfb
commit
1fdd0a480e
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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]; }
|
||||||
|
|
Loading…
Reference in New Issue