1 //===- llvm/IR/TrackingMDRef.h - Tracking Metadata references -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // References to metadata that track RAUW.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_IR_TRACKINGMDREF_H
15 #define LLVM_IR_TRACKINGMDREF_H
17 #include "llvm/IR/MetadataTracking.h"
18 #include "llvm/Support/Casting.h"
24 class ValueAsMetadata;
26 /// \brief Tracking metadata reference.
28 /// This class behaves like \a TrackingVH, but for metadata.
33 TrackingMDRef() : MD(nullptr) {}
34 explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
36 TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
37 TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
38 TrackingMDRef &operator=(TrackingMDRef &&X) {
47 TrackingMDRef &operator=(const TrackingMDRef &X) {
56 ~TrackingMDRef() { untrack(); }
58 LLVM_EXPLICIT operator bool() const { return get(); }
59 Metadata *get() const { return MD; }
60 operator Metadata *() const { return get(); }
61 Metadata *operator->() const { return get(); }
62 Metadata &operator*() const { return *get(); }
68 void reset(Metadata *MD) {
74 /// \brief Check whether this has a trivial destructor.
76 /// If \c MD isn't replaceable, the destructor will be a no-op.
77 bool hasTrivialDestructor() const {
78 return !MD || !MetadataTracking::isReplaceable(*MD);
84 MetadataTracking::track(MD);
88 MetadataTracking::untrack(MD);
90 void retrack(TrackingMDRef &X) {
91 assert(MD == X.MD && "Expected values to match");
93 MetadataTracking::retrack(X.MD, MD);
99 /// \brief Typed tracking ref.
101 /// Track refererences of a particular type. It's useful to use this for \a
102 /// MDNode and \a ValueAsMetadata.
103 template <class T> class TypedTrackingMDRef {
107 TypedTrackingMDRef() {}
108 explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
110 TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
111 TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
112 TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
113 Ref = std::move(X.Ref);
116 TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
121 LLVM_EXPLICIT operator bool() const { return get(); }
122 T *get() const { return (T *)Ref.get(); }
123 operator T *() const { return get(); }
124 T *operator->() const { return get(); }
125 T &operator*() const { return *get(); }
127 void reset() { Ref.reset(); }
128 void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
130 /// \brief Check whether this has a trivial destructor.
131 bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
134 typedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef;
135 typedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef;
137 // Expose the underlying metadata to casting.
138 template <> struct simplify_type<TrackingMDRef> {
139 typedef Metadata *SimpleType;
140 static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
143 template <> struct simplify_type<const TrackingMDRef> {
144 typedef Metadata *SimpleType;
145 static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
150 template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
151 typedef T *SimpleType;
152 static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
157 template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
158 typedef T *SimpleType;
159 static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
164 } // end namespace llvm