14 #ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H 15 #define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/FoldingSet.h" 21 #include "llvm/ADT/Optional.h" 22 #include "llvm/ADT/PointerIntPair.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/DataTypes.h" 32 class AnalysisDeclContext;
34 class LocationContext;
49 const void *
const TagKind;
75 MinPostStmtKind = PostStmtKind,
76 MaxPostStmtKind = PostAllocatorCallKind,
84 MinImplicitCallKind = PreImplicitCallKind,
85 MaxImplicitCallKind = PostImplicitCallKind,
91 llvm::PointerIntPair<const void *, 2, unsigned> Data2;
95 llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
97 llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
106 Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
107 L(l, (((unsigned) k) >> 2) & 0x3),
108 Tag(tag, (((unsigned) k) >> 4) & 0x3) {
110 assert(getLocationContext() == l);
111 assert(getData1() == P);
120 Data2(P2, (((unsigned) k) >> 0) & 0x3),
121 L(l, (((unsigned) k) >> 2) & 0x3),
122 Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
126 const void *
getData2()
const {
return Data2.getPointer(); }
127 void setData2(
const void *d) { Data2.setPointer(d); }
134 getLocationContext(), tag);
141 assert(T::isKind(*
this));
152 if (!T::isKind(*
this))
161 unsigned x = Tag.getInt();
173 return (K == PostStmtPurgeDeadSymbolsKind ||
174 K == PreStmtPurgeDeadSymbolsKind);
180 return L.getPointer();
189 llvm::FoldingSetNodeID
ID;
191 return ID.ComputeHash();
195 return Data1 == RHS.Data1 &&
196 Data2 == RHS.Data2 &&
202 return Data1 != RHS.Data1 ||
203 Data2 != RHS.Data2 ||
209 ID.AddInteger((
unsigned)
getKind());
210 ID.AddPointer(getData1());
211 ID.AddPointer(getData2());
212 ID.AddPointer(getLocationContext());
213 ID.AddPointer(getTag());
216 void printJson(llvm::raw_ostream &Out,
const char *NL =
"\n")
const;
218 LLVM_DUMP_METHOD
void dump()
const;
230 assert(B &&
"BlockEntrance requires non-null block");
234 return reinterpret_cast<const CFGBlock*
>(getData1());
246 return Location.
getKind() == BlockEntranceKind;
256 return reinterpret_cast<const CFGBlock*
>(getData1());
260 return getBlock()->getTerminatorStmt();
267 return Location.
getKind() == BlockExitKind;
281 template <
typename T>
282 const T*
getStmtAs()
const {
return dyn_cast<T>(getStmt()); }
289 unsigned k = Location.
getKind();
290 return k >= PreStmtKind && k <= MaxPostStmtKind;
298 const Stmt *SubStmt =
nullptr)
299 :
StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
307 return Location.
getKind() == PreStmtKind;
325 :
StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
330 unsigned k = Location.
getKind();
331 return k >= MinPostStmtKind && k <= MaxPostStmtKind;
343 return &getLocationContext()->getCFG()->getExit();
347 return reinterpret_cast<const ReturnStmt *
>(getData1());
354 return Location.
getKind() == FunctionExitKind;
363 :
PostStmt(S, PostConditionKind, L, tag) {}
369 return Location.
getKind() == PostConditionKind;
383 unsigned k = location.
getKind();
384 return k == PreLoadKind || k == PreStoreKind;
398 return location.
getKind() == PreLoadKind;
412 return location.
getKind() == PreStoreKind;
420 :
PostStmt(S, PostLoadKind, L, tag) {}
426 return Location.
getKind() == PostLoadKind;
438 :
PostStmt(S, PostStoreKind, L, tag) {
439 assert(getData2() ==
nullptr);
453 return Location.
getKind() == PostStoreKind;
461 :
PostStmt(S, PostLValueKind, L, tag) {}
467 return Location.
getKind() == PostLValueKind;
477 :
StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
483 return Location.
getKind() == PreStmtPurgeDeadSymbolsKind;
493 :
StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
499 return Location.
getKind() == PostStmtPurgeDeadSymbolsKind;
507 assert(B1 &&
"BlockEdge: source block must be non-null");
508 assert(B2 &&
"BlockEdge: destination block must be non-null");
512 return static_cast<const CFGBlock*
>(getData1());
516 return static_cast<const CFGBlock*
>(getData2());
523 return Location.
getKind() == BlockEdgeKind;
552 return Location.
getKind() == PostInitializerKind;
575 return Location.
getKind() >= MinImplicitCallKind &&
576 Location.
getKind() <= MaxImplicitCallKind;
593 return Location.
getKind() == PreImplicitCallKind;
610 return Location.
getKind() == PostImplicitCallKind;
618 :
StmtPoint(S, nullptr, PostAllocatorCallKind, L, Tag) {}
624 return Location.
getKind() == PostAllocatorCallKind;
634 :
ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
637 return static_cast<const Stmt *
>(getData1());
647 const CFG *CalleeCFG = CalleeCtx->
getCFG();
655 return Location.
getKind() == CallEnterKind;
675 return static_cast<const ReturnStmt *
>(getData1());
682 return Location.
getKind() == CallExitBeginKind;
693 :
ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
703 return Location.
getKind() == CallExitEndKind;
719 return static_cast<const Stmt *
>(getData1());
726 return Location.
getKind() == LoopExitKind;
735 const void *Data2 =
nullptr,
739 const void *
getData()
const {
return getData1(); }
745 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)
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
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)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
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)
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)
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()
const void * getTagKind() const
Used to implement 'isKind' in subclasses.