Message ID | 5367BB74.6060805@oracle.com |
---|---|
State | New |
Headers | show |
On 05/05/2014 12:25 PM, Paolo Carlini wrote: > Good, but is it Ok to use uses_template_parms for that? A few days ago I > struggled to find something simpler ready to use, to no avail (well, > this is probably well known to you, but there are surprisingly few > places in pt.c where we explain either in comments or in obvious code > that we are handling full (vs partial) specializations). > +/* True if the given class type is a template or a partial specialization. */ > +#define CLASSTYPE_IS_TEMPLATE_OR_PARTIAL_SPECIALIZATION(NODE) \ > + (CLASSTYPE_TEMPLATE_INFO (NODE) \ > + && uses_template_parms (NODE)) I think this would be true for a non-template member class of a template class. I think we want something like CLASSTYPE_TEMPLATE_INFO (NODE) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)) && uses_template_parms (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (NODE))
Hi again, On 05/05/2014 10:48 PM, Jason Merrill wrote: > On 05/05/2014 12:25 PM, Paolo Carlini wrote: >> Good, but is it Ok to use uses_template_parms for that? A few days ago I >> struggled to find something simpler ready to use, to no avail (well, >> this is probably well known to you, but there are surprisingly few >> places in pt.c where we explain either in comments or in obvious code >> that we are handling full (vs partial) specializations). > >> +/* True if the given class type is a template or a partial >> specialization. */ >> +#define CLASSTYPE_IS_TEMPLATE_OR_PARTIAL_SPECIALIZATION(NODE) \ >> + (CLASSTYPE_TEMPLATE_INFO (NODE) \ >> + && uses_template_parms (NODE)) > > I think this would be true for a non-template member class of a > template class. On further thought (yesterday was a little tired, sorry), I think that nsdmi-template7.C is telling us that, in fact, we *do* want something true when we are handling an NSDMI inside a non-template class of a template class! Because in that case too the user code may want to use the template parameters in the initialization of the NSDMI. Well, assuming this is by and large right, we do *not* want a predicate for template or partial specialization, maybe a predicate for "dependent context", see what I mean?!? In any case, in practice, something rather close to my first try ;) (after all, the simple pattern is already used in tsubst for typedefs...) Paolo.
On 05/06/2014 04:23 AM, Paolo Carlini wrote: > On further thought (yesterday was a little tired, sorry), I think that > nsdmi-template7.C is telling us that, in fact, we *do* want something > true when we are handling an NSDMI inside a non-template class of a > template class! Right, sorry, I was thinking we only had to look at the innermost parameters, but in fact we need to push all levels of parameters. I've been resistant to your change because it wouldn't fix a specialization of a member template of another class template. Currently that is ill-formed, but there have been mumblings in Core about allowing it in the future. But supporting that would probably involve making such a specialization a template itself, so go ahead. But please add a comment clarifying that the test is there to avoid looking past an explicit specialization. Jason
Index: cp-tree.h =================================================================== --- cp-tree.h (revision 210068) +++ cp-tree.h (working copy) @@ -3160,6 +3160,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_a && !CLASSTYPE_USE_TEMPLATE (NODE) \ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) +/* True if the given class type is a template or a partial specialization. */ +#define CLASSTYPE_IS_TEMPLATE_OR_PARTIAL_SPECIALIZATION(NODE) \ + (CLASSTYPE_TEMPLATE_INFO (NODE) \ + && uses_template_parms (NODE)) + /* The name used by the user to name the typename type. Typically, this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the corresponding TYPE_DECL. However, this may also be a Index: pt.c =================================================================== --- pt.c (revision 210068) +++ pt.c (working copy) @@ -462,9 +462,12 @@ maybe_begin_member_template_processing (tree decl) bool nsdmi = TREE_CODE (decl) == FIELD_DECL; if (nsdmi) - decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) - ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl)) - : NULL_TREE); + { + tree ctx = DECL_CONTEXT (decl); + decl = (CLASSTYPE_IS_TEMPLATE_OR_PARTIAL_SPECIALIZATION (ctx) + ? CLASSTYPE_TI_TEMPLATE (ctx) + : NULL_TREE); + } if (inline_needs_template_parms (decl, nsdmi)) { @@ -11519,8 +11522,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain r = instantiate_alias_template (tmpl, gen_args, complain); } else if (DECL_CLASS_SCOPE_P (decl) - && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) - && uses_template_parms (DECL_CONTEXT (decl))) + && (CLASSTYPE_IS_TEMPLATE_OR_PARTIAL_SPECIALIZATION + (DECL_CONTEXT (decl)))) { tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl)); tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl);