diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-01-11 00:43:12 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-01-11 00:43:12 +0000 |
commit | a1d44b5b7dbd39d4cfdbbb5ceb1885499ea03c77 (patch) | |
tree | 04888ca57b08a16a0eaebd6a1939ac2e14aca8f0 /include/clang/Analysis/ProgramPoint.h | |
parent | 83c01da96f57cf732a5da9a83e2981241f205dc4 (diff) |
Renamed ProgramEdge.h to ProgramPoint.h
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45847 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/ProgramPoint.h')
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h new file mode 100644 index 0000000000..8438e5602f --- /dev/null +++ b/include/clang/Analysis/ProgramPoint.h @@ -0,0 +1,158 @@ +//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface ProgramPoint, which identifies a +// distinct location in a function. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT +#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT + +#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/DenseMap.h" +#include <cassert> + +namespace clang { + + class CFG; + class CFGBlock; + class Stmt; + +class ProgramPoint { +public: + enum Kind { BlockEntranceKind=0, PostStmtKind=1, BlockExitKind=2, + BlockEdgeSrcKind=3, BlockEdgeDstKind=4, BlockEdgeAuxKind=5 }; +protected: + uintptr_t Data; + + 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; + } + + ProgramPoint() : Data(0) {} + +public: + unsigned getKind() const { return Data & 0x5; } + void* getRawPtr() const { return reinterpret_cast<void*>(Data & ~0x7); } + void* getRawData() const { return reinterpret_cast<void*>(Data); } + + 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 BlockEntrance : public ProgramPoint { +public: + BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} + + CFGBlock* getBlock() const { + return reinterpret_cast<CFGBlock*>(getRawPtr()); + } + + Stmt* getFirstStmt() const { + CFGBlock* B = getBlock(); + return B->empty() ? NULL : B->front(); + } + + static bool classof(const ProgramPoint* Location) { + return Location->getKind() == BlockEntranceKind; + } +}; + +class BlockExit : public ProgramPoint { +public: + BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} + + CFGBlock* getBlock() const { + return reinterpret_cast<CFGBlock*>(getRawPtr()); + } + + Stmt* getLastStmt() const { + CFGBlock* B = getBlock(); + return B->empty() ? NULL : B->back(); + } + + Stmt* getTerminator() const { + return getBlock()->getTerminator(); + } + + static bool classof(const ProgramPoint* Location) { + return Location->getKind() == BlockExitKind; + } +}; + + +class PostStmt : public ProgramPoint { +public: + PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} + + Stmt* getStmt() const { return (Stmt*) getRawPtr(); } + + static bool classof(const ProgramPoint* Location) { + return Location->getKind() == PostStmtKind; + } +}; + +class BlockEdge : public ProgramPoint { + typedef std::pair<CFGBlock*,CFGBlock*> BPair; +public: + BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2); + + CFGBlock* getSrc() const; + CFGBlock* getDst() const; + + 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::ProgramPoint> { + + 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::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::ProgramPoint& Loc) { + return DenseMapInfo<void*>::getHashValue(Loc.getRawData()); + } + + static bool isEqual(const clang::ProgramPoint& L, + const clang::ProgramPoint& R) { + return L == R; + } + + static bool isPod() { + return true; + } +}; +} // end namespace llvm + +#endif |