15 #ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H 16 #define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/ADT/FoldingSet.h" 22 #include "llvm/ADT/Optional.h" 23 #include "llvm/ADT/PointerIntPair.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/DataTypes.h" 33 class AnalysisDeclContext;
35 class LocationContext;
77 MinPostStmtKind = PostStmtKind,
78 MaxPostStmtKind = PostAllocatorCallKind,
86 MinImplicitCallKind = PreImplicitCallKind,
87 MaxImplicitCallKind = PostImplicitCallKind,
93 llvm::PointerIntPair<const void *, 2, unsigned> Data2;
97 llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
99 llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
108 Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
109 L(l, (((unsigned) k) >> 2) & 0x3),
110 Tag(tag, (((unsigned) k) >> 4) & 0x3) {
112 assert(getLocationContext() == l);
113 assert(getData1() == P);
122 Data2(P2, (((unsigned) k) >> 0) & 0x3),
123 L(l, (((unsigned) k) >> 2) & 0x3),
124 Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
128 const void *
getData2()
const {
return Data2.getPointer(); }
129 void setData2(
const void *d) { Data2.setPointer(d); }
136 getLocationContext(), tag);
143 assert(T::isKind(*
this));
154 if (!T::isKind(*
this))
163 unsigned x = Tag.getInt();
175 return (K == PostStmtPurgeDeadSymbolsKind ||
176 K == PreStmtPurgeDeadSymbolsKind);
182 return L.getPointer();
191 llvm::FoldingSetNodeID
ID;
193 return ID.ComputeHash();
197 return Data1 == RHS.Data1 &&
198 Data2 == RHS.Data2 &&
204 return Data1 != RHS.Data1 ||
205 Data2 != RHS.Data2 ||
211 ID.AddInteger((
unsigned)
getKind());
212 ID.AddPointer(getData1());
213 ID.AddPointer(getData2());
214 ID.AddPointer(getLocationContext());
215 ID.AddPointer(getTag());
218 void print(StringRef CR, llvm::raw_ostream &Out)
const;
220 LLVM_DUMP_METHOD
void dump()
const;
232 assert(B &&
"BlockEntrance requires non-null block");
236 return reinterpret_cast<const CFGBlock*
>(getData1());
248 return Location.
getKind() == BlockEntranceKind;
258 return reinterpret_cast<const CFGBlock*
>(getData1());
262 return getBlock()->getTerminator();
269 return Location.
getKind() == BlockExitKind;
283 template <
typename T>
284 const T*
getStmtAs()
const {
return dyn_cast<T>(getStmt()); }
291 unsigned k = Location.
getKind();
292 return k >= PreStmtKind && k <= MaxPostStmtKind;
300 const Stmt *SubStmt =
nullptr)
301 :
StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
309 return Location.
getKind() == PreStmtKind;
327 :
StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
332 unsigned k = Location.
getKind();
333 return k >= MinPostStmtKind && k <= MaxPostStmtKind;
345 return &getLocationContext()->getCFG()->getExit();
349 return reinterpret_cast<const ReturnStmt *
>(getData1());
356 return Location.
getKind() == FunctionExitKind;
365 :
PostStmt(S, PostConditionKind, L, tag) {}
371 return Location.
getKind() == PostConditionKind;
385 unsigned k = location.
getKind();
386 return k == PreLoadKind || k == PreStoreKind;
400 return location.
getKind() == PreLoadKind;
414 return location.
getKind() == PreStoreKind;
422 :
PostStmt(S, PostLoadKind, L, tag) {}
428 return Location.
getKind() == PostLoadKind;
440 :
PostStmt(S, PostStoreKind, L, tag) {
441 assert(getData2() ==
nullptr);
455 return Location.
getKind() == PostStoreKind;
463 :
PostStmt(S, PostLValueKind, L, tag) {}
469 return Location.
getKind() == PostLValueKind;
479 :
StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
485 return Location.
getKind() == PreStmtPurgeDeadSymbolsKind;
495 :
StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
501 return Location.
getKind() == PostStmtPurgeDeadSymbolsKind;
509 assert(B1 &&
"BlockEdge: source block must be non-null");
510 assert(B2 &&
"BlockEdge: destination block must be non-null");
514 return static_cast<const CFGBlock*
>(getData1());
518 return static_cast<const CFGBlock*
>(getData2());
525 return Location.
getKind() == BlockEdgeKind;
554 return Location.
getKind() == PostInitializerKind;
577 return Location.
getKind() >= MinImplicitCallKind &&
578 Location.
getKind() <= MaxImplicitCallKind;
595 return Location.
getKind() == PreImplicitCallKind;
612 return Location.
getKind() == PostImplicitCallKind;
620 :
StmtPoint(S, nullptr, PostAllocatorCallKind, L, Tag) {}
626 return Location.
getKind() == PostAllocatorCallKind;
636 :
ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
639 return static_cast<const Stmt *
>(getData1());
649 const CFG *CalleeCFG = CalleeCtx->
getCFG();
657 return Location.
getKind() == CallEnterKind;
677 return static_cast<const ReturnStmt *
>(getData1());
684 return Location.
getKind() == CallExitBeginKind;
695 :
ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
705 return Location.
getKind() == CallExitEndKind;
721 return static_cast<const Stmt *
>(getData1());
728 return Location.
getKind() == LoopExitKind;
737 const void *Data2 =
nullptr,
741 const void *
getData()
const {
return getData1(); }
747 return Location.
getKind() == EpsilonKind;
static unsigned getHashValue(const clang::ProgramPoint &Loc)
PreLoad(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
LoopExit(const Stmt *LoopStmt, const LocationContext *LC)
const T * getStmtAs() const
static clang::ProgramPoint getTombstoneKey()
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
ProgramPointTag(void *tagKind=nullptr)
CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Stmt - This represents one statement.
BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, const Stmt *SubStmt=nullptr)
PostLValue(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
const CFGBlock * getSrc() const
Decl - This represents one declaration (or definition), e.g.
Represents a point when we begin processing an inlined call.
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
void setData2(const void *d)
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
Represents a program point just before an implicit call event.
const Stmt * getSubStmt() const
Optional< CFGElement > getFirstElement() const
Represents a point when we exit a loop.
BlockEntrance(const CFGBlock *B, const LocationContext *L, const ProgramPointTag *tag=nullptr)
Represents an implicit call event.
const void * getLocationValue() const
Returns the location of the field.
CallExitEnd(const StackFrameContext *CalleeCtx, const LocationContext *CallerCtx)
ProgramPoint(const void *P, Kind k, const LocationContext *l, const ProgramPointTag *tag=nullptr)
static clang::ProgramPoint getEmptyKey()
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
const Stmt * getCallExpr() const
PostStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
Represents a program point after a store evaluation.
PostInitializer(const CXXCtorInitializer *I, const void *Loc, const LocationContext *L)
Construct a PostInitializer point that represents a location after CXXCtorInitializer expression eval...
const StackFrameContext * getStackFrame() const
PostLoad(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
Represents a point when we start the call exit sequence (for inlined call).
SourceLocation getLocation() const
This is a meta program point, which should be skipped by all the diagnostic reasoning etc...
PostStmt(const Stmt *S, Kind k, const LocationContext *L, const ProgramPointTag *tag=nullptr)
const void * getLocationValue() const
Returns the information about the location used in the store, how it was uttered in the code...
void Profile(llvm::FoldingSetNodeID &ID) const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
static bool isEqual(const clang::ProgramPoint &L, const clang::ProgramPoint &R)
const void * getData() const
Represents a point after we ran remove dead bindings AFTER processing the given statement.
PostAllocatorCall(const Stmt *S, const LocationContext *L, const ProgramPointTag *Tag=nullptr)
const CFGBlock * getBlock() const
const CXXCtorInitializer * getInitializer() const
Represents a single basic block in a source-level CFG.
Represents a point when we finish the call exit sequence (for inlined call).
const CFGBlock * getBlock() const
const ReturnStmt * getStmt() const
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, const ProgramPointTag *tag)
EpsilonPoint(const LocationContext *L, const void *Data1, const void *Data2=nullptr, const ProgramPointTag *tag=nullptr)
virtual StringRef getTagDescription() const =0
const Stmt * getTerminator() const
const CFGBlock * getDst() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
PreStore(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l, const ProgramPointTag *tag=nullptr)
PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L, const ProgramPointTag *Tag=nullptr)
const Stmt * getStmt() const
unsigned getHashValue() const
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, const ProgramPointTag *tag=nullptr)
const Stmt * getLoopStmt() const
PostStore(const Stmt *S, const LocationContext *L, const void *Loc, const ProgramPointTag *tag=nullptr)
Construct the post store point.
Encodes a location in the source.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, const LocationContext *callerCtx)
const Decl * getDecl() const
BlockExit(const CFGBlock *B, const LocationContext *L)
const ReturnStmt * getReturnStmt() const
Dataflow Directional Tag Classes.
Represents a program point just after an implicit call event.
const StackFrameContext * getCalleeContext() const
const StackFrameContext * getCalleeContext() const
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
const CFGBlock * getBlock() const
const ProgramPointTag * getTag() const
PostCondition(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
const void * getTagKind()
Used to implement 'isKind' in subclasses.
ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K, const LocationContext *L, const ProgramPointTag *Tag)
PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag=nullptr)
Represents a C++ base or member initializer.
const void * getData2() const
LocationCheck(const Stmt *S, const LocationContext *L, ProgramPoint::Kind K, const ProgramPointTag *tag)
const LocationContext * getLocationContext() const
const StackFrameContext * getStackFrame() const
PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L, const ProgramPointTag *Tag=nullptr)
FunctionExitPoint(const ReturnStmt *S, const LocationContext *LC, const ProgramPointTag *tag=nullptr)
bool operator!=(const ProgramPoint &RHS) const
bool operator==(const ProgramPoint &RHS) const
const void * getData1() const
static Decl::Kind getKind(const Decl *D)
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
static SourceLocation getFromPtrEncoding(const void *Encoding)
Turn a pointer encoding of a SourceLocation object back into a real SourceLocation.
virtual ~ProgramPointTag()