]> granicus.if.org Git - clang/commitdiff
More linkage improvements.
authorAnders Carlsson <andersca@mac.com>
Sun, 6 Dec 2009 00:53:22 +0000 (00:53 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 6 Dec 2009 00:53:22 +0000 (00:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90687 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
lib/CodeGen/CGVtable.h
test/CodeGenCXX/vtable-linkage.cpp

index 6f8f9ebd834c6d11b0fa6a58a9e0c53e4170665f..67d8c6282b66a12153be32e3130b22b5a5f65b5c 100644 (file)
@@ -1113,6 +1113,7 @@ createGlobalVariable(CodeGenModule &CGM, const CXXRecordDecl *RD,
 
 llvm::GlobalVariable *
 CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
+                             bool GenerateDefinition,
                              const CXXRecordDecl *LayoutClass,
                              const CXXRecordDecl *RD, uint64_t Offset) {
   llvm::SmallString<256> OutName;
@@ -1134,9 +1135,7 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
     if (AddressPoint == 0)
       AddressPoint = 1;
   } else {
-    bool CreateDefinition = Linkage != llvm::GlobalVariable::ExternalLinkage;
-
-    VtableBuilder b(RD, LayoutClass, Offset, CGM, CreateDefinition);
+    VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition);
 
     D1(printf("vtable %s\n", RD->getNameAsCString()));
     // First comes the vtables for all the non-virtual bases...
@@ -1150,12 +1149,15 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
     llvm::ArrayType *ArrayType = 
       llvm::ArrayType::get(Int8PtrTy, b.getVtable().size());
 
-    if (CreateDefinition) {
+    if (GenerateDefinition)
       Init = llvm::ConstantArray::get(ArrayType, &b.getVtable()[0], 
                                       b.getVtable().size());
-    }
+
     llvm::GlobalVariable *OGV = GV;
-    GV = createGlobalVariable(CGM, LayoutClass, ArrayType, Init, Name);
+    
+    GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, 
+                                  /*isConstant=*/true, Linkage, Init, Name);
+    
     if (OGV) {
       GV->takeName(OGV);
       llvm::Constant *NewPtr = 
@@ -1369,17 +1371,21 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
   return llvm::ConstantExpr::getBitCast(VTT, Int8PtrTy);
 }
 
-void CGVtableInfo::GenerateClassData(const CXXRecordDecl *RD) {
-  Vtables[RD] = GenerateVtable(llvm::GlobalValue::WeakODRLinkage, RD, RD, 0);
+void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                                     const CXXRecordDecl *RD) {
+  assert(!Vtables.count(RD) && "Vtable has already been generated!");
+  
+  Vtables[RD] = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0);
   CGM.GenerateRTTI(RD);
   CGM.GenerateVTT(RD);  
 }
 
 llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
-  llvm::GlobalVariable *Vtable = Vtables[RD];
+  llvm::GlobalVariable *Vtable = Vtables.lookup(RD);
   
   if (!Vtable)
-    Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, RD, RD, 0);
+    Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, 
+                            /*GenerateDefinition=*/false, RD, RD, 0);
 
   return Vtable;
 }
@@ -1388,6 +1394,7 @@ llvm::GlobalVariable *
 CGVtableInfo::getCtorVtable(const CXXRecordDecl *LayoutClass,
                             const CXXRecordDecl *RD, uint64_t Offset) {
   return GenerateVtable(llvm::GlobalValue::InternalLinkage, 
+                        /*GenerateDefinition=*/true,
                         LayoutClass, RD, Offset);
 }
 
@@ -1420,7 +1427,15 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
       return;
   }
 
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  if (RD->isInAnonymousNamespace())
+    Linkage = llvm::GlobalVariable::InternalLinkage;
+  else if (KeyFunction)
+    Linkage = llvm::GlobalVariable::ExternalLinkage;
+  else
+    Linkage = llvm::GlobalVariable::WeakODRLinkage;
+  
   // Emit the data.
-  GenerateClassData(RD);
+  GenerateClassData(Linkage, RD);
 }
 
index 37fa1230f69e4a5d4f1a7f7ec0d21649d0cd54ff..107db2f02a9bad3f254619eb7535f74b637c4249 100644 (file)
@@ -92,13 +92,15 @@ class CGVtableInfo {
   /// GenerateClassData - Generate all the class data requires to be generated
   /// upon definition of a KeyFunction.  This includes the vtable, the
   /// rtti data structure and the VTT.
-  void GenerateClassData(const CXXRecordDecl *RD);
+  /// 
+  /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
+  void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                         const CXXRecordDecl *RD);
  
   llvm::GlobalVariable *
-
   GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
-                 const CXXRecordDecl *LayoutClass, const CXXRecordDecl *RD,
-                 uint64_t Offset);
+                 bool GenerateDefinition, const CXXRecordDecl *LayoutClass, 
+                 const CXXRecordDecl *RD, uint64_t Offset);
     
 public:
   CGVtableInfo(CodeGenModule &CGM)
index 4eae3175a07dc19a07dcf18f669a8743d8680f20..81ac0e43b4c563f07daa6f1c5b4934adbea1af59 100644 (file)
@@ -22,6 +22,12 @@ struct C {
 
 C::C() { } 
 
+struct D {
+  virtual void f();
+};
+
+void D::f() { }
+
 // B has a key function that is not defined in this translation unit so its vtable
 // has external linkage.
 // CHECK: @_ZTV1B = external constant
@@ -29,6 +35,10 @@ C::C() { }
 // C has no key function, so its vtable should have weak_odr linkage.
 // CHECK: @_ZTV1C = weak_odr constant
 
+// D has a key function that is defined in this translation unit so its vtable is
+// defined in the translation unit.
+// CHECK: @_ZTV1D = constant
+
 // The A vtable should have internal linkage since it is inside an anonymous 
 // namespace.
 // CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant