- //===- ValueHandle.h - Value Smart Pointer classes --------------*- 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 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file declares the ValueHandle class and its sub-classes. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_IR_VALUEHANDLE_H 
- #define LLVM_IR_VALUEHANDLE_H 
-   
- #include "llvm/ADT/DenseMapInfo.h" 
- #include "llvm/ADT/PointerIntPair.h" 
- #include "llvm/IR/Value.h" 
- #include "llvm/Support/Casting.h" 
- #include <cassert> 
-   
- namespace llvm { 
-   
- /// This is the common base class of value handles. 
- /// 
- /// ValueHandle's are smart pointers to Value's that have special behavior when 
- /// the value is deleted or ReplaceAllUsesWith'd.  See the specific handles 
- /// below for details. 
- class ValueHandleBase { 
-   friend class Value; 
-   
- protected: 
-   /// This indicates what sub class the handle actually is. 
-   /// 
-   /// This is to avoid having a vtable for the light-weight handle pointers. The 
-   /// fully general Callback version does have a vtable. 
-   enum HandleBaseKind { Assert, Callback, Weak, WeakTracking }; 
-   
-   ValueHandleBase(const ValueHandleBase &RHS) 
-       : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} 
-   
-   ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) 
-       : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) { 
-     if (isValid(getValPtr())) 
-       AddToExistingUseList(RHS.getPrevPtr()); 
-   } 
-   
- private: 
-   PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; 
-   ValueHandleBase *Next = nullptr; 
-   Value *Val = nullptr; 
-   
-   void setValPtr(Value *V) { Val = V; } 
-   
- public: 
-   explicit ValueHandleBase(HandleBaseKind Kind) 
-       : PrevPair(nullptr, Kind) {} 
-   ValueHandleBase(HandleBaseKind Kind, Value *V) 
-       : PrevPair(nullptr, Kind), Val(V) { 
-     if (isValid(getValPtr())) 
-       AddToUseList(); 
-   } 
-   
-   ~ValueHandleBase() { 
-     if (isValid(getValPtr())) 
-       RemoveFromUseList(); 
-   } 
-   
-   Value *operator=(Value *RHS) { 
-     if (getValPtr() == RHS) 
-       return RHS; 
-     if (isValid(getValPtr())) 
-       RemoveFromUseList(); 
-     setValPtr(RHS); 
-     if (isValid(getValPtr())) 
-       AddToUseList(); 
-     return RHS; 
-   } 
-   
-   Value *operator=(const ValueHandleBase &RHS) { 
-     if (getValPtr() == RHS.getValPtr()) 
-       return RHS.getValPtr(); 
-     if (isValid(getValPtr())) 
-       RemoveFromUseList(); 
-     setValPtr(RHS.getValPtr()); 
-     if (isValid(getValPtr())) 
-       AddToExistingUseList(RHS.getPrevPtr()); 
-     return getValPtr(); 
-   } 
-   
-   Value *operator->() const { return getValPtr(); } 
-   Value &operator*() const { 
-     Value *V = getValPtr(); 
-     assert(V && "Dereferencing deleted ValueHandle"); 
-     return *V; 
-   } 
-   
- protected: 
-   Value *getValPtr() const { return Val; } 
-   
-   static bool isValid(Value *V) { 
-     return V && 
-            V != DenseMapInfo<Value *>::getEmptyKey() && 
-            V != DenseMapInfo<Value *>::getTombstoneKey(); 
-   } 
-   
-   /// Remove this ValueHandle from its current use list. 
-   void RemoveFromUseList(); 
-   
-   /// Clear the underlying pointer without clearing the use list. 
-   /// 
-   /// This should only be used if a derived class has manually removed the 
-   /// handle from the use list. 
-   void clearValPtr() { setValPtr(nullptr); } 
-   
- public: 
-   // Callbacks made from Value. 
-   static void ValueIsDeleted(Value *V); 
-   static void ValueIsRAUWd(Value *Old, Value *New); 
-   
- private: 
-   // Internal implementation details. 
-   ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); } 
-   HandleBaseKind getKind() const { return PrevPair.getInt(); } 
-   void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); } 
-   
-   /// Add this ValueHandle to the use list for V. 
-   /// 
-   /// List is the address of either the head of the list or a Next node within 
-   /// the existing use list. 
-   void AddToExistingUseList(ValueHandleBase **List); 
-   
-   /// Add this ValueHandle to the use list after Node. 
-   void AddToExistingUseListAfter(ValueHandleBase *Node); 
-   
-   /// Add this ValueHandle to the use list for V. 
-   void AddToUseList(); 
- }; 
-   
- /// A nullable Value handle that is nullable. 
- /// 
- /// This is a value handle that points to a value, and nulls itself 
- /// out if that value is deleted. 
- class WeakVH : public ValueHandleBase { 
- public: 
-   WeakVH() : ValueHandleBase(Weak) {} 
-   WeakVH(Value *P) : ValueHandleBase(Weak, P) {} 
-   WeakVH(const WeakVH &RHS) 
-       : ValueHandleBase(Weak, RHS) {} 
-   
-   WeakVH &operator=(const WeakVH &RHS) = default; 
-   
-   Value *operator=(Value *RHS) { 
-     return ValueHandleBase::operator=(RHS); 
-   } 
-   Value *operator=(const ValueHandleBase &RHS) { 
-     return ValueHandleBase::operator=(RHS); 
-   } 
-   
-   operator Value*() const { 
-     return getValPtr(); 
-   } 
- }; 
-   
- // Specialize simplify_type to allow WeakVH to participate in 
- // dyn_cast, isa, etc. 
- template <> struct simplify_type<WeakVH> { 
-   using SimpleType = Value *; 
-   
-   static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } 
- }; 
- template <> struct simplify_type<const WeakVH> { 
-   using SimpleType = Value *; 
-   
-   static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } 
- }; 
-   
- // Specialize DenseMapInfo to allow WeakVH to participate in DenseMap. 
- template <> struct DenseMapInfo<WeakVH> { 
-   static inline WeakVH getEmptyKey() { 
-     return WeakVH(DenseMapInfo<Value *>::getEmptyKey()); 
-   } 
-   
-   static inline WeakVH getTombstoneKey() { 
-     return WeakVH(DenseMapInfo<Value *>::getTombstoneKey()); 
-   } 
-   
-   static unsigned getHashValue(const WeakVH &Val) { 
-     return DenseMapInfo<Value *>::getHashValue(Val); 
-   } 
-   
-   static bool isEqual(const WeakVH &LHS, const WeakVH &RHS) { 
-     return DenseMapInfo<Value *>::isEqual(LHS, RHS); 
-   } 
- }; 
-   
- /// Value handle that is nullable, but tries to track the Value. 
- /// 
- /// This is a value handle that tries hard to point to a Value, even across 
- /// RAUW operations, but will null itself out if the value is destroyed.  this 
- /// is useful for advisory sorts of information, but should not be used as the 
- /// key of a map (since the map would have to rearrange itself when the pointer 
- /// changes). 
- class WeakTrackingVH : public ValueHandleBase { 
- public: 
-   WeakTrackingVH() : ValueHandleBase(WeakTracking) {} 
-   WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {} 
-   WeakTrackingVH(const WeakTrackingVH &RHS) 
-       : ValueHandleBase(WeakTracking, RHS) {} 
-   
-   WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default; 
-   
-   Value *operator=(Value *RHS) { 
-     return ValueHandleBase::operator=(RHS); 
-   } 
-   Value *operator=(const ValueHandleBase &RHS) { 
-     return ValueHandleBase::operator=(RHS); 
-   } 
-   
-   operator Value*() const { 
-     return getValPtr(); 
-   } 
-   
-   bool pointsToAliveValue() const { 
-     return ValueHandleBase::isValid(getValPtr()); 
-   } 
- }; 
-   
- // Specialize simplify_type to allow WeakTrackingVH to participate in 
- // dyn_cast, isa, etc. 
- template <> struct simplify_type<WeakTrackingVH> { 
-   using SimpleType = Value *; 
-   
-   static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; } 
- }; 
- template <> struct simplify_type<const WeakTrackingVH> { 
-   using SimpleType = Value *; 
-   
-   static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) { 
-     return WVH; 
-   } 
- }; 
-   
- /// Value handle that asserts if the Value is deleted. 
- /// 
- /// This is a Value Handle that points to a value and asserts out if the value 
- /// is destroyed while the handle is still live.  This is very useful for 
- /// catching dangling pointer bugs and other things which can be non-obvious. 
- /// One particularly useful place to use this is as the Key of a map.  Dangling 
- /// pointer bugs often lead to really subtle bugs that only occur if another 
- /// object happens to get allocated to the same address as the old one.  Using 
- /// an AssertingVH ensures that an assert is triggered as soon as the bad 
- /// delete occurs. 
- /// 
- /// Note that an AssertingVH handle does *not* follow values across RAUW 
- /// operations.  This means that RAUW's need to explicitly update the 
- /// AssertingVH's as it moves.  This is required because in non-assert mode this 
- /// class turns into a trivial wrapper around a pointer. 
- template <typename ValueTy> 
- class AssertingVH 
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-     : public ValueHandleBase 
- #endif 
- { 
-   friend struct DenseMapInfo<AssertingVH<ValueTy>>; 
-   
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-   Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } 
-   void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); } 
- #else 
-   Value *ThePtr; 
-   Value *getRawValPtr() const { return ThePtr; } 
-   void setRawValPtr(Value *P) { ThePtr = P; } 
- #endif 
-   // Convert a ValueTy*, which may be const, to the raw Value*. 
-   static Value *GetAsValue(Value *V) { return V; } 
-   static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } 
-   
-   ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } 
-   void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } 
-   
- public: 
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-   AssertingVH() : ValueHandleBase(Assert) {} 
-   AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {} 
-   AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {} 
- #else 
-   AssertingVH() : ThePtr(nullptr) {} 
-   AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} 
-   AssertingVH(const AssertingVH &) = default; 
- #endif 
-   
-   operator ValueTy*() const { 
-     return getValPtr(); 
-   } 
-   
-   ValueTy *operator=(ValueTy *RHS) { 
-     setValPtr(RHS); 
-     return getValPtr(); 
-   } 
-   ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { 
-     setValPtr(RHS.getValPtr()); 
-     return getValPtr(); 
-   } 
-   
-   ValueTy *operator->() const { return getValPtr(); } 
-   ValueTy &operator*() const { return *getValPtr(); } 
- }; 
-   
- // Treat AssertingVH<T> like T* inside maps. This also allows using find_as() 
- // to look up a value without constructing a value handle. 
- template<typename T> 
- struct DenseMapInfo<AssertingVH<T>> : DenseMapInfo<T *> {}; 
-   
- /// Value handle that tracks a Value across RAUW. 
- /// 
- /// TrackingVH is designed for situations where a client needs to hold a handle 
- /// to a Value (or subclass) across some operations which may move that value, 
- /// but should never destroy it or replace it with some unacceptable type. 
- /// 
- /// It is an error to attempt to replace a value with one of a type which is 
- /// incompatible with any of its outstanding TrackingVHs. 
- /// 
- /// It is an error to read from a TrackingVH that does not point to a valid 
- /// value.  A TrackingVH is said to not point to a valid value if either it 
- /// hasn't yet been assigned a value yet or because the value it was tracking 
- /// has since been deleted. 
- /// 
- /// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH 
- /// no longer points to a valid value. 
- template <typename ValueTy> class TrackingVH { 
-   WeakTrackingVH InnerHandle; 
-   
- public: 
-   ValueTy *getValPtr() const { 
-     assert(InnerHandle.pointsToAliveValue() && 
-            "TrackingVH must be non-null and valid on dereference!"); 
-   
-     // Check that the value is a member of the correct subclass. We would like 
-     // to check this property on assignment for better debugging, but we don't 
-     // want to require a virtual interface on this VH. Instead we allow RAUW to 
-     // replace this value with a value of an invalid type, and check it here. 
-     assert(isa<ValueTy>(InnerHandle) && 
-            "Tracked Value was replaced by one with an invalid type!"); 
-     return cast<ValueTy>(InnerHandle); 
-   } 
-   
-   void setValPtr(ValueTy *P) { 
-     // Assigning to non-valid TrackingVH's are fine so we just unconditionally 
-     // assign here. 
-     InnerHandle = GetAsValue(P); 
-   } 
-   
-   // Convert a ValueTy*, which may be const, to the type the base 
-   // class expects. 
-   static Value *GetAsValue(Value *V) { return V; } 
-   static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } 
-   
- public: 
-   TrackingVH() = default; 
-   TrackingVH(ValueTy *P) { setValPtr(P); } 
-   
-   operator ValueTy*() const { 
-     return getValPtr(); 
-   } 
-   
-   ValueTy *operator=(ValueTy *RHS) { 
-     setValPtr(RHS); 
-     return getValPtr(); 
-   } 
-   
-   ValueTy *operator->() const { return getValPtr(); } 
-   ValueTy &operator*() const { return *getValPtr(); } 
- }; 
-   
- /// Value handle with callbacks on RAUW and destruction. 
- /// 
- /// This is a value handle that allows subclasses to define callbacks that run 
- /// when the underlying Value has RAUW called on it or is destroyed.  This 
- /// class can be used as the key of a map, as long as the user takes it out of 
- /// the map before calling setValPtr() (since the map has to rearrange itself 
- /// when the pointer changes).  Unlike ValueHandleBase, this class has a vtable. 
- class CallbackVH : public ValueHandleBase { 
-   virtual void anchor(); 
- protected: 
-   ~CallbackVH() = default; 
-   CallbackVH(const CallbackVH &) = default; 
-   CallbackVH &operator=(const CallbackVH &) = default; 
-   
-   void setValPtr(Value *P) { 
-     ValueHandleBase::operator=(P); 
-   } 
-   
- public: 
-   CallbackVH() : ValueHandleBase(Callback) {} 
-   CallbackVH(Value *P) : ValueHandleBase(Callback, P) {} 
-   CallbackVH(const Value *P) : CallbackVH(const_cast<Value *>(P)) {} 
-   
-   operator Value*() const { 
-     return getValPtr(); 
-   } 
-   
-   /// Callback for Value destruction. 
-   /// 
-   /// Called when this->getValPtr() is destroyed, inside ~Value(), so you 
-   /// may call any non-virtual Value method on getValPtr(), but no subclass 
-   /// methods.  If WeakTrackingVH were implemented as a CallbackVH, it would use 
-   /// this 
-   /// method to call setValPtr(NULL).  AssertingVH would use this method to 
-   /// cause an assertion failure. 
-   /// 
-   /// All implementations must remove the reference from this object to the 
-   /// Value that's being destroyed. 
-   virtual void deleted() { setValPtr(nullptr); } 
-   
-   /// Callback for Value RAUW. 
-   /// 
-   /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, 
-   /// _before_ any of the uses have actually been replaced.  If WeakTrackingVH 
-   /// were 
-   /// implemented as a CallbackVH, it would use this method to call 
-   /// setValPtr(new_value).  AssertingVH would do nothing in this method. 
-   virtual void allUsesReplacedWith(Value *) {} 
- }; 
-   
- /// Value handle that poisons itself if the Value is deleted. 
- /// 
- /// This is a Value Handle that points to a value and poisons itself if the 
- /// value is destroyed while the handle is still live.  This is very useful for 
- /// catching dangling pointer bugs where an \c AssertingVH cannot be used 
- /// because the dangling handle needs to outlive the value without ever being 
- /// used. 
- /// 
- /// One particularly useful place to use this is as the Key of a map. Dangling 
- /// pointer bugs often lead to really subtle bugs that only occur if another 
- /// object happens to get allocated to the same address as the old one. Using 
- /// a PoisoningVH ensures that an assert is triggered if looking up a new value 
- /// in the map finds a handle from the old value. 
- /// 
- /// Note that a PoisoningVH handle does *not* follow values across RAUW 
- /// operations. This means that RAUW's need to explicitly update the 
- /// PoisoningVH's as it moves. This is required because in non-assert mode this 
- /// class turns into a trivial wrapper around a pointer. 
- template <typename ValueTy> 
- class PoisoningVH final 
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-     : public CallbackVH 
- #endif 
- { 
-   friend struct DenseMapInfo<PoisoningVH<ValueTy>>; 
-   
-   // Convert a ValueTy*, which may be const, to the raw Value*. 
-   static Value *GetAsValue(Value *V) { return V; } 
-   static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); } 
-   
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-   /// A flag tracking whether this value has been poisoned. 
-   /// 
-   /// On delete and RAUW, we leave the value pointer alone so that as a raw 
-   /// pointer it produces the same value (and we fit into the same key of 
-   /// a hash table, etc), but we poison the handle so that any top-level usage 
-   /// will fail. 
-   bool Poisoned = false; 
-   
-   Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } 
-   void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); } 
-   
-   /// Handle deletion by poisoning the handle. 
-   void deleted() override { 
-     assert(!Poisoned && "Tried to delete an already poisoned handle!"); 
-     Poisoned = true; 
-     RemoveFromUseList(); 
-   } 
-   
-   /// Handle RAUW by poisoning the handle. 
-   void allUsesReplacedWith(Value *) override { 
-     assert(!Poisoned && "Tried to RAUW an already poisoned handle!"); 
-     Poisoned = true; 
-     RemoveFromUseList(); 
-   } 
- #else // LLVM_ENABLE_ABI_BREAKING_CHECKS 
-   Value *ThePtr = nullptr; 
-   
-   Value *getRawValPtr() const { return ThePtr; } 
-   void setRawValPtr(Value *P) { ThePtr = P; } 
- #endif 
-   
-   ValueTy *getValPtr() const { 
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-     assert(!Poisoned && "Accessed a poisoned value handle!"); 
- #endif 
-     return static_cast<ValueTy *>(getRawValPtr()); 
-   } 
-   void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } 
-   
- public: 
-   PoisoningVH() = default; 
- #if LLVM_ENABLE_ABI_BREAKING_CHECKS 
-   PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {} 
-   PoisoningVH(const PoisoningVH &RHS) 
-       : CallbackVH(RHS), Poisoned(RHS.Poisoned) {} 
-   
-   ~PoisoningVH() { 
-     if (Poisoned) 
-       clearValPtr(); 
-   } 
-   
-   PoisoningVH &operator=(const PoisoningVH &RHS) { 
-     if (Poisoned) 
-       clearValPtr(); 
-     CallbackVH::operator=(RHS); 
-     Poisoned = RHS.Poisoned; 
-     return *this; 
-   } 
- #else 
-   PoisoningVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} 
- #endif 
-   
-   operator ValueTy *() const { return getValPtr(); } 
-   
-   ValueTy *operator->() const { return getValPtr(); } 
-   ValueTy &operator*() const { return *getValPtr(); } 
- }; 
-   
- // Specialize DenseMapInfo to allow PoisoningVH to participate in DenseMap. 
- template <typename T> struct DenseMapInfo<PoisoningVH<T>> { 
-   static inline PoisoningVH<T> getEmptyKey() { 
-     PoisoningVH<T> Res; 
-     Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); 
-     return Res; 
-   } 
-   
-   static inline PoisoningVH<T> getTombstoneKey() { 
-     PoisoningVH<T> Res; 
-     Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); 
-     return Res; 
-   } 
-   
-   static unsigned getHashValue(const PoisoningVH<T> &Val) { 
-     return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); 
-   } 
-   
-   static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) { 
-     return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), 
-                                           RHS.getRawValPtr()); 
-   } 
-   
-   // Allow lookup by T* via find_as(), without constructing a temporary 
-   // value handle. 
-   
-   static unsigned getHashValue(const T *Val) { 
-     return DenseMapInfo<Value *>::getHashValue(Val); 
-   } 
-   
-   static bool isEqual(const T *LHS, const PoisoningVH<T> &RHS) { 
-     return DenseMapInfo<Value *>::isEqual(LHS, RHS.getRawValPtr()); 
-   } 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_IR_VALUEHANDLE_H 
-