[weak vtables] Place class definitions into anonymous namespaces to prevent weak...
authorJuergen Ributzka <juergen@apple.com>
Tue, 19 Nov 2013 03:08:35 +0000 (03:08 +0000)
committerJuergen Ributzka <juergen@apple.com>
Tue, 19 Nov 2013 03:08:35 +0000 (03:08 +0000)
This patch places class definitions in implementation files into anonymous
namespaces to prevent weak vtables. This eliminates the need of providing an
out-of-line definition to pin the vtable explicitly to the file.

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

14 files changed:
examples/ExceptionDemo/ExceptionDemo.cpp
examples/Kaleidoscope/Chapter2/toy.cpp
examples/Kaleidoscope/Chapter3/toy.cpp
examples/Kaleidoscope/Chapter4/toy.cpp
examples/Kaleidoscope/Chapter5/toy.cpp
examples/Kaleidoscope/Chapter6/toy.cpp
examples/Kaleidoscope/Chapter7/toy.cpp
tools/llvm-stress/llvm-stress.cpp
unittests/ADT/IntrusiveRefCntPtrTest.cpp
unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
utils/TableGen/CodeGenSchedule.cpp
utils/TableGen/TGValueTypes.cpp

index 6a0d0d027fd7bdc5fedfea001e8e66d8ba507d58..d6954e83be4b4d45bd16290e2f866272c5d7bbfc 100644 (file)
@@ -1562,7 +1562,7 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module,
   return(outerCatchFunct);
 }
 
-
+namespace {
 /// Represents our foreign exceptions
 class OurCppRunException : public std::runtime_error {
 public:
@@ -1577,11 +1577,9 @@ public:
                                  std::runtime_error::operator=(toCopy)));
   }
 
-  ~OurCppRunException (void) throw ();
+  virtual ~OurCppRunException (void) throw () {}
 };
-
-// Provide out-of-line definition to prevent weak vtable.
-OurCppRunException::~OurCppRunException() throw () {}
+} // end anonymous namespace
 
 /// Throws foreign C++ exception.
 /// @param ignoreIt unused parameter that allows function to match implied
index 99ec90e9b01ce342225eee1daf806097afd0ed6a..cd901394a524e49caf6107ce1f62e094c2fa3d97 100644 (file)
@@ -75,18 +75,17 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
 };
 
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
 public:
   NumberExprAST(double val) {}
-  virtual ~NumberExprAST();
 };
 
 /// VariableExprAST - Expression class for referencing a variable, like "a".
@@ -94,14 +93,12 @@ class VariableExprAST : public ExprAST {
   std::string Name;
 public:
   VariableExprAST(const std::string &name) : Name(name) {}
-  virtual ~VariableExprAST();
 };
 
 /// BinaryExprAST - Expression class for a binary operator.
 class BinaryExprAST : public ExprAST {
 public:
   BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) {}
-  virtual ~BinaryExprAST();
 };
 
 /// CallExprAST - Expression class for function calls.
@@ -111,16 +108,8 @@ class CallExprAST : public ExprAST {
 public:
   CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
     : Callee(callee), Args(args) {}
-  virtual ~CallExprAST();
 };
 
-// Provide out-of-line definitions to prevent weak vtables.
-ExprAST::~ExprAST() {}
-NumberExprAST::~NumberExprAST() {}
-VariableExprAST::~VariableExprAST() {}
-BinaryExprAST::~BinaryExprAST() {}
-CallExprAST::~CallExprAST() {}
-
 /// PrototypeAST - This class represents the "prototype" for a function,
 /// which captures its name, and its argument names (thus implicitly the number
 /// of arguments the function takes).
