Index: include/llvm/BasicBlock.h
===================================================================
--- include/llvm/BasicBlock.h	(revision 44322)
+++ include/llvm/BasicBlock.h	(working copy)
@@ -76,7 +76,7 @@
   ///
   explicit BasicBlock(const std::string &Name = "", Function *Parent = 0,
                       BasicBlock *InsertBefore = 0);
-  ~BasicBlock();
+  static void destroythis(BasicBlock*);
 
   /// getParent - Return the enclosing method, or null if none
   ///
Index: include/llvm/Constants.h
===================================================================
--- include/llvm/Constants.h	(revision 44322)
+++ include/llvm/Constants.h	(working copy)
@@ -24,6 +24,7 @@
 #include "llvm/Type.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/APFloat.h"
+#include "llvm/Instructions.h"
 
 namespace llvm {
 
@@ -295,7 +296,8 @@
   ConstantArray(const ConstantArray &);      // DO NOT IMPLEMENT
 protected:
   ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
-  ~ConstantArray();
+  static void destroythis(ConstantArray*);
+  friend Value;
 public:
   /// get() - Static factory methods - Return objects of the specified value
   static Constant *get(const ArrayType *T, const std::vector<Constant*> &);
@@ -361,7 +363,8 @@
   ConstantStruct(const ConstantStruct &);      // DO NOT IMPLEMENT
 protected:
   ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
-  ~ConstantStruct();
+  static void destroythis(ConstantStruct*);
+  friend Value;
 public:
   /// get() - Static factory methods - Return objects of the specified value
   ///
@@ -405,7 +408,8 @@
   ConstantVector(const ConstantVector &);      // DO NOT IMPLEMENT
 protected:
   ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
-  ~ConstantVector();
+  static void destroythis(ConstantVector*v);
+  friend Value;
 public:
   /// get() - Static factory methods - Return objects of the specified value
   static Constant *get(const VectorType *T, const std::vector<Constant*> &);
@@ -728,6 +732,23 @@
   }
 };
 
+/// GetElementPtrConstantExpr - Helper class for Constants.cpp, and is
+/// used behind the scenes to implement getelementpr constant exprs.
+struct GetElementPtrConstantExpr : public ConstantExpr {
+  GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
+                            const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::GetElementPtr,
+                   new Use[IdxList.size()+1], IdxList.size()+1) {
+    OperandList[0].init(C, this);
+    for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+      OperandList[i+1].init(IdxList[i], this);
+  }
+  
+  static void destroythis(GetElementPtrConstantExpr*v) {
+    delete [] v->OperandList;
+  }
+};
+
 } // End llvm namespace
 
 #endif
Index: include/llvm/Function.h
===================================================================
--- include/llvm/Function.h	(revision 44322)
+++ include/llvm/Function.h	(working copy)
@@ -108,7 +108,7 @@
   ///
   Function(const FunctionType *Ty, LinkageTypes Linkage,
            const std::string &N = "", Module *M = 0);
-  ~Function();
+  static void destroythis(Function*v);
 
   const Type *getReturnType() const;           // Return the type of the ret val
   const FunctionType *getFunctionType() const; // Return the FunctionType for me
Index: include/llvm/GlobalValue.h
===================================================================
--- include/llvm/GlobalValue.h	(revision 44322)
+++ include/llvm/GlobalValue.h	(working copy)
@@ -64,8 +64,8 @@
   unsigned Alignment : 16;    // Alignment of this symbol, must be power of two
   std::string Section;        // Section to emit this into, empty mean default
 public:
