From 152d4dce59a123b9a103b3087dc3be7f0b71033e Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 5 Dec 2009 22:19:10 +0000 Subject: [PATCH] Use createGlobalVariable for creating vtable variables too. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90679 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 78 ++++++++++++++---------------- test/CodeGenCXX/vtable-linkage.cpp | 26 ++++++---- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index e41712ecf9..9ed90f0ba5 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1082,6 +1082,35 @@ uint64_t CGVtableInfo::getVtableAddressPoint(const CXXRecordDecl *RD) { 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 @@ llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass, // 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 @@ public: }; } -/// 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) diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index 3a1d8f38d3..39435a3c7f 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -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 -- 2.40.0