ProgramPoint.h revision f4be8ee748831bc23e35b542e6c1bb6d1eb49baa
183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
2eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//
3eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//                     The LLVM Compiler Infrastructure
4eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
7eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//
8eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===//
9eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//
1083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//  This file defines the interface ProgramPoint, which identifies a
1183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//  distinct location in a function.
12eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//
13eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===//
14eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
1583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
1683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
17eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
1805e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek#include "clang/AST/CFG.h"
19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/DataTypes.h"
204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h"
215226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h"
224c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert>
23eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
24eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang {
2505e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek
2683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
27eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
28f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  enum Kind { BlockEdgeKind = 0x0,
29f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockEntranceKind = 0x1,
30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockExitKind = 0x2,
3182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek              // Keep the following four together and in this order.
32f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtKind = 0x3,
33f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLocationChecksSucceedKind = 0x4,
34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostOutOfBoundsCheckFailedKind = 0x5,
35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostNullCheckFailedKind = 0x6,
36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostUndefLocationCheckFailedKind = 0x7,
37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLoadKind = 0x8,
38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStoreKind = 0x9,
39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostPurgeDeadSymbolsKind = 0x10,
40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtCustomKind = 0x11,
41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
42f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MaxPostStmtKind = PostStmtCustomKind };
434c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
44d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
45f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  enum { TwoPointers = 0x1, Custom = 0x2, Mask = 0x3 };
46f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  std::pair<uintptr_t,uintptr_t> Data;
48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
50d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  ProgramPoint(const void* P, Kind k)
51f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P),
52f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek           (uintptr_t) k) {}
53d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
54d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  ProgramPoint(const void* P1, const void* P2)
55f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P1) | TwoPointers,
56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek           reinterpret_cast<uintptr_t>(P2)) {}
57f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  ProgramPoint(const void* P1, const void* P2, bool)
59f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P1) | Custom,
60f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek           reinterpret_cast<uintptr_t>(P2)) {}
61f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
62d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
63d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1NoMask() const {
64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
65f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(k == BlockEntranceKind || k == BlockExitKind);
66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.first);
676e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis  }
686e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1() const {
70f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
71f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(k == BlockEdgeKind || (k >= MinPostStmtKind && k < MaxPostStmtKind));
72f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return reinterpret_cast<void*>(Data.first & ~Mask);
73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
746e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData2() const {
76f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
77f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(k == BlockEdgeKind || k == PostStmtCustomKind);
78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.second);
794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek  }
80f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
8183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic:
82f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  Kind getKind() const {
83f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    switch (Data.first & Mask) {
84f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      case TwoPointers: return BlockEdgeKind;
85f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      case Custom: return PostStmtCustomKind;
86f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      default: return (Kind) Data.second;
87f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    }
88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
89d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  // For use with DenseMap.
91d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
92d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first),
93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                             reinterpret_cast<void*>(Data.second));
94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P);
95d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
96eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
98d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
99d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
100d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data == RHS.Data;
101d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
104d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data != RHS.Data;
105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
107d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator<(const ProgramPoint& RHS) const {
108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data < RHS.Data;
109d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1105226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek
1115226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
112d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.first));
113d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.second));
1145226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  }
115eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
11783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
118eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
122d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
124eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
12783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
129eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
13183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
132bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
133eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
136eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
13783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
138bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
140d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
141bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
14483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
146bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
147bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
14883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
14983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
150bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
15283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
15383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
154bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
155bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
156eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
15783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint {
1591b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
160f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {}
161f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  PostStmt(const Stmt* S, const void* data) : ProgramPoint(S, data, true) {}
162f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
163eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
16483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {}
1651b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
166f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  Stmt* getStmt() const { return (Stmt*) getData1(); }
16783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
16883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
170f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
1711b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1721b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1738c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1748c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt {
1758c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1768c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostLocationChecksSucceed(const Stmt* S)
1778c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    : PostStmt(S, PostLocationChecksSucceedKind) {}
1788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostLocationChecksSucceedKind;
1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
184f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt {
185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  PostStmtCustom(const Stmt* S, const void* Data)
186f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : PostStmt(S, Data) {
187f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(getKind() == PostStmtCustomKind);
188f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
189f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
190f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  void* getCustomData() const { return getData2(); }
191f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
192f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  static bool classof(const ProgramPoint* Location) {
193f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return Location->getKind() == PostStmtCustomKind;
194f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
195f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek};
196f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt {
1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1998c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostOutOfBoundsCheckFailed(const Stmt* S)
2008c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostOutOfBoundsCheckFailedKind) {}
2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2038c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostOutOfBoundsCheckFailedKind;
2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2058c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2068c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2078c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt {
2088c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2098c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostUndefLocationCheckFailed(const Stmt* S)
2108c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostUndefLocationCheckFailedKind) {}
2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostUndefLocationCheckFailedKind;
2148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt {
2188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostNullCheckFailed(const Stmt* S)
2208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostNullCheckFailedKind) {}
2218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2238c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostNullCheckFailedKind;
2248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2261b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2271b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2281b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
2291b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {}
2301b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2321b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
233bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
234eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
235b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
23682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
23782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostStore(const Stmt* S) : PostStmt(S, PostStoreKind) {}
23982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
24082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
24182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
24282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
24382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
24482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
245331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
246331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
247331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {}
248331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
249331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
250331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
251331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
252331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
253331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
25483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
255b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
256d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
257d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    : ProgramPoint(B1, B2) {}
258d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
260d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData1());
261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
263d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData2());
265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
266b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
26783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
269b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
270b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
27183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
27283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
273eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
2744c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2754c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2764c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap
2774c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
27883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
2794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
280d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
281d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
282d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
284d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
287d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
291d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
293d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
294d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
3044c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
3054c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
3064c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
307eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
308