ProgramPoint.h revision 852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5
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" 22c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek#include "llvm/ADT/PointerIntPair.h" 235226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 246bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h" 25ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "llvm/ADT/StringRef.h" 264c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 2759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility> 28ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include <string> 29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 30eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 3125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 321d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext; 33102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorclass FunctionDecl; 34ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass LocationContext; 35ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag; 36ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 3783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 38eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek enum Kind { BlockEdgeKind, 40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockEntranceKind, 41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockExitKind, 42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PreStmtKind, 4351a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaks PreStmtPurgeDeadSymbolsKind, 4451a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaks PostStmtPurgeDeadSymbolsKind, 45cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtKind, 46b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreLoadKind, 47cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLoadKind, 48b4b817d704287836b52b34369009e682f208aa2bTed Kremenek PreStoreKind, 49cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStoreKind, 508083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek PostConditionKind, 51cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLValueKind, 52852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose MinPostStmtKind = PostStmtKind, 53852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose MaxPostStmtKind = PostLValueKind, 549dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu PostInitializerKind, 55102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor CallEnterKind, 560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CallExitBeginKind, 570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CallExitEndKind, 5828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PreImplicitCallKind, 5928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PostImplicitCallKind, 6028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose MinImplicitCallKind = PreImplicitCallKind, 6128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose MaxImplicitCallKind = PostImplicitCallKind, 625903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks EpsilonKind}; 634c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 64d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 6528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const void *Data1; 66c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek llvm::PointerIntPair<const void *, 2, unsigned> Data2; 6725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 6825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // The LocationContext could be NULL to allow ProgramPoint to be used in 6925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu // context insensitive analysis. 70c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek llvm::PointerIntPair<const LocationContext *, 2, unsigned> L; 71c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek 7228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag; 731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 74ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPoint(); 75ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 77f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek ProgramPoint(const void *P, 78f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek Kind k, 79f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek const LocationContext *l, 80ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 8128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose : Data1(P), 8228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Data2(0, (((unsigned) k) >> 0) & 0x3), 8328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose L(l, (((unsigned) k) >> 2) & 0x3), 8428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Tag(tag, (((unsigned) k) >> 4) & 0x3) { 85f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek assert(getKind() == k); 86f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek assert(getLocationContext() == l); 87f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek assert(getData1() == P); 88f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek } 89f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek 90f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek ProgramPoint(const void *P1, 91f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek const void *P2, 92f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek Kind k, 93f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek const LocationContext *l, 94ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 9528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose : Data1(P1), 9628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Data2(P2, (((unsigned) k) >> 0) & 0x3), 9728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose L(l, (((unsigned) k) >> 2) & 0x3), 9828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Tag(tag, (((unsigned) k) >> 4) & 0x3) {} 99f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 100d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 10128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const void *getData1() const { return Data1; } 102c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek const void *getData2() const { return Data2.getPointer(); } 103c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek void setData2(const void *d) { Data2.setPointer(d); } 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 106af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks /// Create a new ProgramPoint object that is the same as the original 107af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks /// except for using the specified tag value. 10863d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks ProgramPoint withTag(const ProgramPointTag *tag) const { 109c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek return ProgramPoint(getData1(), getData2(), getKind(), 110f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek getLocationContext(), tag); 111af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks } 112af42712cd8f548f15c700d49a7038ddb846aafa8Anna Zaks 113f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek Kind getKind() const { 11428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose unsigned x = Tag.getInt(); 115c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek x <<= 2; 11628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose x |= L.getInt(); 117c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek x <<= 2; 11828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose x |= Data2.getInt(); 119c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek return (Kind) x; 120f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek } 121d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 1220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// \brief Is this a program point corresponding to purge/removal of dead 1230b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// symbols and bindings. 1240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks bool isPurgeKind() { 1250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Kind K = getKind(); 1260b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks return (K == PostStmtPurgeDeadSymbolsKind || 1270b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks K == PreStmtPurgeDeadSymbolsKind); 1280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 1290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 13028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const ProgramPointTag *getTag() const { return Tag.getPointer(); } 13158465900ca10e53b8700a64e9265870de34e1acaTed Kremenek 132f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek const LocationContext *getLocationContext() const { 133c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek return L.getPointer(); 134f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek } 13525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 136e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 137d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 138e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 139d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 140e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 141d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 144d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 145d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 1466403683411dac55afbe3435ceb19033e27cd9f96Ted Kremenek return Data1 == RHS.Data1 && 147c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek Data2 == RHS.Data2 && 148c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek L == RHS.L && 149c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek Tag == RHS.Tag; 150d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 151d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 1529c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const ProgramPoint &RHS) const { 153c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek return Data1 != RHS.Data1 || 154c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek Data2 != RHS.Data2 || 155c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek L != RHS.L || 156c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek Tag != RHS.Tag; 157d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1595226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 160f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek ID.AddInteger((unsigned) getKind()); 161f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek ID.AddPointer(getData1()); 162c8443e592dbab65cd06ddea9fad6c6f049a08942Ted Kremenek ID.AddPointer(getData2()); 163f30c0a97d9addc72a4928b8bb2039b2b464e1f94Ted Kremenek ID.AddPointer(getLocationContext()); 16428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ID.AddPointer(getTag()); 1652680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 16663d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks 16763d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, 16863d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks const LocationContext *LC, 16963d3201619fdac284adfd3b9328562fa20a01c40Anna Zaks const ProgramPointTag *tag); 170eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 173eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1749c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEntrance(const CFGBlock *B, const LocationContext *L, 175ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 1762f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek : ProgramPoint(B, BlockEntranceKind, L, tag) { 1772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek assert(B && "BlockEntrance requires non-null block"); 1782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1809c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 18103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 182bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CFGElement getFirstElement() const { 1859c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *B = getBlock(); 186852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return B->empty() ? CFGElement() : B->front(); 187852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 188852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 18983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 19083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 191bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 192eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 19383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 19483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 195eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1969c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockExit(const CFGBlock *B, const LocationContext *L) 19725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(B, BlockExitKind, L) {} 1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1999c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getBlock() const { 20003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const CFGBlock*>(getData1()); 201bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 20283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 2039c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getTerminator() const { 20483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 205bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 20883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 209bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 210bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2125f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint { 2135f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic: 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, 215ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) 21625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : ProgramPoint(S, p2, k, L, tag) {} 2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2185f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const Stmt *getStmt() const { return (const Stmt*) getData1(); } 2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2205f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek template <typename T> 2215f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2235f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek static bool classof(const ProgramPoint* Location) { 2245f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek unsigned k = Location->getKind(); 2255f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek return k >= PreStmtKind && k <= MaxPostStmtKind; 2265f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek } 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 229eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 2305f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint { 231cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic: 232ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, 23325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu const Stmt *SubStmt = 0) 23425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} 235cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 237cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 238cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek static bool classof(const ProgramPoint* Location) { 239cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek return Location->getKind() == PreStmtKind; 240cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek } 241cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek}; 242cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 2435f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint { 2441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 2459c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, 2463d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const ProgramPointTag *tag = 0) 24725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, data, k, L, tag) {} 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 249eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 2509c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, Kind k, 251ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const LocationContext *L, const ProgramPointTag *tag = 0) 2524bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek : StmtPoint(S, NULL, k, L, tag) {} 2534bac726dadb09ee38bab8147f1e706380368b362Ted Kremenek 2549c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit PostStmt(const Stmt *S, const LocationContext *L, 255ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 25625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : StmtPoint(S, NULL, PostStmtKind, L, tag) {} 25783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 25883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 2591b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 260f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 2611b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 2621b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 2638c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2648083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek// PostCondition represents the post program point of a branch condition. 2658083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekclass PostCondition : public PostStmt { 2668083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenekpublic: 2679c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostCondition(const Stmt *S, const LocationContext *L, 268ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 2698083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek : PostStmt(S, PostConditionKind, L, tag) {} 2708083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 2718083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek static bool classof(const ProgramPoint* Location) { 2728083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek return Location->getKind() == PostConditionKind; 2738083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek } 2748083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek}; 2758083414ee7cc8f5c807ed6a4e120fb4e0ab50ff8Ted Kremenek 276b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass LocationCheck : public StmtPoint { 277b4b817d704287836b52b34369009e682f208aa2bTed Kremenekprotected: 278b4b817d704287836b52b34369009e682f208aa2bTed Kremenek LocationCheck(const Stmt *S, const LocationContext *L, 279ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPoint::Kind K, const ProgramPointTag *tag) 280b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : StmtPoint(S, NULL, K, L, tag) {} 281b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 282b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 283b4b817d704287836b52b34369009e682f208aa2bTed Kremenek unsigned k = location->getKind(); 284d651141308a777d60ff98309d21e045bb936f8b7Ted Kremenek return k == PreLoadKind || k == PreStoreKind; 2858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 287b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 288b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreLoad : public LocationCheck { 2898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 290ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreLoad(const Stmt *S, const LocationContext *L, 291ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 292b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreLoadKind, tag) {} 293b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 294b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 295b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreLoadKind; 2968c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 299b4b817d704287836b52b34369009e682f208aa2bTed Kremenekclass PreStore : public LocationCheck { 3008c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 301ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek PreStore(const Stmt *S, const LocationContext *L, 302ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 303b4b817d704287836b52b34369009e682f208aa2bTed Kremenek : LocationCheck(S, L, PreStoreKind, tag) {} 304b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 305b4b817d704287836b52b34369009e682f208aa2bTed Kremenek static bool classof(const ProgramPoint *location) { 306b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return location->getKind() == PreStoreKind; 3078c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 3088c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3101b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 3111b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 3129c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLoad(const Stmt *S, const LocationContext *L, 313ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 31425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLoadKind, L, tag) {} 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3161b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 3171b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 318bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 319eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32141c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \brief Represents a program point after a store evaluation. 32282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 32382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 3243d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// Construct the post store point. 3253d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// \param Loc can be used to store the information about the location 3263d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// used in the form it was uttered in the code. 3273d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks PostStore(const Stmt *S, const LocationContext *L, const void *Loc, 328ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 3293d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks : PostStmt(S, PostStoreKind, L, tag) { 3303d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks assert(getData2() == 0); 3313d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks setData2(Loc); 3323d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks } 3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 33482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 33582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 33682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 3373d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks 3383d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// \brief Returns the information about the location used in the store, 3393d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// how it was uttered in the code. 3403d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const void *getLocationValue() const { 3413d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks return getData2(); 3423d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks } 3433d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks 34482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 3457090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 3467090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 3477090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 3489c378f705405d37f49795d5e915989de774fe11fTed Kremenek PostLValue(const Stmt *S, const LocationContext *L, 349ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 35025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : PostStmt(S, PostLValueKind, L, tag) {} 3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3527090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 3537090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 3547090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}; 3561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// Represents a point after we ran remove dead bindings BEFORE 3580b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// processing the given statement. 35951a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaksclass PreStmtPurgeDeadSymbols : public StmtPoint { 360331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 3610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, 362ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) 36351a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaks : StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { } 3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 365331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 3660b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks return Location->getKind() == PreStmtPurgeDeadSymbolsKind; 3670b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 3680b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks}; 3690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 37041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// Represents a point after we ran remove dead bindings AFTER 3710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// processing the given statement. 37251a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaksclass PostStmtPurgeDeadSymbols : public StmtPoint { 3730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zakspublic: 3740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, 3750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const ProgramPointTag *tag = 0) 37651a31ca9a9903ecba1b25bc0989f62e1e2bebb4cAnna Zaks : StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { } 3770b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3780b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks static bool classof(const ProgramPoint* Location) { 3790b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks return Location->getKind() == PostStmtPurgeDeadSymbolsKind; 380331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 381331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 384b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 3859c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L) 386e4c6675cccbaac991843def43072687bca50d989Ted Kremenek : ProgramPoint(B1, B2, BlockEdgeKind, L) { 387e4c6675cccbaac991843def43072687bca50d989Ted Kremenek assert(B1 && "BlockEdge: source block must be non-null"); 388e4c6675cccbaac991843def43072687bca50d989Ted Kremenek assert(B2 && "BlockEdge: destination block must be non-null"); 389e4c6675cccbaac991843def43072687bca50d989Ted Kremenek } 3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3919c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getSrc() const { 39203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData1()); 393d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3959c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock *getDst() const { 39603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CFGBlock*>(getData2()); 397d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 39983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 400d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 401b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 402b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 40383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 4049dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xuclass PostInitializer : public ProgramPoint { 4059dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xupublic: 406cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt PostInitializer(const CXXCtorInitializer *I, 4079dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu const LocationContext *L) 4089dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu : ProgramPoint(I, PostInitializerKind, L) {} 4099dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 4109dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu static bool classof(const ProgramPoint *Location) { 4119dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu return Location->getKind() == PostInitializerKind; 4129dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu } 4139dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu}; 4149dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 41528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// Represents an implicit call event. 41628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// 41728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// The nearest statement is provided for diagnostic purposes. 41828038f33aa2db4833881fea757a1f0daf85ac02bJordan Roseclass ImplicitCallPoint : public ProgramPoint { 41928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rosepublic: 42028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K, 42128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const LocationContext *L, const ProgramPointTag *Tag) 42228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {} 42328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 42428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); } 42528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose SourceLocation getLocation() const { 42628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose return SourceLocation::getFromPtrEncoding(getData1()); 42728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 42828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 42928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose static bool classof(const ProgramPoint *Location) { 43028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose return Location->getKind() >= MinImplicitCallKind && 43128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Location->getKind() <= MaxImplicitCallKind; 43228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 43328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose}; 43428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 43528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// Represents a program point just before an implicit call event. 43628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// 43728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// Explicit calls will appear as PreStmt program points. 43828038f33aa2db4833881fea757a1f0daf85ac02bJordan Roseclass PreImplicitCall : public ImplicitCallPoint { 43928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rosepublic: 44028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PreImplicitCall(const Decl *D, SourceLocation Loc, 44128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const LocationContext *L, const ProgramPointTag *Tag = 0) 44228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {} 44328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 44428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose static bool classof(const ProgramPoint *Location) { 44528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose return Location->getKind() == PreImplicitCallKind; 44628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 44728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose}; 44828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 44928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// Represents a program point just after an implicit call event. 45028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// 45128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose/// Explicit calls will appear as PostStmt program points. 45228038f33aa2db4833881fea757a1f0daf85ac02bJordan Roseclass PostImplicitCall : public ImplicitCallPoint { 45328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rosepublic: 45428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PostImplicitCall(const Decl *D, SourceLocation Loc, 45528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const LocationContext *L, const ProgramPointTag *Tag = 0) 45628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {} 45728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 45828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose static bool classof(const ProgramPoint *Location) { 45928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose return Location->getKind() == PostImplicitCallKind; 46028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 46128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose}; 46228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 46341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// Represents a point when we begin processing an inlined call. 464852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Roseclass CallEnter : public ProgramPoint { 465102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 46619b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 46719b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const LocationContext *callerCtx) 468852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {} 469102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 470102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor const Stmt *getCallExpr() const { 471102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return static_cast<const Stmt *>(getData1()); 472102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 473102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 47419b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu const StackFrameContext *getCalleeContext() const { 47519b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu return static_cast<const StackFrameContext *>(getData2()); 476102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 477102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 478102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 479102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor return Location->getKind() == CallEnterKind; 480102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 481102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 482102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 48341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// Represents a point when we start the call exit sequence (for inlined call). 4840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// 4850b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// The call exit is simulated with a sequence of nodes, which occur between 4860b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// CallExitBegin and CallExitEnd. The following operations occur between the 4870b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// two program points: 4880b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// - CallExitBegin 4890b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// - Bind the return value 4900b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// - Run Remove dead bindings (to clean up the dead symbols from the callee). 4910b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// - CallExitEnd 492852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Roseclass CallExitBegin : public ProgramPoint { 4930b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zakspublic: 4940b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // CallExitBegin uses the callee's location context. 495852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose CallExitBegin(const StackFrameContext *L) 496852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose : ProgramPoint(0, CallExitBeginKind, L, 0) {} 4970b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4980b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks static bool classof(const ProgramPoint *Location) { 4990b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks return Location->getKind() == CallExitBeginKind; 5000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 5010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks}; 5020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 50341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// Represents a point when we finish the call exit sequence (for inlined call). 5040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks/// \sa CallExitBegin 505852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Roseclass CallExitEnd : public ProgramPoint { 506102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic: 5070b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // CallExitEnd uses the caller's location context. 508852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose CallExitEnd(const StackFrameContext *CalleeCtx, 509852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose const LocationContext *CallerCtx) 510852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, 0) {} 511852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose 512852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose const StackFrameContext *getCalleeContext() const { 513852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose return static_cast<const StackFrameContext *>(getData1()); 514852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose } 515102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 516102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor static bool classof(const ProgramPoint *Location) { 5170b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks return Location->getKind() == CallExitEndKind; 518102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor } 519102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor}; 520102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 5215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// This is a meta program point, which should be skipped by all the diagnostic 5225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// reasoning etc. 5235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksclass EpsilonPoint : public ProgramPoint { 5245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zakspublic: 5255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks EpsilonPoint(const LocationContext *L, const void *Data1, 5265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const void *Data2 = 0, const ProgramPointTag *tag = 0) 5275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {} 5285903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 5295903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const void *getData() const { return getData1(); } 5305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 5315903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks static bool classof(const ProgramPoint* Location) { 5325903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return Location->getKind() == EpsilonKind; 5335903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 5345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks}; 5355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 536ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// ProgramPoints can be "tagged" as representing points specific to a given 537ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// analysis entity. Tags are abstract annotations, with an associated 538ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek/// description and potentially other information. 539ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass ProgramPointTag { 540ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 541ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {} 542ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual ~ProgramPointTag(); 543ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek virtual StringRef getTagDescription() const = 0; 544ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 545ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprotected: 5461ab69c513239596946286373e081b89fa3358612Ted Kremenek /// Used to implement 'classof' in subclasses. 547ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *getTagKind() { return TagKind; } 548ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 549ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekprivate: 550ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const void *TagKind; 551ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 552ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 553ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass SimpleProgramPointTag : public ProgramPointTag { 554ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek std::string desc; 555ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic: 556ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek SimpleProgramPointTag(StringRef description); 557ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek StringRef getTagDescription() const; 558ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}; 5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 560eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 5614c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 5624c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { // Traits specialization for DenseMap 5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 56583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 5664c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 567d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 568d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 57025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 571d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 572d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 573d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 574d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 57525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 57625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 577d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 578d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 5799c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint &Loc) { 580d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 581d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 582d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 5839c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic bool isEqual(const clang::ProgramPoint &L, 5849c378f705405d37f49795d5e915989de774fe11fTed Kremenek const clang::ProgramPoint &R) { 585d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 586d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 587d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 5884c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 58906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 59006159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnertemplate <> 59106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattnerstruct isPodLike<clang::ProgramPoint> { static const bool value = true; }; 59206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner 5934c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 5944c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 595eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 596