From: Ted Kremenek Date: Fri, 28 Sep 2007 23:15:21 +0000 (+0000) Subject: Added ProgramEdge.h, which defines ProgramEdge (and subclasses) that X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb19188e668d0ad2c968fc0286a6922f9194deb4;p=clang Added ProgramEdge.h, which defines ProgramEdge (and subclasses) that encapsulate a program point within a CFG for use by our path-sensitive dataflow solver. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42455 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/ProgramEdge.h b/include/clang/Analysis/PathSensitive/ProgramEdge.h new file mode 100644 index 0000000000..bfb7a0ae12 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/ProgramEdge.h @@ -0,0 +1,89 @@ +//==- ProgramEdge.h - Program Points for Path-Sensitive Analysis --*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface ProgramEdge, which identifies a distinct +// location in a function based on edges within its CFG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_PATHSENS_PROGRAM_POINT +#define LLVM_CLANG_ANALYSIS_PATHSENS_PROGRAM_POINT + +#include "llvm/Support/DataTypes.h" + +namespace clang { + + class CFGBlock; + class Stmt; + +class ProgramEdge { + uintptr_t Src, Dst; +public: + enum EdgeKind { StmtBlk=0, BlkStmt=1, StmtStmt=2, BlkBlk=3 }; + static bool classof(const ProgramEdge*) { return true; } + + unsigned getKind() const { return (unsigned) Src & 0x3; } + void* RawSrc() const { return reinterpret_cast(Src & ~0x3); } + void* RawDst() const { return reinterpret_cast(Dst); } + +protected: + ProgramEdge(const void* src, const void* dst, EdgeKind k) { + assert (k >= StmtBlk && k <= BlkBlk); + Src = reinterpret_cast(const_cast(src)) | k; + Dst = reinterpret_cast(const_cast(dst)); + } +}; + +class StmtBlkEdge : public ProgramEdge { +public: + StmtBlkEdge(const Stmt* S,const CFGBlock* B) + : ProgramEdge(S,B,StmtBlk) {} + + const Stmt* Src() const { return reinterpret_cast(RawSrc()); } + const CFGBlock* Dst() const { return reinterpret_cast(RawDst()); } + + static bool classof(const ProgramEdge* E) { return E->getKind() == StmtBlk; } +}; + +class BlkStmtEdge : public ProgramEdge { +public: + BlkStmtEdge(const CFGBlock* B, const Stmt* S) + : ProgramEdge(B,S,BlkStmt) {} + + const CFGBlock* Src() const { return reinterpret_cast(RawSrc()); } + const Stmt* Dst() const { return reinterpret_cast(RawDst()); } + + static bool classof(const ProgramEdge* E) { return E->getKind() == StmtBlk; } +}; + +class StmtStmtEdge : public ProgramEdge { +public: + StmtStmtEdge(const Stmt* S1, const Stmt* S2) + : ProgramEdge(S1,S2,StmtStmt) {} + + const Stmt* Src() const { return reinterpret_cast(RawSrc()); } + const Stmt* Dst() const { return reinterpret_cast(RawDst()); } + + static bool classof(const ProgramEdge* E) { return E->getKind() == StmtStmt; } +}; + + +class BlkBlkEdge : public ProgramEdge { +public: + BlkBlkEdge(const CFGBlock* B1, const CFGBlock* B2) + : ProgramEdge(B1,B2,BlkBlk) {} + + const CFGBlock* Src() const { return reinterpret_cast(RawSrc()); } + const CFGBlock* Dst() const { return reinterpret_cast(RawDst()); } + + static bool classof(const ProgramEdge* E) { return E->getKind() == BlkBlk; } +}; + +} // end namespace clang +#endif