ProgramPoint.h revision 2f041d0b12aa87f3345e5fb2e38fefba30c5bff3
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 31c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xuclass AnalysisContext; 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, 544462ee2f0000e6cb966e3fff4516c84292f0cce8Ted Kremenek MaxPostStmtKind = CallExitKind }; 554c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 57d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek std::pair<const void *, const void *> Data; 58d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind K; 5925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 6025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // The LocationContext could be NULL to allow ProgramPoint to be used in 6125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // context insensitive analysis. 6225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const LocationContext *L; 63ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *Tag; 641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 65ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPoint(); 66ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 689c378f705405d37f49795d5e915989de774fe11fTed Kremenek ProgramPoint(const void *P, Kind k, const LocationContext *l, 69ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 70a5fdd9ce694b1c2dbfd225cb6f55ef743d1ab562Douglas Gregor : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {} 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 729c378f705405d37f49795d5e915989de774fe11fTed Kremenek ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l, 73ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 7425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : Data(P1, P2), K(k), L(l), Tag(tag) {} 75f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 779c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *getData1() const { return Data.first; } 789c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *getData2() const { return Data.second; } 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 81d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind getKind() const { return K; } 82d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 83ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *getTag() const { return Tag; } 8458465900ca10e53b8700a64e9265870de34e1acaTed Kremenek 85fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu const LocationContext *getLocationContext() const { return L; } 8625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 87e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 89e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 90d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 91e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 92d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 95d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 96d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 9725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; 98d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 99d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 1009c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const ProgramPoint &RHS) const { 10125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; 102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1045226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 105d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddInteger((unsigned) K); 106d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.first); 107d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.second); 10825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu ID.AddPointer(L); 109e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 1102680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 111eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 114eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1159c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEntrance(const CFGBlock *B, const LocationContext *L, 116ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 1172f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek : ProgramPoint(B, BlockEntranceKind, L, tag) { 1182f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek assert(B && "BlockEntrance requires non-null block"); 1192f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1219c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 12203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGElement getFirstElement() const { 1269c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *B = getBlock(); 127852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return B->empty() ? CFGElement() : B->front(); 128852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 129852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 130b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek /// Create a new BlockEntrance object that is the same as the original 131b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek /// except for using the specified tag value. 132ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek BlockEntrance withTag(const ProgramPointTag *tag) { 133b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek return BlockEntrance(getBlock(), getLocationContext(), tag); 134b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek } 135b6a2b08a6b3fbce1a6a4b69d4185165de970696cTed Kremenek 13683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 138bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 139eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 14083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 142eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1439c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockExit(const CFGBlock *B, const LocationContext *L) 14425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B, BlockExitKind, L) {} 1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1469c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 14703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 148bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 14983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 1509c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getTerminator() const { 15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 152bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 15583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 156bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 157bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1595f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint { 1605f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic: 1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, 162ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) 16325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(S, p2, k, L, tag) {} 1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1655f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const Stmt *getStmt() const { return (const Stmt*) getData1(); } 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1675f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek template <typename T> 1685f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1705f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek static bool classof(const ProgramPoint* Location) { 1715f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek unsigned k = Location->getKind(); 1725f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek return k >= PreStmtKind && k <= MaxPostStmtKind; 1735f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek } 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 176eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1775f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint { 178cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic: 179ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, 18025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const Stmt *SubStmt = 0) 18125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} 182cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 184cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 185cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek static bool classof(const ProgramPoint* Location) { 186cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek return Location->getKind() == PreStmtKind; 187cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek } 188cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek}; 189cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1905f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint { 1911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 1929c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, 193ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag =0) 19425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, data, k, L, tag) {} 1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 196eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1979c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, Kind k, 198ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const LocationContext *L, const ProgramPointTag *tag = 0) 1994bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek : StmtPoint(S, NULL, k, L, tag) {} 2004bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek 2019c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, const LocationContext *L, 202ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 20325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, NULL, PostStmtKind, L, tag) {} 20483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 20583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 2061b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 207f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 2081b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 2091b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 2108c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2118083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek// PostCondition represents the post program point of a branch condition. 2128083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekclass PostCondition : public PostStmt { 2138083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekpublic: 2149c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostCondition(const Stmt *S, const LocationContext *L, 215ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 2168083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek : PostStmt(S, PostConditionKind, L, tag) {} 2178083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 2188083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek static bool classof(const ProgramPoint* Location) { 2198083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek return Location->getKind() == PostConditionKind; 2208083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek } 2218083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek}; 2228083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 223b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint { 224b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected: 225b4b817d704287836b52b34369009e682f208aa2bTed Kremenek LocationCheck(const Stmt *S, const LocationContext *L, 226ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPoint::Kind K, const ProgramPointTag *tag) 227b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : StmtPoint(S, NULL, K, L, tag) {} 228b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 229b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 230b4b817d704287836b52b34369009e682f208aa2bTed Kremenek unsigned k = location->getKind(); 231d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek return k == PreLoadKind || k == PreStoreKind; 2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 234b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 235b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck { 2368c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 237ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreLoad(const Stmt *S, const LocationContext *L, 238ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 239b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreLoadKind, tag) {} 240b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 241b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 242b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreLoadKind; 2438c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2448c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 246b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck { 2478c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 248ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStore(const Stmt *S, const LocationContext *L, 249ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 250b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreStoreKind, tag) {} 251b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 252b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 253b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreStoreKind; 2548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2558c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2571b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2581b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 2599c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLoad(const Stmt *S, const LocationContext *L, 260ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 26125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLoadKind, L, tag) {} 2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2631b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 265bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 266eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 26982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 2709c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostStore(const Stmt *S, const LocationContext *L, 271ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 27225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostStoreKind, L, tag) {} 2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 27582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 27682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 27782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2787090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2797090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2807090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 2819c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLValue(const Stmt *S, const LocationContext *L, 282ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 28325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLValueKind, L, tag) {} 2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2857090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2867090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2877090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 290331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 291331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2929c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostPurgeDeadSymbols(const Stmt *S, const LocationContext *L, 293ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 29425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} 2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 296331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 297331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 298331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 299331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 302b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 3039c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L) 30425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B1, B2, BlockEdgeKind, L) {} 3051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3069c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getSrc() const { 30703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData1()); 308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3109c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getDst() const { 31103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData2()); 312d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 315d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 316b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 317b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 31883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 3199dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint { 3209dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic: 321cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt PostInitializer(const CXXCtorInitializer *I, 3229dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu const LocationContext *L) 3239dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu : ProgramPoint(I, PostInitializerKind, L) {} 3249dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 3259dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu static bool classof(const ProgramPoint *Location) { 3269dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu return Location->getKind() == PostInitializerKind; 3279dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu } 3289dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu}; 3299dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 330102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallEnter : public StmtPoint { 331102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 33219b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 33319b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const LocationContext *callerCtx) 33419b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {} 335102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 336102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor const Stmt *getCallExpr() const { 337102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return static_cast<const Stmt *>(getData1()); 338102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 339102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 34019b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const StackFrameContext *getCalleeContext() const { 34119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu return static_cast<const StackFrameContext *>(getData2()); 342102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 343102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 344102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 345102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallEnterKind; 346102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 347102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 348102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 349102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallExit : public StmtPoint { 350102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 351102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor // CallExit uses the callee's location context. 352102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallExit(const Stmt *S, const LocationContext *L) 353102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor : StmtPoint(S, 0, CallExitKind, L, 0) {} 354102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 355102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 356102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallExitKind; 357102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 358102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 359102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 360ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// ProgramPoints can be "tagged" as representing points specific to a given 361ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// analysis entity. Tags are abstract annotations, with an associated 362ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// description and potentially other information. 363ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag { 364ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 365ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {} 366ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual ~ProgramPointTag(); 367ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual StringRef getTagDescription() const = 0; 368ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 369ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprotected: 3701ab69c513239596946286373e081b89fa3358612Ted Kremenek /// Used to implement 'classof' in subclasses. 371ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *getTagKind() { return TagKind; } 372ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 373ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprivate: 374ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *TagKind; 375ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 376ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 377ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass SimpleProgramPointTag : public ProgramPointTag { 378ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek std::string desc; 379ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 380ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek SimpleProgramPointTag(StringRef description); 381ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek StringRef getTagDescription() const; 382ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 384eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 3854c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3864c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 3904c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 391d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 392d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 39425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 395d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 396d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 397d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 398d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 39925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 40025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 401d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 402d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4039c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint &Loc) { 404d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 405d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 406d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4079c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic bool isEqual(const clang::ProgramPoint &L, 4089c378f705405d37f49795d5e915989de774fe11fTed Kremenek const clang::ProgramPoint &R) { 409d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 410d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 411d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4124c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 41306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 41406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 41506159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; }; 41606159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 4174c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 4184c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 419eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 420