r175326 - Rework the visibility computation algorithm in preparation
Rafael EspĂndola
rafael.espindola at gmail.com
Tue Feb 19 13:07:57 PST 2013
> Rework the visibility computation algorithm in preparation
> for distinguishing type vs. value visibility.
>
> The changes to the visibility of explicit specializations
> are intentional.
Thanks. It is indeed much cleaner to ignore other sources when a
specialization explicitly says what visibility should be used. A
change that looks unintended is that in
struct HIDDEN foo {
};
template <class P>
struct bar {
static DEFAULT void zed();
};
template <class P>
void bar<P>::zed() {
}
//template class bar<foo>;
void test() {
bar<foo>::zed();
}
We produce a hidden symbol for zed, but uncommenting the explicit
template instantiation causes us to produce a default symbol. The idea
was for explicit template instantiations to make a difference only if
they have an attribute, no?
> The change to the "ugly" test case is
> a consequence of a sensible implementation, and I am happy
> to argue that this is better behavior.
This one I think we need back :-(
The problem is that in gcc it is really easy for a project to use
-fvisibility=hidden. They change the build system and then add default
visibility attributes to *definitions* that they need to show up in
the libraries. That is how we end up with things like:
template<typename T>
struct DEFAULT foo {
void bar() {}
};
class zed;
template class foo<zed>;
class DEFAULT zed {
};
It was originally found by clang being unable to build chrome in
"components mode". I did try making it an error, but that then
requires changing quiet a bit of code to forward declare types with
the correct visibility or avoid the forward declaration.
The bit I think we need back from the old implementation is that an
implicit visibility, like the one zed has up to its definition, should
not force foo<zed> to have a hidden visibility since foo has an
explicit visibility. This does mean we would produce a default symbol
for
template<typename T>
struct DEFAULT foo {
void bar() {}
};
class zed;
template class foo<zed>;
class HIDDEN zed {
};
but a hidden one for
template<typename T>
struct DEFAULT foo {
void bar() {}
};
class zed;
class HIDDEN zed {
};
template class foo<zed>;
Cheers,
Rafael
More information about the cfe-commits
mailing list