]> granicus.if.org Git - clang/commitdiff
Make emitting a VTT a two-step process, much like emitting a VTable. You first get...
authorAnders Carlsson <andersca@mac.com>
Sat, 29 Jan 2011 19:16:51 +0000 (19:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 29 Jan 2011 19:16:51 +0000 (19:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124539 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/CodeGen/CGRTTI.cpp
lib/CodeGen/CGVTT.cpp
lib/CodeGen/CGVTables.cpp
lib/CodeGen/CGVTables.h
test/CodeGenCXX/mangle-subst-std.cpp

index a7b8f659786fc14f966c1f168cbe5b6ae4c046d2..7efd2bc807fc66a61cfdb613061b983edbea4e98 100644 (file)
@@ -318,7 +318,7 @@ static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD,
     VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
   } else {
     // We're the complete constructor, so get the VTT by name.
-    VTT = CGF.CGM.getVTables().getVTT(RD);
+    VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD);
     VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
   }
 
index 4ba58c716399bcf9f6523284ce5ebd7650f0444e..244bca8095ec59f4d4196e1a85998d1453d740b7 100644 (file)
@@ -522,7 +522,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
   llvm::SmallString<256> OutName;
   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, OutName);
   llvm::StringRef Name = OutName.str();
-  
+
   llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
   if (OldGV && !OldGV->isDeclaration())
     return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
index 5a99059f1af6f1fb1ce6ead19ec0fb3a92d78439..5ebe92b5394aba8bc8c73380c49ea4c3824aa6bc 100644 (file)
@@ -366,56 +366,45 @@ void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
   
 }
 
-llvm::GlobalVariable *
-CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
-                            bool GenerateDefinition,
-                            const CXXRecordDecl *RD) {
-  // Only classes that have virtual bases need a VTT.
-  if (RD->getNumVBases() == 0)
-    return 0;
+void
+CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
+                                  llvm::GlobalVariable::LinkageTypes Linkage,
+                                  const CXXRecordDecl *RD) {
+  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true);
 
-  llvm::SmallString<256> OutName;
-  CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName);
-  llvm::StringRef Name = OutName.str();
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  const llvm::ArrayType *ArrayType = 
+    llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
+  
+  llvm::Constant *Init = 
+    llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents().data(),
+                             Builder.getVTTComponents().size());
 
-  D1(printf("vtt %s\n", RD->getNameAsCString()));
+  VTT->setInitializer(Init);
 
-  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
-  if (GV == 0 || GV->isDeclaration()) {
-    const llvm::Type *Int8PtrTy = 
-      llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  // Set the correct linkage.
+  VTT->setLinkage(Linkage);
+}
 
-    VTTBuilder Builder(CGM, RD, GenerateDefinition);
+llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
+  assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
 
-    const llvm::ArrayType *Type = 
-      llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
+  llvm::SmallString<256> OutName;
+  CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName);
+  llvm::StringRef Name = OutName.str();
 
-    llvm::Constant *Init = 0;
-    if (GenerateDefinition)
-      Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
-                                      Builder.getVTTComponents().size());
+  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
 
-    llvm::GlobalVariable *OldGV = GV;
-    GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
-                                  Linkage, Init, Name);
-    CGM.setGlobalVisibility(GV, RD, /*ForDefinition*/ GenerateDefinition);
-    GV->setUnnamedAddr(true);
-    
-    if (OldGV) {
-      GV->takeName(OldGV);
-      llvm::Constant *NewPtr = 
-        llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
-      OldGV->replaceAllUsesWith(NewPtr);
-      OldGV->eraseFromParent();
-    }
-  }
-  
-  return GV;
-}
+  const llvm::Type *Int8PtrTy = 
+    llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  const llvm::ArrayType *ArrayType = 
+    llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
 
-llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
-  return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 
-                     /*GenerateDefinition=*/false, RD);
+  llvm::GlobalVariable *GV =
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 
+                                          llvm::GlobalValue::ExternalLinkage);
+  GV->setUnnamedAddr(true);
+  return GV;
 }
 
 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
index 0ff41bb35423362daffb160ad6deee1ecac5d7e1..ad2269418b7fdfa1fc3c76403763b3e188225ddf 100644 (file)
@@ -3040,7 +3040,10 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
   VTable = GetAddrOfVTable(RD);
   EmitVTableDefinition(VTable, Linkage, RD);
 
-  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+  if (RD->getNumVBases()) {
+    llvm::GlobalVariable *VTT = GetAddrOfVTT(RD);
+    EmitVTTDefinition(VTT, Linkage, RD);
+  }
 
   // If this is the magic class __cxxabiv1::__fundamental_type_info,
   // we will emit the typeinfo for the fundamental types. This is the
index 3e3cd4b165aba6cfa9d9d59344e6b76d2499b8f8..3aee49372dfd5e4c75aac1959d33cbc613fde424 100644 (file)
@@ -182,10 +182,6 @@ class CodeGenVTables {
   
   void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
 
-  llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
-                                    bool GenerateDefinition,
-                                    const CXXRecordDecl *RD);
-
   /// EmitThunk - Emit a single thunk.
   void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
   
@@ -257,8 +253,15 @@ public:
   GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, 
                              bool BaseIsVirtual, 
                              VTableAddressPointsMapTy& AddressPoints);
-  
-  llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
+
+    
+  /// GetAddrOfVTable - Get the address of the VTT for the given record decl.
+  llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
+
+  /// EmitVTTDefinition - Emit the definition of the given vtable.
+  void EmitVTTDefinition(llvm::GlobalVariable *VTT,
+                         llvm::GlobalVariable::LinkageTypes Linkage,
+                         const CXXRecordDecl *RD);
 
   /// EmitThunks - Emit the associated thunks for the given global decl.
   void EmitThunks(GlobalDecl GD);
index 2b570ed20236fd147fb406c36281331169a44c82..8d79988da8e344d93749b75a8e887ff5897f3dac 100644 (file)
@@ -3,14 +3,14 @@
 // Check mangling of Vtables, VTTs, and construction vtables that
 // involve standard substitutions.
 
+// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant 
 // CHECK: @_ZTCSd0_Si = internal constant 
 // CHECK: @_ZTCSd16_So = internal constant
-// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
 namespace std {
   struct A { A(); };