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