On Fri, Jan 25, 2019 at 9:18 PM Alexandre Oliva <aol...@redhat.com> wrote:
> On Jan 24, 2019, Jason Merrill <ja...@redhat.com> wrote:
>
> > The latter; you can't have a partial specialization in a function.
>
> *nod* (though not entirely reflected in the patch below, I see)

> >> Any suggestion of a good name for the inline function (or would you
> >> prefer it to be a macro?) that tests whether a decl satisfies this
> >> predicate?  primary_or_partial_spec_p?
>
> > Sounds good.
>
> I was not entirely clear on what the predicate was supposed to be when I
> wrote the above.  I hadn't fully realized we were testing properties of
> a template instantiation by inspecting mostly properties of the
> template, rather than of the instantiation proper.  Once I realized
> that, I hesitated between introducing a function to test properties of
> the base template directly, or a function to test the instantiation for
> those properties.  It wasn't clear to me that having e.g. only
> DECL_TI_TEMPLATE as an argument would be enough to test everything we
> needed: we wouldn't have the context (should be the same) or the
> template args (certainly not the same, but sharing the same depth?) of
> the instantiation we were supposed to assess to begin with.
>
> So I went with a different name that reflected more closely the test I
> implemented: instantiates_primary_template_p.

That sounds good.

> Now, maybe we're better off with something that tests the template
> rather than the instantiation, to use at other places where
> PRIMARY_TEMPLATE_P is found insufficient.  If that's the case, I'll have
> to figure out whether taking just the template is enough, or whether we
> need the tinfo object or are better off taking additional arguments.
> But since that will take additional investigation and you had nodded to
> the logic that involved the args of the instantiation, I'm leaving it at
> this for now.  Please let me know whether the alternate form would be
> preferred.
>
> This patch bootstrapped on x86_64- and i686-linux-gnu, and is undergoing
> regression testing ATM.  Ok to install if it passes?
>
>
> for  gcc/cp/ChangeLog
>
>         PR c++/87770
>         * pt.c (instantiates_primary_template_p): New.
>         (type_dependent_expression_p): Use it.
>
> for  gcc/testsuite/ChangeLog
>
>         PR c++/87770
>         * g++.dg/pr87770.C: New.
> ---
>  gcc/cp/pt.c                    |   55 
> +++++++++++++++++++++++++++++++++++++++-
>  gcc/testsuite/g++.dg/pr87770.C |   11 ++++++++
>  2 files changed, 65 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/pr87770.C
>
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 48c180cc13b3..d413fa81c59e 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -400,6 +400,59 @@ template_class_depth (tree type)
>    return depth;
>  }
>
> +/* Return TRUE if NODE instantiates a template that has arguments of
> +   its own, be it directly a primary template or indirectly through a
> +   partial specializations.  */
> +static inline bool
> +instantiates_primary_template_p (tree node)
> +{
> +  tree tinfo;
> +  if (!DECL_P (node))
> +    tinfo = CLASSTYPE_TEMPLATE_INFO (node);
> +  else if (DECL_LANG_SPECIFIC (node))
> +    tinfo = DECL_TEMPLATE_INFO (node);
> +  else
> +    tinfo = NULL_TREE;

Maybe use get_template_info?

> +  if (!tinfo)
> +    return false;
> +
> +  tree tmpl = TI_TEMPLATE (tinfo);
> +  if (PRIMARY_TEMPLATE_P (tmpl))
> +    return true;
> +
> +  if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
> +    return false;
> +
> +  /* So now we know we have a specialization, but it could be a full
> +     or a partial specialization.  To tell which, compare the depth of
> +     its template arguments with those of its context.  ??? How do we
> +     tell apart a partial from a full explicit specialization in a
> +     non-template context?  */

We don't need to tell them apart here, the caller checks if there are
any dependent template arguments.

> +  tree ctxt;
> +  if (!DECL_P (node))
> +    ctxt = TYPE_CONTEXT (node);
> +  else
> +    ctxt = DECL_CONTEXT (node);

We know tmpl is a decl, so we can unconditionally take its DECL_CONTEXT.

> +  tree ctinfo;
> +  if (!DECL_P (ctxt))
> +    ctinfo = CLASSTYPE_TEMPLATE_INFO (ctxt);
> +  else if (DECL_LANG_SPECIFIC (ctxt))
> +    ctinfo = DECL_TEMPLATE_INFO (ctxt);
> +  else
> +    ctinfo = NULL_TREE;

And you can use get_template_info here as well.

Jason

Reply via email to