ProgramPoint.h revision 1ab69c513239596946286373e081b89fa3358612
107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// 207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// 307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// The LLVM Compiler Infrastructure 407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// 507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// This file is distributed under the University of Illinois Open Source 607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// License. See LICENSE.TXT for details. 7ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark// 8dac1d17027dcaa5596885a9f333979418b35001ccaryclark//===----------------------------------------------------------------------===// 907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// 1007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// This file defines the interface ProgramPoint, which identifies a 11ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark// distinct location in a function. 12ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark// 13ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark//===----------------------------------------------------------------------===// 14ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 15ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT 16ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT 17ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 18ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#include "clang/Analysis/AnalysisContext.h" 19ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#include "clang/Analysis/CFG.h" 20ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#include "llvm/Support/DataTypes.h" 2107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "llvm/ADT/DenseMap.h" 2207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "llvm/ADT/FoldingSet.h" 2307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "llvm/Support/Casting.h" 2407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "llvm/ADT/StringRef.h" 2507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include <cassert> 2607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include <utility> 2707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include <string> 2807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 2907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comnamespace clang { 3007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass AnalysisContext; 3207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass FunctionDecl; 334431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgclass LocationContext; 344431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgclass ProgramPointTag; 3507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass ProgramPoint { 3707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 3807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com enum Kind { BlockEdgeKind, 3907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com BlockEntranceKind, 4007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com BlockExitKind, 4107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PreStmtKind, 4207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PostStmtKind, 4307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PreLoadKind, 4407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PostLoadKind, 45ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PreStoreKind, 46ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostStoreKind, 47ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostPurgeDeadSymbolsKind, 484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org PostStmtCustomKind, 4907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PostConditionKind, 50ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostLValueKind, 51ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostInitializerKind, 5207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com CallEnterKind, 534431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org CallExitKind, 5407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com MinPostStmtKind = PostStmtKind, 5507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com MaxPostStmtKind = CallExitKind }; 56ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 57ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkprivate: 58ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark std::pair<const void *, const void *> Data; 59ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark Kind K; 60ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 61ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark // The LocationContext could be NULL to allow ProgramPoint to be used in 62ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark // context insensitive analysis. 63ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const LocationContext *L; 64ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *Tag; 6507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 66ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark ProgramPoint(); 67ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 68ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkprotected: 694431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org ProgramPoint(const void* P, Kind k, const LocationContext *l, 704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org const ProgramPointTag *tag = 0) 714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {} 724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 73ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l, 7407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const ProgramPointTag *tag = 0) 7507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : Data(P1, P2), K(k), L(l), Tag(tag) {} 76ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 7707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comprotected: 78ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const void* getData1() const { return Data.first; } 79ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const void* getData2() const { return Data.second; } 80ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 81ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 82ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark Kind getKind() const { return K; } 83ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 84ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *getTag() const { return Tag; } 85ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 86ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const LocationContext *getLocationContext() const { return L; } 874431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 884431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org // For use with DenseMap. This hash is probably slow. 8907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com unsigned getHashValue() const { 904431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org llvm::FoldingSetNodeID ID; 91ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark Profile(ID); 9207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return ID.ComputeHash(); 9307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 944431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 954431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org static bool classof(const ProgramPoint*) { return true; } 964431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 97ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark bool operator==(const ProgramPoint & RHS) const { 98ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; 99ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 100ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 101ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark bool operator!=(const ProgramPoint& RHS) const { 102ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; 10307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 10407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 105ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark void Profile(llvm::FoldingSetNodeID& ID) const { 10607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ID.AddInteger((unsigned) K); 10707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ID.AddPointer(Data.first); 10807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ID.AddPointer(Data.second); 10907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ID.AddPointer(L); 11007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ID.AddPointer(Tag); 111ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 112ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 113ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 11407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass BlockEntrance : public ProgramPoint { 11507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 11607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com BlockEntrance(const CFGBlock* B, const LocationContext *L, 117ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag = 0) 11807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : ProgramPoint(B, BlockEntranceKind, L, tag) {} 11907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 120ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const CFGBlock* getBlock() const { 121ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return reinterpret_cast<const CFGBlock*>(getData1()); 12207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 12307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 12407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const CFGElement getFirstElement() const { 125ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const CFGBlock* B = getBlock(); 126ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return B->empty() ? CFGElement() : B->front(); 12707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 12807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 12907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com /// Create a new BlockEntrance object that is the same as the original 130ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark /// except for using the specified tag value. 131ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark BlockEntrance withTag(const ProgramPointTag *tag) { 13207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return BlockEntrance(getBlock(), getLocationContext(), tag); 13307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 13407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 135ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint* Location) { 13607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return Location->getKind() == BlockEntranceKind; 13707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 138ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 139ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 140ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass BlockExit : public ProgramPoint { 141ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 142ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark BlockExit(const CFGBlock* B, const LocationContext *L) 14307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : ProgramPoint(B, BlockExitKind, L) {} 14407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 14507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const CFGBlock* getBlock() const { 146ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return reinterpret_cast<const CFGBlock*>(getData1()); 147ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 148ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 149ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const Stmt* getTerminator() const { 15065f553182ab7069378ef863d30094d0327f178d0caryclark return getBlock()->getTerminator(); 15165f553182ab7069378ef863d30094d0327f178d0caryclark } 15265f553182ab7069378ef863d30094d0327f178d0caryclark 15365f553182ab7069378ef863d30094d0327f178d0caryclark static bool classof(const ProgramPoint* Location) { 154ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == BlockExitKind; 15507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 15607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 157ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 15807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass StmtPoint : public ProgramPoint { 15907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 160ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, 161ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag) 1624431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org : ProgramPoint(S, p2, k, L, tag) {} 163ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 1644431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org const Stmt *getStmt() const { return (const Stmt*) getData1(); } 16507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 16607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com template <typename T> 16707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 16807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 16907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com static bool classof(const ProgramPoint* Location) { 1704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org unsigned k = Location->getKind(); 1714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org return k >= PreStmtKind && k <= MaxPostStmtKind; 1724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1734431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}; 17407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1754431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 1764431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgclass PreStmt : public StmtPoint { 1774431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 1784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, 17907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const Stmt *SubStmt = 0) 18007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} 18107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 182dac1d17027dcaa5596885a9f333979418b35001ccaryclark const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 183ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 184570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com static bool classof(const ProgramPoint* Location) { 18507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return Location->getKind() == PreStmtKind; 18607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 18707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 18807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 189ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostStmt : public StmtPoint { 190ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkprotected: 191ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L, 19207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const ProgramPointTag *tag =0) 19307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : StmtPoint(S, data, k, L, tag) {} 194ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 1954431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 196ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark explicit PostStmt(const Stmt* S, Kind k, 1974431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org const LocationContext *L, const ProgramPointTag *tag = 0) 19807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : StmtPoint(S, NULL, k, L, tag) {} 19907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 20007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com explicit PostStmt(const Stmt* S, const LocationContext *L, 20107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const ProgramPointTag *tag = 0) 20207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : StmtPoint(S, NULL, PostStmtKind, L, tag) {} 203ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 204ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint* Location) { 20507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com unsigned k = Location->getKind(); 20607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return k >= MinPostStmtKind && k <= MaxPostStmtKind; 207ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 20807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 20907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 21007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass PostStmtCustom : public PostStmt { 21107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 21207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PostStmtCustom(const Stmt* S, 21307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const std::pair<const void*, const void*>* TaggedData,\ 21407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const LocationContext *L) 215ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : PostStmt(S, TaggedData, PostStmtCustomKind, L) {} 21607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 217277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com const std::pair<const void*, const void*>& getTaggedPair() const { 21807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return 21907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2()); 22007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 22107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 22207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const void* getTag() const { return getTaggedPair().first; } 22307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 22407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const void* getTaggedData() const { return getTaggedPair().second; } 22507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 22607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com static bool classof(const ProgramPoint* Location) { 22707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return Location->getKind() == PostStmtCustomKind; 22807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 22907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 23007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 23107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// PostCondition represents the post program point of a branch condition. 23207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass PostCondition : public PostStmt { 23307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 23407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com PostCondition(const Stmt* S, const LocationContext *L, 23507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const ProgramPointTag *tag = 0) 23607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : PostStmt(S, PostConditionKind, L, tag) {} 23707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 23807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com static bool classof(const ProgramPoint* Location) { 23907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return Location->getKind() == PostConditionKind; 24007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 24107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 24207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 24307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass LocationCheck : public StmtPoint { 24407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comprotected: 24507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com LocationCheck(const Stmt *S, const LocationContext *L, 24607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ProgramPoint::Kind K, const ProgramPointTag *tag) 24707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : StmtPoint(S, NULL, K, L, tag) {} 24807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 24907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com static bool classof(const ProgramPoint *location) { 250ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark unsigned k = location->getKind(); 251ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return k == PreLoadKind || k == PreStoreKind; 252ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 253ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 2544431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 255ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PreLoad : public LocationCheck { 256ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 257ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PreLoad(const Stmt *S, const LocationContext *L, 258ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag = 0) 259ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : LocationCheck(S, L, PreLoadKind, tag) {} 260ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 261ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint *location) { 262ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return location->getKind() == PreLoadKind; 263ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 264ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 265ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 266ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PreStore : public LocationCheck { 26707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 268ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PreStore(const Stmt *S, const LocationContext *L, 269ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag = 0) 27007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : LocationCheck(S, L, PreStoreKind, tag) {} 27107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 272ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint *location) { 273ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return location->getKind() == PreStoreKind; 274ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 275ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 276ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 277ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostLoad : public PostStmt { 278ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 279ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostLoad(const Stmt* S, const LocationContext *L, 280ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag = 0) 281ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : PostStmt(S, PostLoadKind, L, tag) {} 282ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 283ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint* Location) { 284ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == PostLoadKind; 285ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 286ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 287ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 288ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostStore : public PostStmt { 2894431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 2904431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org PostStore(const Stmt* S, const LocationContext *L, 291ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const ProgramPointTag *tag = 0) 292ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : PostStmt(S, PostStoreKind, L, tag) {} 293ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 2944431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org static bool classof(const ProgramPoint* Location) { 2954431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org return Location->getKind() == PostStoreKind; 296ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 297ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 298ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 299ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostLValue : public PostStmt { 3004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 301ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostLValue(const Stmt* S, const LocationContext *L, 3024431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org const ProgramPointTag *tag = 0) 3034431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org : PostStmt(S, PostLValueKind, L, tag) {} 304ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 3054431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org static bool classof(const ProgramPoint* Location) { 306dac1d17027dcaa5596885a9f333979418b35001ccaryclark return Location->getKind() == PostLValueKind; 3074431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 308ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 3094431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 310ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostPurgeDeadSymbols : public PostStmt { 3114431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 312dac1d17027dcaa5596885a9f333979418b35001ccaryclark PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L, 313dac1d17027dcaa5596885a9f333979418b35001ccaryclark const ProgramPointTag *tag = 0) 3144431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} 3154431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 316ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint* Location) { 317ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == PostPurgeDeadSymbolsKind; 318ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 319ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 320ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 321ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass BlockEdge : public ProgramPoint { 322ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 323ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L) 324ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : ProgramPoint(B1, B2, BlockEdgeKind, L) {} 325ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 326ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const CFGBlock* getSrc() const { 327ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return static_cast<const CFGBlock*>(getData1()); 328ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 329ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 330ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const CFGBlock* getDst() const { 331ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return static_cast<const CFGBlock*>(getData2()); 332ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 333ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 334ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint* Location) { 335ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == BlockEdgeKind; 336ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 337ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 338ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 339ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass PostInitializer : public ProgramPoint { 340ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 341ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark PostInitializer(const CXXCtorInitializer *I, 342ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const LocationContext *L) 343ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : ProgramPoint(I, PostInitializerKind, L) {} 344ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 345ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint *Location) { 3464431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org return Location->getKind() == PostInitializerKind; 3474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 348ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 349ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 350ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass CallEnter : public StmtPoint { 351ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 3524431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 353ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const LocationContext *callerCtx) 354ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : StmtPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {} 355ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 356ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const Stmt *getCallExpr() const { 357ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return static_cast<const Stmt *>(getData1()); 358ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 359ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 360ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const StackFrameContext *getCalleeContext() const { 361ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return static_cast<const StackFrameContext *>(getData2()); 362ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 363ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 364ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint *Location) { 365ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == CallEnterKind; 366ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 367ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 368ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 369ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass CallExit : public StmtPoint { 370ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 371ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark // CallExit uses the callee's location context. 372ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark CallExit(const Stmt *S, const LocationContext *L) 373ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark : StmtPoint(S, 0, CallExitKind, L, 0) {} 374ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 375ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark static bool classof(const ProgramPoint *Location) { 376ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Location->getKind() == CallExitKind; 377ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 378ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 379ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 380ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark/// ProgramPoints can be "tagged" as representing points specific to a given 381ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark/// analysis entity. Tags are abstract annotations, with an associated 382ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark/// description and potentially other information. 383ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass ProgramPointTag { 384ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkpublic: 385ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {} 386ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark virtual ~ProgramPointTag(); 387ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark virtual StringRef getTagDescription() const = 0; 388ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 389ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkprotected: 390ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark /// Used to implement 'classof' in subclasses. 391ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const void *getTagKind() { return TagKind; } 392ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 393ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkprivate: 394ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const void *TagKind; 395ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 396ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 397ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkclass SimpleProgramPointTag : public ProgramPointTag { 3984431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org std::string desc; 3994431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic: 400ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark SimpleProgramPointTag(StringRef description); 401ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark StringRef getTagDescription() const; 402ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 403ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 404ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark} // end namespace clang 405ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 406ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 407ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarknamespace llvm { // Traits specialization for DenseMap 408ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 40907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comtemplate <> struct DenseMapInfo<clang::ProgramPoint> { 41007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 411ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkstatic inline clang::ProgramPoint getEmptyKey() { 41207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com uintptr_t x = 413ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 414ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 41507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com} 416ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 417ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkstatic inline clang::ProgramPoint getTombstoneKey() { 418ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark uintptr_t x = 419ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 420ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); 421ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark} 422ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 423dac1d17027dcaa5596885a9f333979418b35001ccaryclarkstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 424ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return Loc.getHashValue(); 42565f553182ab7069378ef863d30094d0327f178d0caryclark} 42665f553182ab7069378ef863d30094d0327f178d0caryclark 427ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkstatic bool isEqual(const clang::ProgramPoint& L, 428ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark const clang::ProgramPoint& R) { 429ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark return L == R; 430ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark} 43107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 432ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}; 433ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 434ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarktemplate <> 435ccec0f958ffc71a9986d236bc2eb335cb2111119caryclarkstruct isPodLike<clang::ProgramPoint> { static const bool value = true; }; 436ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 437ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark} // end namespace llvm 438ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 43907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 440ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark