1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===// 2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The LLVM Compiler Infrastructure 4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source 6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details. 7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// References to metadata that track RAUW. 11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_IR_TRACKINGMDREF_H 15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_IR_TRACKINGMDREF_H 16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Metadata.h" 18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <algorithm> 19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cassert> 20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm { 22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \brief Tracking metadata reference. 24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class behaves like \a TrackingVH, but for metadata. 26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass TrackingMDRef { 27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Metadata *MD = nullptr; 28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef() = default; 31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); } 32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); } 34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); } 35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef &operator=(TrackingMDRef &&X) { 37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (&X == this) 38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot untrack(); 41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MD = X.MD; 42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot retrack(X); 43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef &operator=(const TrackingMDRef &X) { 47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (&X == this) 48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot untrack(); 51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MD = X.MD; 52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot track(); 53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ~TrackingMDRef() { untrack(); } 57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Metadata *get() const { return MD; } 59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot operator Metadata *() const { return get(); } 60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Metadata *operator->() const { return get(); } 61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Metadata &operator*() const { return *get(); } 62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void reset() { 64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot untrack(); 65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MD = nullptr; 66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void reset(Metadata *MD) { 68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot untrack(); 69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot this->MD = MD; 70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot track(); 71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \brief Check whether this has a trivial destructor. 74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If \c MD isn't replaceable, the destructor will be a no-op. 76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasTrivialDestructor() const { 77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !MD || !MetadataTracking::isReplaceable(*MD); 78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator==(const TrackingMDRef &X) const { return MD == X.MD; } 81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; } 82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void track() { 85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (MD) 86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MetadataTracking::track(MD); 87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void untrack() { 90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (MD) 91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MetadataTracking::untrack(MD); 92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void retrack(TrackingMDRef &X) { 95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(MD == X.MD && "Expected values to match"); 96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (X.MD) { 97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot MetadataTracking::retrack(X.MD, MD); 98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot X.MD = nullptr; 99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \brief Typed tracking ref. 104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Track refererences of a particular type. It's useful to use this for \a 106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// MDNode and \a ValueAsMetadata. 107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <class T> class TypedTrackingMDRef { 108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TrackingMDRef Ref; 109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TypedTrackingMDRef() = default; 112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {} 113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {} 115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {} 116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) { 118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Ref = std::move(X.Ref); 119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) { 123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Ref = X.Ref; 124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot T *get() const { return (T *)Ref.get(); } 128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot operator T *() const { return get(); } 129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot T *operator->() const { return get(); } 130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot T &operator*() const { return *get(); } 131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; } 133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; } 134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void reset() { Ref.reset(); } 136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); } 137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \brief Check whether this has a trivial destructor. 139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); } 140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotusing TrackingMDNodeRef = TypedTrackingMDRef<MDNode>; 143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotusing TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>; 144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Expose the underlying metadata to casting. 146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <> struct simplify_type<TrackingMDRef> { 147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using SimpleType = Metadata *; 148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); } 150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <> struct simplify_type<const TrackingMDRef> { 153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using SimpleType = Metadata *; 154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static SimpleType getSimplifiedValue(const TrackingMDRef &MD) { 156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return MD.get(); 157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <class T> struct simplify_type<TypedTrackingMDRef<T>> { 161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using SimpleType = T *; 162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) { 164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return MD.get(); 165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <class T> struct simplify_type<const TypedTrackingMDRef<T>> { 169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using SimpleType = T *; 170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) { 172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return MD.get(); 173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm 177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_IR_TRACKINGMDREF_H 179