123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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 refererences 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|