[cfe-commits] [patch] Template instantiation and visibility (take 2)

John McCall rjmccall at apple.com
Mon Apr 23 13:17:37 PDT 2012


On Apr 23, 2012, at 1:00 PM, Rafael EspĂ­ndola wrote:
> In the testcases
> 
> namespace t1 {
> struct HIDDEN foo {};
> template<class T>
> DEFAULT void bar() {}
> template DEFAULT void bar<foo>();
> }
> namespace t2 {
> struct HIDDEN foo {};
> template<class T>
> DEFAULT void bar() {}
> template void bar<foo>();
> }
> namespace t3 {
> template<typename T>
> class DEFAULT foo {
>   void bar() {}
> };
> struct HIDDEN zed {};
> template class DEFAULT foo<zed>;
> }
> namespace t4 {
> template<typename T>
> class DEFAULT foo {
>   void bar() {}
> };
> struct HIDDEN zed {};
> template class foo<zed>;
> }
> 
> gcc 4.7 produces symbols with default visibility in t1 and t3, and
> hidden visibility in t2 and t4.
> 
> This requires differentiating attributes in a template and attributes
> in an instantiation.

The right model for an explicit instantiation with a visibility attribute is
  (1) the attribute replaces any attribute from the explicitly-instantiated
    entity (but not its children), and
  (2) visibility should not be modified by the visibility of the template
    arguments from that scope or broader.

As an example, suppose I have this:
  DEFAULT class default_t;
  HIDDEN class hidden_t;
  template <class T> class A {
    template <class U> class B {
      HIDDEN void hidden() {}
      void noattr() {}
      template <class V> void temp() {}
    };
  };
  template class DEFAULT A<hidden_t>::B<hidden_t>;

I claim that I should see:
  A<hidden_t>::B<hidden_t>::hidden() is hidden
  A<hidden_t>::B<hidden_t>::noattr() is default
  A<hidden_t>::B<hidden_t>::temp<default_t>() is default
  A<hidden_t>::B<hidden_t>::temp<hidden_t>() is hidden

John.



More information about the cfe-commits mailing list