ProgramPoint.h revision 5f85e17df3f5b0a8021443f2b590daecfb2cbd17
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:
30cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  enum Kind { BlockEdgeKind,
31cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockEntranceKind,
32cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockExitKind,
33cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PreStmtKind,
34cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              // Keep the following together and in this order.
35cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtKind,
36cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLocationChecksSucceedKind,
37cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostOutOfBoundsCheckFailedKind,
38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostNullCheckFailedKind,
39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostUndefLocationCheckFailedKind,
40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLoadKind,
41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStoreKind,
42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostPurgeDeadSymbolsKind,
43cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtCustomKind,
44cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLValueKind,
45f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
467090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              MaxPostStmtKind = PostLValueKind };
474c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
49d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  std::pair<const void *, const void *> Data;
50d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind K;
51e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *Tag;
52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
53d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
54e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  ProgramPoint(const void* P, Kind k, const void *tag = 0)
55d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : Data(P, NULL), K(k), Tag(tag) {}
56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
57d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  ProgramPoint(const void* P1, const void* P2, Kind k, const void *tag = 0)
58d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : Data(P1, P2), K(k), Tag(tag) {}
59f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
60d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
61d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData1() const { return Data.first; }
62d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData2() const { return Data.second; }
63e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *getTag() const { return Tag; }
64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
6583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic:
66d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind getKind() const { return K; }
67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
68e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
70e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
71d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    Profile(ID);
72e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
74eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
7583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
77d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
78d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return K == RHS.K && Data == RHS.Data && Tag == RHS.Tag;
79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
82d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return K != RHS.K || Data != RHS.Data || Tag != RHS.Tag;
83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
84d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
855226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
86d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddInteger((unsigned) K);
87d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.first);
88d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.second);
89e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
902680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
91eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
9283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
9383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
94eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
95ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek  BlockEntrance(const CFGBlock* B, const void *tag = 0)
96ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek    : ProgramPoint(B, BlockEntranceKind, tag) {}
9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
9883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
99d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
100bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
101eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
103d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
10583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
106eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
10883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
109bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
110eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
11283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
113eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
11483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
115bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
117d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
118bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
121d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
12283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
124bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek
12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
127bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
132bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
1335f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek
1345f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint {
1355f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic:
1365f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  StmtPoint(const Stmt *S, const void *p2, Kind k, const void *tag)
1375f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  : ProgramPoint(S, p2, k, tag) {}
1385f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek
1395f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
1405f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek
1415f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  template <typename T>
1425f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
1435f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek
1445f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1455f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    unsigned k = Location->getKind();
1465f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    return k >= PreStmtKind && k <= MaxPostStmtKind;
1475f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  }
1485f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek};
149eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
1505f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek
1515f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint {
152cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic:
153cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  PreStmt(const Stmt *S, const void *tag, const Stmt *SubStmt = 0)
1545f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    : StmtPoint(S, SubStmt, PreStmtKind, tag) {}
155cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
156cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
157cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
158cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  static bool classof(const ProgramPoint* Location) {
159cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek    return Location->getKind() == PreStmtKind;
160cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  }
161cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek};
162cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
1635f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint {
1641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
165cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  PostStmt(const Stmt* S, Kind k, const void *tag = 0)
1665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    : StmtPoint(S, NULL, k, tag) {}
167e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek
168d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  PostStmt(const Stmt* S, const void* data, Kind k, const void *tag =0)
1695f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    : StmtPoint(S, data, k, tag) {}
170f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
171eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1725f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  explicit PostStmt(const Stmt* S, const void *tag = 0)
1735f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    : StmtPoint(S, NULL, PostStmtKind, tag) {}
17483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
17583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1761b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
177f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
1781b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1791b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt {
1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
183e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLocationChecksSucceed(const Stmt* S, const void *tag = 0)
184e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLocationChecksSucceedKind, tag) {}
1858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
1868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostLocationChecksSucceedKind;
1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
1898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
1908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
191f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt {
1922680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic:
19359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  PostStmtCustom(const Stmt* S,
19459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek                 const std::pair<const void*, const void*>* TaggedData)
195d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : PostStmt(S, TaggedData, PostStmtCustomKind) {}
19659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
19759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const std::pair<const void*, const void*>& getTaggedPair() const {
198d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return
199d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek      *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
20059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  }
20159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
20259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTag() const { return getTaggedPair().first; }
203f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
20459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTaggedData() const { return getTaggedPair().second; }
205f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
206f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  static bool classof(const ProgramPoint* Location) {
207f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return Location->getKind() == PostStmtCustomKind;
208f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
209f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek};
210f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt {
2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2131670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0)
2141670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {}
2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostOutOfBoundsCheckFailedKind;
2188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt {
2228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2231670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0)
2241670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {}
2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2268c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2278c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostUndefLocationCheckFailedKind;
2288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt {
2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
2331670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostNullCheckFailed(const Stmt* S, const void *tag = 0)
2341670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  : PostStmt(S, PostNullCheckFailedKind, tag) {}
2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2368c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2378c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek    return Location->getKind() == PostNullCheckFailedKind;
2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2401b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2421b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
243e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostLoad(const Stmt* S, const void *tag = 0)
244e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostLoadKind, tag) {}
2451b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
2461b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2471b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
248bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
249eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
250b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
25182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
25282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
253e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  PostStore(const Stmt* S, const void *tag = 0)
254e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    : PostStmt(S, PostStoreKind, tag) {}
25582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
25682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
25782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
25882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
25982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
2607090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2617090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
2627090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
2637090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  PostLValue(const Stmt* S, const void *tag = 0)
2647090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  : PostStmt(S, PostLValueKind, tag) {}
2657090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2667090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
2677090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
2687090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
2697090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek};
27082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek
271331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
272331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
2731670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek  PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0)
2741670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek    : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {}
275331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
276331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
277331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
278331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
279331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
280331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek
28183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
282b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
284d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    : ProgramPoint(B1, B2, BlockEdgeKind) {}
285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
287d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
291d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
293b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek
29483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
296b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
297b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
29883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
29983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
300eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
3014c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3024c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3034c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap
3044c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
30583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
3064c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
307d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
309d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
310d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
311d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
312d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
313d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
314d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
315d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
316d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
317d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
318d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
319d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
322d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
323d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
324d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
325d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
326d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
327d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
328d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
329d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
330d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
3314c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
3324c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
3334c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
334eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
335