[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