-  ~GlobalValue() {
-    removeDeadConstantUsers();   // remove any dead constants using this.
+  static void destroythis(GlobalValue*v) {
+    v->removeDeadConstantUsers();   // remove any dead constants using this.
   }
 
   unsigned getAlignment() const { return Alignment; }
Index: include/llvm/InlineAsm.h
===================================================================
--- include/llvm/InlineAsm.h	(revision 44322)
+++ include/llvm/InlineAsm.h	(working copy)
@@ -36,7 +36,8 @@
   
   InlineAsm(const FunctionType *Ty, const std::string &AsmString,
             const std::string &Constraints, bool hasSideEffects);
-  virtual ~InlineAsm();
+  //static void destroythis(InlineAsm*);
+  //friend Value;
 public:
 
   /// InlineAsm::get - Return the the specified uniqued inline asm string.
Index: include/llvm/InstrTypes.h
===================================================================
--- include/llvm/InstrTypes.h	(revision 44322)
+++ include/llvm/InstrTypes.h	(working copy)
@@ -39,7 +39,6 @@
     : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
 
   // Out of line virtual method, so the vtable, etc has a home.
-  ~TerminatorInst();
 
   /// Virtual methods - Terminators should overload these and provide inline
   /// overrides of non-V methods.
@@ -96,7 +95,7 @@
   }
 public:
   // Out of line virtual method, so the vtable, etc has a home.
-  ~UnaryInstruction();
+  //static void destroythis(UnaryInstruction*);
 
   // Transparently provide more efficient getOperand methods.
   Value *getOperand(unsigned i) const {
Index: include/llvm/Instruction.h
===================================================================
--- include/llvm/Instruction.h	(revision 44322)
+++ include/llvm/Instruction.h	(working copy)
@@ -44,7 +44,7 @@
               BasicBlock *InsertAtEnd);
 public:
   // Out of line virtual method, so the vtable, etc has a home.
-  ~Instruction();
+  static void destroythis(Instruction*v);
   
   /// mayWriteToMemory - Return true if this instruction may modify memory.
   ///
Index: include/llvm/Instructions.h
===================================================================
--- include/llvm/Instructions.h	(revision 44322)
+++ include/llvm/Instructions.h	(working copy)
@@ -47,7 +47,7 @@
                  const std::string &Name, BasicBlock *InsertAtEnd);
 public:
   // Out of line virtual method, so the vtable, etc has a home.
-  virtual ~AllocationInst();
+  static void destroythis(AllocationInst*);
 
   /// isArrayAllocation - Return true if there is an allocation size parameter
   /// to the allocation instruction that is not 1.
@@ -476,7 +476,7 @@
                     const std::string &Name = "", Instruction *InsertBefore =0);
   GetElementPtrInst(Value *Ptr, Value *Idx,
                     const std::string &Name, BasicBlock *InsertAtEnd);
-  ~GetElementPtrInst();
+  static void destroythis(GetElementPtrInst*v);
 
   virtual GetElementPtrInst *clone() const;
 
@@ -896,7 +896,7 @@
   explicit CallInst(Value *F, const std::string &Name = "",
                     Instruction *InsertBefore = 0);
   CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd);
-  ~CallInst();
+  static void destroythis(CallInst*v);
 
   virtual CallInst *clone() const;
   
@@ -1227,7 +1227,7 @@
     setName(Name);
   }
 
-  ~PHINode();
+  static void destroythis(PHINode*);
 
   /// reserveOperandSpace - This method can be used to avoid repeated
   /// reallocation of PHI operand lists by reserving space for the correct
@@ -1511,7 +1511,7 @@
   /// constructor also autoinserts at the end of the specified BasicBlock.
   SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
              BasicBlock *InsertAtEnd);
-  ~SwitchInst();
+  static void destroythis(SwitchInst*v);
 
 
   // Accessor Methods for Switch stmt
@@ -1676,7 +1676,7 @@
          typename std::iterator_traits<InputIterator>::iterator_category());
   }
 
-  ~InvokeInst();
+  static void destroythis(InvokeInst*v);
 
   virtual InvokeInst *clone() const;
 
Index: include/llvm/Value.h
===================================================================
--- include/llvm/Value.h	(revision 44322)
+++ include/llvm/Value.h	(working copy)
@@ -64,14 +64,17 @@
 
   friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
   friend class SymbolTable;      // Allow SymbolTable to directly poke Name.
