ProgramPoint.h revision 1d26f48dc2eea1c07431ca1519d7034a21b9bcff
183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// 2eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 3eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// The LLVM Compiler Infrastructure 4eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 8eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 9eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 1083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// This file defines the interface ProgramPoint, which identifies a 1183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// distinct location in a function. 12eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 13eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 14eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT 1683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT 17eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 18c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu#include "clang/Analysis/AnalysisContext.h" 19e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h" 2003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h" 214c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h" 225226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 236bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h" 24ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "llvm/ADT/StringRef.h" 254c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 2659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility> 27ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include <string> 28eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 3025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 311d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext; 32102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass FunctionDecl; 33ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass LocationContext; 34ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag; 35ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 3683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 37eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek enum Kind { BlockEdgeKind, 39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockEntranceKind, 40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockExitKind, 41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PreStmtKind, 42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtKind, 43b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreLoadKind, 44cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLoadKind, 45b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreStoreKind, 46cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStoreKind, 47cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostPurgeDeadSymbolsKind, 488083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek PostConditionKind, 49cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLValueKind, 509dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu PostInitializerKind, 51102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallEnterKind, 52102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallExitKind, 53f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 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: 81af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks /// Create a new ProgramPoint object that is the same as the original 82af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks /// except for using the specified tag value. 8363d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks ProgramPoint withTag(const ProgramPointTag *tag) const { 84af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks return ProgramPoint(Data.first, Data.second, K, L, tag); 85af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks } 86af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks 87d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind getKind() const { return K; } 88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 89ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *getTag() const { return Tag; } 9058465900ca10e53b8700a64e9265870de34e1acaTed Kremenek 91fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu const LocationContext *getLocationContext() const { return L; } 9225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 93e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 95e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 96d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 97e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 98d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 101d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 10325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; 104d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 1069c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const ProgramPoint &RHS) const { 10725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; 108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1105226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 111d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddInteger((unsigned) K); 112d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.first); 113d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.second); 11425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu ID.AddPointer(L); 115e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 1162680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 11763d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks 11863d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, 11963d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks const LocationContext *LC, 12063d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks const ProgramPointTag *tag); 12163d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks 122eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 125eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1269c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEntrance(const CFGBlock *B, const LocationContext *L, 127ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 1282f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek : ProgramPoint(B, BlockEntranceKind, L, tag) { 1292f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek assert(B && "BlockEntrance requires non-null block"); 1302f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1329c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 13303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 134bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGElement getFirstElement() const { 1379c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *B = getBlock(); 138852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return B->empty() ? CFGElement() : B->front(); 139852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 140852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 14183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 143bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 144eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 147eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1489c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockExit(const CFGBlock *B, const LocationContext *L) 14925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B, BlockExitKind, L) {} 1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1519c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 15203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 153bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 15483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 1559c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getTerminator() const { 15683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 157bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 16083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 161bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 162bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1645f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint { 1655f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic: 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, 167ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) 16825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(S, p2, k, L, tag) {} 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1705f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const Stmt *getStmt() const { return (const Stmt*) getData1(); } 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1725f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek template <typename T> 1735f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1755f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek static bool classof(const ProgramPoint* Location) { 1765f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek unsigned k = Location->getKind(); 1775f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek return k >= PreStmtKind && k <= MaxPostStmtKind; 1785f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek } 1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 181eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1825f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint { 183cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic: 184ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, 18525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const Stmt *SubStmt = 0) 18625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} 187cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 189cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 190cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek static bool classof(const ProgramPoint* Location) { 191cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek return Location->getKind() == PreStmtKind; 192cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek } 193cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek}; 194cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1955f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint { 1961b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 1979c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, 198ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag =0) 19925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, data, k, L, tag) {} 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 201eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 2029c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, Kind k, 203ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const LocationContext *L, const ProgramPointTag *tag = 0) 2044bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek : StmtPoint(S, NULL, k, L, tag) {} 2054bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek 2069c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, const LocationContext *L, 207ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 20825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, NULL, PostStmtKind, L, tag) {} 20983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 21083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 2111b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 212f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 2131b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 2141b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2168083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek// PostCondition represents the post program point of a branch condition. 2178083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekclass PostCondition : public PostStmt { 2188083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekpublic: 2199c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostCondition(const Stmt *S, const LocationContext *L, 220ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 2218083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek : PostStmt(S, PostConditionKind, L, tag) {} 2228083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 2238083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek static bool classof(const ProgramPoint* Location) { 2248083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek return Location->getKind() == PostConditionKind; 2258083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek } 2268083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek}; 2278083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 228b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint { 229b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected: 230b4b817d704287836b52b34369009e682f208aa2bTed Kremenek LocationCheck(const Stmt *S, const LocationContext *L, 231ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPoint::Kind K, const ProgramPointTag *tag) 232b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : StmtPoint(S, NULL, K, L, tag) {} 233b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 234b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 235b4b817d704287836b52b34369009e682f208aa2bTed Kremenek unsigned k = location->getKind(); 236d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek return k == PreLoadKind || k == PreStoreKind; 2378c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 239b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 240b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck { 2418c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 242ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreLoad(const Stmt *S, const LocationContext *L, 243ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 244b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreLoadKind, tag) {} 245b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 246b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 247b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreLoadKind; 2488c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2498c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 251b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck { 2528c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 253ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStore(const Stmt *S, const LocationContext *L, 254ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 255b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreStoreKind, tag) {} 256b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 257b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 258b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreStoreKind; 2598c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2608c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2621b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2631b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 2649c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLoad(const Stmt *S, const LocationContext *L, 265ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 26625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLoadKind, L, tag) {} 2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2681b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 270bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 271eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 27482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 2759c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostStore(const Stmt *S, const LocationContext *L, 276ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 27725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostStoreKind, L, tag) {} 2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 28082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 28182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 28282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2837090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2847090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2857090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 2869c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLValue(const Stmt *S, const LocationContext *L, 287ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 28825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLValueKind, L, tag) {} 2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2907090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2917090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2927090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 295331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 296331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2979c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostPurgeDeadSymbols(const Stmt *S, const LocationContext *L, 298ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 29925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} 3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 301331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 302331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 303331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 304331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 3051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 307b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 3089c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L) 309e4c6675cccbaac991843def43072687bca50d989Ted Kremenek : ProgramPoint(B1, B2, BlockEdgeKind, L) { 310e4c6675cccbaac991843def43072687bca50d989Ted Kremenek assert(B1 && "BlockEdge: source block must be non-null"); 311e4c6675cccbaac991843def43072687bca50d989Ted Kremenek assert(B2 && "BlockEdge: destination block must be non-null"); 312e4c6675cccbaac991843def43072687bca50d989Ted Kremenek } 3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3149c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getSrc() const { 31503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData1()); 316d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3189c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getDst() const { 31903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData2()); 320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 323d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 324b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 325b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 32683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 3279dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint { 3289dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic: 329cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt PostInitializer(const CXXCtorInitializer *I, 3309dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu const LocationContext *L) 3319dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu : ProgramPoint(I, PostInitializerKind, L) {} 3329dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 3339dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu static bool classof(const ProgramPoint *Location) { 3349dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu return Location->getKind() == PostInitializerKind; 3359dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu } 3369dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu}; 3379dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 338102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallEnter : public StmtPoint { 339102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 34019b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 34119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const LocationContext *callerCtx) 34219b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {} 343102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 344102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor const Stmt *getCallExpr() const { 345102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return static_cast<const Stmt *>(getData1()); 346102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 347102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 34819b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const StackFrameContext *getCalleeContext() const { 34919b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu return static_cast<const StackFrameContext *>(getData2()); 350102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 351102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 352102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 353102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallEnterKind; 354102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 355102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 356102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 357102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass CallExit : public StmtPoint { 358102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 359102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor // CallExit uses the callee's location context. 360102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallExit(const Stmt *S, const LocationContext *L) 361102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor : StmtPoint(S, 0, CallExitKind, L, 0) {} 362102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 363102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 364102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallExitKind; 365102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 366102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 367102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 368ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// ProgramPoints can be "tagged" as representing points specific to a given 369ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// analysis entity. Tags are abstract annotations, with an associated 370ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// description and potentially other information. 371ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag { 372ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 373ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {} 374ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual ~ProgramPointTag(); 375ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual StringRef getTagDescription() const = 0; 376ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 377ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprotected: 3781ab69c513239596946286373e081b89fa3358612Ted Kremenek /// Used to implement 'classof' in subclasses. 379ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *getTagKind() { return TagKind; } 380ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 381ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprivate: 382ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *TagKind; 383ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 384ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 385ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass SimpleProgramPointTag : public ProgramPointTag { 386ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek std::string desc; 387ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 388ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek SimpleProgramPointTag(StringRef description); 389ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek StringRef getTagDescription() const; 390ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 392eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 3934c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3944c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap 3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 39783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 3984c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 399d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 400d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 40225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 403d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 404d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 405d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 406d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 40725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 40825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 409d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 410d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4119c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint &Loc) { 412d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 413d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 414d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4159c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic bool isEqual(const clang::ProgramPoint &L, 4169c378f705405d37f49795d5e915989de774fe11fTed Kremenek const clang::ProgramPoint &R) { 417d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 418d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 419d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 4204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 42106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 42206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 42306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; }; 42406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 4254c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 4264c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 427eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 428