[Alignment][NFC] Support compile time constants
[llvm-core.git] / include / llvm / IR / TrackingMDRef.h
blobd7377398b91b3cdd6c3eb4a462cb4e5e48390348
1 //===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
17 #include <algorithm>
18 #include <cassert>
20 namespace llvm {
22 /// Tracking metadata reference.
23 ///
24 /// This class behaves like \a TrackingVH, but for metadata.
25 class TrackingMDRef {
26 Metadata *MD = nullptr;
28 public:
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) {
36 if (&X == this)
37 return *this;
39 untrack();
40 MD = X.MD;
41 retrack(X);
42 return *this;
45 TrackingMDRef &operator=(const TrackingMDRef &X) {
46 if (&X == this)
47 return *this;
49 untrack();
50 MD = X.MD;
51 track();
52 return *this;
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(); }
62 void reset() {
63 untrack();
64 MD = nullptr;
66 void reset(Metadata *MD) {
67 untrack();
68 this->MD = MD;
69 track();
72 /// Check whether this has a trivial destructor.
73 ///
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; }
82 private:
83 void track() {
84 if (MD)
85 MetadataTracking::track(MD);
88 void untrack() {
89 if (MD)
90 MetadataTracking::untrack(MD);
93 void retrack(TrackingMDRef &X) {
94 assert(MD == X.MD && "Expected values to match");
95 if (X.MD) {
96 MetadataTracking::retrack(X.MD, MD);
97 X.MD = nullptr;
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 {
107 TrackingMDRef Ref;
109 public:
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);
118 return *this;
121 TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
122 Ref = X.Ref;
123 return *this;
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) {
155 return MD.get();
159 template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
160 using SimpleType = T *;
162 static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
163 return MD.get();
167 template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
168 using SimpleType = T *;
170 static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
171 return MD.get();
175 } // end namespace llvm
177 #endif // LLVM_IR_TRACKINGMDREF_H