diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-06 22:00:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-06 22:00:56 +0000 |
commit | dffb8010a130733f1b55acf0af01deb0a2e083d3 (patch) | |
tree | b3c44ab285ebd917049b50a6e439a38438a2debc | |
parent | b73e281956ff1ba40c921511a2cd6e7e76ed86a7 (diff) |
Fix linkage for RTTI names by re-using the logic for computing the
linkage of vtables. Before this, we were emitting RTTI names for
template instantiations with strong external linkage rather than with
weak ODR linkage.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92857 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 21 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 45 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 3 |
3 files changed, 26 insertions, 43 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 20e5fcec56..29552ce444 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -360,27 +360,12 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { // If we're in an anonymous namespace, then we always want internal linkage. if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) return llvm::GlobalVariable::InternalLinkage; - + + // If this class does not have a vtable, we want weak linkage. if (!RD->isDynamicClass()) return llvm::GlobalValue::WeakODRLinkage; - // Get the key function. - const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD); - if (!KeyFunction) { - // There is no key function, the RTTI descriptor is emitted with weak_odr - // linkage. - return llvm::GlobalValue::WeakODRLinkage; - } - - // If the key function is defined, but inlined, then the RTTI descriptor is - // emitted with weak_odr linkage. - const FunctionDecl* KeyFunctionDefinition; - if (KeyFunction->getBody(KeyFunctionDefinition) && - KeyFunctionDefinition->isInlined()) - return llvm::GlobalValue::WeakODRLinkage; - - // Otherwise, the RTTI descriptor is emitted with external linkage. - return llvm::GlobalValue::ExternalLinkage; + return CodeGenModule::getVtableLinkage(RD); } case Type::Vector: diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index e0e8c54434..0dbf336dcc 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -889,18 +889,17 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) { llvm::GlobalVariable::LinkageTypes CodeGenModule::getVtableLinkage(const CXXRecordDecl *RD) { - // Get the key function. - const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD); - - if (KeyFunction) { + if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) + return llvm::GlobalVariable::InternalLinkage; + + if (const CXXMethodDecl *KeyFunction + = RD->getASTContext().getKeyFunction(RD)) { + // If this class has a key function, use that to determine the linkage of + // the vtable. const FunctionDecl *Def = 0; if (KeyFunction->getBody(Def)) KeyFunction = cast<CXXMethodDecl>(Def); - } - - if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) - return llvm::GlobalVariable::InternalLinkage; - else if (KeyFunction) { + switch (KeyFunction->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: @@ -919,22 +918,20 @@ CodeGenModule::getVtableLinkage(const CXXRecordDecl *RD) { // return llvm::GlobalVariable::AvailableExternallyLinkage; return llvm::GlobalVariable::WeakODRLinkage; } - } else if (KeyFunction) { + } + + switch (RD->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + case TSK_ExplicitInstantiationDefinition: + return llvm::GlobalVariable::WeakODRLinkage; + + case TSK_ExplicitInstantiationDeclaration: + // FIXME: Use available_externally linkage. However, this currently + // breaks LLVM's build due to undefined symbols. + // return llvm::GlobalVariable::AvailableExternallyLinkage; return llvm::GlobalVariable::WeakODRLinkage; - } else { - switch (RD->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - case TSK_ImplicitInstantiation: - case TSK_ExplicitInstantiationDefinition: - return llvm::GlobalVariable::WeakODRLinkage; - - case TSK_ExplicitInstantiationDeclaration: - // FIXME: Use available_externally linkage. However, this currently - // breaks LLVM's build due to undefined symbols. - // return llvm::GlobalVariable::AvailableExternallyLinkage; - return llvm::GlobalVariable::WeakODRLinkage; - } } // Silence GCC warning. diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 575b518767..8f165109f5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -409,7 +409,8 @@ public: /// getVtableLinkage - Return the appropriate linkage for the vtable, VTT, /// and type information of the given class. - llvm::GlobalVariable::LinkageTypes getVtableLinkage(const CXXRecordDecl *RD); + static llvm::GlobalVariable::LinkageTypes + getVtableLinkage(const CXXRecordDecl *RD); private: /// UniqueMangledName - Unique a name by (if necessary) inserting it into the |