-  ValueName *Name;
+public:
+	ValueName *Name;
 
+private:
   void operator=(const Value &);     // Do not implement
   Value(const Value &);              // Do not implement
 
 public:
   Value(const Type *Ty, unsigned scid);
-  virtual ~Value();
+  ~Value();
+  static void destroythis(Value*);
 
   /// dump - Support for debugging, callable in GDB: V->dump()
   //
Index: lib/VMCore/BasicBlock.cpp
===================================================================
--- lib/VMCore/BasicBlock.cpp	(revision 44322)
+++ lib/VMCore/BasicBlock.cpp	(working copy)
@@ -88,10 +88,11 @@
 }
 
 
-BasicBlock::~BasicBlock() {
-  assert(getParent() == 0 && "BasicBlock still linked into the program!");
-  dropAllReferences();
-  InstList.clear();
+void BasicBlock::destroythis(BasicBlock*v)
+{
+  assert(v->getParent() == 0 && "BasicBlock still linked into the program!");
+  v->dropAllReferences();
+  v->InstList.clear();
 }
 
 void BasicBlock::setParent(Function *parent) {
Index: lib/VMCore/Constants.cpp
===================================================================
--- lib/VMCore/Constants.cpp	(revision 44322)
+++ lib/VMCore/Constants.cpp	(working copy)
@@ -356,8 +356,9 @@
   }
 }
 
-ConstantArray::~ConstantArray() {
-  delete [] OperandList;
+void ConstantArray::destroythis(ConstantArray*v)
+{
+  delete [] v->OperandList;
 }
 
 ConstantStruct::ConstantStruct(const StructType *T,
@@ -379,8 +380,9 @@
   }
 }
 
-ConstantStruct::~ConstantStruct() {
-  delete [] OperandList;
+void ConstantStruct::destroythis(ConstantStruct*v)
+{
+  delete [] v->OperandList;
 }
 
 
@@ -399,8 +401,8 @@
   }
 }
 
-ConstantVector::~ConstantVector() {
-  delete [] OperandList;
+void ConstantVector::destroythis(ConstantVector*v) {
+  delete [] v->OperandList;
 }
 
 // We declare several classes private to this file, so use an anonymous
@@ -485,22 +487,8 @@
   }
 };
 
-/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
-/// used behind the scenes to implement getelementpr constant exprs.
-struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
-  GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
-                            const Type *DestTy)
-    : ConstantExpr(DestTy, Instruction::GetElementPtr,
-                   new Use[IdxList.size()+1], IdxList.size()+1) {
-    OperandList[0].init(C, this);
-    for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
-      OperandList[i+1].init(IdxList[i], this);
-  }
-  ~GetElementPtrConstantExpr() {
-    delete [] OperandList;
-  }
-};
 
+
 // CompareConstantExpr - This class is private to Constants.cpp, and is used
 // behind the scenes to implement ICmp and FCmp constant expressions. This is
 // needed in order to store the predicate value for these instructions.
Index: lib/VMCore/Function.cpp
===================================================================
--- lib/VMCore/Function.cpp	(revision 44322)
+++ lib/VMCore/Function.cpp	(working copy)
@@ -219,16 +219,16 @@
     ParentModule->getFunctionList().push_back(this);
 }
 
