ProgramPoint.h revision 6403683411dac55afbe3435ceb19033e27cd9f96
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"
22c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek#include "llvm/ADT/PointerIntPair.h"
235226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h"
246bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h"
25ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "llvm/ADT/StringRef.h"
264c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert>
2759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility>
28ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include <string>
29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
30eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang {
3125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
321d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext;
33102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass FunctionDecl;
34ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass LocationContext;
35ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag;
36ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
3783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
38eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  enum Kind { BlockEdgeKind,
40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockEntranceKind,
41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockExitKind,
42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PreStmtKind,
43cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtKind,
44b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreLoadKind,
45cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLoadKind,
46b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreStoreKind,
47cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStoreKind,
48cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostPurgeDeadSymbolsKind,
498083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek              PostConditionKind,
50cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLValueKind,
519dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu              PostInitializerKind,
52102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor              CallEnterKind,
53102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor              CallExitKind,
54f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks              MaxPostStmtKind = CallExitKind,
565903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks              EpsilonKind};
574c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
58d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
59c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  llvm::PointerIntPair<const void *, 2, unsigned> Data1;
60c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  llvm::PointerIntPair<const void *, 2, unsigned> Data2;
6125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
6225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // The LocationContext could be NULL to allow ProgramPoint to be used in
6325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // context insensitive analysis.
64c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
65c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek
66ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const ProgramPointTag *Tag;
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  ProgramPoint();
69ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
70d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
71f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  ProgramPoint(const void *P,
72f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek               Kind k,
73f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek               const LocationContext *l,
74ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek               const ProgramPointTag *tag = 0)
75c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    : Data1(P, ((unsigned) k) & 0x3),
76c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek      Data2(0, (((unsigned) k) >> 2) & 0x3),
77c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek      L(l, (((unsigned) k) >> 4) & 0x3),
78f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek      Tag(tag) {
79f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek        assert(getKind() == k);
80f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek        assert(getLocationContext() == l);
81f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek        assert(getData1() == P);
82f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek      }
83f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek
84f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  ProgramPoint(const void *P1,
85f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek               const void *P2,
86f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek               Kind k,
87f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek               const LocationContext *l,
88ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek               const ProgramPointTag *tag = 0)
89c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    : Data1(P1, ((unsigned) k) & 0x3),
90c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek      Data2(P2, (((unsigned) k) >> 2) & 0x3),
91c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek      L(l, (((unsigned) k) >> 4) & 0x3),
92f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek      Tag(tag) {}
93f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
95c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  const void *getData1() const { return Data1.getPointer(); }
96c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  const void *getData2() const { return Data2.getPointer(); }
97c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek  void setData2(const void *d) { Data2.setPointer(d); }
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
100af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  /// Create a new ProgramPoint object that is the same as the original
101af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  /// except for using the specified tag value.
10263d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks  ProgramPoint withTag(const ProgramPointTag *tag) const {
103c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    return ProgramPoint(getData1(), getData2(), getKind(),
104f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek                        getLocationContext(), tag);
105af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks  }
106af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks
107f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  Kind getKind() const {
108c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    unsigned x = L.getInt();
109c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    x <<= 2;
110c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    x |= Data2.getInt();
111c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    x <<= 2;
112c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    x |= Data1.getInt();
113c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    return (Kind) x;
114f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  }
115d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
116ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const ProgramPointTag *getTag() const { return Tag; }
11758465900ca10e53b8700a64e9265870de34e1acaTed Kremenek
118f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  const LocationContext *getLocationContext() const {
119c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    return L.getPointer();
120f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek  }
12125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
122e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
123d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
124e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
125d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    Profile(ID);
126e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
127d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
130d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
131d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
1326403683411dac55afbe3435ceb19033e27cd9f96Ted Kremenek    return Data1 == RHS.Data1 &&
133c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           Data2 == RHS.Data2 &&
134c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           L == RHS.L &&
135c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           Tag == RHS.Tag;
136d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
137d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
1389c378f705405d37f49795d5e915989de774fe11fTed Kremenek  bool operator!=(const ProgramPoint &RHS) const {
139c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    return Data1 != RHS.Data1 ||
140c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           Data2 != RHS.Data2 ||
141c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           L != RHS.L ||
142c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek           Tag != RHS.Tag;
143d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1455226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
146f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek    ID.AddInteger((unsigned) getKind());
147f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek    ID.AddPointer(getData1());
148c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek    ID.AddPointer(getData2());
149f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek    ID.AddPointer(getLocationContext());
150e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
1512680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
15263d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks
15363d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks  static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
15463d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks                                      const LocationContext *LC,
15563d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks                                      const ProgramPointTag *tag);
156eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
159eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1609c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockEntrance(const CFGBlock *B, const LocationContext *L,
161ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                const ProgramPointTag *tag = 0)
1622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    : ProgramPoint(B, BlockEntranceKind, L, tag) {
1632f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    assert(B && "BlockEntrance requires non-null block");
1642f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1669c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getBlock() const {
16703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return reinterpret_cast<const CFGBlock*>(getData1());
168bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGElement getFirstElement() const {
1719c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const CFGBlock *B = getBlock();
172852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return B->empty() ? CFGElement() : B->front();
173852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  }
174852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
17583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
17683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
177bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
178eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
17983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
18083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
181eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1829c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockExit(const CFGBlock *B, const LocationContext *L)
18325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(B, BlockExitKind, L) {}
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1859c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getBlock() const {
18603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return reinterpret_cast<const CFGBlock*>(getData1());
187bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
18883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
1899c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Stmt *getTerminator() const {
19083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
191bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
19483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
195bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
196bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1985f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint {
1995f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic:
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
201ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek            const ProgramPointTag *tag)
20225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(S, p2, k, L, tag) {}
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2045f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2065f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  template <typename T>
2075f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2095f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2105f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    unsigned k = Location->getKind();
2115f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    return k >= PreStmtKind && k <= MaxPostStmtKind;
2125f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  }
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
215eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
2165f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint {
217cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic:
218ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
21925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu          const Stmt *SubStmt = 0)
22025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
221cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
223cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
224cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  static bool classof(const ProgramPoint* Location) {
225cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek    return Location->getKind() == PreStmtKind;
226cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  }
227cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek};
228cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
2295f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint {
2301b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
2319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
2323d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks           const ProgramPointTag *tag = 0)
23325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, data, k, L, tag) {}
2341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
235eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
2369c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit PostStmt(const Stmt *S, Kind k,
237ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                    const LocationContext *L, const ProgramPointTag *tag = 0)
2384bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek    : StmtPoint(S, NULL, k, L, tag) {}
2394bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek
2409c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit PostStmt(const Stmt *S, const LocationContext *L,
241ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                    const ProgramPointTag *tag = 0)
24225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
24383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
24483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2451b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
246f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
2471b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
2481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
2498c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
2508083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek// PostCondition represents the post program point of a branch condition.
2518083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekclass PostCondition : public PostStmt {
2528083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekpublic:
2539c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostCondition(const Stmt *S, const LocationContext *L,
254ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                const ProgramPointTag *tag = 0)
2558083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek    : PostStmt(S, PostConditionKind, L, tag) {}
2568083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek
2578083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek  static bool classof(const ProgramPoint* Location) {
2588083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek    return Location->getKind() == PostConditionKind;
2598083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek  }
2608083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek};
2618083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek
262b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint {
263b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected:
264b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  LocationCheck(const Stmt *S, const LocationContext *L,
265ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                ProgramPoint::Kind K, const ProgramPointTag *tag)
266b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : StmtPoint(S, NULL, K, L, tag) {}
267b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
268b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
269b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    unsigned k = location->getKind();
270d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek    return k == PreLoadKind || k == PreStoreKind;
2718c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2728c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
273b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
274b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck {
2758c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
276ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreLoad(const Stmt *S, const LocationContext *L,
277ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek          const ProgramPointTag *tag = 0)
278b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : LocationCheck(S, L, PreLoadKind, tag) {}
279b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
280b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
281b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreLoadKind;
2828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
285b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck {
2868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
287ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  PreStore(const Stmt *S, const LocationContext *L,
288ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek           const ProgramPointTag *tag = 0)
289b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  : LocationCheck(S, L, PreStoreKind, tag) {}
290b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
291b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
292b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreStoreKind;
2938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2948c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2961b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2971b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
2989c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostLoad(const Stmt *S, const LocationContext *L,
299ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek           const ProgramPointTag *tag = 0)
30025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLoadKind, L, tag) {}
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3021b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
3031b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
304bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
305eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3073d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks/// \class Represents a program point after a store evaluation.
30882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
30982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
3103d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// Construct the post store point.
3113d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// \param Loc can be used to store the information about the location
3123d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// used in the form it was uttered in the code.
3133d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
314ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek            const ProgramPointTag *tag = 0)
3153d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    : PostStmt(S, PostStoreKind, L, tag) {
3163d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    assert(getData2() == 0);
3173d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    setData2(Loc);
3183d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  }
3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
32182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
32282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
3233d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks
3243d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// \brief Returns the information about the location used in the store,
3253d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// how it was uttered in the code.
3263d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  const void *getLocationValue() const {
3273d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    return getData2();
3283d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  }
3293d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks
33082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
3317090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
3327090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
3337090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
3349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostLValue(const Stmt *S, const LocationContext *L,
335ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek             const ProgramPointTag *tag = 0)
33625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLValueKind, L, tag) {}
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3387090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
3397090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
3407090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
343331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
344331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
3459c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PostPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
346ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                       const ProgramPointTag *tag = 0)
34725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
349331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
350331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
351331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
352331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
355b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
3569c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
357e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    : ProgramPoint(B1, B2, BlockEdgeKind, L) {
358e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    assert(B1 && "BlockEdge: source block must be non-null");
359e4c6675cccbaac991843def43072687bca50d989Ted Kremenek    assert(B2 && "BlockEdge: destination block must be non-null");
360e4c6675cccbaac991843def43072687bca50d989Ted Kremenek  }
3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3629c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getSrc() const {
36303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CFGBlock*>(getData1());
364d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3669c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const CFGBlock *getDst() const {
36703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CFGBlock*>(getData2());
368d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
3691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
371d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
372b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
373b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
37483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
3759dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint {
3769dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic:
377cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  PostInitializer(const CXXCtorInitializer *I,
3789dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu                  const LocationContext *L)
3799dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu    : ProgramPoint(I, PostInitializerKind, L) {}
3809dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
3819dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  static bool classof(const ProgramPoint *Location) {
3829dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu    return Location->getKind() == PostInitializerKind;
3839dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  }
3849dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu};
3859dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
386102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallEnter : public StmtPoint {
387102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
38819b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
38919b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu            const LocationContext *callerCtx)
39019b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu    : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
391102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
392102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const Stmt *getCallExpr() const {
393102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return static_cast<const Stmt *>(getData1());
394102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
395102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
39619b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  const StackFrameContext *getCalleeContext() const {
39719b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu    return static_cast<const StackFrameContext *>(getData2());
398102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
399102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
400102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  static bool classof(const ProgramPoint *Location) {
401102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return Location->getKind() == CallEnterKind;
402102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
403102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
404102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
405102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallExit : public StmtPoint {
406102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
407102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  // CallExit uses the callee's location context.
408102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  CallExit(const Stmt *S, const LocationContext *L)
409102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    : StmtPoint(S, 0, CallExitKind, L, 0) {}
410102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
411102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  static bool classof(const ProgramPoint *Location) {
412102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return Location->getKind() == CallExitKind;
413102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
414102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
415102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
4165903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// This is a meta program point, which should be skipped by all the diagnostic
4175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// reasoning etc.
4185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksclass EpsilonPoint : public ProgramPoint {
4195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zakspublic:
4205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  EpsilonPoint(const LocationContext *L, const void *Data1,
4215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               const void *Data2 = 0, const ProgramPointTag *tag = 0)
4225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
4235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
4245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const void *getData() const { return getData1(); }
4255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
4265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  static bool classof(const ProgramPoint* Location) {
4275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    return Location->getKind() == EpsilonKind;
4285903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  }
4295903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks};
4305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
431ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// ProgramPoints can be "tagged" as representing points specific to a given
432ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// analysis entity.  Tags are abstract annotations, with an associated
433ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// description and potentially other information.
434ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag {
435ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
436ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {}
437ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  virtual ~ProgramPointTag();
438ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  virtual StringRef getTagDescription() const = 0;
439ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
440ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprotected:
4411ab69c513239596946286373e081b89fa3358612Ted Kremenek  /// Used to implement 'classof' in subclasses.
442ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const void *getTagKind() { return TagKind; }
443ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
444ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprivate:
445ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  const void *TagKind;
446ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
447ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
448ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass SimpleProgramPointTag : public ProgramPointTag {
449ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  std::string desc;
450ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
451ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  SimpleProgramPointTag(StringRef description);
452ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  StringRef getTagDescription() const;
453ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
455eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
4564c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
4574c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
4614c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
462d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
463d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
46525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
466d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
467d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
468d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
469d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
47025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
47125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
472d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
473d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4749c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint &Loc) {
475d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
476d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
477d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4789c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic bool isEqual(const clang::ProgramPoint &L,
4799c378f705405d37f49795d5e915989de774fe11fTed Kremenek                    const clang::ProgramPoint &R) {
480d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
481d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
482d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
4834c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
48406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
48506159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <>
48606159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; };
48706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner
4884c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
4894c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
490eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
491