LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/IR - TrackingMDRef.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 5 5
Test Date: 2026-02-27 04:14:43 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       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          700 :   ~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          700 :   void untrack() {
      89          700 :     if (MD)
      90          700 :       MetadataTracking::untrack(MD);
      91          700 :   }
      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
        

Generated by: LCOV version 2.0-1