CXXRecordDecl *Class = VTableUses[I].first->getDefinition();
if (!Class)
continue;
+ TemplateSpecializationKind ClassTSK =
+ Class->getTemplateSpecializationKind();
SourceLocation Loc = VTableUses[I].second;
// of an explicit instantiation declaration, suppress the
// vtable; it will live with the explicit instantiation
// definition.
- bool IsExplicitInstantiationDeclaration
- = Class->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration;
+ bool IsExplicitInstantiationDeclaration =
+ ClassTSK == TSK_ExplicitInstantiationDeclaration;
for (auto R : Class->redecls()) {
TemplateSpecializationKind TSK
= cast<CXXRecordDecl>(R)->getTemplateSpecializationKind();
if (VTablesUsed[Canonical])
Consumer.HandleVTable(Class);
- // Optionally warn if we're emitting a weak vtable.
- if (Class->isExternallyVisible() &&
- Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+ // Warn if we're emitting a weak vtable. The vtable will be weak if there is
+ // no key function or the key function is inlined. Don't warn in C++ ABIs
+ // that lack key functions, since the user won't be able to make one.
+ if (Context.getTargetInfo().getCXXABI().hasKeyFunctions() &&
+ Class->isExternallyVisible() && ClassTSK != TSK_ImplicitInstantiation) {
const FunctionDecl *KeyFunctionDef = nullptr;
- if (!KeyFunction ||
- (KeyFunction->hasBody(KeyFunctionDef) &&
- KeyFunctionDef->isInlined()))
- Diag(Class->getLocation(), Class->getTemplateSpecializationKind() ==
- TSK_ExplicitInstantiationDefinition
- ? diag::warn_weak_template_vtable : diag::warn_weak_vtable)
- << Class;
+ if (!KeyFunction || (KeyFunction->hasBody(KeyFunctionDef) &&
+ KeyFunctionDef->isInlined())) {
+ Diag(Class->getLocation(),
+ ClassTSK == TSK_ExplicitInstantiationDefinition
+ ? diag::warn_weak_template_vtable
+ : diag::warn_weak_vtable)
+ << Class;
+ }
}
}
VTableUses.clear();