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