ProgramPoint.h revision a1d44b5b7dbd39d4cfdbbb5ceb1885499ea03c77
1//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the interface ProgramPoint, which identifies a 11// distinct location in a function. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT 16#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT 17 18#include "llvm/Support/DataTypes.h" 19#include "llvm/ADT/DenseMap.h" 20#include <cassert> 21 22namespace clang { 23 24 class CFG; 25 class CFGBlock; 26 class Stmt; 27 28class ProgramPoint { 29public: 30 enum Kind { BlockEntranceKind=0, PostStmtKind=1, BlockExitKind=2, 31 BlockEdgeSrcKind=3, BlockEdgeDstKind=4, BlockEdgeAuxKind=5 }; 32protected: 33 uintptr_t Data; 34 35 ProgramPoint(const void* Ptr, Kind k) { 36 assert ((reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & 0x7) == 0 37 && "Address must have at least an 8-byte alignment."); 38 39 Data = reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & k; 40 } 41 42 ProgramPoint() : Data(0) {} 43 44public: 45 unsigned getKind() const { return Data & 0x5; } 46 void* getRawPtr() const { return reinterpret_cast<void*>(Data & ~0x7); } 47 void* getRawData() const { return reinterpret_cast<void*>(Data); } 48 49 static bool classof(const ProgramPoint*) { return true; } 50 bool operator==(const ProgramPoint & RHS) const { return Data == RHS.Data; } 51 bool operator!=(const ProgramPoint& RHS) const { return Data != RHS.Data; } 52}; 53 54class BlockEntrance : public ProgramPoint { 55public: 56 BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} 57 58 CFGBlock* getBlock() const { 59 return reinterpret_cast<CFGBlock*>(getRawPtr()); 60 } 61 62 Stmt* getFirstStmt() const { 63 CFGBlock* B = getBlock(); 64 return B->empty() ? NULL : B->front(); 65 } 66 67 static bool classof(const ProgramPoint* Location) { 68 return Location->getKind() == BlockEntranceKind; 69 } 70}; 71 72class BlockExit : public ProgramPoint { 73public: 74 BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 75 76 CFGBlock* getBlock() const { 77 return reinterpret_cast<CFGBlock*>(getRawPtr()); 78 } 79 80 Stmt* getLastStmt() const { 81 CFGBlock* B = getBlock(); 82 return B->empty() ? NULL : B->back(); 83 } 84 85 Stmt* getTerminator() const { 86 return getBlock()->getTerminator(); 87 } 88 89 static bool classof(const ProgramPoint* Location) { 90 return Location->getKind() == BlockExitKind; 91 } 92}; 93 94 95class PostStmt : public ProgramPoint { 96public: 97 PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} 98 99 Stmt* getStmt() const { return (Stmt*) getRawPtr(); } 100 101 static bool classof(const ProgramPoint* Location) { 102 return Location->getKind() == PostStmtKind; 103 } 104}; 105 106class BlockEdge : public ProgramPoint { 107 typedef std::pair<CFGBlock*,CFGBlock*> BPair; 108public: 109 BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2); 110 111 CFGBlock* getSrc() const; 112 CFGBlock* getDst() const; 113 114 static bool classof(const ProgramPoint* Location) { 115 unsigned k = Location->getKind(); 116 return k >= BlockEdgeSrcKind && k <= BlockEdgeAuxKind; 117 } 118}; 119 120 121 122} // end namespace clang 123 124 125namespace llvm { // Traits specialization for DenseMap 126 127template <> struct DenseMapInfo<clang::ProgramPoint> { 128 129 static inline clang::ProgramPoint getEmptyKey() { 130 uintptr_t x = 131 reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 132 133 return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 134 } 135 136 static inline clang::ProgramPoint getTombstoneKey() { 137 uintptr_t x = 138 reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 139 140 return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 141 } 142 143 static unsigned getHashValue(const clang::ProgramPoint& Loc) { 144 return DenseMapInfo<void*>::getHashValue(Loc.getRawData()); 145 } 146 147 static bool isEqual(const clang::ProgramPoint& L, 148 const clang::ProgramPoint& R) { 149 return L == R; 150 } 151 152 static bool isPod() { 153 return true; 154 } 155}; 156} // end namespace llvm 157 158#endif 159