ProgramPoint.h revision d6b9e37311013bdf24fd709f7e9962e3b141e6fb
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
18e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h"
19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/DataTypes.h"
204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h"
215226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h"
226bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h"
234c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert>
2459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility>
25eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
26eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang {
2705e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek
2883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  enum Kind { BlockEdgeKind = 0x0,
31f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockEntranceKind = 0x1,
32f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockExitKind = 0x2,
3382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek              // Keep the following four together and in this order.
34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtKind = 0x3,
35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLocationChecksSucceedKind = 0x4,
36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostOutOfBoundsCheckFailedKind = 0x5,
37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostNullCheckFailedKind = 0x6,
38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostUndefLocationCheckFailedKind = 0x7,
39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLoadKind = 0x8,
40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStoreKind = 0x9,
41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostPurgeDeadSymbolsKind = 0x10,
42f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtCustomKind = 0x11,
437090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              PostLValueKind = 0x12,
44f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
457090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              MaxPostStmtKind = PostLValueKind };
464c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
48d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  std::pair<const void *, const void *> Data;
49d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind K;
50e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *Tag;
51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
53e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  ProgramPoint(const void* P, Kind k, const void *tag = 0)
54d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : Data(P, NULL), K(k), Tag(tag) {}
55d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
56d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  ProgramPoint(const void* P1, const void* P2, Kind k, const void *tag = 0)
57d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : Data(P1, P2), K(k), Tag(tag) {}
58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
59d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
60d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData1() const { return Data.first; }
61d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData2() const { return Data.second; }
62e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *getTag() const { return Tag; }
63f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
6483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic:
65d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind getKind() const { return K; }
66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
67e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
68d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
69e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
70d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    Profile(ID);
71e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
73eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
7483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
77d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return K == RHS.K && Data == RHS.Data && Tag == RHS.Tag;
78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
81d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return K != RHS.K || Data != RHS.Data || Tag != RHS.Tag;
82d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
845226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
85d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddInteger((unsigned) K);
86d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.first);
87d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.second);
88e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
892680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
90eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
9183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
9283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
93eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
94ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek  BlockEntrance(const CFGBlock* B, const void *tag = 0)
95ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek    : ProgramPoint(B, BlockEntranceKind, tag) {}
9683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
98d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
99bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
100eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
102d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
10383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
105eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
108bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
109eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
11083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
112eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
11383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
114bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
11583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
116d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
117bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
11883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
120d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
12183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
122bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
126bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
12783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
130bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
132eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint {
1341b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
135e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostStmt(const Stmt* S, Kind k,const void *tag = 0)
136e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : ProgramPoint(S, k, tag) {}
137e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek
138d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  PostStmt(const Stmt* S, const void* data, Kind k, const void *tag =0)
139d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : ProgramPoint(S, data, k, tag) {}
140f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
141eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1421670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostStmt(const Stmt* S, const void *tag = 0)
1431670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : ProgramPoint(S, PostStmtKind, tag) {}
1441670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek
145d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek
146f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  Stmt* getStmt() const { return (Stmt*) getData1(); }
1476bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek
148d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  template <typename T>
1496bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek  T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
15083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1521b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
153f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
1541b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1551b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1568c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1578c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt {
1588c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
159e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLocationChecksSucceed(const Stmt* S, const void *tag = 0)
160e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLocationChecksSucceedKind, tag) {}
1618c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1628c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1638c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostLocationChecksSucceedKind;
1648c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1658c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1668c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
167f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt {
1682680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic:
16959753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  PostStmtCustom(const Stmt* S,
17059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek                 const std::pair<const void*, const void*>* TaggedData)
171d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : PostStmt(S, TaggedData, PostStmtCustomKind) {}
17259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
17359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const std::pair<const void*, const void*>& getTaggedPair() const {
174d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return
175d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek      *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
17659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  }
17759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
17859753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTag() const { return getTaggedPair().first; }
179f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
18059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTaggedData() const { return getTaggedPair().second; }
181f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
182f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  static bool classof(const ProgramPoint* Location) {
183f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return Location->getKind() == PostStmtCustomKind;
184f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek};
186f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt {
1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1891670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0)
1901670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {}
1918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostOutOfBoundsCheckFailedKind;
1948c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1958c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1968c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt {
1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1991670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0)
2001670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {}
2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2038c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostUndefLocationCheckFailedKind;
2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2058c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2068c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2078c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt {
2088c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2091670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostNullCheckFailed(const Stmt* S, const void *tag = 0)
2101670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostNullCheckFailedKind, tag) {}
2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostNullCheckFailedKind;
2148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2161b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2171b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2181b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
219e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLoad(const Stmt* S, const void *tag = 0)
220e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLoadKind, tag) {}
2211b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2221b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2231b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
224bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
225eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
226b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
22782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
22882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
229e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostStore(const Stmt* S, const void *tag = 0)
230e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostStoreKind, tag) {}
23182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
23282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
23382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
23482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
23582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
2367090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2377090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
2387090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
2397090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  PostLValue(const Stmt* S, const void *tag = 0)
2407090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  : PostStmt(S, PostLValueKind, tag) {}
2417090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2427090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
2437090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
2447090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
2457090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek};
24682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
247331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
248331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
2491670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0)
2501670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {}
251331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
252331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
253331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
254331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
255331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
256331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
25783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
258b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
260d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : ProgramPoint(B1, B2, BlockEdgeKind) {}
261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
263d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
266d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
267d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
269b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
27083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
271d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
272b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
273b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
27483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
27583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
276eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
2774c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2784c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap
2804c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
28183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
2824c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
284d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
287d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
291d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
293d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
294d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
304d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
306d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
3074c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
3084c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
3094c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
310eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
311