Moved ProgramEdge out out include/.../Analysis/PathSensitive to include/.../Analysis, as it is now used by the FlowSensitive subsystem as well.

Removed "Edge" nested class by CFG, as it is now subsumed by ProgramEdge.

Adjusted DataflowSolver and DataflowValues to use ProgramEdges instead
of CFG::Edge.

llvm-svn: 42534
This commit is contained in:
Ted Kremenek 2007-10-02 17:12:02 +00:00
parent da5d5b57bf
commit 190b1ed4fc
4 changed files with 22 additions and 66 deletions

View File

@ -230,26 +230,6 @@ public:
CFGBlock* getIndirectGotoBlock() { return IndirectGotoBlock; }
const CFGBlock* getIndirectGotoBlock() const { return IndirectGotoBlock; }
//===--------------------------------------------------------------------===//
// CFG Edges (Source Block, Destination Block)
//===--------------------------------------------------------------------===//
class Edge {
const CFGBlock* S;
const CFGBlock* D;
public:
Edge(const CFGBlock* src, const CFGBlock* dst) : S(src), D(dst) {}
Edge(const Edge& RHS) : S(RHS.S), D(RHS.D) {}
Edge& operator=(const Edge& RHS) { S = RHS.S; D = RHS.D; return *this; }
const CFGBlock* getSrc() const { return S; }
const CFGBlock* getDst() const { return D; }
bool operator==(const Edge& RHS) const { return S == RHS.S && D == RHS.D; }
bool operator!=(const Edge& RHS) const { return !(*this == RHS); }
};
//===--------------------------------------------------------------------===//
// Member templates useful for various batch operations over CFGs.
//===--------------------------------------------------------------------===//

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
#include "clang/AST/CFG.h"
#include "clang/Analysis/ProgramEdge.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "functional" // STL
@ -68,12 +69,12 @@ template <> struct ItrTraits<forward_analysis_tag> {
static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); }
static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); }
static CFG::Edge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
return CFG::Edge(PrevBlk,B);
static BlkBlkEdge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
return BlkBlkEdge(PrevBlk,B);
}
static CFG::Edge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
return CFG::Edge(B,NextBlk);
static BlkBlkEdge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
return BlkBlkEdge(B,NextBlk);
}
};
@ -91,12 +92,12 @@ template <> struct ItrTraits<backward_analysis_tag> {
static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); }
static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); }
static CFG::Edge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
return CFG::Edge(B,PrevBlk);
static BlkBlkEdge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
return BlkBlkEdge(B,PrevBlk);
}
static CFG::Edge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
return CFG::Edge(NextBlk,B);
static BlkBlkEdge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
return BlkBlkEdge(NextBlk,B);
}
};
} // end namespace dataflow
@ -241,7 +242,7 @@ private:
}
/// UpdateEdgeValue - Update the value associated with a given edge.
void UpdateEdgeValue(CFG::Edge E, ValTy& V, const CFGBlock* TargetBlock) {
void UpdateEdgeValue(BlkBlkEdge E, ValTy& V, const CFGBlock* TargetBlock) {
EdgeDataMapTy& M = D.getEdgeDataMap();
typename EdgeDataMapTy::iterator I = M.find(E);

View File

@ -17,42 +17,9 @@
#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
#include "clang/AST/CFG.h"
#include "clang/Analysis/ProgramEdge.h"
#include "llvm/ADT/DenseMap.h"
//===----------------------------------------------------------------------===//
// DenseMapInfo for CFG::Edge for use with DenseMap
//===----------------------------------------------------------------------===//
namespace llvm {
template <> struct DenseMapInfo<clang::CFG::Edge> {
static inline clang::CFG::Edge getEmptyKey() {
return clang::CFG::Edge(NULL,NULL);
}
static inline clang::CFG::Edge getTombstoneKey() {
return clang::CFG::Edge(NULL,reinterpret_cast<clang::CFGBlock*>(-1));
}
static unsigned getHashValue(const clang::CFG::Edge& E) {
const clang::CFGBlock* P1 = E.getSrc();
const clang::CFGBlock* P2 = E.getDst();
return static_cast<unsigned>((reinterpret_cast<uintptr_t>(P1) >> 4) ^
(reinterpret_cast<uintptr_t>(P1) >> 9) ^
(reinterpret_cast<uintptr_t>(P2) >> 5) ^
(reinterpret_cast<uintptr_t>(P2) >> 10));
}
static bool isEqual(const clang::CFG::Edge& LHS,
const clang::CFG::Edge& RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
} // end namespace llvm
//===----------------------------------------------------------------------===//
/// Dataflow Directional Tag Classes. These are used for tag dispatching
/// within the dataflow solver/transfer functions to determine what direction
@ -81,7 +48,7 @@ public:
typedef typename ValueTypes::ValTy ValTy;
typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy;
typedef _AnalysisDirTag AnalysisDirTag;
typedef llvm::DenseMap<CFG::Edge, ValTy> EdgeDataMapTy;
typedef llvm::DenseMap<ProgramEdge, ValTy> EdgeDataMapTy;
typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy;
//===--------------------------------------------------------------------===//
@ -113,13 +80,13 @@ public:
/// getEdgeData - Retrieves the dataflow values associated with a
/// CFG edge.
ValTy& getEdgeData(const CFG::Edge& E) {
ValTy& getEdgeData(const BlkBlkEdge& E) {
typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
assert (I != EdgeDataMap.end() && "No data associated with Edge.");
return I->second;
}
const ValTy& getEdgeData(const CFG::Edge& E) const {
const ValTy& getEdgeData(const BlkBlkEdge& E) const {
return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
}

View File

@ -41,6 +41,10 @@ public:
return RawSrc() == RHS.RawSrc() && RawDst() == RHS.RawDst();
}
bool operator!=(const ProgramEdge& RHS) const {
return RawSrc() != RHS.RawSrc() || RawDst() != RHS.RawDst();
}
unsigned getHashValue() const {
uintptr_t v1 = reinterpret_cast<uintptr_t>(RawSrc());
uintptr_t v2 = reinterpret_cast<uintptr_t>(RawDst());
@ -118,6 +122,10 @@ template <> struct DenseMapInfo<clang::ProgramEdge> {
reinterpret_cast<clang::CFGBlock*>(-1));
}
static unsigned getHashValue(const clang::ProgramEdge& E) {
return E.getHashValue();
}
static bool isEqual(const clang::ProgramEdge& LHS,
const clang::ProgramEdge& RHS) {
return LHS == RHS;