aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-03-04 10:39:25 +0000
committerJohn McCall <rjmccall@apple.com>2011-03-04 10:39:25 +0000
commit1a0918ade0a3490c7aff243f9cd519156dfcb0bd (patch)
tree49bd1c63937db53c9cd432d0be12933bd0687721
parentfb4eb9f56c1b7bb4fb632127a5e2d253b65758bf (diff)
Don't consider visibility from template parameter lists if we're
computing for a nested decl with explicit visibility. This is all part of the general philosophy of explicit visibility attributes, where any information that was obviously available at the attribute site should probably be ignored. Fixes PR9371. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126992 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/Decl.cpp17
-rw-r--r--test/CodeGenCXX/visibility.cpp11
2 files changed, 23 insertions, 5 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 6dd47077f3..cc33d84c94 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -100,9 +100,11 @@ namespace {
struct LVFlags {
bool ConsiderGlobalVisibility;
bool ConsiderVisibilityAttributes;
+ bool ConsiderTemplateParameterTypes;
LVFlags() : ConsiderGlobalVisibility(true),
- ConsiderVisibilityAttributes(true) {
+ ConsiderVisibilityAttributes(true),
+ ConsiderTemplateParameterTypes(true) {
}
/// \brief Returns a set of flags that is only useful for computing the
@@ -111,6 +113,7 @@ struct LVFlags {
LVFlags F;
F.ConsiderGlobalVisibility = false;
F.ConsiderVisibilityAttributes = false;
+ F.ConsiderTemplateParameterTypes = false;
return F;
}
@@ -120,6 +123,7 @@ struct LVFlags {
LVFlags F = *this;
F.ConsiderGlobalVisibility = false;
F.ConsiderVisibilityAttributes = false;
+ F.ConsiderTemplateParameterTypes = false;
return F;
}
};
@@ -451,8 +455,9 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// - a template, unless it is a function template that has
// internal linkage (Clause 14);
- } else if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
- LV.merge(getLVForTemplateParameterList(Template->getTemplateParameters()));
+ } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
+ if (F.ConsiderTemplateParameterTypes)
+ LV.merge(getLVForTemplateParameterList(temp->getTemplateParameters()));
// - a namespace (7.3), unless it is declared within an unnamed
// namespace.
@@ -536,7 +541,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
if (FunctionTemplateSpecializationInfo *Spec
= MD->getTemplateSpecializationInfo()) {
LV.merge(getLVForTemplateArgumentList(*Spec->TemplateArguments, F));
- LV.merge(getLVForTemplateParameterList(
+ if (F.ConsiderTemplateParameterTypes)
+ LV.merge(getLVForTemplateParameterList(
Spec->getTemplate()->getTemplateParameters()));
TSK = Spec->getTemplateSpecializationKind();
@@ -571,7 +577,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
// Merge template argument/parameter information for member
// class template specializations.
LV.merge(getLVForTemplateArgumentList(Spec->getTemplateArgs(), F));
- LV.merge(getLVForTemplateParameterList(
+ if (F.ConsiderTemplateParameterTypes)
+ LV.merge(getLVForTemplateParameterList(
Spec->getSpecializedTemplate()->getTemplateParameters()));
}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 931465060b..7644e47ff7 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -411,3 +411,14 @@ namespace Test20 {
B<A<2> >::test5();
}
}
+
+// PR9371
+namespace test21 {
+ enum En { en };
+ template<En> struct A {
+ __attribute__((visibility("default"))) void foo() {}
+ };
+
+ // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
+ template void A<en>::foo();
+}