ProgramPoint.h revision 5903a373db3d27794c90b25687e0dd6adb0e497d
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
18c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu#include "clang/Analysis/AnalysisContext.h"
19e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h"
2003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h"
214c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h"
225226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h"
236bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h"
24ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "llvm/ADT/StringRef.h"
254c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert>
2659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility>
27ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include <string>
28eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang {
3025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
311d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext;
32102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass FunctionDecl;
33ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass LocationContext;
34ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag;
35ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
3683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
37eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  enum Kind { BlockEdgeKind,
39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockEntranceKind,
40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockExitKind,
41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PreStmtKind,
42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtKind,
43b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreLoadKind,
44cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLoadKind,
45b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreStoreKind,
46cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStoreKind,
47cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostPurgeDeadSymbolsKind,
488083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek              PostConditionKind,
49cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLValueKind,
509dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu              PostInitializerKind,
51102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor              CallEnterKind,
52102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor              CallExitKind,
53f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks              MaxPostStmtKind = CallExitKind,
555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks              EpsilonKind};
564c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
57d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
58d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  std::pair<const void *, const void *> Data;
59d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind K;
6025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
6125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // The LocationContext could be NULL to allow ProgramPoint to be used in
6225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // context insensitive analysis.
6325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  const LocationContext *L;
64ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const ProgramPointTag *Tag;
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  ProgramPoint();
67ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
68d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
699c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ProgramPoint(const void *P, Kind k, const LocationContext *l,
70ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek               const ProgramPointTag *tag = 0)
71a5fdd9ce694b1c2dbfd225cb6f55ef743d1ab562Douglas Gregor    : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
739c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l,
74ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek               const ProgramPointTag *tag = 0)
7525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : Data(P1, P2), K(k), L(l), Tag(tag) {}
76f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
77d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
789c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const void *getData1() const { return Data.first; }
799c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const void *getData2() const { return Data.second; }
803d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  void setData2(const void *d) { Data.second = d; }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
83af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  /// Create a new ProgramPoint object that is the same as the original
84af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  /// except for using the specified tag value.
8563d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks  ProgramPoint withTag(const ProgramPointTag *tag) const {
86af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks    return ProgramPoint(Data.first, Data.second, K, L, tag);
87af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  }
88af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks
89d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind getKind() const { return K; }
90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
91ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const ProgramPointTag *getTag() const { return Tag; }
9258465900ca10e53b8700a64e9265870de34e1acaTed Kremenek
93fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu  const LocationContext *getLocationContext() const { return L; }
9425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
95e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
96d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
97e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
98d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    Profile(ID);
99e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
100d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
104d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
10525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
107d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
1089c378f705405d37f49795d5e915989de774fe11fTed Kremenek  bool operator!=(const ProgramPoint &RHS) const {
10925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
110d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1125226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
113d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddInteger((unsigned) K);
114d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.first);
115d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.second);
11625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    ID.AddPointer(L);
117e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
1182680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
11963d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks
12063d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks  static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
12163d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks                                      const LocationContext *LC,
12263d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks                                      const ProgramPointTag *tag);
12363d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks
124eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
127eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1289c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockEntrance(const CFGBlock *B, const LocationContext *L,
129ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                const ProgramPointTag *tag = 0)
1302f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    : ProgramPoint(B, BlockEntranceKind, L, tag) {
1312f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    assert(B && "BlockEntrance requires non-null block");
1322f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getBlock() const {
13503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return reinterpret_cast<const CFGBlock*>(getData1());
136bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGElement getFirstElement() const {
1399c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const CFGBlock *B = getBlock();
140852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return B->empty() ? CFGElement() : B->front();
141852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  }
142852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
14483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
145bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
146eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
14783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
14883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
149eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1509c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockExit(const CFGBlock *B, const LocationContext *L)
15125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(B, BlockExitKind, L) {}
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1539c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getBlock() const {
15403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return reinterpret_cast<const CFGBlock*>(getData1());
155bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
15683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
1579c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Stmt *getTerminator() const {
15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
159bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
16283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
163bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
164bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint {
1675f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic:
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
169ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek            const ProgramPointTag *tag)
17025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(S, p2, k, L, tag) {}
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1725f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1745f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  template <typename T>
1755f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1775f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1785f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    unsigned k = Location->getKind();
1795f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    return k >= PreStmtKind && k <= MaxPostStmtKind;
1805f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  }
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
183eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
1845f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint {
185cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic:
186ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
18725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu          const Stmt *SubStmt = 0)
18825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
189cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
191cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
192cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  static bool classof(const ProgramPoint* Location) {
193cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek    return Location->getKind() == PreStmtKind;
194cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  }
195cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek};
196cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
1975f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint {
1981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
1999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
2003d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks           const ProgramPointTag *tag = 0)
20125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, data, k, L, tag) {}
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
203eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
2049c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit PostStmt(const Stmt *S, Kind k,
205ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                    const LocationContext *L, const ProgramPointTag *tag = 0)
2064bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek    : StmtPoint(S, NULL, k, L, tag) {}
2074bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek
2089c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit PostStmt(const Stmt *S, const LocationContext *L,
209ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                    const ProgramPointTag *tag = 0)
21025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
21183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
21283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2131b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
214f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
2151b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
2161b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2188083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek// PostCondition represents the post program point of a branch condition.
2198083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekclass PostCondition : public PostStmt {
2208083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekpublic:
2219c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostCondition(const Stmt *S, const LocationContext *L,
222ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                const ProgramPointTag *tag = 0)
2238083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek    : PostStmt(S, PostConditionKind, L, tag) {}
2248083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek
2258083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2268083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek    return Location->getKind() == PostConditionKind;
2278083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek  }
2288083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek};
2298083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek
230b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint {
231b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected:
232b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  LocationCheck(const Stmt *S, const LocationContext *L,
233ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                ProgramPoint::Kind K, const ProgramPointTag *tag)
234b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : StmtPoint(S, NULL, K, L, tag) {}
235b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
236b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
237b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    unsigned k = location->getKind();
238d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek    return k == PreLoadKind || k == PreStoreKind;
2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2408c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
241b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
242b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck {
2438c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
244ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreLoad(const Stmt *S, const LocationContext *L,
245ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek          const ProgramPointTag *tag = 0)
246b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : LocationCheck(S, L, PreLoadKind, tag) {}
247b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
248b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
249b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreLoadKind;
2508c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2518c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
253b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck {
2548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
255ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreStore(const Stmt *S, const LocationContext *L,
256ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek           const ProgramPointTag *tag = 0)
257b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  : LocationCheck(S, L, PreStoreKind, tag) {}
258b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
259b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
260b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreStoreKind;
2618c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2628c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2651b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
2669c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostLoad(const Stmt *S, const LocationContext *L,
267ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek           const ProgramPointTag *tag = 0)
26825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLoadKind, L, tag) {}
2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2701b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2711b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
272bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
273eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2753d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks/// \class Represents a program point after a store evaluation.
27682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
27782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
2783d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// Construct the post store point.
2793d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// \param Loc can be used to store the information about the location
2803d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// used in the form it was uttered in the code.
2813d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
282ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek            const ProgramPointTag *tag = 0)
2833d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    : PostStmt(S, PostStoreKind, L, tag) {
2843d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    assert(getData2() == 0);
2853d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    setData2(Loc);
2863d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  }
2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
28882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
28982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
29082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
2913d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks
2923d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// \brief Returns the information about the location used in the store,
2933d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// how it was uttered in the code.
2943d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  const void *getLocationValue() const {
2953d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    return getData2();
2963d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  }
2973d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks
29882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
2997090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
3007090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
3017090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
3029c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostLValue(const Stmt *S, const LocationContext *L,
303ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek             const ProgramPointTag *tag = 0)
30425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLValueKind, L, tag) {}
3051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3067090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
3077090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
3087090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
311331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
312331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
3139c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
314ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                       const ProgramPointTag *tag = 0)
31525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
317331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
318331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
319331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
320331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
323b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
3249c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
325e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    : ProgramPoint(B1, B2, BlockEdgeKind, L) {
326e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    assert(B1 && "BlockEdge: source block must be non-null");
327e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    assert(B2 && "BlockEdge: destination block must be non-null");
328e4c6675cccbaac991843def43072687bca50d989Ted Kremenek  }
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3309c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getSrc() const {
33103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CFGBlock*>(getData1());
332d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getDst() const {
33503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CFGBlock*>(getData2());
336d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
339d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
340b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
341b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
34283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
3439dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint {
3449dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic:
345cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  PostInitializer(const CXXCtorInitializer *I,
3469dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu                  const LocationContext *L)
3479dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu    : ProgramPoint(I, PostInitializerKind, L) {}
3489dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
3499dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  static bool classof(const ProgramPoint *Location) {
3509dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu    return Location->getKind() == PostInitializerKind;
3519dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  }
3529dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu};
3539dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
354102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallEnter : public StmtPoint {
355102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
35619b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
35719b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu            const LocationContext *callerCtx)
35819b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu    : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
359102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
360102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const Stmt *getCallExpr() const {
361102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return static_cast<const Stmt *>(getData1());
362102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
363102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
36419b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  const StackFrameContext *getCalleeContext() const {
36519b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu    return static_cast<const StackFrameContext *>(getData2());
366102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
367102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
368102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  static bool classof(const ProgramPoint *Location) {
369102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return Location->getKind() == CallEnterKind;
370102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
371102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
372102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
373102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallExit : public StmtPoint {
374102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
375102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  // CallExit uses the callee's location context.
376102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  CallExit(const Stmt *S, const LocationContext *L)
377102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    : StmtPoint(S, 0, CallExitKind, L, 0) {}
378102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
379102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  static bool classof(const ProgramPoint *Location) {
380102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return Location->getKind() == CallExitKind;
381102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
382102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
383102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
3845903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// This is a meta program point, which should be skipped by all the diagnostic
3855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// reasoning etc.
3865903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksclass EpsilonPoint : public ProgramPoint {
3875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zakspublic:
3885903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  EpsilonPoint(const LocationContext *L, const void *Data1,
3895903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               const void *Data2 = 0, const ProgramPointTag *tag = 0)
3905903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
3915903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
3925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const void *getData() const { return getData1(); }
3935903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
3945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  static bool classof(const ProgramPoint* Location) {
3955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    return Location->getKind() == EpsilonKind;
3965903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  }
3975903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks};
3985903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
399ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// ProgramPoints can be "tagged" as representing points specific to a given
400ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// analysis entity.  Tags are abstract annotations, with an associated
401ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// description and potentially other information.
402ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag {
403ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
404ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {}
405ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  virtual ~ProgramPointTag();
406ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  virtual StringRef getTagDescription() const = 0;
407ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
408ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprotected:
4091ab69c513239596946286373e081b89fa3358612Ted Kremenek  /// Used to implement 'classof' in subclasses.
410ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const void *getTagKind() { return TagKind; }
411ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
412ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprivate:
413ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const void *TagKind;
414ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
415ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
416ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass SimpleProgramPointTag : public ProgramPointTag {
417ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  std::string desc;
418ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
419ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  SimpleProgramPointTag(StringRef description);
420ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  StringRef getTagDescription() const;
421ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
423eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
4244c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
4254c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
4294c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
430d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
431d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
43325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
434d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
435d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
436d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
437d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
43825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
43925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
440d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
441d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4429c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint &Loc) {
443d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
444d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
445d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4469c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic bool isEqual(const clang::ProgramPoint &L,
4479c378f705405d37f49795d5e915989de774fe11fTed Kremenek                    const clang::ProgramPoint &R) {
448d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
449d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
450d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4514c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
45206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
45306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <>
45406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; };
45506159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
4564c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
4574c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
458eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
459