clang 23.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:
89
90 static StringRef getProgramPointKindName(Kind K);
91 std::optional<SourceLocation> getSourceLocation() const;
92
93private:
94 const void *Data1;
95 llvm::PointerIntPair<const void *, 2, unsigned> Data2;
96
97 // The StackFrame could be NULL to allow ProgramPoint to be used in
98 // context insensitive analysis.
99 llvm::PointerIntPair<const StackFrame *, 2, unsigned> S;
100
101 llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
102
103 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};
104
105protected:
106 ProgramPoint() = default;
107 ProgramPoint(const void *P, Kind k, const StackFrame *SF,
108 const ProgramPointTag *tag = nullptr,
109 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
110 : Data1(P), Data2(nullptr, (((unsigned)k) >> 0) & 0x3),
111 S(SF, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
112 ElemRef(ElemRef) {
113 assert(getKind() == k);
114 assert(getStackFrame() == SF);
115 assert(getData1() == P);
116 }
117
118 ProgramPoint(const void *P1, const void *P2, Kind k, const StackFrame *SF,
119 const ProgramPointTag *tag = nullptr,
120 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
121 : Data1(P1), Data2(P2, (((unsigned)k) >> 0) & 0x3),
122 S(SF, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
123 ElemRef(ElemRef) {}
124
125protected:
126 const void *getData1() const { return Data1; }
127 const void *getData2() const { return Data2.getPointer(); }
128 void setData2(const void *d) { Data2.setPointer(d); }
129 CFGBlock::ConstCFGElementRef getElementRef() const { return ElemRef; }
130
131public:
132 /// Create a new ProgramPoint object that is the same as the original
133 /// except for using the specified tag value.
136 tag);
137 }
138
139 /// Convert to the specified ProgramPoint type, asserting that this
140 /// ProgramPoint is of the desired type.
141 template<typename T>
142 T castAs() const {
143 assert(T::isKind(*this));
144 T t;
145 ProgramPoint& PP = t;
146 PP = *this;
147 return t;
148 }
149
150 /// Convert to the specified ProgramPoint type, returning std::nullopt if this
151 /// ProgramPoint is not of the desired type.
152 template <typename T> std::optional<T> getAs() const {
153 if (!T::isKind(*this))
154 return std::nullopt;
155 T t;
156 ProgramPoint& PP = t;
157 PP = *this;
158 return t;
159 }
160
161 Kind getKind() const {
162 unsigned x = Tag.getInt();
163 x <<= 2;
164 x |= S.getInt();
165 x <<= 2;
166 x |= Data2.getInt();
167 return (Kind) x;
168 }
169
170 /// Is this a program point corresponding to purge/removal of dead
171 /// symbols and bindings.
172 bool isPurgeKind() {
173 Kind K = getKind();
174 return (K == PostStmtPurgeDeadSymbolsKind ||
176 }
177
178 const ProgramPointTag *getTag() const { return Tag.getPointer(); }
179
180 const StackFrame *getStackFrame() const { return S.getPointer(); }
181
182 // For use with DenseMap. This hash is probably slow.
183 unsigned getHashValue() const {
184 llvm::FoldingSetNodeID ID;
185 Profile(ID);
186 return ID.ComputeHash();
187 }
188
189 bool operator==(const ProgramPoint & RHS) const {
190 return Data1 == RHS.Data1 && Data2 == RHS.Data2 && S == RHS.S &&
191 Tag == RHS.Tag && ElemRef == RHS.ElemRef;
192 }
193
194 bool operator!=(const ProgramPoint &RHS) const {
195 return Data1 != RHS.Data1 || Data2 != RHS.Data2 || S != RHS.S ||
196 Tag != RHS.Tag || ElemRef != RHS.ElemRef;
197 }
198
199 void Profile(llvm::FoldingSetNodeID& ID) const {
200 ID.AddInteger((unsigned) getKind());
201 ID.AddPointer(getData1());
202 ID.AddPointer(getData2());
203 ID.AddPointer(getStackFrame());
204 ID.AddPointer(getTag());
205 ID.AddPointer(ElemRef.getParent());
206 ID.AddInteger(ElemRef.getIndexInBlock());
207 }
208
209 void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const;
210
211 LLVM_DUMP_METHOD void dump() const;
212
214 const StackFrame *SF,
215 const ProgramPointTag *tag);
216};
217
219public:
220 BlockEntrance(const CFGBlock *PrevBlock, const CFGBlock *CurrBlock,
221 const StackFrame *SF, const ProgramPointTag *Tag = nullptr)
222 : ProgramPoint(CurrBlock, PrevBlock, BlockEntranceKind, SF, Tag) {
223 assert(CurrBlock && "BlockEntrance requires non-null block");
224 }
225
226 const CFGBlock *getPreviousBlock() const {
227 return reinterpret_cast<const CFGBlock *>(getData2());
228 }
229
230 const CFGBlock *getBlock() const {
231 return reinterpret_cast<const CFGBlock*>(getData1());
232 }
233
234 std::optional<CFGElement> getFirstElement() const {
235 const CFGBlock *B = getBlock();
236 return B->empty() ? std::optional<CFGElement>() : B->front();
237 }
238
239private:
240 friend class ProgramPoint;
241 BlockEntrance() = default;
242 static bool isKind(const ProgramPoint &Location) {
243 return Location.getKind() == BlockEntranceKind;
244 }
245};
246
247class BlockExit : public ProgramPoint {
248public:
249 BlockExit(const CFGBlock *B, const StackFrame *SF)
250 : ProgramPoint(B, BlockExitKind, SF) {}
251
252 const CFGBlock *getBlock() const {
253 return reinterpret_cast<const CFGBlock*>(getData1());
254 }
255
256 const Stmt *getTerminator() const {
257 return getBlock()->getTerminatorStmt();
258 }
259
260private:
261 friend class ProgramPoint;
262 BlockExit() = default;
263 static bool isKind(const ProgramPoint &Location) {
264 return Location.getKind() == BlockExitKind;
265 }
266};
267
268// FIXME: Eventually we want to take a CFGElementRef as parameter here too.
269class StmtPoint : public ProgramPoint {
270public:
271 StmtPoint(const Stmt *S, const void *p2, Kind k, const StackFrame *SF,
272 const ProgramPointTag *tag)
273 : ProgramPoint(S, p2, k, SF, tag) {
274 assert(S);
275 }
276
277 const Stmt *getStmt() const { return (const Stmt*) getData1(); }
278
279 template <typename T>
280 const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
281
282protected:
283 StmtPoint() = default;
284private:
285 friend class ProgramPoint;
286 static bool isKind(const ProgramPoint &Location) {
287 unsigned k = Location.getKind();
288 return k >= PreStmtKind && k <= MaxPostStmtKind;
289 }
290};
291
292
293class PreStmt : public StmtPoint {
294public:
295 PreStmt(const Stmt *S, const StackFrame *SF, const ProgramPointTag *tag,
296 const Stmt *SubStmt = nullptr)
297 : StmtPoint(S, SubStmt, PreStmtKind, SF, tag) {}
298
299 const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
300
301private:
302 friend class ProgramPoint;
303 PreStmt() = default;
304 static bool isKind(const ProgramPoint &Location) {
305 return Location.getKind() == PreStmtKind;
306 }
307};
308
309class PostStmt : public StmtPoint {
310protected:
311 PostStmt() = default;
312 PostStmt(const Stmt *S, const void *data, Kind k, const StackFrame *SF,
313 const ProgramPointTag *tag = nullptr)
314 : StmtPoint(S, data, k, SF, tag) {}
315
316public:
317 explicit PostStmt(const Stmt *S, Kind k, const StackFrame *SF,
318 const ProgramPointTag *tag = nullptr)
319 : StmtPoint(S, nullptr, k, SF, tag) {}
320
321 explicit PostStmt(const Stmt *S, const StackFrame *SF,
322 const ProgramPointTag *tag = nullptr)
323 : StmtPoint(S, nullptr, PostStmtKind, SF, tag) {}
324
325private:
326 friend class ProgramPoint;
327 static bool isKind(const ProgramPoint &Location) {
328 unsigned k = Location.getKind();
329 return k >= MinPostStmtKind && k <= MaxPostStmtKind;
330 }
331};
332
334public:
335 explicit FunctionExitPoint(const ReturnStmt *S, const StackFrame *SF,
336 const ProgramPointTag *tag = nullptr)
337 : ProgramPoint(S, FunctionExitKind, SF, tag) {}
338
339 const CFGBlock *getBlock() const {
340 return &getStackFrame()->getCFG()->getExit();
341 }
342
343 const ReturnStmt *getStmt() const {
344 return reinterpret_cast<const ReturnStmt *>(getData1());
345 }
346
347private:
348 friend class ProgramPoint;
349 FunctionExitPoint() = default;
350 static bool isKind(const ProgramPoint &Location) {
351 return Location.getKind() == FunctionExitKind;
352 }
353};
354
355// PostCondition represents the post program point of a branch condition.
356class PostCondition : public PostStmt {
357public:
358 PostCondition(const Stmt *S, const StackFrame *SF,
359 const ProgramPointTag *tag = nullptr)
360 : PostStmt(S, PostConditionKind, SF, tag) {}
361
362private:
363 friend class ProgramPoint;
364 PostCondition() = default;
365 static bool isKind(const ProgramPoint &Location) {
366 return Location.getKind() == PostConditionKind;
367 }
368};
369
370class LocationCheck : public StmtPoint {
371protected:
372 LocationCheck() = default;
374 const ProgramPointTag *tag)
375 : StmtPoint(S, nullptr, K, SF, tag) {}
376
377private:
378 friend class ProgramPoint;
379 static bool isKind(const ProgramPoint &location) {
380 unsigned k = location.getKind();
381 return k == PreLoadKind || k == PreStoreKind;
382 }
383};
384
385class PreLoad : public LocationCheck {
386public:
387 PreLoad(const Stmt *S, const StackFrame *SF,
388 const ProgramPointTag *tag = nullptr)
389 : LocationCheck(S, SF, PreLoadKind, tag) {}
390
391private:
392 friend class ProgramPoint;
393 PreLoad() = default;
394 static bool isKind(const ProgramPoint &location) {
395 return location.getKind() == PreLoadKind;
396 }
397};
398
399class PreStore : public LocationCheck {
400public:
401 PreStore(const Stmt *S, const StackFrame *SF,
402 const ProgramPointTag *tag = nullptr)
403 : LocationCheck(S, SF, PreStoreKind, tag) {}
404
405private:
406 friend class ProgramPoint;
407 PreStore() = default;
408 static bool isKind(const ProgramPoint &location) {
409 return location.getKind() == PreStoreKind;
410 }
411};
412
413class PostLoad : public PostStmt {
414public:
415 PostLoad(const Stmt *S, const StackFrame *SF,
416 const ProgramPointTag *tag = nullptr)
417 : PostStmt(S, PostLoadKind, SF, tag) {}
418
419private:
420 friend class ProgramPoint;
421 PostLoad() = default;
422 static bool isKind(const ProgramPoint &Location) {
423 return Location.getKind() == PostLoadKind;
424 }
425};
426
427/// Represents a program point after a store evaluation.
428class PostStore : public PostStmt {
429public:
430 /// Construct the post store point.
431 /// \param Loc can be used to store the information about the location
432 /// used in the form it was uttered in the code.
433 PostStore(const Stmt *S, const StackFrame *SF, const void *Loc,
434 const ProgramPointTag *tag = nullptr)
435 : PostStmt(S, PostStoreKind, SF, tag) {
436 assert(getData2() == nullptr);
437 setData2(Loc);
438 }
439
440 /// Returns the information about the location used in the store,
441 /// how it was uttered in the code.
442 const void *getLocationValue() const {
443 return getData2();
444 }
445
446private:
447 friend class ProgramPoint;
448 PostStore() = default;
449 static bool isKind(const ProgramPoint &Location) {
450 return Location.getKind() == PostStoreKind;
451 }
452};
453
454class PostLValue : public PostStmt {
455public:
456 PostLValue(const Stmt *S, const StackFrame *SF,
457 const ProgramPointTag *tag = nullptr)
458 : PostStmt(S, PostLValueKind, SF, tag) {}
459
460private:
461 friend class ProgramPoint;
462 PostLValue() = default;
463 static bool isKind(const ProgramPoint &Location) {
464 return Location.getKind() == PostLValueKind;
465 }
466};
467
468/// Represents a point after we ran remove dead bindings BEFORE
469/// processing the given statement.
471public:
473 const ProgramPointTag *tag = nullptr)
475
476private:
477 friend class ProgramPoint;
478 PreStmtPurgeDeadSymbols() = default;
479 static bool isKind(const ProgramPoint &Location) {
480 return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
481 }
482};
483
484/// Represents a point after we ran remove dead bindings AFTER
485/// processing the given statement.
487public:
489 const ProgramPointTag *tag = nullptr)
491
492private:
493 friend class ProgramPoint;
494 PostStmtPurgeDeadSymbols() = default;
495 static bool isKind(const ProgramPoint &Location) {
496 return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
497 }
498};
499
500class BlockEdge : public ProgramPoint {
501public:
502 BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const StackFrame *SF)
503 : ProgramPoint(B1, B2, BlockEdgeKind, SF) {
504 assert(B1 && "BlockEdge: source block must be non-null");
505 assert(B2 && "BlockEdge: destination block must be non-null");
506 }
507
508 const CFGBlock *getSrc() const {
509 return static_cast<const CFGBlock*>(getData1());
510 }
511
512 const CFGBlock *getDst() const {
513 return static_cast<const CFGBlock*>(getData2());
514 }
515
516private:
517 friend class ProgramPoint;
518 BlockEdge() = default;
519 static bool isKind(const ProgramPoint &Location) {
520 return Location.getKind() == BlockEdgeKind;
521 }
522};
523
525public:
526 /// Construct a PostInitializer point that represents a location after
527 /// CXXCtorInitializer expression evaluation.
528 ///
529 /// \param I The initializer.
530 /// \param Loc The location of the field being initialized.
531 PostInitializer(const CXXCtorInitializer *I, const void *Loc,
532 const StackFrame *SF)
533 : ProgramPoint(I, Loc, PostInitializerKind, SF) {}
534
536 return static_cast<const CXXCtorInitializer *>(getData1());
537 }
538
539 /// Returns the location of the field.
540 const void *getLocationValue() const {
541 return getData2();
542 }
543
544private:
545 friend class ProgramPoint;
546 PostInitializer() = default;
547 static bool isKind(const ProgramPoint &Location) {
548 return Location.getKind() == PostInitializerKind;
549 }
550};
551
552/// Represents an implicit call event.
553///
554/// The nearest statement is provided for diagnostic purposes.
556public:
558 const StackFrame *SF, const ProgramPointTag *Tag,
560 : ProgramPoint(Loc.getPtrEncoding(), D, K, SF, Tag, ElemRef) {}
561
562 const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
566
567protected:
568 ImplicitCallPoint() = default;
569private:
570 friend class ProgramPoint;
571 static bool isKind(const ProgramPoint &Location) {
572 return Location.getKind() >= MinImplicitCallKind &&
573 Location.getKind() <= MaxImplicitCallKind;
574 }
575};
576
577/// Represents a program point just before an implicit call event.
578///
579/// Explicit calls will appear as PreStmt program points.
581public:
584 const ProgramPointTag *Tag = nullptr)
585 : ImplicitCallPoint(D, Loc, PreImplicitCallKind, SF, Tag, ElemRef) {}
586
587private:
588 friend class ProgramPoint;
589 PreImplicitCall() = default;
590 static bool isKind(const ProgramPoint &Location) {
591 return Location.getKind() == PreImplicitCallKind;
592 }
593};
594
595/// Represents a program point just after an implicit call event.
596///
597/// Explicit calls will appear as PostStmt program points.
599public:
602 const ProgramPointTag *Tag = nullptr)
603 : ImplicitCallPoint(D, Loc, PostImplicitCallKind, SF, Tag, ElemRef) {}
604
605private:
606 friend class ProgramPoint;
607 PostImplicitCall() = default;
608 static bool isKind(const ProgramPoint &Location) {
609 return Location.getKind() == PostImplicitCallKind;
610 }
611};
612
614public:
615 PostAllocatorCall(const Stmt *S, const StackFrame *SF,
616 const ProgramPointTag *Tag = nullptr)
617 : StmtPoint(S, nullptr, PostAllocatorCallKind, SF, Tag) {}
618
619private:
620 friend class ProgramPoint;
621 PostAllocatorCall() = default;
622 static bool isKind(const ProgramPoint &Location) {
623 return Location.getKind() == PostAllocatorCallKind;
624 }
625};
626
627/// Represents a point when we begin processing an inlined call.
628/// CallEnter uses the caller's stack frame.
629class CallEnter : public ProgramPoint {
630public:
631 CallEnter(const Stmt *stmt, const StackFrame *CalleeSF,
632 const StackFrame *CallerSF)
633 : ProgramPoint(stmt, CalleeSF, CallEnterKind, CallerSF, nullptr) {}
634
635 const Stmt *getCallExpr() const {
636 return static_cast<const Stmt *>(getData1());
637 }
638
640 return static_cast<const StackFrame *>(getData2());
641 }
642
643 /// Returns the entry block in the CFG for the entered function.
644 const CFGBlock *getEntry() const {
645 const StackFrame *CalleeSF = getCalleeStackFrame();
646 const CFG *CalleeCFG = CalleeSF->getCFG();
647 return &(CalleeCFG->getEntry());
648 }
649
650private:
651 friend class ProgramPoint;
652 CallEnter() = default;
653 static bool isKind(const ProgramPoint &Location) {
654 return Location.getKind() == CallEnterKind;
655 }
656};
657
658/// Represents a point when we start the call exit sequence (for inlined call).
659///
660/// The call exit is simulated with a sequence of nodes, which occur between
661/// CallExitBegin and CallExitEnd. The following operations occur between the
662/// two program points:
663/// - CallExitBegin
664/// - Bind the return value
665/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
666/// - CallExitEnd
668public:
669 // CallExitBegin uses the callee's stack frame.
672
673 const ReturnStmt *getReturnStmt() const {
674 return static_cast<const ReturnStmt *>(getData1());
675 }
676
677private:
678 friend class ProgramPoint;
679 CallExitBegin() = default;
680 static bool isKind(const ProgramPoint &Location) {
681 return Location.getKind() == CallExitBeginKind;
682 }
683};
684
685/// Represents a point when we finish the call exit sequence (for inlined call).
686/// \sa CallExitBegin
687class CallExitEnd : public ProgramPoint {
688public:
689 // CallExitEnd uses the caller's stack frame.
690 CallExitEnd(const StackFrame *CalleeSF, const StackFrame *CallerSF)
691 : ProgramPoint(CalleeSF, CallExitEndKind, CallerSF, nullptr) {}
692
694 return static_cast<const StackFrame *>(getData1());
695 }
696
697private:
698 friend class ProgramPoint;
699 CallExitEnd() = default;
700 static bool isKind(const ProgramPoint &Location) {
701 return Location.getKind() == CallExitEndKind;
702 }
703};
704
705/// Represents a point when we exit a loop.
706/// When this ProgramPoint is encountered we can be sure that the symbolic
707/// execution of the corresponding LoopStmt is finished on the given path.
708/// Note: It is possible to encounter a LoopExit element when we haven't even
709/// encountered the loop itself. At the current state not all loop exits will
710/// result in a LoopExit program point.
711class LoopExit : public ProgramPoint {
712public:
713 LoopExit(const Stmt *LoopStmt, const StackFrame *SF)
714 : ProgramPoint(LoopStmt, nullptr, LoopExitKind, SF) {}
715
716 const Stmt *getLoopStmt() const {
717 return static_cast<const Stmt *>(getData1());
718 }
719
720private:
721 friend class ProgramPoint;
722 LoopExit() = default;
723 static bool isKind(const ProgramPoint &Location) {
724 return Location.getKind() == LoopExitKind;
725 }
726};
727
728/// This is a meta program point, which should be skipped by all the diagnostic
729/// reasoning etc.
731public:
732 EpsilonPoint(const StackFrame *SF, const void *Data1,
733 const void *Data2 = nullptr,
734 const ProgramPointTag *tag = nullptr)
735 : ProgramPoint(Data1, Data2, EpsilonKind, SF, tag) {}
736
737 const void *getData() const { return getData1(); }
738
739private:
740 friend class ProgramPoint;
741 EpsilonPoint() = default;
742 static bool isKind(const ProgramPoint &Location) {
743 return Location.getKind() == EpsilonKind;
744 }
745};
746
747} // end namespace clang
748
749
750namespace llvm { // Traits specialization for DenseMap
751
752template <> struct DenseMapInfo<clang::ProgramPoint> {
753
755 uintptr_t x =
756 reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
757 return clang::BlockEntrance(nullptr, reinterpret_cast<clang::CFGBlock *>(x),
758 nullptr);
759}
760
762 uintptr_t x =
763 reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
764 return clang::BlockEntrance(nullptr, reinterpret_cast<clang::CFGBlock *>(x),
765 nullptr);
766}
767
768static unsigned getHashValue(const clang::ProgramPoint &Loc) {
769 return Loc.getHashValue();
770}
771
772static bool isEqual(const clang::ProgramPoint &L,
773 const clang::ProgramPoint &R) {
774 return L == R;
775}
776
777};
778
779} // end namespace llvm
780
781#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:632
CFGElement front() const
Definition CFG.h:934
bool empty() const
Definition CFG.h:980
ElementRefImpl< true > ConstCFGElementRef
Definition CFG.h:948
Stmt * getTerminatorStmt()
Definition CFG.h:1114
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1250
CFGBlock & getExit()
Definition CFG.h:1366
CFGBlock & getEntry()
Definition CFG.h:1364
Represents a C++ base or member initializer.
Definition DeclCXX.h:2385
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.
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
ProgramPoint(const void *P1, const void *P2, Kind k, const StackFrame *SF, const ProgramPointTag *tag=nullptr, CFGBlock::ConstCFGElementRef ElemRef={nullptr, 0})
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)
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 *tag=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:3170
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:86
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
static bool isEqual(const clang::ProgramPoint &L, const clang::ProgramPoint &R)
static clang::ProgramPoint getTombstoneKey()
static unsigned getHashValue(const clang::ProgramPoint &Loc)
static clang::ProgramPoint getEmptyKey()