[cfe-commits] r45846 - in /cfe/trunk: AST/CFG.cpp Analysis/LiveVariables.cpp include/clang/AST/CFG.h include/clang/Analysis/Analyses/LiveVariables.h include/clang/Analysis/FlowSensitive/DataflowSolver.h include/clang/Analysis/FlowSensitive/DataflowValues.h include/clang/Analysis/ProgramEdge.h
Ted Kremenek
kremenek at apple.com
Thu Jan 10 16:40:30 PST 2008
Author: kremenek
Date: Thu Jan 10 18:40:29 2008
New Revision: 45846
URL: http://llvm.org/viewvc/llvm-project?rev=45846&view=rev
Log:
Renamed ProgramEdge to ProgramPoint and changed subclasses of ProgramEdge
to have a much simpler, cleaner interpretation of what is a "location"
in a function (as encoded by a CFG).
Modified:
cfe/trunk/AST/CFG.cpp
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/include/clang/AST/CFG.h
cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
cfe/trunk/include/clang/Analysis/ProgramEdge.h
Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Thu Jan 10 18:40:29 2008
@@ -21,10 +21,12 @@
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/Compiler.h"
+#include <set>
#include <iomanip>
#include <algorithm>
#include <sstream>
+
using namespace clang;
namespace {
@@ -1030,8 +1032,21 @@
}
}
+typedef std::set<std::pair<CFGBlock*,CFGBlock*> > BlkEdgeSetTy;
+
+const std::pair<CFGBlock*,CFGBlock*>*
+CFG::getBlockEdgeImpl(const CFGBlock* B1, const CFGBlock* B2) {
+
+ BlkEdgeSetTy*& p = reinterpret_cast<BlkEdgeSetTy*&>(BlkEdgeSet);
+ if (!p) p = new BlkEdgeSetTy();
+
+ return &*(p->insert(std::make_pair(const_cast<CFGBlock*>(B1),
+ const_cast<CFGBlock*>(B2))).first);
+}
+
CFG::~CFG() {
delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
+ delete reinterpret_cast<BlkEdgeSetTy*>(BlkEdgeSet);
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Thu Jan 10 18:40:29 2008
@@ -172,7 +172,7 @@
// External interface to run Liveness analysis.
//===----------------------------------------------------------------------===//
-void LiveVariables::runOnCFG(const CFG& cfg) {
+void LiveVariables::runOnCFG(CFG& cfg) {
Solver S(*this);
S.runOnCFG(cfg);
}
Modified: cfe/trunk/include/clang/AST/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CFG.h?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CFG.h (original)
+++ cfe/trunk/include/clang/AST/CFG.h Thu Jan 10 18:40:29 2008
@@ -22,11 +22,11 @@
#include <cassert>
namespace clang {
-
class Stmt;
class Expr;
class CFG;
class PrinterHelper;
+ class BlockEdge;
/// CFGBlock - Represents a single basic block in a source-level CFG.
/// It consists of:
@@ -273,7 +273,7 @@
//===--------------------------------------------------------------------===//
CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
- BlkExprMap(NULL) {};
+ BlkExprMap(NULL), BlkEdgeSet(NULL) {};
~CFG();
@@ -287,6 +287,22 @@
// opaque pointer to prevent inclusion of DenseMap.h. Map from expressions
// to integers to record block-level expressions.
void* BlkExprMap;
+
+ // opaque pointer to prevent inclusion of <set>. This records a set of
+ // CFGBlock edges for using with ProgramPoint. These edges represent
+ // the edges that cannot be succinctly represented, and in practice this
+ // set should be small.
+ void* BlkEdgeSet;
+
+ friend class BlockEdge;
+
+ /// getBlockEdgeImpl - Utility method used by the class BlockEdge. The CFG
+ /// stores a set of interned std::pair<CFGBlock*,CFGBlock*> that can
+ /// be used by BlockEdge to refer to edges that cannot be represented
+ /// by a single pointer.
+ const std::pair<CFGBlock*,CFGBlock*>* getBlockEdgeImpl(const CFGBlock* B1,
+ const CFGBlock* B2);
+
};
} // end namespace clang
Modified: cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h Thu Jan 10 18:40:29 2008
@@ -92,7 +92,7 @@
/// a given CFG. This is intended to be called by the dataflow solver.
void InitializeValues(const CFG& cfg);
- void runOnCFG(const CFG& cfg);
+ void runOnCFG(CFG& cfg);
void runOnAllBlocks(const CFG& cfg, ObserverTy& Obs);
};
Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h Thu Jan 10 18:40:29 2008
@@ -69,12 +69,12 @@
static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); }
static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); }
- static BlkBlkEdge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
- return BlkBlkEdge(PrevBlk,B);
+ static BlockEdge PrevEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) {
+ return BlockEdge(cfg,Prev,B);
}
- static BlkBlkEdge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
- return BlkBlkEdge(B,NextBlk);
+ static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) {
+ return BlockEdge(cfg,B,Next);
}
};
@@ -92,12 +92,12 @@
static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); }
static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); }
- static BlkBlkEdge PrevEdge(const CFGBlock* B, const CFGBlock* PrevBlk) {
- return BlkBlkEdge(B,PrevBlk);
+ static BlockEdge PrevEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) {
+ return BlockEdge(cfg,B,Prev);
}
- static BlkBlkEdge NextEdge(const CFGBlock* B, const CFGBlock* NextBlk) {
- return BlkBlkEdge(NextBlk,B);
+ static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) {
+ return BlockEdge(cfg,Next,B);
}
};
} // end namespace dataflow
@@ -140,7 +140,7 @@
~DataflowSolver() {}
/// runOnCFG - Computes dataflow values for all blocks in a CFG.
- void runOnCFG(const CFG& cfg) {
+ void runOnCFG(CFG& cfg) {
// Set initial dataflow values and boundary conditions.
D.InitializeValues(cfg);
// Solve the dataflow equations. This will populate D.EdgeDataMap
@@ -180,14 +180,14 @@
/// SolveDataflowEquations - Perform the actual worklist algorithm
/// to compute dataflow values.
- void SolveDataflowEquations(const CFG& cfg) {
+ void SolveDataflowEquations(CFG& cfg) {
EnqueueFirstBlock(cfg,AnalysisDirTag());
while (!WorkList.isEmpty()) {
const CFGBlock* B = WorkList.dequeue();
- ProcessMerge(B);
+ ProcessMerge(cfg,B);
ProcessBlock(B);
- UpdateEdges(B,TF.getVal());
+ UpdateEdges(cfg,B,TF.getVal());
}
}
@@ -199,7 +199,7 @@
WorkList.enqueue(&cfg.getExit());
}
- void ProcessMerge(const CFGBlock* B) {
+ void ProcessMerge(CFG& cfg, const CFGBlock* B) {
// Merge dataflow values from all predecessors of this block.
ValTy& V = TF.getVal();
V.resetValues(D.getAnalysisData());
@@ -210,7 +210,8 @@
for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
- typename EdgeDataMapTy::iterator EI = M.find(ItrTraits::PrevEdge(B,*I));
+ typename EdgeDataMapTy::iterator EI =
+ M.find(ItrTraits::PrevEdge(cfg,B,*I));
if (EI != M.end()) {
if (firstMerge) {
@@ -236,13 +237,13 @@
/// block, update the dataflow value associated with the block's
/// outgoing/incoming edges (depending on whether we do a
// forward/backward analysis respectively)
- void UpdateEdges(const CFGBlock* B, ValTy& V) {
+ void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) {
for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
- UpdateEdgeValue(ItrTraits::NextEdge(B,*I),V,*I);
+ UpdateEdgeValue(ItrTraits::NextEdge(cfg,B,*I),V,*I);
}
/// UpdateEdgeValue - Update the value associated with a given edge.
- void UpdateEdgeValue(BlkBlkEdge E, ValTy& V, const CFGBlock* TargetBlock) {
+ void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) {
EdgeDataMapTy& M = D.getEdgeDataMap();
typename EdgeDataMapTy::iterator I = M.find(E);
@@ -261,8 +262,7 @@
DFValuesTy& D;
DataflowWorkListTy WorkList;
TransferFuncsTy TF;
-};
-
+};
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h Thu Jan 10 18:40:29 2008
@@ -48,7 +48,7 @@
typedef typename ValueTypes::ValTy ValTy;
typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy;
typedef _AnalysisDirTag AnalysisDirTag;
- typedef llvm::DenseMap<ProgramEdge, ValTy> EdgeDataMapTy;
+ typedef llvm::DenseMap<ProgramPoint, ValTy> EdgeDataMapTy;
typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy;
//===--------------------------------------------------------------------===//
@@ -80,13 +80,13 @@
/// getEdgeData - Retrieves the dataflow values associated with a
/// CFG edge.
- ValTy& getEdgeData(const BlkBlkEdge& E) {
+ ValTy& getEdgeData(const BlockEdge& E) {
typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
assert (I != EdgeDataMap.end() && "No data associated with Edge.");
return I->second;
}
- const ValTy& getEdgeData(const BlkBlkEdge& E) const {
+ const ValTy& getEdgeData(const BlockEdge& E) const {
return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
}
Modified: cfe/trunk/include/clang/Analysis/ProgramEdge.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramEdge.h?rev=45846&r1=45845&r2=45846&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramEdge.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramEdge.h Thu Jan 10 18:40:29 2008
@@ -1,4 +1,4 @@
-//==- ProgramEdge.h - Program Points for Path-Sensitive Analysis --*- C++ -*-=//
+//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the interface ProgramEdge, which identifies a distinct
-// location in a function based on edges within its CFG.
+// This file defines the interface ProgramPoint, which identifies a
+// distinct location in a function.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_PATHSENS_PROGRAM_POINT
-#define LLVM_CLANG_ANALYSIS_PATHSENS_PROGRAM_POINT
+#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
@@ -21,178 +21,137 @@
namespace clang {
+ class CFG;
class CFGBlock;
class Stmt;
-class ProgramEdge {
- uintptr_t Src, Dst;
+class ProgramPoint {
public:
- enum EdgeKind { BExprBlk=0, BlkBExpr=1, BExprBExpr=2, BlkBlk=3,
- BExprSExpr=4, SExprSExpr=5, SExprBExpr=6, Infeasible=7 };
-
- static bool classof(const ProgramEdge*) { return true; }
-
- unsigned getKind() const { return (((unsigned) Src & 0x3) << 2) |
- ((unsigned) Dst & 0x3); }
-
- void* RawSrc() const { return reinterpret_cast<void*>(Src & ~0x3); }
- void* RawDst() const { return reinterpret_cast<void*>(Dst & ~0x3); }
+ enum Kind { BlockEntranceKind=0, PostStmtKind=1, BlockExitKind=2,
+ BlockEdgeSrcKind=3, BlockEdgeDstKind=4, BlockEdgeAuxKind=5 };
+protected:
+ uintptr_t Data;
- bool operator==(const ProgramEdge & RHS) const {
- // comparing pointer values canoncalizes "NULL" edges where both pointers
- // are NULL without having to worry about edgekind. We can otherwise
- // ignore edgekind because no CFGBlock* or Stmt* will have the same value.
- return RawSrc() == RHS.RawSrc() && RawDst() == RHS.RawDst();
+ ProgramPoint(const void* Ptr, Kind k) {
+ assert ((reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & 0x7) == 0
+ && "Address must have at least an 8-byte alignment.");
+
+ Data = reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & k;
}
- bool operator!=(const ProgramEdge& RHS) const {
- return RawSrc() != RHS.RawSrc() || RawDst() != RHS.RawDst();
- }
+ ProgramPoint() : Data(0) {}
- unsigned getHashValue() const {
- uintptr_t v1 = reinterpret_cast<uintptr_t>(RawSrc());
- uintptr_t v2 = reinterpret_cast<uintptr_t>(RawDst());
- return static_cast<unsigned>( (v1 >> 4) ^ (v1 >> 9) ^
- (v2 >> 5) ^ (v2 >> 10) );
- }
+public:
+ unsigned getKind() const { return Data & 0x5; }
+ void* getRawPtr() const { return reinterpret_cast<void*>(Data & ~0x7); }
+ void* getRawData() const { return reinterpret_cast<void*>(Data); }
-protected:
-
- ProgramEdge(const void* src, const void* dst, EdgeKind k) {
- assert (k >= BExprBlk && k <= BlkBlk);
- Src = reinterpret_cast<uintptr_t>(const_cast<void*>(src)) | (k >> 2);
- Dst = reinterpret_cast<uintptr_t>(const_cast<void*>(dst)) | (k & 0x3);
- }
+ static bool classof(const ProgramPoint*) { return true; }
+ bool operator==(const ProgramPoint & RHS) const { return Data == RHS.Data; }
+ bool operator!=(const ProgramPoint& RHS) const { return Data != RHS.Data; }
};
-
-class BExprBlkEdge : public ProgramEdge {
+
+class BlockEntrance : public ProgramPoint {
public:
- BExprBlkEdge(const Stmt* S,const CFGBlock* B)
- : ProgramEdge(S,B,BExprBlk) {}
-
- Stmt* Src() const { return reinterpret_cast<Stmt*>(RawSrc()); }
- CFGBlock* Dst() const { return reinterpret_cast<CFGBlock*>(RawDst()); }
-
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == BExprBlk;
+ BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
+
+ CFGBlock* getBlock() const {
+ return reinterpret_cast<CFGBlock*>(getRawPtr());
}
-};
-
-class BlkBExprEdge : public ProgramEdge {
-public:
- BlkBExprEdge(const CFGBlock* B, const Stmt* S)
- : ProgramEdge(B,S,BlkBExpr) {}
- CFGBlock* Src() const { return reinterpret_cast<CFGBlock*>(RawSrc()); }
- Stmt* Dst() const { return reinterpret_cast<Stmt*>(RawDst()); }
+ Stmt* getFirstStmt() const {
+ CFGBlock* B = getBlock();
+ return B->empty() ? NULL : B->front();
+ }
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == BlkBExpr;
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == BlockEntranceKind;
}
};
-
-class BExprBExprEdge : public ProgramEdge {
+
+class BlockExit : public ProgramPoint {
public:
- BExprBExprEdge(const Stmt* S1, const Stmt* S2)
- : ProgramEdge(S1,S2,BExprBExpr) {}
-
- Stmt* Src() const { return reinterpret_cast<Stmt*>(RawSrc()); }
- Stmt* Dst() const { return reinterpret_cast<Stmt*>(RawDst()); }
+ BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == BExprBExpr;
+ CFGBlock* getBlock() const {
+ return reinterpret_cast<CFGBlock*>(getRawPtr());
}
-};
-
-class BExprSExprEdge : public ProgramEdge {
-public:
- BExprSExprEdge(const Stmt* S1, const Expr* S2)
- : ProgramEdge(S1,S2,BExprSExpr) {}
-
- Stmt* Src() const { return reinterpret_cast<Stmt*>(RawSrc()); }
- Expr* Dst() const { return reinterpret_cast<Expr*>(RawDst()); }
-
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == BExprSExpr;
+
+ Stmt* getLastStmt() const {
+ CFGBlock* B = getBlock();
+ return B->empty() ? NULL : B->back();
}
-};
-class SExprSExprEdge : public ProgramEdge {
-public:
- SExprSExprEdge(const Expr* S1, const Expr* S2)
- : ProgramEdge(S1,S2,SExprSExpr) {}
-
- Expr* Src() const { return reinterpret_cast<Expr*>(RawSrc()); }
- Expr* Dst() const { return reinterpret_cast<Expr*>(RawDst()); }
-
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == SExprSExpr;
+ Stmt* getTerminator() const {
+ return getBlock()->getTerminator();
}
-};
-
-class SExprBExprEdge : public ProgramEdge {
-public:
- SExprBExprEdge(const Expr* S1, const Stmt* S2)
- : ProgramEdge(S1,S2,SExprBExpr) {}
-
- Expr* Src() const { return reinterpret_cast<Expr*>(RawSrc()); }
- Stmt* Dst() const { return reinterpret_cast<Stmt*>(RawDst()); }
-
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == SExprBExpr;
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == BlockExitKind;
}
};
-class BlkBlkEdge : public ProgramEdge {
+
+class PostStmt : public ProgramPoint {
public:
- BlkBlkEdge(const CFGBlock* B1, const CFGBlock* B2)
- : ProgramEdge(B1,B2,BlkBlk) {}
+ PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {}
- CFGBlock* Src() const { return reinterpret_cast<CFGBlock*>(RawSrc()); }
- CFGBlock* Dst() const { return reinterpret_cast<CFGBlock*>(RawDst()); }
-
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == BlkBlk;
+ Stmt* getStmt() const { return (Stmt*) getRawPtr(); }
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostStmtKind;
}
};
-class InfeasibleEdge : public ProgramEdge {
+class BlockEdge : public ProgramPoint {
+ typedef std::pair<CFGBlock*,CFGBlock*> BPair;
public:
- InfeasibleEdge(Stmt* S) : ProgramEdge(S,NULL,Infeasible) {}
-
- Stmt* getStmt() const { return reinterpret_cast<Stmt*>(RawSrc()); }
+ BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2);
+
+ CFGBlock* getSrc() const;
+ CFGBlock* getDst() const;
- static bool classof(const ProgramEdge* E) {
- return E->getKind() == Infeasible;
+ static bool classof(const ProgramPoint* Location) {
+ unsigned k = Location->getKind();
+ return k >= BlockEdgeSrcKind && k <= BlockEdgeAuxKind;
}
};
+
+
} // end namespace clang
namespace llvm { // Traits specialization for DenseMap
-template <> struct DenseMapInfo<clang::ProgramEdge> {
+template <> struct DenseMapInfo<clang::ProgramPoint> {
- static inline clang::ProgramEdge getEmptyKey() {
- return clang::BlkBlkEdge(0, 0);
+ static inline clang::ProgramPoint getEmptyKey() {
+ uintptr_t x =
+ reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
+
+ return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
}
- static inline clang::ProgramEdge getTombstoneKey() {
- return clang::BlkBlkEdge(reinterpret_cast<clang::CFGBlock*>(-1),
- reinterpret_cast<clang::CFGBlock*>(-1));
+ static inline clang::ProgramPoint getTombstoneKey() {
+ uintptr_t x =
+ reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
+
+ return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
}
- static unsigned getHashValue(const clang::ProgramEdge& E) {
- return E.getHashValue();
+ static unsigned getHashValue(const clang::ProgramPoint& Loc) {
+ return DenseMapInfo<void*>::getHashValue(Loc.getRawData());
}
- static bool isEqual(const clang::ProgramEdge& LHS,
- const clang::ProgramEdge& RHS) {
- return LHS == RHS;
+ static bool isEqual(const clang::ProgramPoint& L,
+ const clang::ProgramPoint& R) {
+ return L == R;
}
- static bool isPod() { return true; }
+ static bool isPod() {
+ return true;
+ }
};
} // end namespace llvm
More information about the cfe-commits
mailing list