-Function::~Function() {
-  dropAllReferences();    // After this it is safe to delete instructions.
+void Function::destroythis(Function*v) {
+  v->dropAllReferences();    // After this it is safe to delete instructions.
 
   // Delete all of the method arguments and unlink from symbol table...
-  ArgumentList.clear();
-  delete SymTab;
+  v->ArgumentList.clear();
+  delete v->SymTab;
 
   // Drop our reference to the parameter attributes, if any.
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
+  if (v->ParamAttrs)
+    v->ParamAttrs->dropRef();
 }
 
 void Function::BuildLazyArguments() const {
Index: lib/VMCore/InlineAsm.cpp
===================================================================
--- lib/VMCore/InlineAsm.cpp	(revision 44322)
+++ lib/VMCore/InlineAsm.cpp	(working copy)
@@ -19,8 +19,8 @@
 
 // Implement the first virtual method in this class in this file so the
 // InlineAsm vtable is emitted here.
-InlineAsm::~InlineAsm() {
-}
+//void InlineAsm::destroythis(InlineAsm*v) {
+//}
 
 
 // NOTE: when memoizing the function type, we have to be careful to handle the
Index: lib/VMCore/Instruction.cpp
===================================================================
--- lib/VMCore/Instruction.cpp	(revision 44322)
+++ lib/VMCore/Instruction.cpp	(working copy)
@@ -45,8 +45,8 @@
 
 
 // Out of line virtual method, so the vtable, etc has a home.
-Instruction::~Instruction() {
-  assert(Parent == 0 && "Instruction still linked in the program!");
+void Instruction::destroythis(Instruction*v) {
+  assert(v->Parent == 0 && "Instruction still linked in the program!");
 }
 
 
Index: lib/VMCore/Instructions.cpp
===================================================================
--- lib/VMCore/Instructions.cpp	(revision 44322)
+++ lib/VMCore/Instructions.cpp	(working copy)
@@ -36,23 +36,7 @@
     cast<InvokeInst>(I)->setCallingConv(CC);
 }
 
-
-
-
 //===----------------------------------------------------------------------===//
-//                            TerminatorInst Class
-//===----------------------------------------------------------------------===//
-
-// Out of line virtual method, so the vtable, etc has a home.
-TerminatorInst::~TerminatorInst() {
-}
-
-// Out of line virtual method, so the vtable, etc has a home.
-UnaryInstruction::~UnaryInstruction() {
-}
-
-
-//===----------------------------------------------------------------------===//
 //                               PHINode Class
 //===----------------------------------------------------------------------===//
 
@@ -67,8 +51,8 @@
   }
 }
 
