ProgramPoint.h revision b4b817d704287836b52b34369009e682f208aa2b
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"
199f8eb2032030482b1d3de86e9bee725d93564302Chandler Carruth#include "llvm/System/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 {
2725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
2825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xuclass LocationContext;
291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint {
31eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
32cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  enum Kind { BlockEdgeKind,
33cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockEntranceKind,
34cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              BlockExitKind,
35cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PreStmtKind,
36cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtKind,
37b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreLoadKind,
38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLoadKind,
39b4b817d704287836b52b34369009e682f208aa2bTed Kremenek              PreStoreKind,
40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStoreKind,
41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostPurgeDeadSymbolsKind,
42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostStmtCustomKind,
43cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek              PostLValueKind,
44f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek              MinPostStmtKind = PostStmtKind,
457090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek              MaxPostStmtKind = PostLValueKind };
464c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate:
48d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  std::pair<const void *, const void *> Data;
49d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind K;
5025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
5125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // The LocationContext could be NULL to allow ProgramPoint to be used in
5225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  // context insensitive analysis.
5325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  const LocationContext *L;
54e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *Tag;
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ProgramPoint(const void* P, Kind k, const LocationContext *l,
5825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu               const void *tag = 0)
5925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : Data(P, NULL), K(k), L(l), Tag(tag) {}
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
6225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu               const void *tag = 0)
6325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : Data(P1, P2), K(k), L(l), Tag(tag) {}
64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek
65d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected:
66d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData1() const { return Data.first; }
67d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  const void* getData2() const { return Data.second; }
68e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  const void *getTag() const { return Tag; }
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
71d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek  Kind getKind() const { return K; }
72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
73fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu  const LocationContext *getLocationContext() const { return L; }
7425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
75e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek  // For use with DenseMap.  This hash is probably slow.
76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  unsigned getHashValue() const {
77e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    llvm::FoldingSetNodeID ID;
78d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    Profile(ID);
79e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    return ID.ComputeHash();
80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint*) { return true; }
83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
84d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator==(const ProgramPoint & RHS) const {
8525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
86d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
87d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  bool operator!=(const ProgramPoint& RHS) const {
8925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
925226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
93d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddInteger((unsigned) K);
94d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.first);
95d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    ID.AddPointer(Data.second);
9625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    ID.AddPointer(L);
97e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek    ID.AddPointer(Tag);
982680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek  }
99eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint {
102eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  BlockEntrance(const CFGBlock* B, const LocationContext *L,
10425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu                const void *tag = 0)
10525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(B, BlockEntranceKind, L, tag) {}
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
108d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
109bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getFirstStmt() const {
112d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
11383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->front();
11483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  }
115eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
11783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockEntranceKind;
118bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
119eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
12183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint {
122eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  BlockExit(const CFGBlock* B, const LocationContext *L)
12425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(B, BlockExitKind, L) {}
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  CFGBlock* getBlock() const {
127d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
128bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getLastStmt() const {
131d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    const CFGBlock* B = getBlock();
13283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return B->empty() ? NULL : B->back();
133bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  Stmt* getTerminator() const {
13683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return getBlock()->getTerminator();
137bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
14083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek    return Location->getKind() == BlockExitKind;
141bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
142bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek};
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1445f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint {
1455f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic:
1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
14725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu            const void *tag)
14825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(S, p2, k, L, tag) {}
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1505f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1525f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  template <typename T>
1535f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1555f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1565f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    unsigned k = Location->getKind();
1575f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    return k >= PreStmtKind && k <= MaxPostStmtKind;
1585f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  }
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek
1625f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint {
163cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic:
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PreStmt(const Stmt *S, const LocationContext *L, const void *tag,
16525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu          const Stmt *SubStmt = 0)
16625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
167cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
169cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
170cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  static bool classof(const ProgramPoint* Location) {
171cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek    return Location->getKind() == PreStmtKind;
172cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek  }
173cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek};
174cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek
1755f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint {
1761b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected:
17725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0)
17825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, NULL, k, L, tag) {}
179e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek
18025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
18125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu           const void *tag =0)
18225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, data, k, L, tag) {}
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic:
18525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
18625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
18783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
18883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
1891b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    unsigned k = Location->getKind();
190f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
1911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1921b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek};
1938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
194f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt {
1952680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic:
19659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  PostStmtCustom(const Stmt* S,
19725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu                 const std::pair<const void*, const void*>* TaggedData,\
19825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu                 const LocationContext *L)
19925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, TaggedData, PostStmtCustomKind, L) {}
20059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek
20159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const std::pair<const void*, const void*>& getTaggedPair() const {
202d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return
203d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek      *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
20459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  }
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTag() const { return getTaggedPair().first; }
2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20859753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek  const void* getTaggedData() const { return getTaggedPair().second; }
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
210f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  static bool classof(const ProgramPoint* Location) {
211f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek    return Location->getKind() == PostStmtCustomKind;
212f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek  }
213f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek};
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
215b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
216b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint {
217b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected:
218b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  LocationCheck(const Stmt *S, const LocationContext *L,
219b4b817d704287836b52b34369009e682f208aa2bTed Kremenek                ProgramPoint::Kind K, const void *tag)
220b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : StmtPoint(S, NULL, K, L, tag) {}
221b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
222b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
223b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    unsigned k = location->getKind();
224b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return k == PreLoadKind || PreStoreKind;
2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2268c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
227b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
228b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck {
2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
230b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
231b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    : LocationCheck(S, L, PreLoadKind, tag) {}
232b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
233b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
234b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreLoadKind;
2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2368c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
238b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck {
2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic:
240b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
241b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  : LocationCheck(S, L, PreStoreKind, tag) {}
242b4b817d704287836b52b34369009e682f208aa2bTed Kremenek
243b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  static bool classof(const ProgramPoint *location) {
244b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return location->getKind() == PreStoreKind;
2458c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek  }
2468c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek};
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt {
2491b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic:
25025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0)
25125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLoadKind, L, tag) {}
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2531b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  static bool classof(const ProgramPoint* Location) {
2541b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return Location->getKind() == PostLoadKind;
255bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek  }
256eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek};
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt {
25982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic:
26025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0)
26125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostStoreKind, L, tag) {}
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  static bool classof(const ProgramPoint* Location) {
26482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek    return Location->getKind() == PostStoreKind;
26582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek  }
26682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek};
2677090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek
2687090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt {
2697090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic:
27025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0)
27125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostLValueKind, L, tag) {}
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2737090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  static bool classof(const ProgramPoint* Location) {
2747090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek    return Location->getKind() == PostLValueKind;
2757090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek  }
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
278331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt {
279331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic:
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L,
28125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu                       const void *tag = 0)
28225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
284331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  static bool classof(const ProgramPoint* Location) {
285331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek    return Location->getKind() == PostPurgeDeadSymbolsKind;
286331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  }
287331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek};
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
28983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint {
290b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic:
29125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L)
29225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu    : ProgramPoint(B1, B2, BlockEdgeKind, L) {}
2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
294d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getSrc() const {
295d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  CFGBlock* getDst() const {
299d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  }
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
30283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek  static bool classof(const ProgramPoint* Location) {
303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek    return Location->getKind() == BlockEdgeKind;
304b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek  }
305b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek};
30683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
308eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang
3094c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3104c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> {
3144c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
315d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() {
316d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
31825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
319d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() {
322d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  uintptr_t x =
32325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
32425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
325d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
326d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
327d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) {
328d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return Loc.getHashValue();
329d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
330d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
331d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L,
332d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek                    const clang::ProgramPoint& R) {
333d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return L == R;
334d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
335d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek
336d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() {
337d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  return true;
338d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek}
3394c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek};
3404c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm
3414c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek
342eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif
343