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