-PHINode::~PHINode() {
-  delete [] OperandList;
+void PHINode::destroythis(PHINode*v) {
+  delete [] v->OperandList;
 }
 
 // removeIncomingValue - Remove an incoming value.  This is useful if a
@@ -185,10 +169,10 @@
 //                        CallInst Implementation
 //===----------------------------------------------------------------------===//
 
-CallInst::~CallInst() {
-  delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
+void CallInst::destroythis(CallInst*v) {
+  delete [] v->OperandList;
+  if (v->ParamAttrs)
+    v->ParamAttrs->dropRef();
 }
 
 void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
@@ -364,10 +348,10 @@
 //                        InvokeInst Implementation
 //===----------------------------------------------------------------------===//
 
-InvokeInst::~InvokeInst() {
-  delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
+void InvokeInst::destroythis(InvokeInst*v) {
+  delete [] v->OperandList;
+  if (v->ParamAttrs)
+    v->ParamAttrs->dropRef();
 }
 
 void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
@@ -629,7 +613,7 @@
 }
 
 // Out of line virtual method, so the vtable, etc has a home.
-AllocationInst::~AllocationInst() {
+void AllocationInst::destroythis(AllocationInst*v) {
 }
 
 bool AllocationInst::isArrayAllocation() const {
@@ -896,8 +880,8 @@
   setName(Name);
 }
 
-GetElementPtrInst::~GetElementPtrInst() {
-  delete[] OperandList;
+void GetElementPtrInst::destroythis(GetElementPtrInst*v) {
+  delete[] v->OperandList;
 }
 
 // getIndexedType - Returns the type of the element that would be loaded with
@@ -2414,8 +2398,8 @@
   }
 }
 
-SwitchInst::~SwitchInst() {
-  delete [] OperandList;
+void SwitchInst::destroythis(SwitchInst*v) {
+  delete [] v->OperandList;
 }
 
 
Index: lib/VMCore/Value.cpp
===================================================================
--- lib/VMCore/Value.cpp	(revision 44322)
+++ lib/VMCore/Value.cpp	(working copy)
@@ -18,6 +18,11 @@
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/LeakDetector.h"
+#include "llvm/Constants.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/InstrTypes.h"
 #include <algorithm>
 using namespace llvm;
 
@@ -39,7 +44,66 @@
            "Cannot create non-first-class values except for constants!");
 }
 
-Value::~Value() {
+Value::~Value() 
+{
+	if(SubclassID == BasicBlockVal)
+	{
+		BasicBlock::destroythis((BasicBlock*)this);
+	}
+	else if(SubclassID == ConstantArrayVal)
+	{
+		ConstantArray::destroythis((ConstantArray*)this);
+	}
+	else if(SubclassID == ConstantExprVal && ((ConstantExpr*)this)->SubclassData == Instruction::GetElementPtr)
+	{
+		GetElementPtrConstantExpr::destroythis((GetElementPtrConstantExpr*)this);
+	}
+	else if(SubclassID == ConstantStructVal)
+	{
+		ConstantStruct::destroythis((ConstantStruct*)this);
+	}
+	else if(SubclassID == ConstantVectorVal)
+	{
+		ConstantVector::destroythis((ConstantVector*)this);
+	}
+	else if(SubclassID == FunctionVal)
+	{
+		Function::destroythis((Function*)this);
+		GlobalValue::destroythis((GlobalValue*)this);
+	}
+	else if(SubclassID == GlobalAliasVal || SubclassID == GlobalVariableVal) //GlobalValue but !Function
+	{
+		GlobalValue::destroythis((GlobalValue*)this);
+	}
+	else if(SubclassID >= InstructionVal)
+	{
+		if(SubclassID == InstructionVal + Instruction::Call)
+		{
+			CallInst::destroythis((CallInst*)this);
+		}
+		else if(SubclassID == InstructionVal + Instruction::PHI)
+		{
+			PHINode::destroythis((PHINode*)this);
+		}
+		else if(SubclassID == InstructionVal + Instruction::Invoke)
+		{
+			InvokeInst::destroythis((InvokeInst*)this);
+		}
+		else if(SubclassID == InstructionVal + Instruction::Switch)
+		{
+			SwitchInst::destroythis((SwitchInst*)this);
+		}
+		else if(SubclassID == InstructionVal + Instruction::Malloc || SubclassID == InstructionVal + Instruction::Alloca)
+		{
+			AllocationInst::destroythis((AllocationInst*)this);
+		}
+		Instruction::destroythis((Instruction*)this);
+	}
+	Value::destroythis(this);	
+}
+
+void Value::destroythis(Value*v)
+{
 #ifndef NDEBUG      // Only in -g mode...
   // Check to make sure that there are no uses of this value that are still
   // around when the value is destroyed.  If there are, then we have a dangling
@@ -47,22 +111,22 @@
   // still being referenced.  The value in question should be printed as
   // a <badref>
   //
-  if (!use_empty()) {
-    DOUT << "While deleting: " << *Ty << " %" << Name << "\n";
-    for (use_iterator I = use_begin(), E = use_end(); I != E; ++I)
+  if (!v->use_empty()) {
+    DOUT << "While deleting: " << *v->Ty << " %" << v->Name << "\n";
+    for (use_iterator I = v->use_begin(), E = v->use_end(); I != E; ++I)
       DOUT << "Use still stuck around after Def is destroyed:"
            << **I << "\n";
   }
 #endif
-  assert(use_empty() && "Uses remain when a value is destroyed!");
+  assert(v->use_empty() && "Uses remain when a value is destroyed!");
 
   // If this value is named, destroy the name.  This should not be in a symtab
   // at this point.
-  if (Name)
-    Name->Destroy();
+  if (v->Name)
+    v->Name->Destroy();
   
   // There should be no uses of this object anymore, remove it.
-  LeakDetector::removeGarbageObject(this);
+  LeakDetector::removeGarbageObject(v);
 }
 
 /// hasNUses - Return true if this Value has exactly N users.
