ProgramPoint.h revision 8c354758c2d39db87c77c723d81e34b4d967f762
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 1805e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek#include "clang/AST/CFG.h" 19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/DataTypes.h" 204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h" 215226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 224c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 23eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 24eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 2505e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek 2683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 27eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 28d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek enum Kind { BlockEdgeKind=0, BlockEntranceKind, BlockExitKind, 2982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek // Keep the following four together and in this order. 308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostStmtKind, 318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostLocationChecksSucceedKind, 328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostOutOfBoundsCheckFailedKind, 338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostNullCheckFailedKind, 348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostUndefLocationCheckFailedKind, 358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostLoadKind, PostStoreKind, 3682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek PostPurgeDeadSymbolsKind }; 374c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 38d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 39d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<uintptr_t,uintptr_t> Data; 40d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 41d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 42d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P, Kind k) 43d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : Data(reinterpret_cast<uintptr_t>(P), (uintptr_t) k) {} 44d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 45d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P1, const void* P2) 46d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | 0x1, 47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(P2)) {} 48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 50d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1NoMask() const { 51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek assert (getKind() != BlockEdgeKind); 52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.first); 536e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis } 546e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 55d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1() const { 56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek assert (getKind() == BlockEdgeKind); 57d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.first & ~0x1); 58d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 596e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 60d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData2() const { 61d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek assert (getKind() == BlockEdgeKind); 62d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.second); 634c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek } 644c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 6583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t getKind() const { 68d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data.first & 0x1 ? (uintptr_t) BlockEdgeKind : Data.second; 69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 70d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 71d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek // For use with DenseMap. 72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first), 74d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<void*>(Data.second)); 75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P); 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 77eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 7883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data == RHS.Data; 82d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 84d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 85d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data != RHS.Data; 86d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 87d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator<(const ProgramPoint& RHS) const { 89d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data < RHS.Data; 90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 915226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek 925226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.first)); 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.second)); 955226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek } 96eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 9883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 99eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 10083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} 10183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 10283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 104bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 105eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 10883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 10983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 110eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 11283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 113bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 114eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 11583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 117eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 11883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 119bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 121d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 122bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 12383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 127bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 128bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 13283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 135bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 136bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 137eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 13883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint { 1401b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 1411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {} 142eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} 1441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 145d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek Stmt* getStmt() const { return (Stmt*) getData1NoMask(); } 14683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 149331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return k >= PostStmtKind && k <= PostPurgeDeadSymbolsKind; 1501b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1511b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1528c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1538c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1558c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostLocationChecksSucceed(const Stmt* S) 1568c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostLocationChecksSucceedKind) {} 1578c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1588c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1598c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 1608c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1618c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1628c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1638c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 1648c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1658c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S) 1668c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind) {} 1678c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1688c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1698c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 1708c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1718c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1728c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1738c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 1748c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1758c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S) 1768c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind) {} 1778c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 1848c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostNullCheckFailed(const Stmt* S) 1868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostNullCheckFailedKind) {} 1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 1908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1921b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1931b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 1941b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 1951b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {} 1961b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1971b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 1981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 199bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 200eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 201b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 20282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 20382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostStore(const Stmt* S) : PostStmt(S, PostStoreKind) {} 20582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 20682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 20782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 20882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 20982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 21082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 211331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 212331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 213331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {} 214331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 215331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 216331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 217331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 218331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 219331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 22083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 221b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 222d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 223d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : ProgramPoint(B1, B2) {} 224d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 225d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 226d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData1()); 227d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 228d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 229d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 230d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData2()); 231d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 232b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 23383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 234d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 235b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 236b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 23783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 23883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 239eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 2404c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2414c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2424c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 2434c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 24483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 2454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 246d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 247d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 248d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 249d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 250d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 251d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 252d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 253d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 254d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 255d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 256d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 257d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 258d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 260d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 263d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 266d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 267d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 269d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 2704c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 2714c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 2724c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 273eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 274