@@ -138,6 +127,7 @@ class FunctionAST {
 public:
   FunctionAST(PrototypeAST *proto, ExprAST *body) {}
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
@@ -169,7 +159,6 @@ static int GetTokPrecedence() {
 /// Error* - These are little helper functions for error handling.
 ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
 PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
-FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
 
 static ExprAST *ParseExpression();
 
index 2494345c3f174b8ac0b963849fe7eea8e531e18f..a7b60ba3220a47d5c342d742a9cfe0b9b8852ae4 100644 (file)
@@ -80,17 +80,14 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
   virtual Value *Codegen() = 0;
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExprAST::~ExprAST() {}
-
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
   double Val;
@@ -150,6 +147,7 @@ public:
   
   Function *Codegen();
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
index 4d56c0f2dfbed7c62476c5a3f672e18e748ebc44..27c3f4f22d67da8ad1cbfa4c432d333d2677a424 100644 (file)
@@ -87,17 +87,14 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
   virtual Value *Codegen() = 0;
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExprAST::~ExprAST() {}
-
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
   double Val;
@@ -157,6 +154,7 @@ public:
   
   Function *Codegen();
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
index 113016a3264bc0607d4f5c0637288b27a1585998..fe4cdfe757450c174b1a776a2da4281525b79d38 100644 (file)
@@ -96,17 +96,14 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
   virtual Value *Codegen() = 0;
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExprAST::~ExprAST() {}
-
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
   double Val;
@@ -186,6 +183,7 @@ public:
   
   Function *Codegen();
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
index 70f233bf487407c9dffcde66516934c45b6d2bb9..b7b347db0d877db5c6aa2a200a19e4597e36d2eb 100644 (file)
@@ -101,17 +101,14 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
   virtual Value *Codegen() = 0;
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExprAST::~ExprAST() {}
-
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
   double Val;
@@ -214,6 +211,7 @@ public:
   
   Function *Codegen();
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
index a05d134a1af97a5225293c01dbc0961d03accbc8..5c66f5c83722a2402f69d4b532e7d4d10142b15a 100644 (file)
@@ -105,17 +105,14 @@ static int gettok() {
 //===----------------------------------------------------------------------===//
 // Abstract Syntax Tree (aka Parse Tree)
 //===----------------------------------------------------------------------===//
-
+namespace {
 /// ExprAST - Base class for all expression nodes.
 class ExprAST {
 public:
-  virtual ~ExprAST();
+  virtual ~ExprAST() {}
   virtual Value *Codegen() = 0;
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExprAST::~ExprAST() {}
-
 /// NumberExprAST - Expression class for numeric literals like "1.0".
 class NumberExprAST : public ExprAST {
   double Val;
@@ -232,6 +229,7 @@ public:
   
   Function *Codegen();
 };
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Parser
index 672e4815690d204bcfbc051f081285defa4002d0..fd10baf5a4a3df454cda4b0e91ad73317d79c043 100644 (file)
@@ -52,6 +52,7 @@ static cl::opt<bool> GenPPCFP128("generate-ppc-fp128",
 static cl::opt<bool> GenX86MMX("generate-x86-mmx",
   cl::desc("Generate X86 MMX floating-point values"), cl::init(false));
 
+namespace {
 /// A utility class to provide a pseudo-random number generator which is
 /// the same across all platforms. This is somewhat close to the libc
 /// implementation. Note: This is not a cryptographically secure pseudorandom
@@ -128,7 +129,7 @@ public:
     BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {}
 
   /// virtual D'tor to silence warnings.
-  virtual ~Modifier();
+  virtual ~Modifier() {}
 
   /// Add a new instruction.
   virtual void Act() = 0;
@@ -287,7 +288,6 @@ protected:
 
 struct LoadModifier: public Modifier {
   LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~LoadModifier();
   virtual void Act() {
     // Try to use predefined pointers. If non exist, use undef pointer value;
     Value *Ptr = getRandomPointerValue();
@@ -298,7 +298,6 @@ struct LoadModifier: public Modifier {
 
 struct StoreModifier: public Modifier {
   StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~StoreModifier();
   virtual void Act() {
     // Try to use predefined pointers. If non exist, use undef pointer value;
     Value *Ptr = getRandomPointerValue();
@@ -317,7 +316,6 @@ struct StoreModifier: public Modifier {
 
 struct BinModifier: public Modifier {
   BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~BinModifier();
 
   virtual void Act() {
     Value *Val0 = getRandomVal();
@@ -362,8 +360,6 @@ struct BinModifier: public Modifier {
 /// Generate constant values.
 struct ConstModifier: public Modifier {
   ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~ConstModifier();
-
   virtual void Act() {
     Type *Ty = pickType();
 
@@ -410,7 +406,6 @@ struct ConstModifier: public Modifier {
 
 struct AllocaModifier: public Modifier {
   AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){}
-  virtual ~AllocaModifier();
 
   virtual void Act() {
     Type *Tp = pickType();
@@ -421,7 +416,6 @@ struct AllocaModifier: public Modifier {
 struct ExtractElementModifier: public Modifier {
   ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
     Modifier(BB, PT, R) {}
-  virtual ~ExtractElementModifier();
 
   virtual void Act() {
     Value *Val0 = getRandomVectorValue();
@@ -435,8 +429,6 @@ struct ExtractElementModifier: public Modifier {
 
 struct ShuffModifier: public Modifier {
   ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~ShuffModifier();
-
   virtual void Act() {
 
     Value *Val0 = getRandomVectorValue();
@@ -465,7 +457,6 @@ struct ShuffModifier: public Modifier {
 struct InsertElementModifier: public Modifier {
   InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
     Modifier(BB, PT, R) {}
-  virtual ~InsertElementModifier();
 
   virtual void Act() {
     Value *Val0 = getRandomVectorValue();
@@ -482,8 +473,6 @@ struct InsertElementModifier: public Modifier {
 
 struct CastModifier: public Modifier {
   CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~CastModifier();
-
   virtual void Act() {
 
     Value *V = getRandomVal();
@@ -570,7 +559,6 @@ struct CastModifier: public Modifier {
 struct SelectModifier: public Modifier {
   SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R):
     Modifier(BB, PT, R) {}
-  virtual ~SelectModifier();
 
   virtual void Act() {
     // Try a bunch of different select configuration until a valid one is found.
@@ -595,8 +583,6 @@ struct SelectModifier: public Modifier {
 
 struct CmpModifier: public Modifier {
   CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
-  virtual ~CmpModifier();
-
   virtual void Act() {
 
     Value *Val0 = getRandomVal();
@@ -622,21 +608,9 @@ struct CmpModifier: public Modifier {
   }
 };
 
-// Use out-of-line definitions to prevent weak vtables.
-Modifier::~Modifier() {}
-LoadModifier::~LoadModifier() {}
-StoreModifier::~StoreModifier() {}
-BinModifier::~BinModifier() {}
-ConstModifier::~ConstModifier() {}
-AllocaModifier::~AllocaModifier() {}
-ExtractElementModifier::~ExtractElementModifier() {}
-ShuffModifier::~ShuffModifier() {}
-InsertElementModifier::~InsertElementModifier() {}
-CastModifier::~CastModifier() {}
-SelectModifier::~SelectModifier() {}
-CmpModifier::~CmpModifier() {}
-
-void FillFunction(Function *F, Random &R) {
+} // end anonymous namespace
+
+static void FillFunction(Function *F, Random &R) {
   // Create a legal entry block.
   BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F);
   ReturnInst::Create(F->getContext(), BB);
@@ -683,7 +657,7 @@ void FillFunction(Function *F, Random &R) {
   SM->ActN(5); // Throw in a few stores.
 }
 
-void IntroduceControlFlow(Function *F, Random &R) {
+static void IntroduceControlFlow(Function *F, Random &R) {
   std::vector<Instruction*> BoolInst;
   for (BasicBlock::iterator it = F->begin()->begin(),
        e = F->begin()->end(); it != e; ++it) {
index a74e05e7b2467fab0133cd0b6dc4e7c7039aa268..c67ec130912de43cf67cf35c0d551e27af10fec6 100644 (file)
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "gtest/gtest.h"
 
-namespace llvm {
-
-struct VirtualRefCounted : public RefCountedBaseVPTR {
-  virtual void f();
+namespace {
+struct VirtualRefCounted : public llvm::RefCountedBaseVPTR {
+  virtual void f() {}
 };
+}
 
-// Provide out-of-line definition to prevent weak vtable.
-void VirtualRefCounted::f() {}
+namespace llvm {
 
 // Run this test with valgrind to detect memory leaks.
 TEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
index 15c58c480aab4efc272fa85264b66b466def5b7a..46d6d9b8a9a600c281475274e0c7e6fc116927f7 100644 (file)
@@ -59,6 +59,7 @@ static void roundTripDestroy(void *object) {
   delete static_cast<SectionMemoryManager*>(object);
 }
 
+namespace {
 class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
 protected:
   MCJITCAPITest() {
@@ -83,8 +84,14 @@ protected:
     UnsupportedOSs.push_back(Triple::Cygwin);
   }
   
-  virtual void SetUp();
-
+  virtual void SetUp() {
+    didCallAllocateCodeSection = false;
+    Module = 0;
+    Function = 0;
+    Engine = 0;
+    Error = 0;
+  }
+  
   virtual void TearDown() {
     if (Engine)
       LLVMDisposeExecutionEngine(Engine);
@@ -150,15 +157,7 @@ protected:
   LLVMExecutionEngineRef Engine;
   char *Error;
 };
-
-// Provide out-of-line definition to prevent weak vtable.
-void MCJITCAPITest::SetUp() {
-  didCallAllocateCodeSection = false;
-  Module = 0;
-  Function = 0;
-  Engine = 0;
-  Error = 0;
-}
+} // end anonymous namespace
 
 TEST_F(MCJITCAPITest, simple_function) {
   SKIP_UNSUPPORTED_PLATFORM;
index cea6274656b85b966db0fdbf293831ec4bce67e2..7c3239ea2598def80d230c076e5c9ce3ea080eb6 100644 (file)
 
 using namespace llvm;
 
-class MCJITMultipleModuleTest : public testing::Test, public MCJITTestBase {
-public:
-  virtual ~MCJITMultipleModuleTest();
-};
-
-// Provide out-of-line definition to prevent weak vtable.
-MCJITMultipleModuleTest::~MCJITMultipleModuleTest() {}
-
 namespace {
 
+class MCJITMultipleModuleTest : public testing::Test, public MCJITTestBase {};
+
 // FIXME: ExecutionEngine has no support empty modules
 /*
 TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
index 9786befd720f1698ceab4df16bc540812a875570..fab81551fa5eb5668ffbba3c80cbcd8b073b39d5 100644 (file)
 
 using namespace llvm;
 
+namespace {
+
 class MCJITTest : public testing::Test, public MCJITTestBase {
 protected:
-
-  virtual void SetUp();
+  virtual void SetUp() { M.reset(createEmptyModule("<main>")); }
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-void MCJITTest::SetUp() {
-  M.reset(createEmptyModule("<main>"));
-}
-
-namespace {
-
 // FIXME: Ensure creating an execution engine does not crash when constructed
 //        with a null module.
 /*
index 6da3ad720265b5dce4402af05dda07983a6615f5..dd06433d6ab702f5877a9be678b1a744a74cb0c9 100644 (file)
@@ -36,17 +36,14 @@ static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
 }
 #endif
 
+namespace {
 // (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp.
 struct InstrsOp : public SetTheory::Operator {
   virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
-                     ArrayRef<SMLoc> Loc);
-};
-
-// Provide out-of-line definition to prevent weak vtable.
-void InstrsOp::apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
                      ArrayRef<SMLoc> Loc) {
-  ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
-}
+    ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
+  }
+};
 
 // (instregex "OpcPat",...) Find all instructions matching an opcode pattern.
 //
@@ -60,38 +57,35 @@ struct InstRegexOp : public SetTheory::Operator {
   const CodeGenTarget &Target;
   InstRegexOp(const CodeGenTarget &t): Target(t) {}
 
-  virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
-                     ArrayRef<SMLoc> Loc);
-};
-
-// Provide out-of-line definition to prevent weak vtable.
-void InstRegexOp::apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
-                       ArrayRef<SMLoc> Loc) {
-  SmallVector<Regex*, 4> RegexList;
-  for (DagInit::const_arg_iterator
-       AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) {
-    StringInit *SI = dyn_cast<StringInit>(*AI);
-    if (!SI)
-      PrintFatalError(Loc, "instregex requires pattern string: "
-                      + Expr->getAsString());
-    std::string pat = SI->getValue();
-    // Implement a python-style prefix match.
-    if (pat[0] != '^') {
-      pat.insert(0, "^(");
-      pat.insert(pat.end(), ')');
-    }
-    RegexList.push_back(new Regex(pat));
-  }
-  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
-       E = Target.inst_end(); I != E; ++I) {
-    for (SmallVectorImpl<Regex*>::iterator
-         RI = RegexList.begin(), RE = RegexList.end(); RI != RE; ++RI) {
-      if ((*RI)->match((*I)->TheDef->getName()))
-        Elts.insert((*I)->TheDef);
+  void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+             ArrayRef<SMLoc> Loc) {
+    SmallVector<Regex*, 4> RegexList;
+    for (DagInit::const_arg_iterator
+           AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) {
+      StringInit *SI = dyn_cast<StringInit>(*AI);
+      if (!SI)
+        PrintFatalError(Loc, "instregex requires pattern string: "
+          + Expr->getAsString());
+      std::string pat = SI->getValue();
+      // Implement a python-style prefix match.
+      if (pat[0] != '^') {
+        pat.insert(0, "^(");
+        pat.insert(pat.end(), ')');
+      }
+      RegexList.push_back(new Regex(pat));
+    }
+    for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
+           E = Target.inst_end(); I != E; ++I) {
+      for (SmallVectorImpl<Regex*>::iterator
+             RI = RegexList.begin(), RE = RegexList.end(); RI != RE; ++RI) {
+        if ((*RI)->match((*I)->TheDef->getName()))
+          Elts.insert((*I)->TheDef);
+      }
     }
+    DeleteContainerPointers(RegexList);
   }
-  DeleteContainerPointers(RegexList);
-}
+};
+} // end anonymous namespace
 
 /// CodeGenModels ctor interprets machine model records and populates maps.
 CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
index b0bbdf946b28aff475be90c1a9e731e632bf320b..f4893f50a6ff86032509a8b998f4cf39e5ae33d7 100644 (file)
@@ -43,12 +43,12 @@ Type::~Type() {}
 
 }
 
+namespace {
 class ExtendedIntegerType : public Type {
   unsigned BitWidth;
 public:
   explicit ExtendedIntegerType(unsigned bits)
     : Type(TK_ExtendedIntegerType), BitWidth(bits) {}
-  virtual ~ExtendedIntegerType();
   static bool classof(const Type *T) {
     return T->getKind() == TK_ExtendedIntegerType;
   }
@@ -60,16 +60,12 @@ public:
   }
 };
 
-// Provide out-of-line definition to prevent weak vtable.
-ExtendedIntegerType::~ExtendedIntegerType() {}
-
 class ExtendedVectorType : public Type {
   EVT ElementType;
   unsigned NumElements;
 public:
   ExtendedVectorType(EVT elty, unsigned num)
     : Type(TK_ExtendedVectorType), ElementType(elty), NumElements(num) {}
-  virtual ~ExtendedVectorType();
   static bool classof(const Type *T) {
     return T->getKind() == TK_ExtendedVectorType;
   }
@@ -83,9 +79,7 @@ public:
     return NumElements;
   }
 };
-
-// Provide out-of-line definition to prevent weak vtable.
-ExtendedVectorType::~ExtendedVectorType() {}
+} // end anonymous namespace
 
 static std::map<unsigned, const Type *>
   ExtendedIntegerTypeMap;