ProgramPoint.h revision 58465900ca10e53b8700a64e9265870de34e1aca
183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// 2eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 3eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// The LLVM Compiler Infrastructure 4eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 8eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 9eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 1083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// This file defines the interface ProgramPoint, which identifies a 1183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// distinct location in a function. 12eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 13eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 14eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT 1683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT 17eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 18c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu#include "clang/Analysis/AnalysisContext.h" 19e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h" 2003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h" 214c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h" 225226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 236bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h" 244c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 2559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility> 26eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 27eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 2825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 2925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xuclass LocationContext; 30c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xuclass AnalysisContext; 31102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass FunctionDecl; 321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 34eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 35cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek enum Kind { BlockEdgeKind, 36cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockEntranceKind, 37cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockExitKind, 38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PreStmtKind, 39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtKind, 40b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreLoadKind, 41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLoadKind, 42b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreStoreKind, 43cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStoreKind, 44cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostPurgeDeadSymbolsKind, 45cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtCustomKind, 46cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLValueKind, 479dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu PostInitializerKind, 48102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallEnterKind, 49102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallExitKind, 50f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 514462ee2f0000e6cb966e3fff4516c84292f0cce8Ted Kremenek MaxPostStmtKind = CallExitKind }; 524c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 53d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 54d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek std::pair<const void *, const void *> Data; 55d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind K; 5625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 5725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // The LocationContext could be NULL to allow ProgramPoint to be used in 5825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // context insensitive analysis. 5925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const LocationContext *L; 60e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *Tag; 611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 62d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ProgramPoint(const void* P, Kind k, const LocationContext *l, 6425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag = 0) 65a5fdd9ce694b1c2dbfd225cb6f55ef743d1ab562Douglas Gregor : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {} 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l, 6825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag = 0) 6925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : Data(P1, P2), K(k), L(l), Tag(tag) {} 70f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 71d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 72d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData1() const { return Data.first; } 73d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData2() const { return Data.second; } 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 76d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind getKind() const { return K; } 77d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 7858465900ca10e53b8700a64e9265870de34e1acaTed Kremenek const void *getTag() const { return Tag; } 7958465900ca10e53b8700a64e9265870de34e1acaTed Kremenek 80fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu const LocationContext *getLocationContext() const { return L; } 8125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 82e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 84e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 85d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 86e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 87d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 91d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 9225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; 93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 95d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 9625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; 97d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 995226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 100d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddInteger((unsigned) K); 101d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.first); 102d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.second); 10325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu ID.AddPointer(L); 104e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 1052680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 106eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 109eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BlockEntrance(const CFGBlock* B, const LocationContext *L, 11125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag = 0) 11225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B, BlockEntranceKind, L, tag) {} 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGBlock* getBlock() const { 11503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 116bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGElement getFirstElement() const { 119d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const CFGBlock* B = getBlock(); 120852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return B->empty() ? CFGElement() : B->front(); 121852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 122852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 123b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek /// Create a new BlockEntrance object that is the same as the original 124b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek /// except for using the specified tag value. 125b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek BlockEntrance withTag(const void *tag) { 126b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek return BlockEntrance(getBlock(), getLocationContext(), tag); 127b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek } 128b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek 12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 132eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 135eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BlockExit(const CFGBlock* B, const LocationContext *L) 13725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B, BlockExitKind, L) {} 1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGBlock* getBlock() const { 14003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 141bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Stmt* getTerminator() const { 14483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 145bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 14883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 149bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 150bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1525f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint { 1535f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic: 1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, 15525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag) 15625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(S, p2, k, L, tag) {} 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1585f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const Stmt *getStmt() const { return (const Stmt*) getData1(); } 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1605f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek template <typename T> 1615f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1635f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek static bool classof(const ProgramPoint* Location) { 1645f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek unsigned k = Location->getKind(); 1655f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek return k >= PreStmtKind && k <= MaxPostStmtKind; 1665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek } 1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 169eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1705f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint { 171cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic: 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump PreStmt(const Stmt *S, const LocationContext *L, const void *tag, 17325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const Stmt *SubStmt = 0) 17425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} 175cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 177cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 178cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek static bool classof(const ProgramPoint* Location) { 179cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek return Location->getKind() == PreStmtKind; 180cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek } 181cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek}; 182cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1835f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint { 1841b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 18525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L, 18625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag =0) 18725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, data, k, L, tag) {} 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 189eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1904bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek explicit PostStmt(const Stmt* S, Kind k, 1914bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek const LocationContext *L, const void *tag = 0) 1924bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek : StmtPoint(S, NULL, k, L, tag) {} 1934bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek 19425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0) 19525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, NULL, PostStmtKind, L, tag) {} 19683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 19783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 199f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 2001b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 2011b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 203f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 2042680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic: 20559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek PostStmtCustom(const Stmt* S, 20625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const std::pair<const void*, const void*>* TaggedData,\ 20725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const LocationContext *L) 20825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, TaggedData, PostStmtCustomKind, L) {} 20959753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 21059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>& getTaggedPair() const { 211d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return 212d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2()); 21359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek } 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTag() const { return getTaggedPair().first; } 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTaggedData() const { return getTaggedPair().second; } 2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 219f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 220f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 221f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 222f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 224b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 225b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint { 226b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected: 227b4b817d704287836b52b34369009e682f208aa2bTed Kremenek LocationCheck(const Stmt *S, const LocationContext *L, 228b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ProgramPoint::Kind K, const void *tag) 229b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : StmtPoint(S, NULL, K, L, tag) {} 230b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 231b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 232b4b817d704287836b52b34369009e682f208aa2bTed Kremenek unsigned k = location->getKind(); 233d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek return k == PreLoadKind || k == PreStoreKind; 2348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 236b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 237b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck { 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 239b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0) 240b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreLoadKind, tag) {} 241b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 242b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 243b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreLoadKind; 2448c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2458c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 247b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck { 2488c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 249b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0) 250b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreStoreKind, tag) {} 251b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 252b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 253b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreStoreKind; 2548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2558c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2571b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2581b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 25925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0) 26025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLoadKind, L, tag) {} 2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2621b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2631b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 264bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 265eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 26882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 26925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0) 27025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostStoreKind, L, tag) {} 2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 27382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 27482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 27582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2767090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2777090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2787090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 27925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0) 28025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLValueKind, L, tag) {} 2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2827090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2837090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2847090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 287331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 288331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L, 29025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const void *tag = 0) 29125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} 2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 293331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 294331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 295331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 296331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 299b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 30025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L) 30125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B1, B2, BlockEdgeKind, L) {} 3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGBlock* getSrc() const { 30403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData1()); 305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGBlock* getDst() const { 30803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData2()); 309d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 312d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 313b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 314b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 31583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 3169dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint { 3179dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic: 318cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt PostInitializer(const CXXCtorInitializer *I, 3199dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu const LocationContext *L) 3209dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu : ProgramPoint(I, PostInitializerKind, L) {} 3219dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 3229dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu static bool classof(const ProgramPoint *Location) { 3239dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu return Location->getKind() == PostInitializerKind; 3249dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu } 3259dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu}; 3269dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 327102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallEnter : public StmtPoint { 328102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 32919b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 33019b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const LocationContext *callerCtx) 33119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {} 332102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 333102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor const Stmt *getCallExpr() const { 334102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return static_cast<const Stmt *>(getData1()); 335102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 336102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 33719b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const StackFrameContext *getCalleeContext() const { 33819b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu return static_cast<const StackFrameContext *>(getData2()); 339102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 340102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 341102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 342102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallEnterKind; 343102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 344102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 345102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 346102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallExit : public StmtPoint { 347102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 348102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor // CallExit uses the callee's location context. 349102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallExit(const Stmt *S, const LocationContext *L) 350102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor : StmtPoint(S, 0, CallExitKind, L, 0) {} 351102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 352102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 353102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallExitKind; 354102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 355102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 356102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 358eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 3594c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3604c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 36383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 3644c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 365d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 366d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 36825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 369d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 370d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 371d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 372d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 37325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 37425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 375d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 376d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 377d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 378d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 379d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 380d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 381d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 382d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 383d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 384d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 385d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 3864c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 38706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 38806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 38906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; }; 39006159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 3914c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3924c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 393eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 394