File indexing completed on 2026-05-10 08:44:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_IR_TRACKINGMDREF_H
0014 #define LLVM_IR_TRACKINGMDREF_H
0015
0016 #include "llvm/IR/Metadata.h"
0017 #include <algorithm>
0018 #include <cassert>
0019
0020 namespace llvm {
0021
0022
0023
0024
0025 class TrackingMDRef {
0026 Metadata *MD = nullptr;
0027
0028 public:
0029 TrackingMDRef() = default;
0030 explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
0031
0032 TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
0033 TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
0034
0035 TrackingMDRef &operator=(TrackingMDRef &&X) {
0036 if (&X == this)
0037 return *this;
0038
0039 untrack();
0040 MD = X.MD;
0041 retrack(X);
0042 return *this;
0043 }
0044
0045 TrackingMDRef &operator=(const TrackingMDRef &X) {
0046 if (&X == this)
0047 return *this;
0048
0049 untrack();
0050 MD = X.MD;
0051 track();
0052 return *this;
0053 }
0054
0055 ~TrackingMDRef() { untrack(); }
0056
0057 Metadata *get() const { return MD; }
0058 operator Metadata *() const { return get(); }
0059 Metadata *operator->() const { return get(); }
0060 Metadata &operator*() const { return *get(); }
0061
0062 void reset() {
0063 untrack();
0064 MD = nullptr;
0065 }
0066 void reset(Metadata *MD) {
0067 untrack();
0068 this->MD = MD;
0069 track();
0070 }
0071
0072
0073
0074
0075 bool hasTrivialDestructor() const {
0076 return !MD || !MetadataTracking::isReplaceable(*MD);
0077 }
0078
0079 bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
0080 bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
0081
0082 private:
0083 void track() {
0084 if (MD)
0085 MetadataTracking::track(MD);
0086 }
0087
0088 void untrack() {
0089 if (MD)
0090 MetadataTracking::untrack(MD);
0091 }
0092
0093 void retrack(TrackingMDRef &X) {
0094 assert(MD == X.MD && "Expected values to match");
0095 if (X.MD) {
0096 MetadataTracking::retrack(X.MD, MD);
0097 X.MD = nullptr;
0098 }
0099 }
0100 };
0101
0102
0103
0104
0105
0106 template <class T> class TypedTrackingMDRef {
0107 TrackingMDRef Ref;
0108
0109 public:
0110 TypedTrackingMDRef() = default;
0111 explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
0112
0113 TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
0114 TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
0115
0116 TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
0117 Ref = std::move(X.Ref);
0118 return *this;
0119 }
0120
0121 TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
0122 Ref = X.Ref;
0123 return *this;
0124 }
0125
0126 T *get() const { return (T *)Ref.get(); }
0127 operator T *() const { return get(); }
0128 T *operator->() const { return get(); }
0129 T &operator*() const { return *get(); }
0130
0131 bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
0132 bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
0133
0134 void reset() { Ref.reset(); }
0135 void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
0136
0137
0138 bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
0139 };
0140
0141 using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
0142 using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
0143
0144
0145 template <> struct simplify_type<TrackingMDRef> {
0146 using SimpleType = Metadata *;
0147
0148 static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
0149 };
0150
0151 template <> struct simplify_type<const TrackingMDRef> {
0152 using SimpleType = Metadata *;
0153
0154 static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
0155 return MD.get();
0156 }
0157 };
0158
0159 template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
0160 using SimpleType = T *;
0161
0162 static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
0163 return MD.get();
0164 }
0165 };
0166
0167 template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
0168 using SimpleType = T *;
0169
0170 static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
0171 return MD.get();
0172 }
0173 };
0174
0175 }
0176
0177 #endif