Coverage Report

Created: 2025-12-12 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hermes/external/llvh/include/llvh/IR/TrackingMDRef.h
Line
Count
Source
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
17
#include "llvh/IR/Metadata.h"
18
#include <algorithm>
19
#include <cassert>
20
21
namespace llvh {
22
23
/// Tracking metadata reference.
24
///
25
/// This class behaves like \a TrackingVH, but for metadata.
26
class TrackingMDRef {
27
  Metadata *MD = nullptr;
28
29
public:
30
  TrackingMDRef() = default;
31
0
  explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
32
33
0
  TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
34
0
  TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
35
36
0
  TrackingMDRef &operator=(TrackingMDRef &&X) {
37
0
    if (&X == this)
38
0
      return *this;
39
0
40
0
    untrack();
41
0
    MD = X.MD;
42
0
    retrack(X);
43
0
    return *this;
44
0
  }
45
46
0
  TrackingMDRef &operator=(const TrackingMDRef &X) {
47
0
    if (&X == this)
48
0
      return *this;
49
0
50
0
    untrack();
51
0
    MD = X.MD;
52
0
    track();
53
0
    return *this;
54
0
  }
55
56
0
  ~TrackingMDRef() { untrack(); }
57
58
0
  Metadata *get() const { return MD; }
59
0
  operator Metadata *() const { return get(); }
60
0
  Metadata *operator->() const { return get(); }
61
0
  Metadata &operator*() const { return *get(); }
62
63
0
  void reset() {
64
0
    untrack();
65
0
    MD = nullptr;
66
0
  }
67
0
  void reset(Metadata *MD) {
68
0
    untrack();
69
0
    this->MD = MD;
70
0
    track();
71
0
  }
72
73
  /// Check whether this has a trivial destructor.
74
  ///
75
  /// If \c MD isn't replaceable, the destructor will be a no-op.
76
0
  bool hasTrivialDestructor() const {
77
0
    return !MD || !MetadataTracking::isReplaceable(*MD);
78
0
  }
79
80
0
  bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
81
0
  bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
82
83
private:
84
0
  void track() {
85
0
    if (MD)
86
0
      MetadataTracking::track(MD);
87
0
  }
88
89
0
  void untrack() {
90
0
    if (MD)
91
0
      MetadataTracking::untrack(MD);
92
0
  }
93
94
0
  void retrack(TrackingMDRef &X) {
95
0
    assert(MD == X.MD && "Expected values to match");
96
0
    if (X.MD) {
97
0
      MetadataTracking::retrack(X.MD, MD);
98
0
      X.MD = nullptr;
99
0
    }
100
0
  }
101
};
102
103
/// Typed tracking ref.
104
///
105
/// Track refererences of a particular type.  It's useful to use this for \a
106
/// MDNode and \a ValueAsMetadata.
107
template <class T> class TypedTrackingMDRef {
108
  TrackingMDRef Ref;
109
110
public:
111
  TypedTrackingMDRef() = default;
112
  explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
113
114
  TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
115
  TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
116
117
0
  TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
118
0
    Ref = std::move(X.Ref);
119
0
    return *this;
120
0
  }
121
122
  TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
123
    Ref = X.Ref;
124
    return *this;
125
  }
126
127
0
  T *get() const { return (T *)Ref.get(); }
128
0
  operator T *() const { return get(); }
129
  T *operator->() const { return get(); }
130
  T &operator*() const { return *get(); }
131
132
0
  bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
133
0
  bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
134
135
  void reset() { Ref.reset(); }
136
  void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
137
138
  /// Check whether this has a trivial destructor.
139
0
  bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
140
};
141
142
using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
143
using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
144
145
// Expose the underlying metadata to casting.
146
template <> struct simplify_type<TrackingMDRef> {
147
  using SimpleType = Metadata *;
148
149
0
  static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
150
};
151
152
template <> struct simplify_type<const TrackingMDRef> {
153
  using SimpleType = Metadata *;
154
155
0
  static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
156
0
    return MD.get();
157
0
  }
158
};
159
160
template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
161
  using SimpleType = T *;
162
163
  static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
164
    return MD.get();
165
  }
166
};
167
168
template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
169
  using SimpleType = T *;
170
171
  static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
172
    return MD.get();
173
  }
174
};
175
176
} // end namespace llvh
177
178
#endif // LLVM_IR_TRACKINGMDREF_H