1 //===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // References to metadata that track RAUW.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_IR_TRACKINGMDREF_H
14 #define LLVM_IR_TRACKINGMDREF_H
16 #include "llvm/IR/Metadata.h"
22 /// Tracking metadata reference.
24 /// This class behaves like \a TrackingVH, but for metadata.
26 Metadata
*MD
= nullptr;
29 TrackingMDRef() = default;
30 explicit TrackingMDRef(Metadata
*MD
) : MD(MD
) { track(); }
32 TrackingMDRef(TrackingMDRef
&&X
) : MD(X
.MD
) { retrack(X
); }
33 TrackingMDRef(const TrackingMDRef
&X
) : MD(X
.MD
) { track(); }
35 TrackingMDRef
&operator=(TrackingMDRef
&&X
) {
45 TrackingMDRef
&operator=(const TrackingMDRef
&X
) {
55 ~TrackingMDRef() { untrack(); }
57 Metadata
*get() const { return MD
; }
58 operator Metadata
*() const { return get(); }
59 Metadata
*operator->() const { return get(); }
60 Metadata
&operator*() const { return *get(); }
66 void reset(Metadata
*MD
) {
72 /// Check whether this has a trivial destructor.
74 /// If \c MD isn't replaceable, the destructor will be a no-op.
75 bool hasTrivialDestructor() const {
76 return !MD
|| !MetadataTracking::isReplaceable(*MD
);
79 bool operator==(const TrackingMDRef
&X
) const { return MD
== X
.MD
; }
80 bool operator!=(const TrackingMDRef
&X
) const { return MD
!= X
.MD
; }
85 MetadataTracking::track(MD
);
90 MetadataTracking::untrack(MD
);
93 void retrack(TrackingMDRef
&X
) {
94 assert(MD
== X
.MD
&& "Expected values to match");
96 MetadataTracking::retrack(X
.MD
, MD
);
102 /// Typed tracking ref.
104 /// Track refererences of a particular type. It's useful to use this for \a
105 /// MDNode and \a ValueAsMetadata.
106 template <class T
> class TypedTrackingMDRef
{
110 TypedTrackingMDRef() = default;
111 explicit TypedTrackingMDRef(T
*MD
) : Ref(static_cast<Metadata
*>(MD
)) {}
113 TypedTrackingMDRef(TypedTrackingMDRef
&&X
) : Ref(std::move(X
.Ref
)) {}
114 TypedTrackingMDRef(const TypedTrackingMDRef
&X
) : Ref(X
.Ref
) {}
116 TypedTrackingMDRef
&operator=(TypedTrackingMDRef
&&X
) {
117 Ref
= std::move(X
.Ref
);
121 TypedTrackingMDRef
&operator=(const TypedTrackingMDRef
&X
) {
126 T
*get() const { return (T
*)Ref
.get(); }
127 operator T
*() const { return get(); }
128 T
*operator->() const { return get(); }
129 T
&operator*() const { return *get(); }
131 bool operator==(const TypedTrackingMDRef
&X
) const { return Ref
== X
.Ref
; }
132 bool operator!=(const TypedTrackingMDRef
&X
) const { return Ref
!= X
.Ref
; }
134 void reset() { Ref
.reset(); }
135 void reset(T
*MD
) { Ref
.reset(static_cast<Metadata
*>(MD
)); }
137 /// Check whether this has a trivial destructor.
138 bool hasTrivialDestructor() const { return Ref
.hasTrivialDestructor(); }
141 using TrackingMDNodeRef
= TypedTrackingMDRef
<MDNode
>;
142 using TrackingValueAsMetadataRef
= TypedTrackingMDRef
<ValueAsMetadata
>;
144 // Expose the underlying metadata to casting.
145 template <> struct simplify_type
<TrackingMDRef
> {
146 using SimpleType
= Metadata
*;
148 static SimpleType
getSimplifiedValue(TrackingMDRef
&MD
) { return MD
.get(); }
151 template <> struct simplify_type
<const TrackingMDRef
> {
152 using SimpleType
= Metadata
*;
154 static SimpleType
getSimplifiedValue(const TrackingMDRef
&MD
) {
159 template <class T
> struct simplify_type
<TypedTrackingMDRef
<T
>> {
160 using SimpleType
= T
*;
162 static SimpleType
getSimplifiedValue(TypedTrackingMDRef
<T
> &MD
) {
167 template <class T
> struct simplify_type
<const TypedTrackingMDRef
<T
>> {
168 using SimpleType
= T
*;
170 static SimpleType
getSimplifiedValue(const TypedTrackingMDRef
<T
> &MD
) {
175 } // end namespace llvm
177 #endif // LLVM_IR_TRACKINGMDREF_H