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