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