ProgramPoint.h revision 8c354758c2d39db87c77c723d81e34b4d967f762
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:
28d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  enum Kind { BlockEdgeKind=0, BlockEntranceKind, BlockExitKind,
2982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek              // Keep the following four together and in this order.
308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostStmtKind,
318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostLocationChecksSucceedKind,
328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostOutOfBoundsCheckFailedKind,
338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostNullCheckFailedKind,
348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostUndefLocationCheckFailedKind,
358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek              PostLoadKind, PostStoreKind,
3682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek              PostPurgeDeadSymbolsKind };
374c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
38d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
39d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  std::pair<uintptr_t,uintptr_t> Data;
40d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
41d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
42d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  ProgramPoint(const void* P, Kind k)
43d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P), (uintptr_t) k) {}
44d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
45d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  ProgramPoint(const void* P1, const void* P2)
46d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    : Data(reinterpret_cast<uintptr_t>(P1) | 0x1,
47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek           reinterpret_cast<uintptr_t>(P2)) {}
48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
50d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1NoMask() const {
51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    assert (getKind() != BlockEdgeKind);
52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.first);
536e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis  }
546e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
55d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData1() const {
56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    assert (getKind() == BlockEdgeKind);
57d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.first & ~0x1);
58d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
596e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis
60d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  void* getData2() const {
61d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    assert (getKind() == BlockEdgeKind);
62d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<void*>(Data.second);
634c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek  }
644c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
6583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic:
66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t getKind() const {
68d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data.first & 0x1 ? (uintptr_t) BlockEdgeKind : Data.second;
69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
70d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
71d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  // For use with DenseMap.
72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first),
74d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                             reinterpret_cast<void*>(Data.second));
75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P);
76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
77eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
7883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data == RHS.Data;
82d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
84d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
85d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data != RHS.Data;
86d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
87d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator<(const ProgramPoint& RHS) const {
89d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Data < RHS.Data;
90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
915226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek
925226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.first));
94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data.second));
955226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  }
96eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
9883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
99eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
10083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
10183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
10283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
104bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
105eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
10883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
10983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
110eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
11283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
113bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
114eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
11583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
117eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
11883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
119bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
121d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return reinterpret_cast<CFGBlock*>(getData1NoMask());
122bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
12383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    CFGBlock* B = getBlock();
12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
127bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
128bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
13283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
135bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
136bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
137eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
13883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint {
1401b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
1411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {}
142eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {}
1441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
145d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  Stmt* getStmt() const { return (Stmt*) getData1NoMask(); }
14683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
14783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
149331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return k >= PostStmtKind && k <= PostPurgeDeadSymbolsKind;
1501b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1511b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1528c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1538c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt {
1548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1558c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostLocationChecksSucceed(const Stmt* S)
1568c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    : PostStmt(S, PostLocationChecksSucceedKind) {}
1578c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1588c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1598c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostLocationChecksSucceedKind;
1608c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1618c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1628c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1638c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt {
1648c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1658c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostOutOfBoundsCheckFailed(const Stmt* S)
1668c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostOutOfBoundsCheckFailedKind) {}
1678c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1688c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1698c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostOutOfBoundsCheckFailedKind;
1708c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1718c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1728c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1738c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt {
1748c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1758c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostUndefLocationCheckFailed(const Stmt* S)
1768c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostUndefLocationCheckFailedKind) {}
1778c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostUndefLocationCheckFailedKind;
1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt {
1848c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
1858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostNullCheckFailed(const Stmt* S)
1868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  : PostStmt(S, PostNullCheckFailedKind) {}
1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostNullCheckFailedKind;
1908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1921b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1931b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
1941b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
1951b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {}
1961b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1971b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
1981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
199bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
200eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
201b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
20282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
20382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  PostStore(const Stmt* S) : PostStmt(S, PostStoreKind) {}
20582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
20682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
20782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
20882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
20982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
21082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
211331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
212331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
213331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {}
214331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
215331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
216331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
217331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
218331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
219331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
22083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
221b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
222d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
223d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    : ProgramPoint(B1, B2) {}
224d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
225d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
226d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData1());
227d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
228d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
229d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
230d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return static_cast<CFGBlock*>(getData2());
231d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
232b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
23383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
234d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
235b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
236b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
23783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
23883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
239eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
2404c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2414c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
2424c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap
2434c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
24483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
2454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
246d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
247d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
248d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
249d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
250d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
251d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
252d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
253d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
254d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
255d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
256d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
257d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
258d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
260d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
263d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
266d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
267d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
269d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
2704c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
2714c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
2724c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
273eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
274