summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-03-24 23:54:09 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-03-24 23:54:09 +0000
commit750f511f11d49f5632880a38eca97818e872961c (patch)
treefafcf3c95c35e92429eee9925348d3edd08afd43
parent6f228bf9651254370567ff7a1fc56a85e5536a57 (diff)
downloadbcm5719-llvm-750f511f11d49f5632880a38eca97818e872961c.tar.gz
bcm5719-llvm-750f511f11d49f5632880a38eca97818e872961c.zip
Fix a bug where an explicit instantiation declaration of a class template
specialization would make us think it might have a key function. llvm-svn: 204686
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp3
-rw-r--r--clang/test/CodeGenCXX/template-instantiation.cpp24
2 files changed, 21 insertions, 6 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 0c21bde3820..ce55d2e49ab 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1957,10 +1957,11 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
if (!RD->isExternallyVisible())
return 0;
- // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6.
+ // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6.
// Same behavior as GCC.
TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
+ TSK == TSK_ExplicitInstantiationDeclaration ||
TSK == TSK_ExplicitInstantiationDefinition)
return 0;
diff --git a/clang/test/CodeGenCXX/template-instantiation.cpp b/clang/test/CodeGenCXX/template-instantiation.cpp
index 80283a1edd0..3baa946b0b1 100644
--- a/clang/test/CodeGenCXX/template-instantiation.cpp
+++ b/clang/test/CodeGenCXX/template-instantiation.cpp
@@ -5,11 +5,15 @@
//
// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
-// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
+// CHECK: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
// CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32]
// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A
+// CHECK: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
+
// CHECK-NOT: _ZTVN5test31SIiEE
// CHECK-NOT: _ZTSN5test31SIiEE
@@ -39,11 +43,21 @@ namespace test0 {
virtual void xsgetn();
};
- // This specialization should cause the vtable to be emitted, even with
- // the following extern template declaration.
- template<> void stdio_sync_filebuf<wchar_t>::xsgetn() {
+ // This specialization is not a key function, so doesn't cause the vtable to
+ // be instantiated unless we're instantiating a class definition anyway.
+ template<> void stdio_sync_filebuf<int[1]>::xsgetn() {
+ }
+ template<> void stdio_sync_filebuf<int[2]>::xsgetn() {
+ }
+ template<> void stdio_sync_filebuf<int[3]>::xsgetn() {
}
- extern template class stdio_sync_filebuf<wchar_t>;
+ template<> void stdio_sync_filebuf<int[4]>::xsgetn() {
+ }
+ extern template class stdio_sync_filebuf<int[2]>;
+
+ // These two both cause vtables to be emitted.
+ template class stdio_sync_filebuf<int[3]>;
+ stdio_sync_filebuf<int[4]> implicit_instantiation;
}
namespace test1 {
OpenPOWER on IntegriCloud