summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-08 01:51:59 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-08 01:51:59 +0000
commit26d11be738d670d229039be500716733e976910a (patch)
treeb7e0e2d4e795ba47f0284a00a4130fee06b8a99f /clang
parent360a1434f048b13f16cfb65b704842ff36c52f7a (diff)
downloadbcm5719-llvm-26d11be738d670d229039be500716733e976910a.tar.gz
bcm5719-llvm-26d11be738d670d229039be500716733e976910a.zip
RP18408: If a member template is used as a template template argument, it does
not cause the template specialization to have no linkage. llvm-svn: 198726
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/Decl.cpp9
-rw-r--r--clang/test/CodeGenCXX/linkage.cpp8
2 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 29443960c47..4e69a906369 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -782,11 +782,18 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// really have linkage, but it's convenient to say they do for the
// purposes of calculating linkage of pointer-to-data-member
// template arguments.
+ //
+ // Templates also don't officially have linkage, but since we ignore
+ // the C++ standard and look at template arguments when determining
+ // linkage and visibility of a template specialization, we might hit
+ // a template template argument that way. If we do, we need to
+ // consider its linkage.
if (!(isa<CXXMethodDecl>(D) ||
isa<VarDecl>(D) ||
isa<FieldDecl>(D) ||
isa<IndirectFieldDecl>(D) ||
- isa<TagDecl>(D)))
+ isa<TagDecl>(D) ||
+ isa<TemplateDecl>(D)))
return LinkageInfo::none();
LinkageInfo LV;
diff --git a/clang/test/CodeGenCXX/linkage.cpp b/clang/test/CodeGenCXX/linkage.cpp
index 19f1b20773c..b858ecbfe47 100644
--- a/clang/test/CodeGenCXX/linkage.cpp
+++ b/clang/test/CodeGenCXX/linkage.cpp
@@ -220,3 +220,11 @@ namespace test17 {
}
template int *foo<42>();
}
+
+// PR18408
+namespace test18 {
+ template<template<typename> class> struct A {};
+ struct B { template<typename> struct C; };
+ void f(A<B::C>) {}
+ // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE(
+}
OpenPOWER on IntegriCloud