summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/ProgramPoint.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/ProgramPoint.h')
-rw-r--r--include/clang/Analysis/ProgramPoint.h704
1 files changed, 0 insertions, 704 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
deleted file mode 100644
index 6d816fd..0000000
--- a/include/clang/Analysis/ProgramPoint.h
+++ /dev/null
@@ -1,704 +0,0 @@
-//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface ProgramPoint, which identifies a
-// distinct location in a function.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
-#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/CFG.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <string>
-#include <utility>
-
-namespace clang {
-
-class AnalysisDeclContext;
-class FunctionDecl;
-class LocationContext;
-
-/// ProgramPoints can be "tagged" as representing points specific to a given
-/// analysis entity. Tags are abstract annotations, with an associated
-/// description and potentially other information.
-class ProgramPointTag {
-public:
- ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
- virtual ~ProgramPointTag();
- virtual StringRef getTagDescription() const = 0;
-
-protected:
- /// Used to implement 'isKind' in subclasses.
- const void *getTagKind() { return TagKind; }
-
-private:
- const void *TagKind;
-};
-
-class SimpleProgramPointTag : public ProgramPointTag {
- std::string Desc;
-public:
- SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
- StringRef getTagDescription() const override;
-};
-
-class ProgramPoint {
-public:
- enum Kind { BlockEdgeKind,
- BlockEntranceKind,
- BlockExitKind,
- PreStmtKind,
- PreStmtPurgeDeadSymbolsKind,
- PostStmtPurgeDeadSymbolsKind,
- PostStmtKind,
- PreLoadKind,
- PostLoadKind,
- PreStoreKind,
- PostStoreKind,
- PostConditionKind,
- PostLValueKind,
- MinPostStmtKind = PostStmtKind,
- MaxPostStmtKind = PostLValueKind,
- PostInitializerKind,
- CallEnterKind,
- CallExitBeginKind,
- CallExitEndKind,
- PreImplicitCallKind,
- PostImplicitCallKind,
- MinImplicitCallKind = PreImplicitCallKind,
- MaxImplicitCallKind = PostImplicitCallKind,
- EpsilonKind};
-
-private:
- const void *Data1;
- llvm::PointerIntPair<const void *, 2, unsigned> Data2;
-
- // The LocationContext could be NULL to allow ProgramPoint to be used in
- // context insensitive analysis.
- llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
-
- llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
-
-protected:
- ProgramPoint() {}
- ProgramPoint(const void *P,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P),
- Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {
- assert(getKind() == k);
- assert(getLocationContext() == l);
- assert(getData1() == P);
- }
-
- ProgramPoint(const void *P1,
- const void *P2,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P1),
- Data2(P2, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
-
-protected:
- const void *getData1() const { return Data1; }
- const void *getData2() const { return Data2.getPointer(); }
- void setData2(const void *d) { Data2.setPointer(d); }
-
-public:
- /// Create a new ProgramPoint object that is the same as the original
- /// except for using the specified tag value.
- ProgramPoint withTag(const ProgramPointTag *tag) const {
- return ProgramPoint(getData1(), getData2(), getKind(),
- getLocationContext(), tag);
- }
-
- /// \brief Convert to the specified ProgramPoint type, asserting that this
- /// ProgramPoint is of the desired type.
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- ProgramPoint& PP = t;
- PP = *this;
- return t;
- }
-
- /// \brief Convert to the specified ProgramPoint type, returning None if this
- /// ProgramPoint is not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
- if (!T::isKind(*this))
- return None;
- T t;
- ProgramPoint& PP = t;
- PP = *this;
- return t;
- }
-
- Kind getKind() const {
- unsigned x = Tag.getInt();
- x <<= 2;
- x |= L.getInt();
- x <<= 2;
- x |= Data2.getInt();
- return (Kind) x;
- }
-
- /// \brief Is this a program point corresponding to purge/removal of dead
- /// symbols and bindings.
- bool isPurgeKind() {
- Kind K = getKind();
- return (K == PostStmtPurgeDeadSymbolsKind ||
- K == PreStmtPurgeDeadSymbolsKind);
- }
-
- const ProgramPointTag *getTag() const { return Tag.getPointer(); }
-
- const LocationContext *getLocationContext() const {
- return L.getPointer();
- }
-
- // For use with DenseMap. This hash is probably slow.
- unsigned getHashValue() const {
- llvm::FoldingSetNodeID ID;
- Profile(ID);
- return ID.ComputeHash();
- }
-
- bool operator==(const ProgramPoint & RHS) const {
- return Data1 == RHS.Data1 &&
- Data2 == RHS.Data2 &&
- L == RHS.L &&
- Tag == RHS.Tag;
- }
-
- bool operator!=(const ProgramPoint &RHS) const {
- return Data1 != RHS.Data1 ||
- Data2 != RHS.Data2 ||
- L != RHS.L ||
- Tag != RHS.Tag;
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) getKind());
- ID.AddPointer(getData1());
- ID.AddPointer(getData2());
- ID.AddPointer(getLocationContext());
- ID.AddPointer(getTag());
- }
-
- static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
- const LocationContext *LC,
- const ProgramPointTag *tag);
-};
-
-class BlockEntrance : public ProgramPoint {
-public:
- BlockEntrance(const CFGBlock *B, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : ProgramPoint(B, BlockEntranceKind, L, tag) {
- assert(B && "BlockEntrance requires non-null block");
- }
-
- const CFGBlock *getBlock() const {
- return reinterpret_cast<const CFGBlock*>(getData1());
- }
-
- Optional<CFGElement> getFirstElement() const {
- const CFGBlock *B = getBlock();
- return B->empty() ? Optional<CFGElement>() : B->front();
- }
-
-private:
- friend class ProgramPoint;
- BlockEntrance() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockEntranceKind;
- }
-};
-
-class BlockExit : public ProgramPoint {
-public:
- BlockExit(const CFGBlock *B, const LocationContext *L)
- : ProgramPoint(B, BlockExitKind, L) {}
-
- const CFGBlock *getBlock() const {
- return reinterpret_cast<const CFGBlock*>(getData1());
- }
-
- const Stmt *getTerminator() const {
- return getBlock()->getTerminator();
- }
-
-private:
- friend class ProgramPoint;
- BlockExit() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockExitKind;
- }
-};
-
-class StmtPoint : public ProgramPoint {
-public:
- StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
- const ProgramPointTag *tag)
- : ProgramPoint(S, p2, k, L, tag) {
- assert(S);
- }
-
- const Stmt *getStmt() const { return (const Stmt*) getData1(); }
-
- template <typename T>
- const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
-
-protected:
- StmtPoint() {}
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- unsigned k = Location.getKind();
- return k >= PreStmtKind && k <= MaxPostStmtKind;
- }
-};
-
-
-class PreStmt : public StmtPoint {
-public:
- PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
- const Stmt *SubStmt = nullptr)
- : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
-
- const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
-
-private:
- friend class ProgramPoint;
- PreStmt() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreStmtKind;
- }
-};
-
-class PostStmt : public StmtPoint {
-protected:
- PostStmt() {}
- PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, data, k, L, tag) {}
-
-public:
- explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, k, L, tag) {}
-
- explicit PostStmt(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- unsigned k = Location.getKind();
- return k >= MinPostStmtKind && k <= MaxPostStmtKind;
- }
-};
-
-// PostCondition represents the post program point of a branch condition.
-class PostCondition : public PostStmt {
-public:
- PostCondition(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostConditionKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostCondition() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostConditionKind;
- }
-};
-
-class LocationCheck : public StmtPoint {
-protected:
- LocationCheck() {}
- LocationCheck(const Stmt *S, const LocationContext *L,
- ProgramPoint::Kind K, const ProgramPointTag *tag)
- : StmtPoint(S, nullptr, K, L, tag) {}
-
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &location) {
- unsigned k = location.getKind();
- return k == PreLoadKind || k == PreStoreKind;
- }
-};
-
-class PreLoad : public LocationCheck {
-public:
- PreLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : LocationCheck(S, L, PreLoadKind, tag) {}
-
-private:
- friend class ProgramPoint;
- PreLoad() {}
- static bool isKind(const ProgramPoint &location) {
- return location.getKind() == PreLoadKind;
- }
-};
-
-class PreStore : public LocationCheck {
-public:
- PreStore(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : LocationCheck(S, L, PreStoreKind, tag) {}
-
-private:
- friend class ProgramPoint;
- PreStore() {}
- static bool isKind(const ProgramPoint &location) {
- return location.getKind() == PreStoreKind;
- }
-};
-
-class PostLoad : public PostStmt {
-public:
- PostLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostLoadKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostLoad() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostLoadKind;
- }
-};
-
-/// \brief Represents a program point after a store evaluation.
-class PostStore : public PostStmt {
-public:
- /// Construct the post store point.
- /// \param Loc can be used to store the information about the location
- /// used in the form it was uttered in the code.
- PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostStoreKind, L, tag) {
- assert(getData2() == nullptr);
- setData2(Loc);
- }
-
- /// \brief Returns the information about the location used in the store,
- /// how it was uttered in the code.
- const void *getLocationValue() const {
- return getData2();
- }
-
-private:
- friend class ProgramPoint;
- PostStore() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostStoreKind;
- }
-};
-
-class PostLValue : public PostStmt {
-public:
- PostLValue(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostLValueKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostLValue() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostLValueKind;
- }
-};
-
-/// Represents a point after we ran remove dead bindings BEFORE
-/// processing the given statement.
-class PreStmtPurgeDeadSymbols : public StmtPoint {
-public:
- PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
-
-private:
- friend class ProgramPoint;
- PreStmtPurgeDeadSymbols() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
- }
-};
-
-/// Represents a point after we ran remove dead bindings AFTER
-/// processing the given statement.
-class PostStmtPurgeDeadSymbols : public StmtPoint {
-public:
- PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
-
-private:
- friend class ProgramPoint;
- PostStmtPurgeDeadSymbols() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
- }
-};
-
-class BlockEdge : public ProgramPoint {
-public:
- BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
- : ProgramPoint(B1, B2, BlockEdgeKind, L) {
- assert(B1 && "BlockEdge: source block must be non-null");
- assert(B2 && "BlockEdge: destination block must be non-null");
- }
-
- const CFGBlock *getSrc() const {
- return static_cast<const CFGBlock*>(getData1());
- }
-
- const CFGBlock *getDst() const {
- return static_cast<const CFGBlock*>(getData2());
- }
-
-private:
- friend class ProgramPoint;
- BlockEdge() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockEdgeKind;
- }
-};
-
-class PostInitializer : public ProgramPoint {
-public:
- /// \brief Construct a PostInitializer point that represents a location after
- /// CXXCtorInitializer expression evaluation.
- ///
- /// \param I The initializer.
- /// \param Loc The location of the field being initialized.
- PostInitializer(const CXXCtorInitializer *I,
- const void *Loc,
- const LocationContext *L)
- : ProgramPoint(I, Loc, PostInitializerKind, L) {}
-
- const CXXCtorInitializer *getInitializer() const {
- return static_cast<const CXXCtorInitializer *>(getData1());
- }
-
- /// \brief Returns the location of the field.
- const void *getLocationValue() const {
- return getData2();
- }
-
-private:
- friend class ProgramPoint;
- PostInitializer() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostInitializerKind;
- }
-};
-
-/// Represents an implicit call event.
-///
-/// The nearest statement is provided for diagnostic purposes.
-class ImplicitCallPoint : public ProgramPoint {
-public:
- ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
- const LocationContext *L, const ProgramPointTag *Tag)
- : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
-
- const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
- SourceLocation getLocation() const {
- return SourceLocation::getFromPtrEncoding(getData1());
- }
-
-protected:
- ImplicitCallPoint() {}
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() >= MinImplicitCallKind &&
- Location.getKind() <= MaxImplicitCallKind;
- }
-};
-
-/// Represents a program point just before an implicit call event.
-///
-/// Explicit calls will appear as PreStmt program points.
-class PreImplicitCall : public ImplicitCallPoint {
-public:
- PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
- const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
-
-private:
- friend class ProgramPoint;
- PreImplicitCall() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreImplicitCallKind;
- }
-};
-
-/// Represents a program point just after an implicit call event.
-///
-/// Explicit calls will appear as PostStmt program points.
-class PostImplicitCall : public ImplicitCallPoint {
-public:
- PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
- const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
-
-private:
- friend class ProgramPoint;
- PostImplicitCall() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostImplicitCallKind;
- }
-};
-
-/// Represents a point when we begin processing an inlined call.
-/// CallEnter uses the caller's location context.
-class CallEnter : public ProgramPoint {
-public:
- CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
- const LocationContext *callerCtx)
- : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
-
- const Stmt *getCallExpr() const {
- return static_cast<const Stmt *>(getData1());
- }
-
- const StackFrameContext *getCalleeContext() const {
- return static_cast<const StackFrameContext *>(getData2());
- }
-
-private:
- friend class ProgramPoint;
- CallEnter() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallEnterKind;
- }
-};
-
-/// Represents a point when we start the call exit sequence (for inlined call).
-///
-/// The call exit is simulated with a sequence of nodes, which occur between
-/// CallExitBegin and CallExitEnd. The following operations occur between the
-/// two program points:
-/// - CallExitBegin
-/// - Bind the return value
-/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
-/// - CallExitEnd
-class CallExitBegin : public ProgramPoint {
-public:
- // CallExitBegin uses the callee's location context.
- CallExitBegin(const StackFrameContext *L)
- : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
-
-private:
- friend class ProgramPoint;
- CallExitBegin() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallExitBeginKind;
- }
-};
-
-/// Represents a point when we finish the call exit sequence (for inlined call).
-/// \sa CallExitBegin
-class CallExitEnd : public ProgramPoint {
-public:
- // CallExitEnd uses the caller's location context.
- CallExitEnd(const StackFrameContext *CalleeCtx,
- const LocationContext *CallerCtx)
- : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
-
- const StackFrameContext *getCalleeContext() const {
- return static_cast<const StackFrameContext *>(getData1());
- }
-
-private:
- friend class ProgramPoint;
- CallExitEnd() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallExitEndKind;
- }
-};
-
-/// This is a meta program point, which should be skipped by all the diagnostic
-/// reasoning etc.
-class EpsilonPoint : public ProgramPoint {
-public:
- EpsilonPoint(const LocationContext *L, const void *Data1,
- const void *Data2 = nullptr,
- const ProgramPointTag *tag = nullptr)
- : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
-
- const void *getData() const { return getData1(); }
-
-private:
- friend class ProgramPoint;
- EpsilonPoint() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == EpsilonKind;
- }
-};
-
-} // end namespace clang
-
-
-namespace llvm { // Traits specialization for DenseMap
-
-template <> struct DenseMapInfo<clang::ProgramPoint> {
-
-static inline clang::ProgramPoint getEmptyKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
-}
-
-static inline clang::ProgramPoint getTombstoneKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
-}
-
-static unsigned getHashValue(const clang::ProgramPoint &Loc) {
- return Loc.getHashValue();
-}
-
-static bool isEqual(const clang::ProgramPoint &L,
- const clang::ProgramPoint &R) {
- return L == R;
-}
-
-};
-
-template <>
-struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
-
-} // end namespace llvm
-
-#endif
OpenPOWER on IntegriCloud