clang 24.0.0git
ProgramPoint.h
Go to the documentation of this file.
1//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interface ProgramPoint, which identifies a
10// distinct location in a function.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
15#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
16
18#include "clang/Analysis/CFG.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/Casting.h"
24#include "llvm/Support/DataTypes.h"
25#include <cassert>
26#include <optional>
27#include <string>
28#include <utility>
29
30namespace clang {
31
33
34/// ProgramPoints can be "tagged" as representing points specific to a given
35/// analysis entity. Tags are abstract annotations, with an associated
36/// description and potentially other information.
38public:
39 ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
40 virtual ~ProgramPointTag();
41
42 /// The description of this program point which will be dumped for debugging
43 /// purposes. Do not use in user-facing output!
44 virtual StringRef getDebugTag() const = 0;
45
46 /// Used to implement 'isKind' in subclasses.
47 const void *getTagKind() const { return TagKind; }
48
49private:
50 const void *const TagKind;
51};
52
54 std::string Desc;
55public:
56 SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
57 StringRef getDebugTag() const override;
58};
59
61public:
92
93 static StringRef getProgramPointKindName(Kind K);
94 std::optional<SourceLocation> getSourceLocation() const;
95
96private:
97 const void *Data1;
98 llvm::PointerIntPair<const void *, 2, unsigned> Data2;
99
100 // The StackFrame could be NULL to allow ProgramPoint to be used in
101 // context insensitive analysis.
102 llvm::PointerIntPair<const StackFrame *, 2, unsigned> S;
103
104 llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
105
106 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};
107
108protected:
109 ProgramPoint() = default;
110 ProgramPoint(const void *P, Kind K, const StackFrame *SF,
111 const ProgramPointTag *T = nullptr,
112 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
113 : ProgramPoint(P, nullptr, K, SF, T, ElemRef) {}
114
115 ProgramPoint(const void *P1, const void *P2, Kind K, const StackFrame *SF,
116 const ProgramPointTag *T = nullptr,
117 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
118 : Data1(P1), Data2(P2, (((unsigned)K) >> 0) & 0x3),
119 S(SF, (((unsigned)K) >> 2) & 0x3), Tag(T, (((unsigned)K) >> 4) & 0x3),
120 ElemRef(ElemRef) {
121 assert(getKind() == K);
122 assert(getStackFrame() == SF);
123 assert(getData1() == P1);
124 assert(getData2() == P2);
125 }
126
127protected:
128 const void *getData1() const { return Data1; }
129 const void *getData2() const { return Data2.getPointer(); }
130 void setData2(const void *d) { Data2.setPointer(d); }
131 CFGBlock::ConstCFGElementRef getElementRef() const { return ElemRef; }
132
133public:
134 /// Create a new ProgramPoint object that is the same as the original
135 /// except for using the specified tag value.
138 tag);
139 }
140
141 /// Convert to the specified ProgramPoint type, asserting that this
142 /// ProgramPoint is of the desired type.
143 template<typename T>
144 T castAs() const {
145 assert(T::isKind(*this));
146 T t;
147 ProgramPoint& PP = t;
148 PP = *this;
149 return t;
150 }
151
152 /// Convert to the specified ProgramPoint type, returning std::nullopt if this
153 /// ProgramPoint is not of the desired type.
154 template <typename T> std::optional<T> getAs() const {
155 if (!T::isKind(*this))
156 return std::nullopt;
157 T t;
158 ProgramPoint& PP = t;
159 PP = *this;
160 return t;
161 }
162
163 Kind getKind() const {
164 unsigned x = Tag.getInt();
165 x <<= 2;
166 x |= S.getInt();
167 x <<= 2;
168 x |= Data2.getInt();
169 return (Kind) x;
170 }
171
172 /// Is this a program point corresponding to purge/removal of dead
173 /// symbols and bindings.
174 bool isPurgeKind() {
175 Kind K = getKind();
176 return (K == PostStmtPurgeDeadSymbolsKind ||
178 }
179
180 const ProgramPointTag *getTag() const { return Tag.getPointer(); }
181
182 const StackFrame *getStackFrame() const { return S.getPointer(); }
183
184 // For use with DenseMap. This hash is probably slow.
185 unsigned getHashValue() const {
186 llvm::FoldingSetNodeID ID;
187 Profile(ID);
188 return ID.computeHash();
189 }
190
191 bool operator==(const ProgramPoint & RHS) const {
192 return Data1 == RHS.Data1 && Data2 == RHS.Data2 && S == RHS.S &&
193 Tag == RHS.Tag && ElemRef == RHS.ElemRef;
194 }
195
196 bool operator!=(const ProgramPoint &RHS) const {
197 return Data1 != RHS.Data1 || Data2 != RHS.Data2 || S != RHS.S ||
198 Tag != RHS.Tag || ElemRef != RHS.ElemRef;
199 }
200
201 void Profile(llvm::FoldingSetNodeID& ID) const {
202 ID.AddInteger((unsigned) getKind());
203 ID.AddPointer(getData1());
204 ID.AddPointer(getData2());
205 ID.AddPointer(getStackFrame());
206 ID.AddPointer(getTag());
207 ID.AddPointer(ElemRef.getParent());
208 ID.AddInteger(ElemRef.getIndexInBlock());
209 }
210
211 void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const;
212
213 LLVM_DUMP_METHOD void dump() const;
214
216 const StackFrame *SF,
217 const ProgramPointTag *tag);
218};
219
221public:
222 BlockEntrance(const CFGBlock *PrevBlock, const CFGBlock *CurrBlock,
223 const StackFrame *SF, const ProgramPointTag *Tag = nullptr)
224 : ProgramPoint(CurrBlock, PrevBlock, BlockEntranceKind, SF, Tag) {
225 assert(CurrBlock && "BlockEntrance requires non-null block");
226 }
227
228 const CFGBlock *getPreviousBlock() const {
229 return reinterpret_cast<const CFGBlock *>(getData2());
230 }
231
232 const CFGBlock *getBlock() const {
233 return reinterpret_cast<const CFGBlock*>(getData1());
234 }
235
236 std::optional<CFGElement> getFirstElement() const {
237 const CFGBlock *B = getBlock();
238 return B->empty() ? std::optional<CFGElement>() : B->front();
239 }
240
241private:
242 friend class ProgramPoint;
243 BlockEntrance() = default;
244 static bool isKind(const ProgramPoint &Location) {
245 return Location.getKind() == BlockEntranceKind;
246 }
247};
248
249class BlockExit : public ProgramPoint {
250public:
251 BlockExit(const CFGBlock *B, const StackFrame *SF)
252 : ProgramPoint(B, BlockExitKind, SF) {}
253
254 const CFGBlock *getBlock() const {
255 return reinterpret_cast<const CFGBlock*>(getData1());
256 }
257
258 const Stmt *getTerminator() const {
259 return getBlock()->getTerminatorStmt();
260 }
261
262private:
263 friend class ProgramPoint;
264 BlockExit() = default;
265 static bool isKind(const ProgramPoint &Location) {
266 return Location.getKind() == BlockExitKind;
267 }
268};
269
270// FIXME: Eventually we want to take a CFGElementRef as parameter here too.
271class StmtPoint : public ProgramPoint {
272public:
273 StmtPoint(const Stmt *S, const void *p2, Kind k, const StackFrame *SF,
274 const ProgramPointTag *tag)
275 : ProgramPoint(S, p2, k, SF, tag) {
276 assert(S);
277 }
278
279 const Stmt *getStmt() const { return (const Stmt*) getData1(); }
280
281 template <typename T>
282 const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
283
284protected:
285 StmtPoint() = default;
286private:
287 friend class ProgramPoint;
288 static bool isKind(const ProgramPoint &Location) {
289 unsigned k = Location.getKind();
290 return k >= PreStmtKind && k <= MaxPostStmtKind;
291 }
292};
293
294
295class PreStmt : public StmtPoint {
296public:
297 PreStmt(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag,
298 const Stmt *SubStmt = nullptr)
299 : StmtPoint(S, SubStmt, PreStmtKind, SF, tag) {}
300
301 const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
302
303private:
304 friend class ProgramPoint;
305 PreStmt() = default;
306 static bool isKind(const ProgramPoint &Location) {
307 return Location.getKind() == PreStmtKind;
308 }
309};
310
311class PostStmt : public StmtPoint {
312protected:
313 PostStmt() = default;
314 PostStmt(const Stmt *S, const void *data, Kind k, const StackFrame *SF,
315 const ProgramPointTag *tag = nullptr)
316 : StmtPoint(S, data, k, SF, tag) {}
317
318public:
319 explicit PostStmt(const Stmt *S, Kind k, const StackFrame *SF,
320 const ProgramPointTag *tag = nullptr)
321 : StmtPoint(S, nullptr, k, SF, tag) {}
322
323 explicit PostStmt(const Stmt *S, const StackFrame *SF,
324 const ProgramPointTag *tag = nullptr)
325 : StmtPoint(S, nullptr, PostStmtKind, SF, tag) {}
326
327private:
328 friend class ProgramPoint;
329 static bool isKind(const ProgramPoint &Location) {
330 unsigned k = Location.getKind();
331 return k >= MinPostStmtKind && k <= MaxPostStmtKind;
332 }
333};
334
336public:
337 explicit FunctionExitPoint(const ReturnStmt *S, const StackFrame *SF,
338 const ProgramPointTag *tag = nullptr)
339 : ProgramPoint(S, FunctionExitKind, SF, tag) {}
340
341 const CFGBlock *getBlock() const {
342 return &getStackFrame()->getCFG()->getExit();
343 }
344
345 const ReturnStmt *getStmt() const {
346 return reinterpret_cast<const ReturnStmt *>(getData1());
347 }
348
349private:
350 friend class ProgramPoint;
351 FunctionExitPoint() = default;
352 static bool isKind(const ProgramPoint &Location) {
353 return Location.getKind() == FunctionExitKind;
354 }
355};
356
357// PostCondition represents the post program point of a branch condition.
358class PostCondition : public PostStmt {
359public:
360 PostCondition(const Stmt *S, const StackFrame *SF,
361 const ProgramPointTag *tag = nullptr)
362 : PostStmt(S, PostConditionKind, SF, tag) {}
363
364private:
365 friend class ProgramPoint;
366 PostCondition() = default;
367 static bool isKind(const ProgramPoint &Location) {
368 return Location.getKind() == PostConditionKind;
369 }
370};
371
372class LocationCheck : public StmtPoint {
373protected:
374 LocationCheck() = default;
376 const ProgramPointTag *tag)
377 : StmtPoint(S, nullptr, K, SF, tag) {}
378
379private:
380 friend class ProgramPoint;
381 static bool isKind(const ProgramPoint &location) {
382 unsigned k = location.getKind();
383 return k == PreLoadKind || k == PreStoreKind;
384 }
385};
386
387class PreLoad : public LocationCheck {
388public:
389 PreLoad(const Stmt *S, const StackFrame *SF,
390 const ProgramPointTag *tag = nullptr)
391 : LocationCheck(S, SF, PreLoadKind, tag) {}
392
393private:
394 friend class ProgramPoint;
395 PreLoad() = default;
396 static bool isKind(const ProgramPoint &location) {
397 return location.getKind() == PreLoadKind;
398 }
399};
400
401class PreStore : public LocationCheck {
402public:
403 PreStore(const Stmt *S, const StackFrame *SF,
404 const ProgramPointTag *tag = nullptr)
405 : LocationCheck(S, SF, PreStoreKind, tag) {}
406
407private:
408 friend class ProgramPoint;
409 PreStore() = default;
410 static bool isKind(const ProgramPoint &location) {
411 return location.getKind() == PreStoreKind;
412 }
413};
414
415class PostLoad : public PostStmt {
416public:
417 PostLoad(const Stmt *S, const StackFrame *SF,
418 const ProgramPointTag *tag = nullptr)
419 : PostStmt(S, PostLoadKind, SF, tag) {}
420
421private:
422 friend class ProgramPoint;
423 PostLoad() = default;
424 static bool isKind(const ProgramPoint &Location) {
425 return Location.getKind() == PostLoadKind;
426 }
427};
428
429/// Represents a program point after a store evaluation.
430class PostStore : public PostStmt {
431public:
432 /// Construct the post store point.
433 /// \param Loc can be used to store the information about the location
434 /// used in the form it was uttered in the code.
435 PostStore(const Stmt *S, const StackFrame *SF, const void *Loc,
436 const ProgramPointTag *tag = nullptr)
437 : PostStmt(S, PostStoreKind, SF, tag) {
438 assert(getData2() == nullptr);
439 setData2(Loc);
440 }
441
442 /// Returns the information about the location used in the store,
443 /// how it was uttered in the code.
444 const void *getLocationValue() const {
445 return getData2();
446 }
447
448private:
449 friend class ProgramPoint;
450 PostStore() = default;
451 static bool isKind(const ProgramPoint &Location) {
452 return Location.getKind() == PostStoreKind;
453 }
454};
455
456class PostLValue : public PostStmt {
457public:
458 PostLValue(const Stmt *S, const StackFrame *SF,
459 const ProgramPointTag *tag = nullptr)
460 : PostStmt(S, PostLValueKind, SF, tag) {}
461
462private:
463 friend class ProgramPoint;
464 PostLValue() = default;
465 static bool isKind(const ProgramPoint &Location) {
466 return Location.getKind() == PostLValueKind;
467 }
468};
469
470/// Represents a point after we ran remove dead bindings BEFORE
471/// processing the given statement.
473public:
475 const ProgramPointTag *tag = nullptr)
477
478private:
479 friend class ProgramPoint;
480 PreStmtPurgeDeadSymbols() = default;
481 static bool isKind(const ProgramPoint &Location) {
482 return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
483 }
484};
485
486/// Represents a point after we ran remove dead bindings AFTER
487/// processing the given statement.
489public:
491 const ProgramPointTag *tag = nullptr)
493
494private:
495 friend class ProgramPoint;
496 PostStmtPurgeDeadSymbols() = default;
497 static bool isKind(const ProgramPoint &Location) {
498 return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
499 }
500};
501
502class BlockEdge : public ProgramPoint {
503public:
504 BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const StackFrame *SF)
505 : ProgramPoint(B1, B2, BlockEdgeKind, SF) {
506 assert(B1 && "BlockEdge: source block must be non-null");
507 assert(B2 && "BlockEdge: destination block must be non-null");
508 }
509
510 const CFGBlock *getSrc() const {
511 return static_cast<const CFGBlock*>(getData1());
512 }
513
514 const CFGBlock *getDst() const {
515 return static_cast<const CFGBlock*>(getData2());
516 }
517
518private:
519 friend class ProgramPoint;
520 BlockEdge() = default;
521 static bool isKind(const ProgramPoint &Location) {
522 return Location.getKind() == BlockEdgeKind;
523 }
524};
525
527public:
528 /// Construct a PostInitializer point that represents a location after
529 /// CXXCtorInitializer expression evaluation.
530 ///
531 /// \param I The initializer.
532 /// \param Loc The location of the field being initialized.
533 PostInitializer(const CXXCtorInitializer *I, const void *Loc,
534 const StackFrame *SF)
535 : ProgramPoint(I, Loc, PostInitializerKind, SF) {}
536
538 return static_cast<const CXXCtorInitializer *>(getData1());
539 }
540
541 /// Returns the location of the field.
542 const void *getLocationValue() const {
543 return getData2();
544 }
545
546private:
547 friend class ProgramPoint;
548 PostInitializer() = default;
549 static bool isKind(const ProgramPoint &Location) {
550 return Location.getKind() == PostInitializerKind;
551 }
552};
553
554/// Represents an implicit call event.
555///
556/// The nearest statement is provided for diagnostic purposes.
558public:
560 const StackFrame *SF, const ProgramPointTag *Tag,
562 : ProgramPoint(Loc.getPtrEncoding(), D, K, SF, Tag, ElemRef) {}
563
564 const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
568
569protected:
570 ImplicitCallPoint() = default;
571private:
572 friend class ProgramPoint;
573 static bool isKind(const ProgramPoint &Location) {
574 return Location.getKind() >= MinImplicitCallKind &&
575 Location.getKind() <= MaxImplicitCallKind;
576 }
577};
578
579/// Represents a program point just before an implicit call event.
580///
581/// Explicit calls will appear as PreStmt program points.
583public:
586 const ProgramPointTag *Tag = nullptr)
587 : ImplicitCallPoint(D, Loc, PreImplicitCallKind, SF, Tag, ElemRef) {}
588
589private:
590 friend class ProgramPoint;
591 PreImplicitCall() = default;
592 static bool isKind(const ProgramPoint &Location) {
593 return Location.getKind() == PreImplicitCallKind;
594 }
595};
596
597/// Represents a program point just after an implicit call event.
598///
599/// Explicit calls will appear as PostStmt program points.
601public:
604 const ProgramPointTag *Tag = nullptr)
605 : ImplicitCallPoint(D, Loc, PostImplicitCallKind, SF, Tag, ElemRef) {}
606
607private:
608 friend class ProgramPoint;
609 PostImplicitCall() = default;
610 static bool isKind(const ProgramPoint &Location) {
611 return Location.getKind() == PostImplicitCallKind;
612 }
613};
614
616public:
617 PostAllocatorCall(const Stmt *S, const StackFrame *SF,
618 const ProgramPointTag *Tag = nullptr)
619 : StmtPoint(S, nullptr, PostAllocatorCallKind, SF, Tag) {}
620
621private:
622 friend class ProgramPoint;
623 PostAllocatorCall() = default;
624 static bool isKind(const ProgramPoint &Location) {
625 return Location.getKind() == PostAllocatorCallKind;
626 }
627};
628
629/// Represents a point when we begin processing an inlined call.
630/// CallEnter uses the caller's stack frame.
631class CallEnter : public ProgramPoint {
632public:
633 CallEnter(const Stmt *stmt, const StackFrame *CalleeSF,
634 const StackFrame *CallerSF)
635 : ProgramPoint(stmt, CalleeSF, CallEnterKind, CallerSF, nullptr) {}
636
637 const Stmt *getCallExpr() const {
638 return static_cast<const Stmt *>(getData1());
639 }
640
642 return static_cast<const StackFrame *>(getData2());
643 }
644
645 /// Returns the entry block in the CFG for the entered function.
646 const CFGBlock *getEntry() const {
647 const StackFrame *CalleeSF = getCalleeStackFrame();
648 const CFG *CalleeCFG = CalleeSF->getCFG();
649 return &(CalleeCFG->getEntry());
650 }
651
652private:
653 friend class ProgramPoint;
654 CallEnter() = default;
655 static bool isKind(const ProgramPoint &Location) {
656 return Location.getKind() == CallEnterKind;
657 }
658};
659
660/// Represents a point when we start the call exit sequence (for inlined call).
661///
662/// The call exit is simulated with a sequence of nodes, which occur between
663/// CallExitBegin and CallExitEnd. The following operations occur between the
664/// two program points:
665/// - CallExitBegin
666/// - Bind the return value
667/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
668/// - CallExitEnd
670public:
671 // CallExitBegin uses the callee's stack frame.
674
675 const ReturnStmt *getReturnStmt() const {
676 return static_cast<const ReturnStmt *>(getData1());
677 }
678
679private:
680 friend class ProgramPoint;
681 CallExitBegin() = default;
682 static bool isKind(const ProgramPoint &Location) {
683 return Location.getKind() == CallExitBeginKind;
684 }
685};
686
687/// Represents a point when we finish the call exit sequence (for inlined call).
688/// \sa CallExitBegin
689class CallExitEnd : public ProgramPoint {
690public:
691 // CallExitEnd uses the caller's stack frame.
692 CallExitEnd(const StackFrame *CalleeSF, const StackFrame *CallerSF)
693 : ProgramPoint(CalleeSF, CallExitEndKind, CallerSF, nullptr) {}
694
696 return static_cast<const StackFrame *>(getData1());
697 }
698
699private:
700 friend class ProgramPoint;
701 CallExitEnd() = default;
702 static bool isKind(const ProgramPoint &Location) {
703 return Location.getKind() == CallExitEndKind;
704 }
705};
706
707/// Represents a point when we exit a loop.
708/// When this ProgramPoint is encountered we can be sure that the symbolic
709/// execution of the corresponding LoopStmt is finished on the given path.
710/// Note: It is possible to encounter a LoopExit element when we haven't even
711/// encountered the loop itself. At the current state not all loop exits will
712/// result in a LoopExit program point.
713class LoopExit : public ProgramPoint {
714public:
715 LoopExit(const Stmt *LoopStmt, const StackFrame *SF)
716 : ProgramPoint(LoopStmt, nullptr, LoopExitKind, SF) {}
717
718 const Stmt *getLoopStmt() const {
719 return static_cast<const Stmt *>(getData1());
720 }
721
722private:
723 friend class ProgramPoint;
724 LoopExit() = default;
725 static bool isKind(const ProgramPoint &Location) {
726 return Location.getKind() == LoopExitKind;
727 }
728};
729
730/// Represents a point when the lifetime of an automatic object ends.
731class LifetimeEnd : public ProgramPoint {
732public:
733 LifetimeEnd(const Stmt *S, const VarDecl *D, const StackFrame *SF)
734 : ProgramPoint(S, D, LifetimeEndKind, SF) {}
735
736 LLVM_ATTRIBUTE_RETURNS_NONNULL const Stmt *getTriggerStmt() const {
737 return static_cast<const Stmt *>(getData1());
738 }
739
740 /// Returns the variable declaration whose lifetime has ended.
741 LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl *getDecl() const {
742 return static_cast<const VarDecl *>(getData2());
743 }
744
745private:
746 friend class ProgramPoint;
747 LifetimeEnd() = default;
748 static bool isKind(const ProgramPoint &Location) {
749 return Location.getKind() == LifetimeEndKind;
750 }
751};
752
753/// This is a meta program point, which should be skipped by all the diagnostic
754/// reasoning etc.
756public:
757 EpsilonPoint(const StackFrame *SF, const void *Data1,
758 const void *Data2 = nullptr,
759 const ProgramPointTag *tag = nullptr)
760 : ProgramPoint(Data1, Data2, EpsilonKind, SF, tag) {}
761
762 const void *getData() const { return getData1(); }
763
764private:
765 friend class ProgramPoint;
766 EpsilonPoint() = default;
767 static bool isKind(const ProgramPoint &Location) {
768 return Location.getKind() == EpsilonKind;
769 }
770};
771
772} // end namespace clang
773
774
775namespace llvm { // Traits specialization for DenseMap
776
777template <> struct DenseMapInfo<clang::ProgramPoint> {
778
779static unsigned getHashValue(const clang::ProgramPoint &Loc) {
780 return Loc.getHashValue();
781}
782
783static bool isEqual(const clang::ProgramPoint &L,
784 const clang::ProgramPoint &R) {
785 return L == R;
786}
787
788};
789
790} // end namespace llvm
791
792#endif
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const CFGBlock * getSrc() const
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const CFGBlock * getDst() const
BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const StackFrame *SF)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
std::optional< CFGElement > getFirstElement() const
BlockEntrance(const CFGBlock *PrevBlock, const CFGBlock *CurrBlock, const StackFrame *SF, const ProgramPointTag *Tag=nullptr)
const CFGBlock * getPreviousBlock() const
const CFGBlock * getBlock() const
const CFGBlock * getBlock() const
const Stmt * getTerminator() const
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
BlockExit(const CFGBlock *B, const StackFrame *SF)
Represents a single basic block in a source-level CFG.
Definition CFG.h:652
CFGElement front() const
Definition CFG.h:963
bool empty() const
Definition CFG.h:1009
ElementRefImpl< true > ConstCFGElementRef
Definition CFG.h:977
Stmt * getTerminatorStmt()
Definition CFG.h:1148
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1295
CFGBlock & getExit()
Definition CFG.h:1411
CFGBlock & getEntry()
Definition CFG.h:1409
Represents a C++ base or member initializer.
Definition DeclCXX.h:2407
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
CallEnter(const Stmt *stmt, const StackFrame *CalleeSF, const StackFrame *CallerSF)
const StackFrame * getCalleeStackFrame() const
const Stmt * getCallExpr() const
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
CallExitBegin(const StackFrame *SF, const ReturnStmt *RS)
const ReturnStmt * getReturnStmt() const
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const StackFrame * getCalleeStackFrame() const
CallExitEnd(const StackFrame *CalleeSF, const StackFrame *CallerSF)
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
EpsilonPoint(const StackFrame *SF, const void *Data1, const void *Data2=nullptr, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const void * getData() const
const CFGBlock * getBlock() const
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const ReturnStmt * getStmt() const
FunctionExitPoint(const ReturnStmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
SourceLocation getLocation() const
const Decl * getDecl() const
ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K, const StackFrame *SF, const ProgramPointTag *Tag, CFGBlock::ConstCFGElementRef ElemRef)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
LifetimeEnd(const Stmt *S, const VarDecl *D, const StackFrame *SF)
LLVM_ATTRIBUTE_RETURNS_NONNULL const Stmt * getTriggerStmt() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const
Returns the variable declaration whose lifetime has ended.
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
LocationCheck(const Stmt *S, const StackFrame *SF, ProgramPoint::Kind K, const ProgramPointTag *tag)
LoopExit(const Stmt *LoopStmt, const StackFrame *SF)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const Stmt * getLoopStmt() const
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostAllocatorCall(const Stmt *S, const StackFrame *SF, const ProgramPointTag *Tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostCondition(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostImplicitCall(const Decl *D, SourceLocation Loc, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef, const ProgramPointTag *Tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const void * getLocationValue() const
Returns the location of the field.
const CXXCtorInitializer * getInitializer() const
PostInitializer(const CXXCtorInitializer *I, const void *Loc, const StackFrame *SF)
Construct a PostInitializer point that represents a location after CXXCtorInitializer expression eval...
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostLValue(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostLoad(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
PostStmtPurgeDeadSymbols(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PostStmt(const Stmt *S, Kind k, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
PostStmt(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
PostStmt(const Stmt *S, const void *data, Kind k, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
PostStmt()=default
PostStore(const Stmt *S, const StackFrame *SF, const void *Loc, const ProgramPointTag *tag=nullptr)
Construct the post store point.
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const void * getLocationValue() const
Returns the information about the location used in the store, how it was uttered in the code.
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PreImplicitCall(const Decl *D, SourceLocation Loc, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef, const ProgramPointTag *Tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PreLoad(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
PreStmtPurgeDeadSymbols(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
const Stmt * getSubStmt() const
PreStmt(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag, const Stmt *SubStmt=nullptr)
PreStore(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag=nullptr)
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
const void * getTagKind() const
Used to implement 'isKind' in subclasses.
virtual StringRef getDebugTag() const =0
The description of this program point which will be dumped for debugging purposes.
ProgramPointTag(void *tagKind=nullptr)
const ProgramPointTag * getTag() const
Kind getKind() const
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const StackFrame *SF, const ProgramPointTag *tag)
static StringRef getProgramPointKindName(Kind K)
ProgramPoint()=default
LLVM_DUMP_METHOD void dump() const
CFGBlock::ConstCFGElementRef getElementRef() const
std::optional< SourceLocation > getSourceLocation() const
void Profile(llvm::FoldingSetNodeID &ID) const
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
void setData2(const void *d)
ProgramPoint(const void *P1, const void *P2, Kind K, const StackFrame *SF, const ProgramPointTag *T=nullptr, CFGBlock::ConstCFGElementRef ElemRef={nullptr, 0})
bool operator!=(const ProgramPoint &RHS) const
bool operator==(const ProgramPoint &RHS) const
unsigned getHashValue() const
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
const void * getData1() const
const StackFrame * getStackFrame() const
ProgramPoint(const void *P, Kind K, const StackFrame *SF, const ProgramPointTag *T=nullptr, CFGBlock::ConstCFGElementRef ElemRef={nullptr, 0})
const void * getData2() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3172
StringRef getDebugTag() const override
The description of this program point which will be dumped for debugging purposes.
SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg)
Encodes a location in the source.
static SourceLocation getFromPtrEncoding(const void *Encoding)
Turn a pointer encoding of a SourceLocation object back into a real SourceLocation.
It represents a stack frame of the call stack.
StmtPoint()=default
friend class ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
StmtPoint(const Stmt *S, const void *p2, Kind k, const StackFrame *SF, const ProgramPointTag *tag)
const Stmt * getStmt() const
const T * getStmtAs() const
Stmt - This represents one statement.
Definition Stmt.h:85
Represents a variable declaration or definition.
Definition Decl.h:933
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Top level wrappers for InstallAPI frontend operations.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
static bool isEqual(const clang::ProgramPoint &L, const clang::ProgramPoint &R)
static unsigned getHashValue(const clang::ProgramPoint &Loc)