diff options
author | Anders Carlsson <andersca@mac.com> | 2009-12-06 00:53:22 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-12-06 00:53:22 +0000 |
commit | 232324c5c08bdbc2dd289a2340849043e05ff485 (patch) | |
tree | 8d6a947a154ee57ffa17d7b51146fa5c752cfd95 /clang | |
parent | 0911ae8ef20f0251d51cb840cbe41b4255565351 (diff) | |
download | bcm5719-llvm-232324c5c08bdbc2dd289a2340849043e05ff485.tar.gz bcm5719-llvm-232324c5c08bdbc2dd289a2340849043e05ff485.zip |
More linkage improvements.
llvm-svn: 90687
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVtable.h | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/vtable-linkage.cpp | 10 |
3 files changed, 42 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 6f8f9ebd834..67d8c6282b6 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -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); } diff --git a/clang/lib/CodeGen/CGVtable.h b/clang/lib/CodeGen/CGVtable.h index 37fa1230f69..107db2f02a9 100644 --- a/clang/lib/CodeGen/CGVtable.h +++ b/clang/lib/CodeGen/CGVtable.h @@ -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) diff --git a/clang/test/CodeGenCXX/vtable-linkage.cpp b/clang/test/CodeGenCXX/vtable-linkage.cpp index 4eae3175a07..81ac0e43b4c 100644 --- a/clang/test/CodeGenCXX/vtable-linkage.cpp +++ b/clang/test/CodeGenCXX/vtable-linkage.cpp @@ -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 |