diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-01-11 00:40:29 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-01-11 00:40:29 +0000 |
commit | 83c01da96f57cf732a5da9a83e2981241f205dc4 (patch) | |
tree | ccc2753d494c98e24b017ad38db0f72fd0f80e20 /include/clang/Analysis/ProgramEdge.h | |
parent | 80aeaa20837165713520bc6304e376c8eb606c93 (diff) |
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).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45846 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/ProgramEdge.h')
-rw-r--r-- | include/clang/Analysis/ProgramEdge.h | 215 |
1 files changed, 87 insertions, 128 deletions
diff --git a/include/clang/Analysis/ProgramEdge.h b/include/clang/Analysis/ProgramEdge.h index 1c10196c28..8438e5602f 100644 --- a/include/clang/Analysis/ProgramEdge.h +++ b/include/clang/Analysis/ProgramEdge.h @@ -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 |