clang  19.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 
30 namespace clang {
31 
32 class AnalysisDeclContext;
33 class 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.
39 public:
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 
47 private:
48  const void *const TagKind;
49 };
50 
52  std::string Desc;
53 public:
54  SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
55  StringRef getTagDescription() const override;
56 };
57 
58 class ProgramPoint {
59 public:
87 
88 private:
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 
100 protected:
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 
120 protected:
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 
126 public:
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 
180  return getLocationContext()->getStackFrame();
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 
219 class BlockEntrance : public ProgramPoint {
220 public:
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 
236 private:
237  friend class ProgramPoint;
238  BlockEntrance() = default;
239  static bool isKind(const ProgramPoint &Location) {
240  return Location.getKind() == BlockEntranceKind;
241  }
242 };
243 
244 class BlockExit : public ProgramPoint {
245 public:
246  BlockExit(const CFGBlock *B, const LocationContext *L)
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 
257 private:
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.
266 class StmtPoint : public ProgramPoint {
267 public:
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 
279 protected:
280  StmtPoint() = default;
281 private:
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 
290 class PreStmt : public StmtPoint {
291 public:
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 
298 private:
299  friend class ProgramPoint;
300  PreStmt() = default;
301  static bool isKind(const ProgramPoint &Location) {
302  return Location.getKind() == PreStmtKind;
303  }
304 };
305 
306 class PostStmt : public StmtPoint {
307 protected:
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 
313 public:
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 
322 private:
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 
331 public:
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 
345 private:
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.
354 class PostCondition : public PostStmt {
355 public:
356  PostCondition(const Stmt *S, const LocationContext *L,
357  const ProgramPointTag *tag = nullptr)
358  : PostStmt(S, PostConditionKind, L, tag) {}
359 
360 private:
361  friend class ProgramPoint;
362  PostCondition() = default;
363  static bool isKind(const ProgramPoint &Location) {
364  return Location.getKind() == PostConditionKind;
365  }
366 };
367 
368 class LocationCheck : public StmtPoint {
369 protected:
370  LocationCheck() = default;
371  LocationCheck(const Stmt *S, const LocationContext *L,
372  ProgramPoint::Kind K, const ProgramPointTag *tag)
373  : StmtPoint(S, nullptr, K, L, tag) {}
374 
375 private:
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 
383 class PreLoad : public LocationCheck {
384 public:
385  PreLoad(const Stmt *S, const LocationContext *L,
386  const ProgramPointTag *tag = nullptr)
387  : LocationCheck(S, L, PreLoadKind, tag) {}
388 
389 private:
390  friend class ProgramPoint;
391  PreLoad() = default;
392  static bool isKind(const ProgramPoint &location) {
393  return location.getKind() == PreLoadKind;
394  }
395 };
396 
397 class PreStore : public LocationCheck {
398 public:
399  PreStore(const Stmt *S, const LocationContext *L,
400  const ProgramPointTag *tag = nullptr)
401  : LocationCheck(S, L, PreStoreKind, tag) {}
402 
403 private:
404  friend class ProgramPoint;
405  PreStore() = default;
406  static bool isKind(const ProgramPoint &location) {
407  return location.getKind() == PreStoreKind;
408  }
409 };
410 
411 class PostLoad : public PostStmt {
412 public:
413  PostLoad(const Stmt *S, const LocationContext *L,
414  const ProgramPointTag *tag = nullptr)
415  : PostStmt(S, PostLoadKind, L, tag) {}
416 
417 private:
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.
426 class PostStore : public PostStmt {
427 public:
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 
444 private:
445  friend class ProgramPoint;
446  PostStore() = default;
447  static bool isKind(const ProgramPoint &Location) {
448  return Location.getKind() == PostStoreKind;
449  }
450 };
451 
452 class PostLValue : public PostStmt {
453 public:
454  PostLValue(const Stmt *S, const LocationContext *L,
455  const ProgramPointTag *tag = nullptr)
456  : PostStmt(S, PostLValueKind, L, tag) {}
457 
458 private:
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.
469 public:
471  const ProgramPointTag *tag = nullptr)
472  : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
473 
474 private:
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.
485 public:
487  const ProgramPointTag *tag = nullptr)
488  : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
489 
490 private:
491  friend class ProgramPoint;
492  PostStmtPurgeDeadSymbols() = default;
493  static bool isKind(const ProgramPoint &Location) {
494  return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
495  }
496 };
497 
498 class BlockEdge : public ProgramPoint {
499 public:
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 
514 private:
515  friend class ProgramPoint;
516  BlockEdge() = default;
517  static bool isKind(const ProgramPoint &Location) {
518  return Location.getKind() == BlockEdgeKind;
519  }
520 };
521 
523 public:
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 
543 private:
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.
555 public:
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 
566 protected:
567  ImplicitCallPoint() = default;
568 private:
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.
580 public:
583  const ProgramPointTag *Tag = nullptr)
584  : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag, ElemRef) {}
585 
586 private:
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.
598 public:
601  const ProgramPointTag *Tag = nullptr)
602  : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag, ElemRef) {}
603 
604 private:
605  friend class ProgramPoint;
606  PostImplicitCall() = default;
607  static bool isKind(const ProgramPoint &Location) {
608  return Location.getKind() == PostImplicitCallKind;
609  }
610 };
611 
612 class PostAllocatorCall : public StmtPoint {
613 public:
615  const ProgramPointTag *Tag = nullptr)
616  : StmtPoint(S, nullptr, PostAllocatorCallKind, L, Tag) {}
617 
618 private:
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.
628 class CallEnter : public ProgramPoint {
629 public:
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 
649 private:
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
666 class CallExitBegin : public ProgramPoint {
667 public:
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 
676 private:
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
686 class CallExitEnd : public ProgramPoint {
687 public:
688  // CallExitEnd uses the caller's location context.
689  CallExitEnd(const StackFrameContext *CalleeCtx,
690  const LocationContext *CallerCtx)
691  : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
692 
694  return static_cast<const StackFrameContext *>(getData1());
695  }
696 
697 private:
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.
711 class LoopExit : public ProgramPoint {
712 public:
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 
720 private:
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.
730 class EpsilonPoint : public ProgramPoint {
731 public:
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 
739 private:
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 
750 namespace llvm { // Traits specialization for DenseMap
751 
752 template <> 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 
766 static unsigned getHashValue(const clang::ProgramPoint &Loc) {
767  return Loc.getHashValue();
768 }
769 
770 static 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
SourceLocation Loc
Definition: SemaObjC.cpp:755
BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
Definition: ProgramPoint.h:500
const CFGBlock * getDst() const
Definition: ProgramPoint.h:510
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:506
BlockEntrance(const CFGBlock *B, const LocationContext *L, const ProgramPointTag *tag=nullptr)
Definition: ProgramPoint.h:221
std::optional< CFGElement > getFirstElement() const
Definition: ProgramPoint.h:231
const CFGBlock * getBlock() const
Definition: ProgramPoint.h:227
const Stmt * getTerminator() const
Definition: ProgramPoint.h:253
BlockExit(const CFGBlock *B, const LocationContext *L)
Definition: ProgramPoint.h:246
const CFGBlock * getBlock() const
Definition: ProgramPoint.h:249
Represents a single basic block in a source-level CFG.
Definition: CFG.h:604
CFGElement front() const
Definition: CFG.h:901
Stmt * getTerminatorStmt()
Definition: CFG.h:1081
bool empty() const
Definition: CFG.h:947
ElementRefImpl< true > ConstCFGElementRef
Definition: CFG.h:915
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:2300
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:628
const Stmt * getCallExpr() const
Definition: ProgramPoint.h:634
const StackFrameContext * getCalleeContext() const
Definition: ProgramPoint.h:638
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, const LocationContext *callerCtx)
Definition: ProgramPoint.h:630
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
Definition: ProgramPoint.h:643
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
const StackFrameContext * getCalleeContext() const
Definition: ProgramPoint.h:693
CallExitEnd(const StackFrameContext *CalleeCtx, const LocationContext *CallerCtx)
Definition: ProgramPoint.h:689
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
const void * getData() const
Definition: ProgramPoint.h:737
EpsilonPoint(const LocationContext *L, const void *Data1, const void *Data2=nullptr, const ProgramPointTag *tag=nullptr)
Definition: ProgramPoint.h:732
const ReturnStmt * getStmt() const
Definition: ProgramPoint.h:341
const CFGBlock * getBlock() const
Definition: ProgramPoint.h:337
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
PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, const Stmt *SubStmt=nullptr)
Definition: ProgramPoint.h:292
const Stmt * getSubStmt() const
Definition: ProgramPoint.h:296
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
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
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
const void * getData2() const
Definition: ProgramPoint.h:122
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
const ProgramPointTag * getTag() const
Definition: ProgramPoint.h:173
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
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:175
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 StackFrameContext * getStackFrame() const
Definition: ProgramPoint.h:179
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3019
SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg)
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
const Stmt * getStmt() const
Definition: ProgramPoint.h:274
StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, const ProgramPointTag *tag)
Definition: ProgramPoint.h:268
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