aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/ProgramPoint.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/ProgramPoint.h')
-rw-r--r--include/clang/Analysis/ProgramPoint.h158
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