diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 |
2 files changed, 18 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index ba5a0c35439..ca148da9560 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1493,8 +1493,22 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) { llvm::GlobalVariable::LinkageTypes Linkage; if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) Linkage = llvm::GlobalVariable::InternalLinkage; - else if (KeyFunction && !MD->isInlined()) - Linkage = llvm::GlobalVariable::ExternalLinkage; + else if (KeyFunction && !MD->isInlined()) { + switch (MD->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + Linkage = llvm::GlobalVariable::ExternalLinkage; + break; + + case TSK_ImplicitInstantiation: + case TSK_ExplicitInstantiationDeclaration: + // FIXME: could an explicit instantiation declaration imply + // available_externally linkage? + case TSK_ExplicitInstantiationDefinition: + Linkage = llvm::GlobalVariable::WeakODRLinkage; + break; + } + } else Linkage = llvm::GlobalVariable::WeakODRLinkage; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 16a01cfd58f..85d57e7cbec 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -547,7 +547,8 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { const CXXRecordDecl *RD = MD->getParent(); if (MD->isOutOfLine() && RD->isDynamicClass()) { const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD); - if (KeyFunction == MD->getCanonicalDecl()) + if (KeyFunction && + KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl()) return false; } } |