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