From: Rafael Espindola Date: Tue, 30 Mar 2010 18:07:27 +0000 (+0000) Subject: Don't produce a vtable if we are just instantiating a method and the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0f38678f01291e68fc70ea6056260b54d529307;p=clang Don't produce a vtable if we are just instantiating a method and the class has no key function. Fix PR6738. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99900 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 841281cdc4..bae588ab9b 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3138,19 +3138,28 @@ void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { // Get the key function. const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); + TemplateSpecializationKind RDKind = RD->getTemplateSpecializationKind(); + TemplateSpecializationKind MDKind = MD->getTemplateSpecializationKind(); + if (KeyFunction) { // We don't have the right key function. if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) return; + } else { + // If this is an explicit instantiation of a method, we don't need a vtable. + // Since we have no key function, we will emit the vtable when we see + // a use, and just defining a function is not an use. + if ((RDKind == TSK_ImplicitInstantiation || + RDKind == TSK_ExplicitInstantiationDeclaration) && + MDKind == TSK_ExplicitInstantiationDefinition) + return; } if (Vtables.count(RD)) return; - TemplateSpecializationKind kind = RD->getTemplateSpecializationKind(); - if (kind == TSK_ImplicitInstantiation) + if (RDKind == TSK_ImplicitInstantiation) CGM.DeferredVtables.push_back(RD); else GenerateClassData(CGM.getVtableLinkage(RD), RD); } - diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp index 9e0593998b..416c0a1a20 100644 --- a/test/CodeGenCXX/template-instantiation.cpp +++ b/test/CodeGenCXX/template-instantiation.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant +// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE // CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = constant // CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev( @@ -60,3 +61,16 @@ namespace test2 { a.zedbar(0.0); } } + +namespace test3 { + template + class basic_fstreamXX { + virtual void foo(){} + virtual void is_open() const { } + }; + + extern template class basic_fstreamXX; + // This template instantiation should not cause us to produce a vtable. + // (test at the top). + template void basic_fstreamXX::is_open() const; +}