ProgramPoint.h revision d6b9e37311013bdf24fd709f7e9962e3b141e6fb
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" 19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/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 { 2705e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek 2883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum Kind { BlockEdgeKind = 0x0, 31f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockEntranceKind = 0x1, 32f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockExitKind = 0x2, 3382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek // Keep the following four together and in this order. 34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtKind = 0x3, 35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLocationChecksSucceedKind = 0x4, 36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostOutOfBoundsCheckFailedKind = 0x5, 37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostNullCheckFailedKind = 0x6, 38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostUndefLocationCheckFailedKind = 0x7, 39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLoadKind = 0x8, 40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStoreKind = 0x9, 41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostPurgeDeadSymbolsKind = 0x10, 42f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtCustomKind = 0x11, 437090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek PostLValueKind = 0x12, 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; 50e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *Tag; 51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 53e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ProgramPoint(const void* P, Kind k, const void *tag = 0) 54d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : Data(P, NULL), K(k), Tag(tag) {} 55d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 56d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ProgramPoint(const void* P1, const void* P2, Kind k, const void *tag = 0) 57d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : Data(P1, P2), K(k), Tag(tag) {} 58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 59d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 60d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData1() const { return Data.first; } 61d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData2() const { return Data.second; } 62e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *getTag() const { return Tag; } 63f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 6483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 65d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind getKind() const { return K; } 66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 67e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 68d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 69e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 70d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 71e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 73eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 7483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 77d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return K == RHS.K && Data == RHS.Data && Tag == RHS.Tag; 78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 81d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return K != RHS.K || Data != RHS.Data || Tag != RHS.Tag; 82d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 845226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 85d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddInteger((unsigned) K); 86d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.first); 87d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.second); 88e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 892680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 90eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 9183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 9283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 93eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 94ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek BlockEntrance(const CFGBlock* B, const void *tag = 0) 95ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek : ProgramPoint(B, BlockEntranceKind, tag) {} 9683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 98d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); 99bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 100eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 102d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const CFGBlock* B = getBlock(); 10383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 105eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 108bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 109eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 11083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 112eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 11383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 114bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 11583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 116d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); 117bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 11883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 120d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const CFGBlock* B = getBlock(); 12183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 122bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 126bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 12783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 130bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 132eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint { 1341b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 135e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostStmt(const Stmt* S, Kind k,const void *tag = 0) 136e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : ProgramPoint(S, k, tag) {} 137e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek 138d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek PostStmt(const Stmt* S, const void* data, Kind k, const void *tag =0) 139d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : ProgramPoint(S, data, k, tag) {} 140f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 141eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1421670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostStmt(const Stmt* S, const void *tag = 0) 1431670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : ProgramPoint(S, PostStmtKind, tag) {} 1441670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek 145d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek 146f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Stmt* getStmt() const { return (Stmt*) getData1(); } 1476bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek 148d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek template <typename T> 1496bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 15083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1521b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 153f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 1541b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1551b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1568c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1578c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1588c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 159e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLocationChecksSucceed(const Stmt* S, const void *tag = 0) 160e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLocationChecksSucceedKind, tag) {} 1618c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1628c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1638c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 1648c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1658c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1668c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 167f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 1682680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic: 16959753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek PostStmtCustom(const Stmt* S, 17059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>* TaggedData) 171d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : PostStmt(S, TaggedData, PostStmtCustomKind) {} 17259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 17359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>& getTaggedPair() const { 174d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return 175d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2()); 17659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek } 17759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 17859753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTag() const { return getTaggedPair().first; } 179f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 18059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTaggedData() const { return getTaggedPair().second; } 181f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 182f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 183f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 184f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 186f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1891670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0) 1901670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {} 1918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 1948c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1958c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1968c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1991670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0) 2001670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {} 2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2038c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2058c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2068c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2078c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 2088c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2091670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostNullCheckFailed(const Stmt* S, const void *tag = 0) 2101670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostNullCheckFailedKind, tag) {} 2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 2148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2161b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2171b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2181b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 219e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLoad(const Stmt* S, const void *tag = 0) 220e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLoadKind, tag) {} 2211b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2221b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2231b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 224bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 225eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 226b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 22782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 22882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 229e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostStore(const Stmt* S, const void *tag = 0) 230e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostStoreKind, tag) {} 23182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 23282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 23382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 23482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 23582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2367090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2377090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2387090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 2397090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek PostLValue(const Stmt* S, const void *tag = 0) 2407090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek : PostStmt(S, PostLValueKind, tag) {} 2417090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2427090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2437090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2447090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2457090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek}; 24682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 247331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 248331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2491670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0) 2501670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {} 251331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 252331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 253331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 254331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 255331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 256331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 25783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 258b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 260d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : ProgramPoint(B1, B2, BlockEdgeKind) {} 261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 263d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1())); 264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 266d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 267d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2())); 268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 269b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 27083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 271d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 272b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 273b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 27483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 27583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 276eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 2774c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2784c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 2804c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 28183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 2824c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 284d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 287d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 291d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 293d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 294d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 304d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 306d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 3074c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 3084c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3094c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 310eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 311