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