TrackingMDRef.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- 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. // References to metadata that track RAUW.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_IR_TRACKINGMDREF_H
  14. #define LLVM_IR_TRACKINGMDREF_H
  15. #include "llvm/IR/MetadataTracking.h"
  16. #include "llvm/Support/Casting.h"
  17. namespace llvm {
  18. class Metadata;
  19. class MDNode;
  20. class ValueAsMetadata;
  21. /// \brief Tracking metadata reference.
  22. ///
  23. /// This class behaves like \a TrackingVH, but for metadata.
  24. class TrackingMDRef {
  25. Metadata *MD;
  26. public:
  27. TrackingMDRef() : MD(nullptr) {}
  28. explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
  29. TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
  30. TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
  31. TrackingMDRef &operator=(TrackingMDRef &&X) {
  32. if (&X == this)
  33. return *this;
  34. untrack();
  35. MD = X.MD;
  36. retrack(X);
  37. return *this;
  38. }
  39. TrackingMDRef &operator=(const TrackingMDRef &X) {
  40. if (&X == this)
  41. return *this;
  42. untrack();
  43. MD = X.MD;
  44. track();
  45. return *this;
  46. }
  47. ~TrackingMDRef() { untrack(); }
  48. Metadata *get() const { return MD; }
  49. operator Metadata *() const { return get(); }
  50. Metadata *operator->() const { return get(); }
  51. Metadata &operator*() const { return *get(); }
  52. void reset() {
  53. untrack();
  54. MD = nullptr;
  55. }
  56. void reset(Metadata *MD) {
  57. untrack();
  58. this->MD = MD;
  59. track();
  60. }
  61. /// \brief Check whether this has a trivial destructor.
  62. ///
  63. /// If \c MD isn't replaceable, the destructor will be a no-op.
  64. bool hasTrivialDestructor() const {
  65. return !MD || !MetadataTracking::isReplaceable(*MD);
  66. }
  67. bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
  68. bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
  69. private:
  70. void track() {
  71. if (MD)
  72. MetadataTracking::track(MD);
  73. }
  74. void untrack() {
  75. if (MD)
  76. MetadataTracking::untrack(MD);
  77. }
  78. void retrack(TrackingMDRef &X) {
  79. assert(MD == X.MD && "Expected values to match");
  80. if (X.MD) {
  81. MetadataTracking::retrack(X.MD, MD);
  82. X.MD = nullptr;
  83. }
  84. }
  85. };
  86. /// \brief Typed tracking ref.
  87. ///
  88. /// Track refererences of a particular type. It's useful to use this for \a
  89. /// MDNode and \a ValueAsMetadata.
  90. template <class T> class TypedTrackingMDRef {
  91. TrackingMDRef Ref;
  92. public:
  93. TypedTrackingMDRef() {}
  94. explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
  95. TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
  96. TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
  97. TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
  98. Ref = std::move(X.Ref);
  99. return *this;
  100. }
  101. TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
  102. Ref = X.Ref;
  103. return *this;
  104. }
  105. T *get() const { return (T *)Ref.get(); }
  106. operator T *() const { return get(); }
  107. T *operator->() const { return get(); }
  108. T &operator*() const { return *get(); }
  109. bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
  110. bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
  111. void reset() { Ref.reset(); }
  112. void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
  113. /// \brief Check whether this has a trivial destructor.
  114. bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
  115. };
  116. typedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef;
  117. typedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef;
  118. // Expose the underlying metadata to casting.
  119. template <> struct simplify_type<TrackingMDRef> {
  120. typedef Metadata *SimpleType;
  121. static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
  122. };
  123. template <> struct simplify_type<const TrackingMDRef> {
  124. typedef Metadata *SimpleType;
  125. static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
  126. return MD.get();
  127. }
  128. };
  129. template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
  130. typedef T *SimpleType;
  131. static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
  132. return MD.get();
  133. }
  134. };
  135. template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
  136. typedef T *SimpleType;
  137. static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
  138. return MD.get();
  139. }
  140. };
  141. } // end namespace llvm
  142. #endif