[PATCH] D51789: [clang] Add the no_extern_template attribute

Louis Dionne via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 14 10:32:46 PDT 2018


ldionne added a comment.

In https://reviews.llvm.org/D51789#1235113, @rsmith wrote:

> In https://reviews.llvm.org/D51789#1235100, @ldionne wrote:
>
> > In https://reviews.llvm.org/D51789#1235096, @rsmith wrote:
> >
> > > OK, so the semantics of this attribute are "explicit instantiation declarations or definitions applied to the enclosing class do not apply to this member", right? So it opts the member out of both `extern template` and (non-`extern`) `template`, but only when applied to an enclosing class.
> >
> >
> > Yes, but it also (obviously) opts the member out when applied to the member itself, not only to an enclosing class.
>
>
> Assuming I'm understanding you correctly, I don't think the current implementation does that (nor does the documentation change say that), and I think that's a feature not a bug. For example, given:
>
>   template<typename T> struct A {
>     [[clang::no_extern_template]] void f() {}
>     void g() {}
>   };
>   template struct A<int>; // instantiates A<int> and definition of A<int>::g(), does not instantiate definition of A<int>::f()
>   template void A<int>::f(); // instantiates definition of A<int>::f() despite attribute
>
>
> ... the attribute affects the first explicit instantiation but not the second (I think you're saying it should affect both, and make the second explicit instantiation have no effect). I think the current behavior in this patch is appropriate: making the attribute also affect the second case makes it strictly less useful. [...]


Sorry, that's a misunderstanding. We're on the same page. What I meant is that if you apply the attribute to the entity itself but explicitly instantiate the enclosing class, then the entity is not instantiated. It's very obvious, but your previous comment:

> So it opts the member out of both `extern template` and (non-`extern`) `template`, but only when applied to an enclosing class.

suggested that it only applied in the following case:

  template <class T> struct Foo {
    struct __attribute__((no_extern_template)) nested { static void f() { } };
  };
  
  template struct Foo<int>; // Foo<int>::nested::f not instantiated


Repository:
  rC Clang

https://reviews.llvm.org/D51789





More information about the cfe-commits mailing list