[Modules] Move ValueHandle into the IR library where Value itself lives.
authorChandler Carruth <chandlerc@gmail.com>
Tue, 4 Mar 2014 11:17:44 +0000 (11:17 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 4 Mar 2014 11:17:44 +0000 (11:17 +0000)
Move the test for this class into the IR unittests as well.

This uncovers that ValueMap too is in the IR library. Ironically, the
unittest for ValueMap is useless in the Support library (honestly, so
was the ValueHandle test) and so it already lives in the IR unittests.
Mmmm, tasty layering.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202821 91177308-0d34-0410-b5e6-96231b3b80d8

52 files changed:
include/llvm/ADT/ValueMap.h
include/llvm/Analysis/AliasSetTracker.h
include/llvm/Analysis/CallGraph.h
include/llvm/Analysis/IVUsers.h
include/llvm/Analysis/MemoryBuiltins.h
include/llvm/Analysis/MemoryDependenceAnalysis.h
include/llvm/Analysis/ScalarEvolution.h
include/llvm/Analysis/ScalarEvolutionExpander.h
include/llvm/CodeGen/LexicalScopes.h
include/llvm/CodeGen/MachineModuleInfo.h
include/llvm/DIBuilder.h
include/llvm/ExecutionEngine/ExecutionEngine.h
include/llvm/IR/IRBuilder.h
include/llvm/IR/Value.h
include/llvm/IR/ValueHandle.h [new file with mode: 0644]
include/llvm/Support/ValueHandle.h [deleted file]
include/llvm/Transforms/Utils/Cloning.h
include/llvm/Transforms/Utils/SSAUpdaterImpl.h
include/llvm/Transforms/Utils/SimplifyIndVar.h
lib/Analysis/InstructionSimplify.cpp
lib/Analysis/LazyValueInfo.cpp
lib/AsmParser/LLParser.h
lib/Bitcode/Reader/BitcodeReader.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/CodeGenPrepare.cpp
lib/ExecutionEngine/EventListenerCommon.h
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
lib/ExecutionEngine/JIT/JIT.h
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/IR/DebugInfo.cpp
lib/IR/LLVMContextImpl.h
lib/IR/Metadata.cpp
lib/IR/Value.cpp
lib/Target/PowerPC/PPCCTRLoops.cpp
lib/Target/XCore/XCoreLowerThreadLocal.cpp
lib/Transforms/IPO/GlobalOpt.cpp
lib/Transforms/IPO/MergeFunctions.cpp
lib/Transforms/InstCombine/InstructionCombining.cpp
lib/Transforms/Scalar/JumpThreading.cpp
lib/Transforms/Scalar/LoopStrengthReduce.cpp
lib/Transforms/Scalar/Reassociate.cpp
lib/Transforms/Scalar/TailRecursionElimination.cpp
lib/Transforms/Utils/BasicBlockUtils.cpp
lib/Transforms/Utils/Local.cpp
lib/Transforms/Vectorize/BBVectorize.cpp
lib/Transforms/Vectorize/LoopVectorize.cpp
unittests/IR/CMakeLists.txt
unittests/IR/MetadataTest.cpp
unittests/IR/ValueHandleTest.cpp [new file with mode: 0644]
unittests/Support/CMakeLists.txt
unittests/Support/ValueHandleTest.cpp [deleted file]

index b4fed7a0ebd26962a40dceb555320385f2f6ee59..18913d8b8d72e3659984479127fa37188a56852d 100644 (file)
@@ -27,8 +27,8 @@
 #define LLVM_ADT_VALUEMAP_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Mutex.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/type_traits.h"
 #include <iterator>
 
index da007072e559534f19006d5dc5c169e7d82f81f4..a8005058e7ea5fb4b532c1efc5c14500edd6323f 100644 (file)
@@ -20,7 +20,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include <vector>
 
 namespace llvm {
index c813e4b318971d61da90dc5ab55291eb20731b62..2866ed6e92a7dd90f9c71269701f09d9e3330920 100644 (file)
@@ -57,9 +57,9 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/IncludeFile.h"
-#include "llvm/Support/ValueHandle.h"
 #include <map>
 
 namespace llvm {
index 58d347ed19b9cc255d2ff7483e26290e3c738c2c..52df2fff8e974224c6c6d6f91f34a63821f2d9ac 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 
 namespace llvm {
 
index ec2fea838fa74daa901c4b24cdb44d6966475665..7784db402c18fa22cb952f1498fd7ce1e7a7ca42 100644 (file)
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/InstVisitor.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/TargetFolder.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 class CallInst;
index b4b401a1e6b3f76e77e25047368595ff7c42801f..329aa253648739c61c730fdc4728de316d2ea22a 100644 (file)
@@ -20,8 +20,8 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
   class Function;
index e1d4861a555af6ab6bb38c48e0aa24a75e01a883..e2d8765b4a82c66a959aafddc4fc899813496ff1 100644 (file)
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
 #include <map>
 
 namespace llvm {
index 167861db621ea628c91b3459ca933db77f51d9ce..3e57ba877ee1f3c887e09042a69212eb38c9a764 100644 (file)
@@ -17,8 +17,8 @@
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/Analysis/ScalarEvolutionNormalization.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/TargetFolder.h"
-#include "llvm/Support/ValueHandle.h"
 #include <set>
 
 namespace llvm {
index af1f8470a4256be4ed709891caa397873e763ec8..bfa787dbe591b01f6752ba146f2b9a450598b1d0 100644 (file)
@@ -22,8 +22,8 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/ValueHandle.h"
 #include <utility>
 namespace llvm {
 
index 460c08c8ca7ee6d630d9c1114f789af334012e11..b51020654af558267e05629114433a44597d5f36 100644 (file)
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MachineLocation.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/DebugLoc.h"
 #include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
index df900e29ef12562122665dd04ae0ab762a64ab30..d795859adaa99cdc9df3ea39c365b90deb013ac7 100644 (file)
@@ -18,8 +18,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
   class BasicBlock;
index b906b274f3131788b4dbaa096d7e96a3d916e530..605236ba87aad09466ee34b02ad39d957fa05b23 100644 (file)
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/ValueMap.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/MC/MCCodeGenInfo.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Mutex.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 #include <map>
index e43bc9fc5d3b1e608a8e02a609ac5b0373ae503a..29264668e1b7b8ab7e57aac1ead270e0f1f80323 100644 (file)
@@ -23,9 +23,9 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/ConstantFolder.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
   class MDNode;
index 858c6e3f4f8a707a138b4fb90cf2ee5697bace45..f1945020d508eeaad7c02e46e9ddd3f690426d8a 100644 (file)
@@ -61,7 +61,7 @@ typedef StringMapEntry<Value*> ValueName;
 /// Every value has a "use list" that keeps track of which other Values are
 /// using this Value.  A Value can also have an arbitrary number of ValueHandle
 /// objects that watch it and listen to RAUW and Destroy events.  See
-/// llvm/Support/ValueHandle.h for details.
+/// llvm/IR/ValueHandle.h for details.
 ///
 /// @brief LLVM Value Representation
 class Value {
diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h
new file mode 100644 (file)
index 0000000..9b5e11a
--- /dev/null
@@ -0,0 +1,380 @@
+//===- ValueHandle.h - Value Smart Pointer classes --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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"
+
+namespace llvm {
+class ValueHandleBase;
+template<typename From> struct simplify_type;
+
+// ValueHandleBase** is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<ValueHandleBase**> {
+public:
+  static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
+  static inline ValueHandleBase **getFromVoidPointer(void *P) {
+    return static_cast<ValueHandleBase**>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+
+/// ValueHandleBase - 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:
+  /// HandleBaseKind - 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,
+    Tracking,
+    Weak
+  };
+
+private:
+  PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
+  ValueHandleBase *Next;
+
+  // A subclass may want to store some information along with the value
+  // pointer. Allow them to do this by making the value pointer a pointer-int
+  // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
+  // access.
+  PointerIntPair<Value*, 2> VP;
+
+  ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
+public:
+  explicit ValueHandleBase(HandleBaseKind Kind)
+    : PrevPair(0, Kind), Next(0), VP(0, 0) {}
+  ValueHandleBase(HandleBaseKind Kind, Value *V)
+    : PrevPair(0, Kind), Next(0), VP(V, 0) {
+    if (isValid(VP.getPointer()))
+      AddToUseList();
+  }
+  ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
+    : PrevPair(0, Kind), Next(0), VP(RHS.VP) {
+    if (isValid(VP.getPointer()))
+      AddToExistingUseList(RHS.getPrevPtr());
+  }
+  ~ValueHandleBase() {
+    if (isValid(VP.getPointer()))
+      RemoveFromUseList();
+  }
+
+  Value *operator=(Value *RHS) {
+    if (VP.getPointer() == RHS) return RHS;
+    if (isValid(VP.getPointer())) RemoveFromUseList();
+    VP.setPointer(RHS);
+    if (isValid(VP.getPointer())) AddToUseList();
+    return RHS;
+  }
+
+  Value *operator=(const ValueHandleBase &RHS) {
+    if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
+    if (isValid(VP.getPointer())) RemoveFromUseList();
+    VP.setPointer(RHS.VP.getPointer());
+    if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
+    return VP.getPointer();
+  }
+
+  Value *operator->() const { return getValPtr(); }
+  Value &operator*() const { return *getValPtr(); }
+
+protected:
+  Value *getValPtr() const { return VP.getPointer(); }
+
+  void setValPtrInt(unsigned K) { VP.setInt(K); }
+  unsigned getValPtrInt() const { return VP.getInt(); }
+
+  static bool isValid(Value *V) {
+    return V &&
+           V != DenseMapInfo<Value *>::getEmptyKey() &&
+           V != DenseMapInfo<Value *>::getTombstoneKey();
+  }
+
+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); }
+
+  /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
+  /// List is the address of either the head of the list or a Next node within
+  /// the existing use list.
+  void AddToExistingUseList(ValueHandleBase **List);
+
+  /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
+  /// Node.
+  void AddToExistingUseListAfter(ValueHandleBase *Node);
+
+  /// AddToUseList - Add this ValueHandle to the use list for VP.
+  void AddToUseList();
+  /// RemoveFromUseList - Remove this ValueHandle from its current use list.
+  void RemoveFromUseList();
+};
+
+/// WeakVH - 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 WeakVH : public ValueHandleBase {
+public:
+  WeakVH() : ValueHandleBase(Weak) {}
+  WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
+  WeakVH(const WeakVH &RHS)
+    : ValueHandleBase(Weak, RHS) {}
+
+  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> {
+  typedef Value* SimpleType;
+  static SimpleType getSimplifiedValue(WeakVH &WVH) {
+    return WVH;
+  }
+};
+
+/// AssertingVH - 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
+#ifndef NDEBUG
+  : public ValueHandleBase
+#endif
+  {
+
+#ifndef NDEBUG
+  ValueTy *getValPtr() const {
+    return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+  }
+  void setValPtr(ValueTy *P) {
+    ValueHandleBase::operator=(GetAsValue(P));
+  }
+#else
+  ValueTy *ThePtr;
+  ValueTy *getValPtr() const { return ThePtr; }
+  void setValPtr(ValueTy *P) { ThePtr = P; }
+#endif
+
+  // 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:
+#ifndef NDEBUG
+  AssertingVH() : ValueHandleBase(Assert) {}
+  AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
+  AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
+#else
+  AssertingVH() : ThePtr(0) {}
+  AssertingVH(ValueTy *P) : ThePtr(P) {}
+#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(); }
+};
+
+// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
+template<typename T>
+struct DenseMapInfo<AssertingVH<T> > {
+  typedef DenseMapInfo<T*> PointerInfo;
+  static inline AssertingVH<T> getEmptyKey() {
+    return AssertingVH<T>(PointerInfo::getEmptyKey());
+  }
+  static inline T* getTombstoneKey() {
+    return AssertingVH<T>(PointerInfo::getTombstoneKey());
+  }
+  static unsigned getHashValue(const AssertingVH<T> &Val) {
+    return PointerInfo::getHashValue(Val);
+  }
+  static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
+    return LHS == RHS;
+  }
+};
+  
+template <typename T>
+struct isPodLike<AssertingVH<T> > {
+#ifdef NDEBUG
+  static const bool value = true;
+#else
+  static const bool value = false;
+#endif
+};
+
+
+/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
+/// even across RAUW operations.
+///
+/// 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 do anything with a TrackingVH whose value has been
+/// destroyed, except to destruct it.
+///
+/// It is an error to attempt to replace a value with one of a type which is
+/// incompatible with any of its outstanding TrackingVHs.
+template<typename ValueTy>
+class TrackingVH : public ValueHandleBase {
+  void CheckValidity() const {
+    Value *VP = ValueHandleBase::getValPtr();
+
+    // Null is always ok.
+    if (!VP) return;
+
+    // Check that this value is valid (i.e., it hasn't been deleted). We
+    // explicitly delay this check until access to avoid requiring clients to be
+    // unnecessarily careful w.r.t. destruction.
+    assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
+
+    // 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>(VP) &&
+           "Tracked Value was replaced by one with an invalid type!");
+  }
+
+  ValueTy *getValPtr() const {
+    CheckValidity();
+    return (ValueTy*)ValueHandleBase::getValPtr();
+  }
+  void setValPtr(ValueTy *P) {
+    CheckValidity();
+    ValueHandleBase::operator=(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() : ValueHandleBase(Tracking) {}
+  TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
+  TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
+
+  operator ValueTy*() const {
+    return getValPtr();
+  }
+
+  ValueTy *operator=(ValueTy *RHS) {
+    setValPtr(RHS);
+    return getValPtr();
+  }
+  ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
+    setValPtr(RHS.getValPtr());
+    return getValPtr();
+  }
+
+  ValueTy *operator->() const { return getValPtr(); }
+  ValueTy &operator*() const { return *getValPtr(); }
+};
+
+/// CallbackVH - 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 and a virtual destructor.
+class CallbackVH : public ValueHandleBase {
+  virtual void anchor();
+protected:
+  CallbackVH(const CallbackVH &RHS)
+    : ValueHandleBase(Callback, RHS) {}
+
+  virtual ~CallbackVH() {}
+
+  void setValPtr(Value *P) {
+    ValueHandleBase::operator=(P);
+  }
+
+public:
+  CallbackVH() : ValueHandleBase(Callback) {}
+  CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
+
+  operator Value*() const {
+    return getValPtr();
+  }
+
+  /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
+  /// call any non-virtual Value method on getValPtr(), but no subclass methods.
+  /// If WeakVH 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(NULL); }
+
+  /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
+  /// _before_ any of the uses have actually been replaced.  If WeakVH 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 *) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
deleted file mode 100644 (file)
index bc02ba3..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the ValueHandle class and its sub-classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_VALUEHANDLE_H
-#define LLVM_SUPPORT_VALUEHANDLE_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/IR/Value.h"
-
-namespace llvm {
-class ValueHandleBase;
-template<typename From> struct simplify_type;
-
-// ValueHandleBase** is only 4-byte aligned.
-template<>
-class PointerLikeTypeTraits<ValueHandleBase**> {
-public:
-  static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
-  static inline ValueHandleBase **getFromVoidPointer(void *P) {
-    return static_cast<ValueHandleBase**>(P);
-  }
-  enum { NumLowBitsAvailable = 2 };
-};
-
-/// ValueHandleBase - 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:
-  /// HandleBaseKind - 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,
-    Tracking,
-    Weak
-  };
-
-private:
-  PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
-  ValueHandleBase *Next;
-
-  // A subclass may want to store some information along with the value
-  // pointer. Allow them to do this by making the value pointer a pointer-int
-  // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
-  // access.
-  PointerIntPair<Value*, 2> VP;
-
-  ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
-public:
-  explicit ValueHandleBase(HandleBaseKind Kind)
-    : PrevPair(0, Kind), Next(0), VP(0, 0) {}
-  ValueHandleBase(HandleBaseKind Kind, Value *V)
-    : PrevPair(0, Kind), Next(0), VP(V, 0) {
-    if (isValid(VP.getPointer()))
-      AddToUseList();
-  }
-  ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
-    : PrevPair(0, Kind), Next(0), VP(RHS.VP) {
-    if (isValid(VP.getPointer()))
-      AddToExistingUseList(RHS.getPrevPtr());
-  }
-  ~ValueHandleBase() {
-    if (isValid(VP.getPointer()))
-      RemoveFromUseList();
-  }
-
-  Value *operator=(Value *RHS) {
-    if (VP.getPointer() == RHS) return RHS;
-    if (isValid(VP.getPointer())) RemoveFromUseList();
-    VP.setPointer(RHS);
-    if (isValid(VP.getPointer())) AddToUseList();
-    return RHS;
-  }
-
-  Value *operator=(const ValueHandleBase &RHS) {
-    if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
-    if (isValid(VP.getPointer())) RemoveFromUseList();
-    VP.setPointer(RHS.VP.getPointer());
-    if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
-    return VP.getPointer();
-  }
-
-  Value *operator->() const { return getValPtr(); }
-  Value &operator*() const { return *getValPtr(); }
-
-protected:
-  Value *getValPtr() const { return VP.getPointer(); }
-
-  void setValPtrInt(unsigned K) { VP.setInt(K); }
-  unsigned getValPtrInt() const { return VP.getInt(); }
-
-  static bool isValid(Value *V) {
-    return V &&
-           V != DenseMapInfo<Value *>::getEmptyKey() &&
-           V != DenseMapInfo<Value *>::getTombstoneKey();
-  }
-
-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); }
-
-  /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
-  /// List is the address of either the head of the list or a Next node within
-  /// the existing use list.
-  void AddToExistingUseList(ValueHandleBase **List);
-
-  /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
-  /// Node.
-  void AddToExistingUseListAfter(ValueHandleBase *Node);
-
-  /// AddToUseList - Add this ValueHandle to the use list for VP.
-  void AddToUseList();
-  /// RemoveFromUseList - Remove this ValueHandle from its current use list.
-  void RemoveFromUseList();
-};
-
-/// WeakVH - 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 WeakVH : public ValueHandleBase {
-public:
-  WeakVH() : ValueHandleBase(Weak) {}
-  WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
-  WeakVH(const WeakVH &RHS)
-    : ValueHandleBase(Weak, RHS) {}
-
-  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> {
-  typedef Value* SimpleType;
-  static SimpleType getSimplifiedValue(WeakVH &WVH) {
-    return WVH;
-  }
-};
-
-/// AssertingVH - 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
-#ifndef NDEBUG
-  : public ValueHandleBase
-#endif
-  {
-
-#ifndef NDEBUG
-  ValueTy *getValPtr() const {
-    return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
-  }
-  void setValPtr(ValueTy *P) {
-    ValueHandleBase::operator=(GetAsValue(P));
-  }
-#else
-  ValueTy *ThePtr;
-  ValueTy *getValPtr() const { return ThePtr; }
-  void setValPtr(ValueTy *P) { ThePtr = P; }
-#endif
-
-  // 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:
-#ifndef NDEBUG
-  AssertingVH() : ValueHandleBase(Assert) {}
-  AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
-  AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
-#else
-  AssertingVH() : ThePtr(0) {}
-  AssertingVH(ValueTy *P) : ThePtr(P) {}
-#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(); }
-};
-
-// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
-template<typename T>
-struct DenseMapInfo<AssertingVH<T> > {
-  typedef DenseMapInfo<T*> PointerInfo;
-  static inline AssertingVH<T> getEmptyKey() {
-    return AssertingVH<T>(PointerInfo::getEmptyKey());
-  }
-  static inline T* getTombstoneKey() {
-    return AssertingVH<T>(PointerInfo::getTombstoneKey());
-  }
-  static unsigned getHashValue(const AssertingVH<T> &Val) {
-    return PointerInfo::getHashValue(Val);
-  }
-  static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
-    return LHS == RHS;
-  }
-};
-  
-template <typename T>
-struct isPodLike<AssertingVH<T> > {
-#ifdef NDEBUG
-  static const bool value = true;
-#else
-  static const bool value = false;
-#endif
-};
-
-
-/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
-/// even across RAUW operations.
-///
-/// 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 do anything with a TrackingVH whose value has been
-/// destroyed, except to destruct it.
-///
-/// It is an error to attempt to replace a value with one of a type which is
-/// incompatible with any of its outstanding TrackingVHs.
-template<typename ValueTy>
-class TrackingVH : public ValueHandleBase {
-  void CheckValidity() const {
-    Value *VP = ValueHandleBase::getValPtr();
-
-    // Null is always ok.
-    if (!VP) return;
-
-    // Check that this value is valid (i.e., it hasn't been deleted). We
-    // explicitly delay this check until access to avoid requiring clients to be
-    // unnecessarily careful w.r.t. destruction.
-    assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
-
-    // 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>(VP) &&
-           "Tracked Value was replaced by one with an invalid type!");
-  }
-
-  ValueTy *getValPtr() const {
-    CheckValidity();
-    return (ValueTy*)ValueHandleBase::getValPtr();
-  }
-  void setValPtr(ValueTy *P) {
-    CheckValidity();
-    ValueHandleBase::operator=(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() : ValueHandleBase(Tracking) {}
-  TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
-  TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
-
-  operator ValueTy*() const {
-    return getValPtr();
-  }
-
-  ValueTy *operator=(ValueTy *RHS) {
-    setValPtr(RHS);
-    return getValPtr();
-  }
-  ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
-    setValPtr(RHS.getValPtr());
-    return getValPtr();
-  }
-
-  ValueTy *operator->() const { return getValPtr(); }
-  ValueTy &operator*() const { return *getValPtr(); }
-};
-
-/// CallbackVH - 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 and a virtual destructor.
-class CallbackVH : public ValueHandleBase {
-  virtual void anchor();
-protected:
-  CallbackVH(const CallbackVH &RHS)
-    : ValueHandleBase(Callback, RHS) {}
-
-  virtual ~CallbackVH() {}
-
-  void setValPtr(Value *P) {
-    ValueHandleBase::operator=(P);
-  }
-
-public:
-  CallbackVH() : ValueHandleBase(Callback) {}
-  CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
-
-  operator Value*() const {
-    return getValPtr();
-  }
-
-  /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
-  /// call any non-virtual Value method on getValPtr(), but no subclass methods.
-  /// If WeakVH 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(NULL); }
-
-  /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
-  /// _before_ any of the uses have actually been replaced.  If WeakVH 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 *) {}
-};
-
-} // End llvm namespace
-
-#endif
index 7b6db47a81f4bf7e1fb509faf2a64b0efde7af34..6c4e50125ef3a5609780922ed4dd14bff0222d34 100644 (file)
@@ -21,7 +21,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ADT/ValueMap.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Transforms/Utils/ValueMapper.h"
 
 namespace llvm {
index a9adbd73c152e590894bb730533575864ddee28a..0f3da1650811e6204e1185960140fe03556e192d 100644 (file)
@@ -17,9 +17,9 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
index 3c3de467c45e5a4f9a19ed38e434e23f43db96f4..dedeca3b30a6467d42410fff2f0614bf7620faad 100644 (file)
@@ -16,8 +16,8 @@
 #ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
 #define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
 
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
index b1af8f814214f2a5566310052eff51e224056c83..6cefc785baf764c0d890abae33c9091be55114ab 100644 (file)
@@ -30,8 +30,8 @@
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/ConstantRange.h"
-#include "llvm/Support/ValueHandle.h"
 using namespace llvm;
 using namespace llvm::PatternMatch;
 
index c78763f206952330772eb0caccd56da8293f3e10..b68b3869e70695bfe3acc9957eed98d5989ee939 100644 (file)
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include <map>
index d25374ff0531bf071bc60229b8e34479151b0d27..790ffd2c71050e957a67065abfd958c48cc13c55 100644 (file)
@@ -22,7 +22,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include <map>
 
 namespace llvm {
index f6c9d6678a47110ae20d4937e2613e761010ad50..56795e23676e9e808a23992f97c0ab0295917266 100644 (file)
@@ -21,7 +21,7 @@
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/OperandTraits.h"
 #include "llvm/IR/Type.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/system_error.h"
 #include <vector>
 
index 5d46620423360d423d18793d69a1a8d705454724..91aa7639ad3993c54a412ec065661fce3d540197 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
@@ -42,7 +43,6 @@
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Timer.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Target/TargetFrameLowering.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
index 8ad68bdfbb4ec785a01c65d0627e8aaa3a1c8c2d..7e2dce6a717b52145c8a85f76b2747a43072fd29 100644 (file)
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Target/TargetLowering.h"
index 314db8bd84c2cad6387938280574207cef6be880..5d756ed062f54c4b211cbb895e00a4020240c2e7 100644 (file)
@@ -17,8 +17,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/DebugInfo.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
index 335efaf8a1bb85fd5c9601b94a00bd02afd9fe58..062c13f27896ba28d2946cde6f628ebb8b5c665a 100644 (file)
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MutexGuard.h"
 #include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
 #include <cmath>
index 7dc295fcbf73b4982c85b5e32c982131fb479235..bfcbbc850c37097d30099ada147b82a4ba655abc 100644 (file)
@@ -28,7 +28,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Errno.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include "EventListenerCommon.h"
 #include "IntelJITEventsWrapper.h"
 
index 4f6416ff10bfeb444115d656d31a9ce5fa8a8321..6af2b4ae365383f6441af5cd838ed065932f7231 100644 (file)
@@ -15,8 +15,8 @@
 #define JIT_H
 
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/PassManager.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
index acbbfa145521b21455d2983a9ce4be0c4a525cc0..ba5d4e42addc7314fbe832c4ce9962a3a9690278 100644 (file)
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Disassembler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/MutexGuard.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetJITInfo.h"
index df059c4d7fc58eb0d83d2c488c58aa885099471d..add4b87a8b12b3eb2bcf6dd326147e17d9233949 100644 (file)
@@ -24,9 +24,9 @@
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 using namespace llvm::dwarf;
index 8b94ab1c779844ca6be6fee1ba7e2657b5109fb6..7a3cdb9e9d3544b3453a396318747a4e6ddb02a3 100644 (file)
@@ -30,7 +30,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include <vector>
 
 namespace llvm {
index ad943de88cc5a5e9ede7827b078bd67250e8f568..512dec196f2665bca86b0f9ffe4d47bd0658fd18 100644 (file)
@@ -22,9 +22,9 @@
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/LeakDetector.h"
-#include "llvm/Support/ValueHandle.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
index cc850cb2cb9c8e1bac5982f40d10b79178bb3cd6..eb12bc5a8e3c2a580f20f6a5ebd2f28c97711255 100644 (file)
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/IR/ValueSymbolTable.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/LeakDetector.h"
 #include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/ValueHandle.h"
 #include <algorithm>
 using namespace llvm;
 
index feba3f1b794ec553610b7c221cf13cb6d58b28b6..9c5db50b92d7d4bdf86ca584f326a70d67399953 100644 (file)
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/PassSupport.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
index 3a93d2ac2e72dbe6bc74f6e34f97d256cefe9910..da8309821c2d1681e6aa3bca08f1a04034a4cac1 100644 (file)
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/NoFolder.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 
 #define DEBUG_TYPE "xcore-lower-thread-local"
index 0a2338422d72be5b96bf60508f77aff8732aec98..71c5e05b3d15353992fc113cd3f86339a7c6bfdb 100644 (file)
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/Utils/GlobalStatus.h"
index c4a39fa4128db10b2dce0d13825be2506be41033..ec8f72cdccd2808ff11d51706302f0f406d2a1cd 100644 (file)
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include <vector>
 using namespace llvm;
index d6c8a54f092fe282bbf84956a05fd2493b15426c..b960d47b62cf22e1ce79d9151f0ea144621b78f6 100644 (file)
 #include "llvm/IR/GetElementPtrTypeIterator.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include <algorithm>
index ed784f661b329a07defe47151909faa9c94c92b8..d24148986b44ef377221aef1f01cbdaf5d0afa6c 100644 (file)
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
index 5ab32d91f52e0963307b43760b0244e2170337ef..f4cf5704e74b613a25035359a2ee001630f57503 100644 (file)
@@ -68,9 +68,9 @@
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
index b6535a735f00dfb1a0a11054dd58975867963035..99b55058b71cc29b21052a9655f3a0db68ba9a77 100644 (file)
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include <algorithm>
index 855ae43cbe68780c8a2386d738d0f58cf53bbf9f..ad92a5961432e5f63888255f429258ef02f6fbec 100644 (file)
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
index 918bd16c98c58b621e4c6f2d5aa394a2879d8cc1..67c8649f27ca1cc9933ffa8e25a7f1af856df2a7 100644 (file)
@@ -24,8 +24,8 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Type.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include <algorithm>
index b6d9fb72c728c9c131d68b57ec23d463e743e488..f437be6270013458001d9c6d77cc80d56a16bfeb 100644 (file)
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
index 4855d4e027fc6c7cd9df60eac41f5a342c96d633..df65e01d4a39904c3318d4bd271b186689c715c3 100644 (file)
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Type.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include <algorithm>
index 70a0bafbe882e419dda42666ac19b1609684f36e..1ff347df6e7d59f13c3bf33c646f6d0ee6918af4 100644 (file)
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/BranchProbability.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/Scalar.h"
index 305079f2dd84233bfcad3c6b2a961ef9edcf0c3c..fd8d842c80e3a0a931dcfc9107d12ccb64268d2e 100644 (file)
@@ -19,6 +19,7 @@ set(IRSources
   PatternMatch.cpp
   TypeBuilderTest.cpp
   TypesTest.cpp
+  ValueHandleTest.cpp
   ValueMapTest.cpp
   ValueTest.cpp
   VerifierTest.cpp
index 352e83ee662ee2b276ab06d4a7dacd5900991cc4..00a2783fbf6735eeb5107c70907680e33877619c 100644 (file)
@@ -13,7 +13,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gtest/gtest.h"
 using namespace llvm;
diff --git a/unittests/IR/ValueHandleTest.cpp b/unittests/IR/ValueHandleTest.cpp
new file mode 100644 (file)
index 0000000..bbca701
--- /dev/null
@@ -0,0 +1,408 @@
+//===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+class ValueHandle : public testing::Test {
+protected:
+  Constant *ConstantV;
+  std::auto_ptr<BitCastInst> BitcastV;
+
+  ValueHandle() :
+    ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
+    BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
+  }
+};
+
+class ConcreteCallbackVH : public CallbackVH {
+public:
+  ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
+};
+
+TEST_F(ValueHandle, WeakVH_BasicOperation) {
+  WeakVH WVH(BitcastV.get());
+  EXPECT_EQ(BitcastV.get(), WVH);
+  WVH = ConstantV;
+  EXPECT_EQ(ConstantV, WVH);
+
+  // Make sure I can call a method on the underlying Value.  It
+  // doesn't matter which method.
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
+}
+
+TEST_F(ValueHandle, WeakVH_Comparisons) {
+  WeakVH BitcastWVH(BitcastV.get());
+  WeakVH ConstantWVH(ConstantV);
+
+  EXPECT_TRUE(BitcastWVH == BitcastWVH);
+  EXPECT_TRUE(BitcastV.get() == BitcastWVH);
+  EXPECT_TRUE(BitcastWVH == BitcastV.get());
+  EXPECT_FALSE(BitcastWVH == ConstantWVH);
+
+  EXPECT_TRUE(BitcastWVH != ConstantWVH);
+  EXPECT_TRUE(BitcastV.get() != ConstantWVH);
+  EXPECT_TRUE(BitcastWVH != ConstantV);
+  EXPECT_FALSE(BitcastWVH != BitcastWVH);
+
+  // Cast to Value* so comparisons work.
+  Value *BV = BitcastV.get();
+  Value *CV = ConstantV;
+  EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
+  EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
+  EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
+  EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
+
+  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
+  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
+  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
+  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
+
+  EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
+  EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
+  EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
+  EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
+  WeakVH WVH(BitcastV.get());
+  WeakVH WVH_Copy(WVH);
+  WeakVH WVH_Recreated(BitcastV.get());
+  BitcastV->replaceAllUsesWith(ConstantV);
+  EXPECT_EQ(ConstantV, WVH);
+  EXPECT_EQ(ConstantV, WVH_Copy);
+  EXPECT_EQ(ConstantV, WVH_Recreated);
+}
+
+TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
+  WeakVH WVH(BitcastV.get());
+  WeakVH WVH_Copy(WVH);
+  WeakVH WVH_Recreated(BitcastV.get());
+  BitcastV.reset();
+  Value *null_value = NULL;
+  EXPECT_EQ(null_value, WVH);
+  EXPECT_EQ(null_value, WVH_Copy);
+  EXPECT_EQ(null_value, WVH_Recreated);
+}
+
+
+TEST_F(ValueHandle, AssertingVH_BasicOperation) {
+  AssertingVH<CastInst> AVH(BitcastV.get());
+  CastInst *implicit_to_exact_type = AVH;
+  (void)implicit_to_exact_type;  // Avoid warning.
+
+  AssertingVH<Value> GenericAVH(BitcastV.get());
+  EXPECT_EQ(BitcastV.get(), GenericAVH);
+  GenericAVH = ConstantV;
+  EXPECT_EQ(ConstantV, GenericAVH);
+
+  // Make sure I can call a method on the underlying CastInst.  It
+  // doesn't matter which method.
+  EXPECT_FALSE(AVH->mayWriteToMemory());
+  EXPECT_FALSE((*AVH).mayWriteToMemory());
+}
+
+TEST_F(ValueHandle, AssertingVH_Const) {
+  const CastInst *ConstBitcast = BitcastV.get();
+  AssertingVH<const CastInst> AVH(ConstBitcast);
+  const CastInst *implicit_to_exact_type = AVH;
+  (void)implicit_to_exact_type;  // Avoid warning.
+}
+
+TEST_F(ValueHandle, AssertingVH_Comparisons) {
+  AssertingVH<Value> BitcastAVH(BitcastV.get());
+  AssertingVH<Value> ConstantAVH(ConstantV);
+
+  EXPECT_TRUE(BitcastAVH == BitcastAVH);
+  EXPECT_TRUE(BitcastV.get() == BitcastAVH);
+  EXPECT_TRUE(BitcastAVH == BitcastV.get());
+  EXPECT_FALSE(BitcastAVH == ConstantAVH);
+
+  EXPECT_TRUE(BitcastAVH != ConstantAVH);
+  EXPECT_TRUE(BitcastV.get() != ConstantAVH);
+  EXPECT_TRUE(BitcastAVH != ConstantV);
+  EXPECT_FALSE(BitcastAVH != BitcastAVH);
+
+  // Cast to Value* so comparisons work.
+  Value *BV = BitcastV.get();
+  Value *CV = ConstantV;
+  EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
+  EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
+  EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
+  EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
+
+  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
+  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
+  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
+  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
+
+  EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
+  EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
+  EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
+  EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
+  AssertingVH<Value> AVH(BitcastV.get());
+  BitcastV->replaceAllUsesWith(ConstantV);
+  EXPECT_EQ(BitcastV.get(), AVH);
+}
+
+#ifdef NDEBUG
+
+TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
+  EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
+}
+
+#else  // !NDEBUG
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST_F(ValueHandle, AssertingVH_Asserts) {
+  AssertingVH<Value> AVH(BitcastV.get());
+  EXPECT_DEATH({BitcastV.reset();},
+               "An asserting value handle still pointed to this value!");
+  AssertingVH<Value> Copy(AVH);
+  AVH = NULL;
+  EXPECT_DEATH({BitcastV.reset();},
+               "An asserting value handle still pointed to this value!");
+  Copy = NULL;
+  BitcastV.reset();
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#endif  // NDEBUG
+
+TEST_F(ValueHandle, CallbackVH_BasicOperation) {
+  ConcreteCallbackVH CVH(BitcastV.get());
+  EXPECT_EQ(BitcastV.get(), CVH);
+  CVH = ConstantV;
+  EXPECT_EQ(ConstantV, CVH);
+
+  // Make sure I can call a method on the underlying Value.  It
+  // doesn't matter which method.
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
+}
+
+TEST_F(ValueHandle, CallbackVH_Comparisons) {
+  ConcreteCallbackVH BitcastCVH(BitcastV.get());
+  ConcreteCallbackVH ConstantCVH(ConstantV);
+
+  EXPECT_TRUE(BitcastCVH == BitcastCVH);
+  EXPECT_TRUE(BitcastV.get() == BitcastCVH);
+  EXPECT_TRUE(BitcastCVH == BitcastV.get());
+  EXPECT_FALSE(BitcastCVH == ConstantCVH);
+
+  EXPECT_TRUE(BitcastCVH != ConstantCVH);
+  EXPECT_TRUE(BitcastV.get() != ConstantCVH);
+  EXPECT_TRUE(BitcastCVH != ConstantV);
+  EXPECT_FALSE(BitcastCVH != BitcastCVH);
+
+  // Cast to Value* so comparisons work.
+  Value *BV = BitcastV.get();
+  Value *CV = ConstantV;
+  EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
+  EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
+  EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
+  EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
+
+  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
+  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
+  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
+  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
+
+  EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
+  EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
+  EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
+  EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
+  class RecordingVH : public CallbackVH {
+  public:
+    int DeletedCalls;
+    int AURWCalls;
+
+    RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
+    RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
+
+  private:
+    virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
+    virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
+  };
+
+  RecordingVH RVH;
+  RVH = BitcastV.get();
+  EXPECT_EQ(0, RVH.DeletedCalls);
+  EXPECT_EQ(0, RVH.AURWCalls);
+  BitcastV.reset();
+  EXPECT_EQ(1, RVH.DeletedCalls);
+  EXPECT_EQ(0, RVH.AURWCalls);
+}
+
+TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
+  class RecordingVH : public CallbackVH {
+  public:
+    int DeletedCalls;
+    Value *AURWArgument;
+
+    RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
+    RecordingVH(Value *V)
+      : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+
+  private:
+    virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
+    virtual void allUsesReplacedWith(Value *new_value) {
+      EXPECT_EQ(NULL, AURWArgument);
+      AURWArgument = new_value;
+    }
+  };
+
+  RecordingVH RVH;
+  RVH = BitcastV.get();
+  EXPECT_EQ(0, RVH.DeletedCalls);
+  EXPECT_EQ(NULL, RVH.AURWArgument);
+  BitcastV->replaceAllUsesWith(ConstantV);
+  EXPECT_EQ(0, RVH.DeletedCalls);
+  EXPECT_EQ(ConstantV, RVH.AURWArgument);
+}
+
+TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
+  class RecoveringVH : public CallbackVH {
+  public:
+    int DeletedCalls;
+    Value *AURWArgument;
+    LLVMContext *Context;
+
+    RecoveringVH() : DeletedCalls(0), AURWArgument(NULL), 
+                     Context(&getGlobalContext()) {}
+    RecoveringVH(Value *V)
+      : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL), 
+        Context(&getGlobalContext()) {}
+
+  private:
+    virtual void deleted() {
+      getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
+      setValPtr(NULL);
+    }
+    virtual void allUsesReplacedWith(Value *new_value) {
+      ASSERT_TRUE(NULL != getValPtr());
+      EXPECT_EQ(1U, getValPtr()->getNumUses());
+      EXPECT_EQ(NULL, AURWArgument);
+      AURWArgument = new_value;
+    }
+  };
+
+  // Normally, if a value has uses, deleting it will crash.  However, we can use
+  // a CallbackVH to remove the uses before the check for no uses.
+  RecoveringVH RVH;
+  RVH = BitcastV.get();
+  std::auto_ptr<BinaryOperator> BitcastUser(
+    BinaryOperator::CreateAdd(RVH, 
+                              Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
+  EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
+  BitcastV.reset();  // Would crash without the ValueHandler.
+  EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
+  EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
+            BitcastUser->getOperand(0));
+}
+
+TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
+  // When a CallbackVH modifies other ValueHandles in its callbacks,
+  // that shouldn't interfere with non-modified ValueHandles receiving
+  // their appropriate callbacks.
+  //
+  // We create the active CallbackVH in the middle of a palindromic
+  // arrangement of other VHs so that the bad behavior would be
+  // triggered in whichever order callbacks run.
+
+  class DestroyingVH : public CallbackVH {
+  public:
+    OwningPtr<WeakVH> ToClear[2];
+    DestroyingVH(Value *V) {
+      ToClear[0].reset(new WeakVH(V));
+      setValPtr(V);
+      ToClear[1].reset(new WeakVH(V));
+    }
+    virtual void deleted() {
+      ToClear[0].reset();
+      ToClear[1].reset();
+      CallbackVH::deleted();
+    }
+    virtual void allUsesReplacedWith(Value *) {
+      ToClear[0].reset();
+      ToClear[1].reset();
+    }
+  };
+
+  {
+    WeakVH ShouldBeVisited1(BitcastV.get());
+    DestroyingVH C(BitcastV.get());
+    WeakVH ShouldBeVisited2(BitcastV.get());
+
+    BitcastV->replaceAllUsesWith(ConstantV);
+    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
+    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
+  }
+
+  {
+    WeakVH ShouldBeVisited1(BitcastV.get());
+    DestroyingVH C(BitcastV.get());
+    WeakVH ShouldBeVisited2(BitcastV.get());
+
+    BitcastV.reset();
+    EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
+    EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
+  }
+}
+
+TEST_F(ValueHandle, AssertingVHCheckedLast) {
+  // If a CallbackVH exists to clear out a group of AssertingVHs on
+  // Value deletion, the CallbackVH should get a chance to do so
+  // before the AssertingVHs assert.
+
+  class ClearingVH : public CallbackVH {
+  public:
+    AssertingVH<Value> *ToClear[2];
+    ClearingVH(Value *V,
+               AssertingVH<Value> &A0, AssertingVH<Value> &A1)
+      : CallbackVH(V) {
+      ToClear[0] = &A0;
+      ToClear[1] = &A1;
+    }
+
+    virtual void deleted() {
+      *ToClear[0] = 0;
+      *ToClear[1] = 0;
+      CallbackVH::deleted();
+    }
+  };
+
+  AssertingVH<Value> A1, A2;
+  A1 = BitcastV.get();
+  ClearingVH C(BitcastV.get(), A1, A2);
+  A2 = BitcastV.get();
+  // C.deleted() should run first, clearing the two AssertingVHs,
+  // which should prevent them from asserting.
+  BitcastV.reset();
+}
+
+}
index bfbef982e2e5bd134778c6165ad82e9860c2e87c..46c5c334ff4109ea262aff5db59a86bfc375909a 100644 (file)
@@ -35,7 +35,6 @@ add_llvm_unittest(SupportTests
   ThreadLocalTest.cpp
   TimeValueTest.cpp
   UnicodeTest.cpp
-  ValueHandleTest.cpp
   YAMLIOTest.cpp
   YAMLParserTest.cpp
   formatted_raw_ostream_test.cpp
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp
deleted file mode 100644 (file)
index 05aafa2..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-//===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "gtest/gtest.h"
-#include <memory>
-
-using namespace llvm;
-
-namespace {
-
-class ValueHandle : public testing::Test {
-protected:
-  Constant *ConstantV;
-  std::auto_ptr<BitCastInst> BitcastV;
-
-  ValueHandle() :
-    ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
-    BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
-  }
-};
-
-class ConcreteCallbackVH : public CallbackVH {
-public:
-  ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
-};
-
-TEST_F(ValueHandle, WeakVH_BasicOperation) {
-  WeakVH WVH(BitcastV.get());
-  EXPECT_EQ(BitcastV.get(), WVH);
-  WVH = ConstantV;
-  EXPECT_EQ(ConstantV, WVH);
-
-  // Make sure I can call a method on the underlying Value.  It
-  // doesn't matter which method.
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
-}
-
-TEST_F(ValueHandle, WeakVH_Comparisons) {
-  WeakVH BitcastWVH(BitcastV.get());
-  WeakVH ConstantWVH(ConstantV);
-
-  EXPECT_TRUE(BitcastWVH == BitcastWVH);
-  EXPECT_TRUE(BitcastV.get() == BitcastWVH);
-  EXPECT_TRUE(BitcastWVH == BitcastV.get());
-  EXPECT_FALSE(BitcastWVH == ConstantWVH);
-
-  EXPECT_TRUE(BitcastWVH != ConstantWVH);
-  EXPECT_TRUE(BitcastV.get() != ConstantWVH);
-  EXPECT_TRUE(BitcastWVH != ConstantV);
-  EXPECT_FALSE(BitcastWVH != BitcastWVH);
-
-  // Cast to Value* so comparisons work.
-  Value *BV = BitcastV.get();
-  Value *CV = ConstantV;
-  EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
-  EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
-  EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
-  EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
-
-  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
-  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
-  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
-  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
-
-  EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
-  EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
-  EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
-  EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
-  WeakVH WVH(BitcastV.get());
-  WeakVH WVH_Copy(WVH);
-  WeakVH WVH_Recreated(BitcastV.get());
-  BitcastV->replaceAllUsesWith(ConstantV);
-  EXPECT_EQ(ConstantV, WVH);
-  EXPECT_EQ(ConstantV, WVH_Copy);
-  EXPECT_EQ(ConstantV, WVH_Recreated);
-}
-
-TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
-  WeakVH WVH(BitcastV.get());
-  WeakVH WVH_Copy(WVH);
-  WeakVH WVH_Recreated(BitcastV.get());
-  BitcastV.reset();
-  Value *null_value = NULL;
-  EXPECT_EQ(null_value, WVH);
-  EXPECT_EQ(null_value, WVH_Copy);
-  EXPECT_EQ(null_value, WVH_Recreated);
-}
-
-
-TEST_F(ValueHandle, AssertingVH_BasicOperation) {
-  AssertingVH<CastInst> AVH(BitcastV.get());
-  CastInst *implicit_to_exact_type = AVH;
-  (void)implicit_to_exact_type;  // Avoid warning.
-
-  AssertingVH<Value> GenericAVH(BitcastV.get());
-  EXPECT_EQ(BitcastV.get(), GenericAVH);
-  GenericAVH = ConstantV;
-  EXPECT_EQ(ConstantV, GenericAVH);
-
-  // Make sure I can call a method on the underlying CastInst.  It
-  // doesn't matter which method.
-  EXPECT_FALSE(AVH->mayWriteToMemory());
-  EXPECT_FALSE((*AVH).mayWriteToMemory());
-}
-
-TEST_F(ValueHandle, AssertingVH_Const) {
-  const CastInst *ConstBitcast = BitcastV.get();
-  AssertingVH<const CastInst> AVH(ConstBitcast);
-  const CastInst *implicit_to_exact_type = AVH;
-  (void)implicit_to_exact_type;  // Avoid warning.
-}
-
-TEST_F(ValueHandle, AssertingVH_Comparisons) {
-  AssertingVH<Value> BitcastAVH(BitcastV.get());
-  AssertingVH<Value> ConstantAVH(ConstantV);
-
-  EXPECT_TRUE(BitcastAVH == BitcastAVH);
-  EXPECT_TRUE(BitcastV.get() == BitcastAVH);
-  EXPECT_TRUE(BitcastAVH == BitcastV.get());
-  EXPECT_FALSE(BitcastAVH == ConstantAVH);
-
-  EXPECT_TRUE(BitcastAVH != ConstantAVH);
-  EXPECT_TRUE(BitcastV.get() != ConstantAVH);
-  EXPECT_TRUE(BitcastAVH != ConstantV);
-  EXPECT_FALSE(BitcastAVH != BitcastAVH);
-
-  // Cast to Value* so comparisons work.
-  Value *BV = BitcastV.get();
-  Value *CV = ConstantV;
-  EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
-  EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
-  EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
-  EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
-
-  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
-  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
-  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
-  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
-
-  EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
-  EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
-  EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
-  EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
-  AssertingVH<Value> AVH(BitcastV.get());
-  BitcastV->replaceAllUsesWith(ConstantV);
-  EXPECT_EQ(BitcastV.get(), AVH);
-}
-
-#ifdef NDEBUG
-
-TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
-  EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
-}
-
-#else  // !NDEBUG
-
-#ifdef GTEST_HAS_DEATH_TEST
-
-TEST_F(ValueHandle, AssertingVH_Asserts) {
-  AssertingVH<Value> AVH(BitcastV.get());
-  EXPECT_DEATH({BitcastV.reset();},
-               "An asserting value handle still pointed to this value!");
-  AssertingVH<Value> Copy(AVH);
-  AVH = NULL;
-  EXPECT_DEATH({BitcastV.reset();},
-               "An asserting value handle still pointed to this value!");
-  Copy = NULL;
-  BitcastV.reset();
-}
-
-#endif  // GTEST_HAS_DEATH_TEST
-
-#endif  // NDEBUG
-
-TEST_F(ValueHandle, CallbackVH_BasicOperation) {
-  ConcreteCallbackVH CVH(BitcastV.get());
-  EXPECT_EQ(BitcastV.get(), CVH);
-  CVH = ConstantV;
-  EXPECT_EQ(ConstantV, CVH);
-
-  // Make sure I can call a method on the underlying Value.  It
-  // doesn't matter which method.
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
-}
-
-TEST_F(ValueHandle, CallbackVH_Comparisons) {
-  ConcreteCallbackVH BitcastCVH(BitcastV.get());
-  ConcreteCallbackVH ConstantCVH(ConstantV);
-
-  EXPECT_TRUE(BitcastCVH == BitcastCVH);
-  EXPECT_TRUE(BitcastV.get() == BitcastCVH);
-  EXPECT_TRUE(BitcastCVH == BitcastV.get());
-  EXPECT_FALSE(BitcastCVH == ConstantCVH);
-
-  EXPECT_TRUE(BitcastCVH != ConstantCVH);
-  EXPECT_TRUE(BitcastV.get() != ConstantCVH);
-  EXPECT_TRUE(BitcastCVH != ConstantV);
-  EXPECT_FALSE(BitcastCVH != BitcastCVH);
-
-  // Cast to Value* so comparisons work.
-  Value *BV = BitcastV.get();
-  Value *CV = ConstantV;
-  EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
-  EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
-  EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
-  EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
-
-  EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
-  EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
-  EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
-  EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
-
-  EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
-  EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
-  EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
-  EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
-  class RecordingVH : public CallbackVH {
-  public:
-    int DeletedCalls;
-    int AURWCalls;
-
-    RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
-    RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
-
-  private:
-    virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
-    virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
-  };
-
-  RecordingVH RVH;
-  RVH = BitcastV.get();
-  EXPECT_EQ(0, RVH.DeletedCalls);
-  EXPECT_EQ(0, RVH.AURWCalls);
-  BitcastV.reset();
-  EXPECT_EQ(1, RVH.DeletedCalls);
-  EXPECT_EQ(0, RVH.AURWCalls);
-}
-
-TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
-  class RecordingVH : public CallbackVH {
-  public:
-    int DeletedCalls;
-    Value *AURWArgument;
-
-    RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
-    RecordingVH(Value *V)
-      : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
-
-  private:
-    virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
-    virtual void allUsesReplacedWith(Value *new_value) {
-      EXPECT_EQ(NULL, AURWArgument);
-      AURWArgument = new_value;
-    }
-  };
-
-  RecordingVH RVH;
-  RVH = BitcastV.get();
-  EXPECT_EQ(0, RVH.DeletedCalls);
-  EXPECT_EQ(NULL, RVH.AURWArgument);
-  BitcastV->replaceAllUsesWith(ConstantV);
-  EXPECT_EQ(0, RVH.DeletedCalls);
-  EXPECT_EQ(ConstantV, RVH.AURWArgument);
-}
-
-TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
-  class RecoveringVH : public CallbackVH {
-  public:
-    int DeletedCalls;
-    Value *AURWArgument;
-    LLVMContext *Context;
-
-    RecoveringVH() : DeletedCalls(0), AURWArgument(NULL), 
-                     Context(&getGlobalContext()) {}
-    RecoveringVH(Value *V)
-      : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL), 
-        Context(&getGlobalContext()) {}
-
-  private:
-    virtual void deleted() {
-      getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
-      setValPtr(NULL);
-    }
-    virtual void allUsesReplacedWith(Value *new_value) {
-      ASSERT_TRUE(NULL != getValPtr());
-      EXPECT_EQ(1U, getValPtr()->getNumUses());
-      EXPECT_EQ(NULL, AURWArgument);
-      AURWArgument = new_value;
-    }
-  };
-
-  // Normally, if a value has uses, deleting it will crash.  However, we can use
-  // a CallbackVH to remove the uses before the check for no uses.
-  RecoveringVH RVH;
-  RVH = BitcastV.get();
-  std::auto_ptr<BinaryOperator> BitcastUser(
-    BinaryOperator::CreateAdd(RVH, 
-                              Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
-  EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
-  BitcastV.reset();  // Would crash without the ValueHandler.
-  EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
-  EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
-            BitcastUser->getOperand(0));
-}
-
-TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
-  // When a CallbackVH modifies other ValueHandles in its callbacks,
-  // that shouldn't interfere with non-modified ValueHandles receiving
-  // their appropriate callbacks.
-  //
-  // We create the active CallbackVH in the middle of a palindromic
-  // arrangement of other VHs so that the bad behavior would be
-  // triggered in whichever order callbacks run.
-
-  class DestroyingVH : public CallbackVH {
-  public:
-    OwningPtr<WeakVH> ToClear[2];
-    DestroyingVH(Value *V) {
-      ToClear[0].reset(new WeakVH(V));
-      setValPtr(V);
-      ToClear[1].reset(new WeakVH(V));
-    }
-    virtual void deleted() {
-      ToClear[0].reset();
-      ToClear[1].reset();
-      CallbackVH::deleted();
-    }
-    virtual void allUsesReplacedWith(Value *) {
-      ToClear[0].reset();
-      ToClear[1].reset();
-    }
-  };
-
-  {
-    WeakVH ShouldBeVisited1(BitcastV.get());
-    DestroyingVH C(BitcastV.get());
-    WeakVH ShouldBeVisited2(BitcastV.get());
-
-    BitcastV->replaceAllUsesWith(ConstantV);
-    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
-    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
-  }
-
-  {
-    WeakVH ShouldBeVisited1(BitcastV.get());
-    DestroyingVH C(BitcastV.get());
-    WeakVH ShouldBeVisited2(BitcastV.get());
-
-    BitcastV.reset();
-    EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
-    EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
-  }
-}
-
-TEST_F(ValueHandle, AssertingVHCheckedLast) {
-  // If a CallbackVH exists to clear out a group of AssertingVHs on
-  // Value deletion, the CallbackVH should get a chance to do so
-  // before the AssertingVHs assert.
-
-  class ClearingVH : public CallbackVH {
-  public:
-    AssertingVH<Value> *ToClear[2];
-    ClearingVH(Value *V,
-               AssertingVH<Value> &A0, AssertingVH<Value> &A1)
-      : CallbackVH(V) {
-      ToClear[0] = &A0;
-      ToClear[1] = &A1;
-    }
-
-    virtual void deleted() {
-      *ToClear[0] = 0;
-      *ToClear[1] = 0;
-      CallbackVH::deleted();
-    }
-  };
-
-  AssertingVH<Value> A1, A2;
-  A1 = BitcastV.get();
-  ClearingVH C(BitcastV.get(), A1, A2);
-  A2 = BitcastV.get();
-  // C.deleted() should run first, clearing the two AssertingVHs,
-  // which should prevent them from asserting.
-  BitcastV.reset();
-}
-
-}