ProgramPoint.h revision 7090d5465de7ca620da16211cf886edf1edc1f1f
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>
2359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility>
24eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
25eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang {
2605e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek
2783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
28eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
29f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  enum Kind { BlockEdgeKind = 0x0,
30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockEntranceKind = 0x1,
31f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              BlockExitKind = 0x2,
3282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek              // Keep the following four together and in this order.
33f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtKind = 0x3,
34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLocationChecksSucceedKind = 0x4,
35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostOutOfBoundsCheckFailedKind = 0x5,
36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostNullCheckFailedKind = 0x6,
37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostUndefLocationCheckFailedKind = 0x7,
38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostLoadKind = 0x8,
39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStoreKind = 0x9,
40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostPurgeDeadSymbolsKind = 0x10,
41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              PostStmtCustomKind = 0x11,
427090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              PostLValueKind = 0x12,
43f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
447090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              MaxPostStmtKind = PostLValueKind };
454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
46d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
47f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  enum { TwoPointers = 0x1, Custom = 0x2, Mask = 0x3 };
48f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  std::pair<uintptr_t,uintptr_t> Data;
50e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *Tag;
51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
53e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  ProgramPoint(const void* P, Kind k, const void *tag = 0)
54f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P),
55e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek           (uintptr_t) k), Tag(tag) {}
56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
57e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  ProgramPoint(const void* P1, const void* P2, const void *tag = 0)
58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P1) | TwoPointers,
59e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek           reinterpret_cast<uintptr_t>(P2)), Tag(tag) {}
60f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
611670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  ProgramPoint(const void* P1, const void* P2, bool, const void *tag = 0)
62f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P1) | Custom,
631670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek           reinterpret_cast<uintptr_t>(P2)), Tag(tag) {}
64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
65d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1NoMask() const {
67f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
68f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(k == BlockEntranceKind || k == BlockExitKind);
69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.first);
706e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis  }
716e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1() const {
73f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
742680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek    assert(k == BlockEdgeKind ||(k >= MinPostStmtKind && k <= MaxPostStmtKind));
75f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return reinterpret_cast<void*>(Data.first & ~Mask);
76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
776e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData2() const {
79f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    Kind k = getKind(); k = k;
80f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(k == BlockEdgeKind || k == PostStmtCustomKind);
81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.second);
824c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek  }
83e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek
84e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *getTag() const { return Tag; }
85f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
8683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic:
87f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  Kind getKind() const {
88f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    switch (Data.first & Mask) {
89f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      case TwoPointers: return BlockEdgeKind;
90f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      case Custom: return PostStmtCustomKind;
91f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek      default: return (Kind) Data.second;
92f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    }
93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
95e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
96d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
97e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
98e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.first));
99e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.second));
100e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
101e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
103eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
107e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return Data == RHS.Data && Tag == RHS.Tag;
108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
109d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
110d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
111e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return Data != RHS.Data || Tag != RHS.Tag;
112d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
113d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
114d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator<(const ProgramPoint& RHS) const {
115e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return Data < RHS.Data && Tag < RHS.Tag;
116d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1175226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek
1185226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
119d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.first));
1202680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek    if (getKind() != PostStmtCustomKind)
1212680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek      ID.AddPointer(reinterpret_cast<void*>(Data.second));
1222680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek    else {
1232680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek      const std::pair<const void*, const void*> *P =
1242680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek        reinterpret_cast<std::pair<const void*, const void*>*>(Data.second);
1252680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek      ID.AddPointer(P->first);
1262680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek      ID.AddPointer(P->second);
1272680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek    }
128e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
1292680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
130eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
13183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
133eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
137d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
138bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
139eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
14083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
14183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
144eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
14683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
147bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
148eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
14983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
15083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
151eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
15283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
153bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
15483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
155d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
156bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
15783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
15983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
16083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
161bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
162bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
16383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
16483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
165bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
16683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
16783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
16883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
169bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
170bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
171eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
17283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint {
1731b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
174e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostStmt(const Stmt* S, Kind k,const void *tag = 0)
175e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : ProgramPoint(S, k, tag) {}
176e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek
1771670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostStmt(const Stmt* S, const void* data, bool, const void *tag =0)
1781670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : ProgramPoint(S, data, true, tag) {}
179f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
180eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1811670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostStmt(const Stmt* S, const void *tag = 0)
1821670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : ProgramPoint(S, PostStmtKind, tag) {}
1831670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek
1841b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  Stmt* getStmt() const { return (Stmt*) getData1(); }
18683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
18783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1881b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
189f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
1901b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt {
1948c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
195e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLocationChecksSucceed(const Stmt* S, const void *tag = 0)
196e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLocationChecksSucceedKind, tag) {}
1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1998c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostLocationChecksSucceedKind;
2008c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
203f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt {
2042680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic:
20559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  PostStmtCustom(const Stmt* S,
20659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek                 const std::pair<const void*, const void*>* TaggedData)
2071670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : PostStmt(S, TaggedData, true) {
208f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    assert(getKind() == PostStmtCustomKind);
209f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
21059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
21159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const std::pair<const void*, const void*>& getTaggedPair() const {
21259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek    return *reinterpret_cast<std::pair<const void*, const void*>*>(getData2());
21359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  }
21459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
21559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTag() const { return getTaggedPair().first; }
216f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
21759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTaggedData() const { return getTaggedPair().second; }
218f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
219f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  static bool classof(const ProgramPoint* Location) {
220f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return Location->getKind() == PostStmtCustomKind;
221f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
222f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek};
223f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
2248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt {
2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2261670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0)
2271670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {}
2288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostOutOfBoundsCheckFailedKind;
2318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt {
2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2361670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0)
2371670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {}
2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2408c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostUndefLocationCheckFailedKind;
2418c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2428c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2438c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2448c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt {
2458c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2461670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostNullCheckFailed(const Stmt* S, const void *tag = 0)
2471670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostNullCheckFailedKind, tag) {}
2488c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2498c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2508c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostNullCheckFailedKind;
2518c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2528c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2531b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2541b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2551b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
256e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLoad(const Stmt* S, const void *tag = 0)
257e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLoadKind, tag) {}
2581b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2591b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2601b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
261bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
262eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
263b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
26482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
26582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
266e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostStore(const Stmt* S, const void *tag = 0)
267e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostStoreKind, tag) {}
26882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
26982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
27082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
27182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
27282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
2737090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2747090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
2757090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
2767090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  PostLValue(const Stmt* S, const void *tag = 0)
2777090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  : PostStmt(S, PostLValueKind, tag) {}
2787090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2797090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
2807090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
2817090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
2827090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek};
28382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
284331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
285331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
2861670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0)
2871670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {}
288331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
289331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
290331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
291331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
292331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
293331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
29483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
295b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    : ProgramPoint(B1, B2) {}
298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData1());
301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
304d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData2());
305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
306b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
30783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
309b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
310b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
31183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
31283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
313eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
3144c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3154c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3164c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap
3174c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
31883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
3194c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
322d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
323d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
324d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
325d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
326d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
327d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
328d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
329d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
330d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
331d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
332d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
333d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
334d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
335d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
336d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
337d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
338d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
339d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
340d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
341d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
342d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
343d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
3444c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
3454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
3464c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
347eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
348