Hi Rafael,<div><br></div><div>I have a reduced repro for the regression caused by this CL (as mentioned in IRC). I attached it to <a href="http://llvm.org/PR12835">http://llvm.org/PR12835</a></div><div><br></div><div>Nico<br>
<br><div class="gmail_quote">On Tue, May 15, 2012 at 7:09 AM, Rafael Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: rafael<br>
Date: Tue May 15 09:09:55 2012<br>
New Revision: 156821<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=156821&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=156821&view=rev</a><br>
Log:<br>
Fix our handling of visibility in explicit template instantiations.<br>
<br>
* Don't copy the visibility attribute during instantiations. We have to be able<br>
to distinguish<br>
<br>
struct HIDDEN foo {};<br>
template<class T><br>
DEFAULT void bar() {}<br>
template DEFAULT void bar<foo>();<br>
<br>
from<br>
<br>
struct HIDDEN foo {};<br>
template<class T><br>
DEFAULT void bar() {}<br>
template void bar<foo>();<br>
<br>
* If an instantiation has an attribute, it takes precedence over an attribute<br>
in the template.<br>
<br>
* With instantiation attributes handled with the above logic, we can now<br>
select the minimum visibility when looking at template arguments.<br>
<br>
Modified:<br>
cfe/trunk/include/clang/Basic/Attr.td<br>
cfe/trunk/lib/AST/Decl.cpp<br>
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
cfe/trunk/test/CodeGenCXX/visibility.cpp<br>
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=156821&r1=156820&r2=156821&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=156821&r1=156820&r2=156821&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Tue May 15 09:09:55 2012<br>
@@ -93,6 +93,9 @@<br>
list<string> Namespaces = [];<br>
// Set to true for attributes with arguments which require delayed parsing.<br>
bit LateParsed = 0;<br>
+ // Set to false to prevent an attribute from being propagated from a template<br>
+ // to the instantiation.<br>
+ bit Clone = 1;<br>
// Set to true for attributes which must be instantiated within templates<br>
bit TemplateDependent = 0;<br>
// Set to true for attributes that have a corresponding AST node.<br>
@@ -660,6 +663,7 @@<br>
}<br>
<br>
def Visibility : InheritableAttr {<br>
+ let Clone = 0;<br>
let Spellings = ["visibility"];<br>
let Args = [EnumArgument<"Visibility", "VisibilityType",<br>
["default", "hidden", "internal", "protected"],<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=156821&r1=156820&r2=156821&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=156821&r1=156820&r2=156821&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Tue May 15 09:09:55 2012<br>
@@ -158,14 +158,12 @@<br>
return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), OnlyTemplate);<br>
}<br>
<br>
-static bool shouldConsiderTemplateLV(const FunctionDecl *fn,<br>
- const FunctionTemplateSpecializationInfo *spec) {<br>
- return !(spec->isExplicitSpecialization() &&<br>
- fn->hasAttr<VisibilityAttr>());<br>
+static bool shouldConsiderTemplateLV(const FunctionDecl *fn) {<br>
+ return !fn->hasAttr<VisibilityAttr>();<br>
}<br>
<br>
static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) {<br>
- return !(d->isExplicitSpecialization() && d->hasAttr<VisibilityAttr>());<br>
+ return !d->hasAttr<VisibilityAttr>();<br>
}<br>
<br>
static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,<br>
@@ -376,7 +374,7 @@<br>
// this is an explicit specialization with a visibility attribute.<br>
if (FunctionTemplateSpecializationInfo *specInfo<br>
= Function->getTemplateSpecializationInfo()) {<br>
- if (shouldConsiderTemplateLV(Function, specInfo)) {<br>
+ if (shouldConsiderTemplateLV(Function)) {<br>
LV.merge(getLVForDecl(specInfo->getTemplate(),<br>
true));<br>
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;<br>
@@ -407,8 +405,8 @@<br>
<br>
// The arguments at which the template was instantiated.<br>
const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();<br>
- LV.merge(getLVForTemplateArgumentList(TemplateArgs,<br>
- OnlyTemplate));<br>
+ LV.mergeWithMin(getLVForTemplateArgumentList(TemplateArgs,<br>
+ OnlyTemplate));<br>
}<br>
}<br>
<br>
@@ -527,7 +525,7 @@<br>
// the template parameters and arguments.<br>
if (FunctionTemplateSpecializationInfo *spec<br>
= MD->getTemplateSpecializationInfo()) {<br>
- if (shouldConsiderTemplateLV(MD, spec)) {<br>
+ if (shouldConsiderTemplateLV(MD)) {<br>
LV.mergeWithMin(getLVForTemplateArgumentList(*spec->TemplateArguments,<br>
OnlyTemplate));<br>
if (!OnlyTemplate)<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=156821&r1=156820&r2=156821&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=156821&r1=156820&r2=156821&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue May 15 09:09:55 2012<br>
@@ -102,7 +102,8 @@<br>
} else {<br>
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,<br>
*this, TemplateArgs);<br>
- New->addAttr(NewAttr);<br>
+ if (NewAttr)<br>
+ New->addAttr(NewAttr);<br>
}<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/visibility.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility.cpp?rev=156821&r1=156820&r2=156821&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility.cpp?rev=156821&r1=156820&r2=156821&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/visibility.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/visibility.cpp Tue May 15 09:09:55 2012<br>
@@ -712,3 +712,55 @@<br>
// CHECK: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv<br>
// CHECK-HIDDEN: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv<br>
}<br>
+<br>
+namespace test37 {<br>
+ struct HIDDEN foo {<br>
+ };<br>
+ template<class T><br>
+ DEFAULT void bar() {}<br>
+ template DEFAULT void bar<foo>();<br>
+ // CHECK: define weak_odr void @_ZN6test373barINS_3fooEEEvv<br>
+ // CHECK-HIDDEN: define weak_odr void @_ZN6test373barINS_3fooEEEvv<br>
+}<br>
+<br>
+namespace test38 {<br>
+ template<typename T><br>
+ class DEFAULT foo {<br>
+ void bar() {}<br>
+ };<br>
+ struct HIDDEN zed {<br>
+ };<br>
+ template class foo<zed>;<br>
+ // CHECK: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv<br>
+ // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv<br>
+}<br>
+<br>
+namespace test39 {<br>
+ class DEFAULT default_t;<br>
+ class HIDDEN hidden_t;<br>
+ template <class T> class A {<br>
+ template <class U> class B {<br>
+ HIDDEN void hidden() {}<br>
+ void noattr() {}<br>
+ template <class V> void temp() {}<br>
+ };<br>
+ };<br>
+ template class DEFAULT A<hidden_t>;<br>
+ template class DEFAULT A<hidden_t>::B<hidden_t>;<br>
+ template void A<hidden_t>::B<hidden_t>::temp<default_t>();<br>
+ template void A<hidden_t>::B<hidden_t>::temp<hidden_t>();<br>
+<br>
+ // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv<br>
+ // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv<br>
+ // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv<br>
+<br>
+ // GCC produces a default for this one. Why?<br>
+ // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv<br>
+<br>
+ // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv<br>
+ // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv<br>
+ // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv<br>
+<br>
+ // GCC produces a default for this one. Why?<br>
+ // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv<br>
+}<br>
<br>
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=156821&r1=156820&r2=156821&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=156821&r1=156820&r2=156821&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)<br>
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue May 15 09:09:55 2012<br>
@@ -1004,6 +1004,14 @@<br>
continue;<br>
<br>
OS << " case attr::" << R.getName() << ": {\n";<br>
+ bool ShouldClone = R.getValueAsBit("Clone");<br>
+<br>
+ if (!ShouldClone) {<br>
+ OS << " return NULL;\n";<br>
+ OS << " }\n";<br>
+ continue;<br>
+ }<br>
+<br>
OS << " const " << R.getName() << "Attr *A = cast<"<br>
<< R.getName() << "Attr>(At);\n";<br>
bool TDependent = R.getValueAsBit("TemplateDependent");<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>