LLVM  3.7.0
TrackingMDRef.h
Go to the documentation of this file.
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 
14 #ifndef LLVM_IR_TRACKINGMDREF_H
15 #define LLVM_IR_TRACKINGMDREF_H
16 
18 #include "llvm/Support/Casting.h"
19 
20 namespace llvm {
21 
22 class Metadata;
23 class MDNode;
24 class ValueAsMetadata;
25 
26 /// \brief Tracking metadata reference.
27 ///
28 /// This class behaves like \a TrackingVH, but for metadata.
30  Metadata *MD;
31 
32 public:
33  TrackingMDRef() : MD(nullptr) {}
34  explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
35 
36  TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
37  TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
39  if (&X == this)
40  return *this;
41 
42  untrack();
43  MD = X.MD;
44  retrack(X);
45  return *this;
46  }
48  if (&X == this)
49  return *this;
50 
51  untrack();
52  MD = X.MD;
53  track();
54  return *this;
55  }
56  ~TrackingMDRef() { untrack(); }
57 
58  Metadata *get() const { return MD; }
59  operator Metadata *() const { return get(); }
60  Metadata *operator->() const { return get(); }
61  Metadata &operator*() const { return *get(); }
62 
63  void reset() {
64  untrack();
65  MD = nullptr;
66  }
67  void reset(Metadata *MD) {
68  untrack();
69  this->MD = MD;
70  track();
71  }
72 
73  /// \brief Check whether this has a trivial destructor.
74  ///
75  /// If \c MD isn't replaceable, the destructor will be a no-op.
76  bool hasTrivialDestructor() const {
77  return !MD || !MetadataTracking::isReplaceable(*MD);
78  }
79 
80  bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
81  bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
82 
83 private:
84  void track() {
85  if (MD)
87  }
88  void untrack() {
89  if (MD)
91  }
92  void retrack(TrackingMDRef &X) {
93  assert(MD == X.MD && "Expected values to match");
94  if (X.MD) {
95  MetadataTracking::retrack(X.MD, MD);
96  X.MD = nullptr;
97  }
98  }
99 };
100 
101 /// \brief Typed tracking ref.
102 ///
103 /// Track refererences of a particular type. It's useful to use this for \a
104 /// MDNode and \a ValueAsMetadata.
105 template <class T> class TypedTrackingMDRef {
106  TrackingMDRef Ref;
107 
108 public:
110  explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
111 
112  TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
113  TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
115  Ref = std::move(X.Ref);
116  return *this;
117  }
119  Ref = X.Ref;
120  return *this;
121  }
122 
123  T *get() const { return (T *)Ref.get(); }
124  operator T *() const { return get(); }
125  T *operator->() const { return get(); }
126  T &operator*() const { return *get(); }
127 
128  bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
129  bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
130 
131  void reset() { Ref.reset(); }
132  void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
133 
134  /// \brief Check whether this has a trivial destructor.
135  bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
136 };
137 
140 
141 // Expose the underlying metadata to casting.
142 template <> struct simplify_type<TrackingMDRef> {
144  static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
145 };
146 
147 template <> struct simplify_type<const TrackingMDRef> {
150  return MD.get();
151  }
152 };
153 
154 template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
155  typedef T *SimpleType;
157  return MD.get();
158  }
159 };
160 
161 template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
162  typedef T *SimpleType;
164  return MD.get();
165  }
166 };
167 
168 } // end namespace llvm
169 
170 #endif
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
Definition: TrackingMDRef.h:76
static SimpleType getSimplifiedValue(const TrackingMDRef &MD)
Metadata * operator->() const
Definition: TrackingMDRef.h:60
TrackingMDRef & operator=(TrackingMDRef &&X)
Definition: TrackingMDRef.h:38
Tracking metadata reference.
Definition: TrackingMDRef.h:29
TypedTrackingMDRef & operator=(const TypedTrackingMDRef &X)
bool operator!=(const TrackingMDRef &X) const
Definition: TrackingMDRef.h:81
bool operator==(const TypedTrackingMDRef &X) const
TypedTrackingMDRef< ValueAsMetadata > TrackingValueAsMetadataRef
static bool track(Metadata *&MD)
Track the reference to metadata.
TypedTrackingMDRef & operator=(TypedTrackingMDRef &&X)
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
TypedTrackingMDRef(const TypedTrackingMDRef &X)
TrackingMDRef(TrackingMDRef &&X)
Definition: TrackingMDRef.h:36
static SimpleType getSimplifiedValue(TypedTrackingMDRef< T > &MD)
bool operator==(const TrackingMDRef &X) const
Definition: TrackingMDRef.h:80
Metadata * get() const
Definition: TrackingMDRef.h:58
TrackingMDRef(const TrackingMDRef &X)
Definition: TrackingMDRef.h:37
static SimpleType getSimplifiedValue(const TypedTrackingMDRef< T > &MD)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static bool retrack(Metadata *&MD, Metadata *&New)
Move tracking from one reference to another.
Typed tracking ref.
TrackingMDRef & operator=(const TrackingMDRef &X)
Definition: TrackingMDRef.h:47
bool operator!=(const TypedTrackingMDRef &X) const
static void untrack(Metadata *&MD)
Stop tracking a reference to metadata.
TrackingMDRef(Metadata *MD)
Definition: TrackingMDRef.h:34
Metadata & operator*() const
Definition: TrackingMDRef.h:61
TypedTrackingMDRef< MDNode > TrackingMDNodeRef
static SimpleType getSimplifiedValue(TrackingMDRef &MD)
aarch64 promote const
void reset(Metadata *MD)
Definition: TrackingMDRef.h:67
static bool isReplaceable(const Metadata &MD)
Check whether metadata is replaceable.
Root of the metadata hierarchy.
Definition: Metadata.h:45
TypedTrackingMDRef(TypedTrackingMDRef &&X)