mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-12-13 15:24:57 +00:00
Initial Commit
This commit is contained in:
177
thirdparty/capstone/suite/synctools/tablegen/include/llvm/IR/TrackingMDRef.h
vendored
Normal file
177
thirdparty/capstone/suite/synctools/tablegen/include/llvm/IR/TrackingMDRef.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
//===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// References to metadata that track RAUW.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_IR_TRACKINGMDREF_H
|
||||
#define LLVM_IR_TRACKINGMDREF_H
|
||||
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Tracking metadata reference.
|
||||
///
|
||||
/// This class behaves like \a TrackingVH, but for metadata.
|
||||
class TrackingMDRef {
|
||||
Metadata *MD = nullptr;
|
||||
|
||||
public:
|
||||
TrackingMDRef() = default;
|
||||
explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
|
||||
|
||||
TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
|
||||
TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
|
||||
|
||||
TrackingMDRef &operator=(TrackingMDRef &&X) {
|
||||
if (&X == this)
|
||||
return *this;
|
||||
|
||||
untrack();
|
||||
MD = X.MD;
|
||||
retrack(X);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TrackingMDRef &operator=(const TrackingMDRef &X) {
|
||||
if (&X == this)
|
||||
return *this;
|
||||
|
||||
untrack();
|
||||
MD = X.MD;
|
||||
track();
|
||||
return *this;
|
||||
}
|
||||
|
||||
~TrackingMDRef() { untrack(); }
|
||||
|
||||
Metadata *get() const { return MD; }
|
||||
operator Metadata *() const { return get(); }
|
||||
Metadata *operator->() const { return get(); }
|
||||
Metadata &operator*() const { return *get(); }
|
||||
|
||||
void reset() {
|
||||
untrack();
|
||||
MD = nullptr;
|
||||
}
|
||||
void reset(Metadata *MD) {
|
||||
untrack();
|
||||
this->MD = MD;
|
||||
track();
|
||||
}
|
||||
|
||||
/// Check whether this has a trivial destructor.
|
||||
///
|
||||
/// If \c MD isn't replaceable, the destructor will be a no-op.
|
||||
bool hasTrivialDestructor() const {
|
||||
return !MD || !MetadataTracking::isReplaceable(*MD);
|
||||
}
|
||||
|
||||
bool operator==(const TrackingMDRef &X) const { return MD == X.MD; }
|
||||
bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; }
|
||||
|
||||
private:
|
||||
void track() {
|
||||
if (MD)
|
||||
MetadataTracking::track(MD);
|
||||
}
|
||||
|
||||
void untrack() {
|
||||
if (MD)
|
||||
MetadataTracking::untrack(MD);
|
||||
}
|
||||
|
||||
void retrack(TrackingMDRef &X) {
|
||||
assert(MD == X.MD && "Expected values to match");
|
||||
if (X.MD) {
|
||||
MetadataTracking::retrack(X.MD, MD);
|
||||
X.MD = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Typed tracking ref.
|
||||
///
|
||||
/// Track references of a particular type. It's useful to use this for \a
|
||||
/// MDNode and \a ValueAsMetadata.
|
||||
template <class T> class TypedTrackingMDRef {
|
||||
TrackingMDRef Ref;
|
||||
|
||||
public:
|
||||
TypedTrackingMDRef() = default;
|
||||
explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
|
||||
|
||||
TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
|
||||
TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
|
||||
|
||||
TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
|
||||
Ref = std::move(X.Ref);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
|
||||
Ref = X.Ref;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T *get() const { return (T *)Ref.get(); }
|
||||
operator T *() const { return get(); }
|
||||
T *operator->() const { return get(); }
|
||||
T &operator*() const { return *get(); }
|
||||
|
||||
bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; }
|
||||
bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; }
|
||||
|
||||
void reset() { Ref.reset(); }
|
||||
void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); }
|
||||
|
||||
/// Check whether this has a trivial destructor.
|
||||
bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
|
||||
};
|
||||
|
||||
using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
|
||||
using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
|
||||
|
||||
// Expose the underlying metadata to casting.
|
||||
template <> struct simplify_type<TrackingMDRef> {
|
||||
using SimpleType = Metadata *;
|
||||
|
||||
static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
|
||||
};
|
||||
|
||||
template <> struct simplify_type<const TrackingMDRef> {
|
||||
using SimpleType = Metadata *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
|
||||
using SimpleType = T *;
|
||||
|
||||
static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
|
||||
using SimpleType = T *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_IR_TRACKINGMDREF_H
|
||||
Reference in New Issue
Block a user