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