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