summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGVtable.cpp18
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp3
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;
}
}
OpenPOWER on IntegriCloud