Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  178.