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