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