[cfe-commits] r90679 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-linkage.cpp

Anders Carlsson andersca at mac.com
Sat Dec 5 14:19:10 PST 2009


Author: andersca
Date: Sat Dec  5 16:19:10 2009
New Revision: 90679

URL: http://llvm.org/viewvc/llvm-project?rev=90679&view=rev
Log:
Use createGlobalVariable for creating vtable variables too.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=90679&r1=90678&r2=90679&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sat Dec  5 16:19:10 2009
@@ -1082,6 +1082,35 @@
   return AddressPoint;
 }
 
+/// createGlobalVariable - Create a global variable to be used for storing 
+/// either a vtable, a construction vtable or a VTT. The returned global
+// variable will have the correct linkage set based on the given record decl.
+static llvm::GlobalVariable *
+createGlobalVariable(CodeGenModule &CGM, const CXXRecordDecl *RD, 
+                     const llvm::Type *Type, llvm::Constant *Init,
+                     const llvm::Twine &Name) {
+  
+  // Figure out the right linkage.
+  llvm::GlobalVariable::LinkageTypes Linkage = 
+    llvm::GlobalValue::LinkOnceODRLinkage;
+  if (!Init)
+    Linkage = llvm::GlobalValue::ExternalLinkage;
+  else if (RD->isInAnonymousNamespace())
+    Linkage = llvm::GlobalValue::InternalLinkage;
+
+  // Create the variable.
+  llvm::GlobalVariable *V = 
+    new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
+                             Linkage, Init, Name);
+  
+
+  bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+  if (Hidden)
+    V->setVisibility(llvm::GlobalVariable::HiddenVisibility);
+  
+  return V;
+}
+
 llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass,
                                               const CXXRecordDecl *RD,
                                               uint64_t Offset) {
@@ -1129,31 +1158,23 @@
     // then the vtables for all the virtual bases.
     b.GenerateVtableForVBases(RD, Offset);
 
-    llvm::Constant *C = 0;
-    llvm::ArrayType *ntype = 
+    llvm::Constant *Init = 0;
+    llvm::ArrayType *ArrayType = 
       llvm::ArrayType::get(Ptr8Ty, b.getVtable().size());
 
-    llvm::GlobalVariable::LinkageTypes linktype
-      = llvm::GlobalValue::ExternalLinkage;
     if (CreateDefinition) {
-      C = llvm::ConstantArray::get(ntype, &b.getVtable()[0], 
-                                   b.getVtable().size());
-      linktype = llvm::GlobalValue::LinkOnceODRLinkage;
-      if (LayoutClass->isInAnonymousNamespace())
-        linktype = llvm::GlobalValue::InternalLinkage;
+      Init = llvm::ConstantArray::get(ArrayType, &b.getVtable()[0], 
+                                      b.getVtable().size());
     }
     llvm::GlobalVariable *OGV = GV;
-    GV = new llvm::GlobalVariable(getModule(), ntype, true, linktype, C, Name);
+    GV = createGlobalVariable(*this, LayoutClass, ntype, C, Name);
     if (OGV) {
       GV->takeName(OGV);
-      llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
-                                                              OGV->getType());
+      llvm::Constant *NewPtr = 
+        llvm::ConstantExpr::getBitCast(GV, OGV->getType());
       OGV->replaceAllUsesWith(NewPtr);
       OGV->eraseFromParent();
     }
-    bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
-    if (Hidden)
-      GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
   }
   
   return GV;
@@ -1334,33 +1355,6 @@
 };
 }
 
-/// createGlobalVariable - Create a global variable to be used for storing 
-/// either a vtable, a construction vtable or a VTT. The returned global
-// variable will have the correct linkage set based on the given record decl.
-static llvm::GlobalVariable *
-createGlobalVariable(CodeGenModule &CGM, const CXXRecordDecl *RD, 
-                     const llvm::Type *Type, llvm::Constant *Init,
-                     const llvm::Twine &Name) {
-  
-  // Figure out the right linkage.
-  llvm::GlobalVariable::LinkageTypes Linkage = 
-    llvm::GlobalValue::LinkOnceODRLinkage;
-  if (RD->isInAnonymousNamespace())
-    Linkage = llvm::GlobalValue::InternalLinkage;
-
-  // Create the variable.
-  llvm::GlobalVariable *V = 
-    new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
-                             Linkage, Init, Name);
-  
-
-  bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
-  if (Hidden)
-    V->setVisibility(llvm::GlobalVariable::HiddenVisibility);
-  
-  return V;
-}
-
 llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
   // Only classes that have virtual bases need a VTT.
   if (RD->getNumVBases() == 0)

Modified: cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp?rev=90679&r1=90678&r2=90679&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp Sat Dec  5 16:19:10 2009
@@ -1,18 +1,24 @@
 // RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
 
 namespace {
-  // The vtables should have internal linkage.
   struct A {
     virtual void f() { }
   };
-  
-  struct B : virtual A {
-    virtual void f() { } 
-  };
-
-  // CHECK: @_ZTVN12_GLOBAL__N_11BE = internal constant
-  // CHECK: @_ZTTN12_GLOBAL__N_11BE = internal constant
-  // CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant
 }
 
-void f() { B b; }
+void f() { A b; }
+
+struct B {
+  B();
+  virtual void f();
+};
+
+B::B() { }
+
+// B has a key function that is not defined in this translation unit so its vtable
+// has external linkage.
+// CHECK: @_ZTV1B = external constant
+
+// The A vtable should have internal linkage since it is inside an anonymous 
+// namespace.
+// CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant





More information about the cfe-commits mailing list