Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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.
10
//
11
//===----------------------------------------------------------------------===//
12
 
13
#ifndef LLVM_IR_TRACKINGMDREF_H
14
#define LLVM_IR_TRACKINGMDREF_H
15
 
16
#include "llvm/IR/Metadata.h"
17
#include <algorithm>
18
#include <cassert>
19
 
20
namespace llvm {
21
 
22
/// Tracking metadata reference.
23
///
24
/// This class behaves like \a TrackingVH, but for metadata.
25
class TrackingMDRef {
26
  Metadata *MD = nullptr;
27
 
28
public:
29
  TrackingMDRef() = default;
30
  explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
31
 
32
  TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
33
  TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
34
 
35
  TrackingMDRef &operator=(TrackingMDRef &&X) {
36
    if (&X == this)
37
      return *this;
38
 
39
    untrack();
40
    MD = X.MD;
41
    retrack(X);
42
    return *this;
43
  }
44
 
45
  TrackingMDRef &operator=(const TrackingMDRef &X) {
46
    if (&X == this)
47
      return *this;
48
 
49
    untrack();
50
    MD = X.MD;
51
    track();
52
    return *this;
53
  }
54
 
55
  ~TrackingMDRef() { untrack(); }
56
 
57
  Metadata *get() const { return MD; }
58
  operator Metadata *() const { return get(); }
59
  Metadata *operator->() const { return get(); }
60
  Metadata &operator*() const { return *get(); }
61
 
62
  void reset() {
63
    untrack();
64
    MD = nullptr;
65
  }
66
  void reset(Metadata *MD) {
67
    untrack();
68
    this->MD = MD;
69
    track();
70
  }
71
 
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);
77
  }
78
 
79
  bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
80
  bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
81
 
82
private:
83
  void track() {
84
    if (MD)
85
      MetadataTracking::track(MD);
86
  }
87
 
88
  void untrack() {
89
    if (MD)
90
      MetadataTracking::untrack(MD);
91
  }
92
 
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;
98
    }
99
  }
100
};
101
 
102
/// Typed tracking ref.
103
///
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;
108
 
109
public:
110
  TypedTrackingMDRef() = default;
111
  explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
112
 
113
  TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
114
  TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
115
 
116
  TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
117
    Ref = std::move(X.Ref);
118
    return *this;
119
  }
120
 
121
  TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
122
    Ref = X.Ref;
123
    return *this;
124
  }
125
 
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(); }
130
 
131
  bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
132
  bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
133
 
134
  void reset() { Ref.reset(); }
135
  void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
136
 
137
  /// Check whether this has a trivial destructor.
138
  bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
139
};
140
 
141
using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
142
using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
143
 
144
// Expose the underlying metadata to casting.
145
template <> struct simplify_type<TrackingMDRef> {
146
  using SimpleType = Metadata *;
147
 
148
  static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
149
};
150
 
151
template <> struct simplify_type<const TrackingMDRef> {
152
  using SimpleType = Metadata *;
153
 
154
  static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
155
    return MD.get();
156
  }
157
};
158
 
159
template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
160
  using SimpleType = T *;
161
 
162
  static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
163
    return MD.get();
164
  }
165
};
166
 
167
template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
168
  using SimpleType = T *;
169
 
170
  static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
171
    return MD.get();
172
  }
173
};
174
 
175
} // end namespace llvm
176
 
177
#endif // LLVM_IR_TRACKINGMDREF_H