On 03/08/2012 08:21 AM, Dodji Seketeli wrote:
So I needed to say somehow that the P in the pack expansion
(in the pattern) is actually a Pr "in spirit".
Ah, I see.
+ /*we will fixup the siblings for
Space and capital W.
+get_root_index_same_level (tree index)
+ tree i = index;
+ if (TREE_CODE (TEMPLATE_PARM_DECL (i)) == CONST_DECL)
+ if (TEMPLATE_PARM_ORIG_LEVEL (i) == TEMPLATE_PARM_LEVEL (index))
+ i = TEMPLATE_PARM_ORIG_INDEX (i);
If the levels are the same, shouldn't the ORIG_INDEX already be the same
+ if (template_type_parameter_type_p (TREE_TYPE (i))
+ && TREE_CODE (TEMPLATE_PARM_DECL (i)) != CONST_DECL
+ && TYPE_CANONICAL (TREE_TYPE (i)) != NULL_TREE)
You already checked the TREE_CODE of TEMPLATE_PARM_DECL in the outer if.
And if it's not a CONST_DECL, it must be either a type parameter or
template parameter. So I think you only need the last test here.
+get_template_parameter_level_and_index (tree parameter, int *level, int *index)
+ int l = 0, i = -1;
+ tree parm;
+ if (TREE_CODE (parameter) == TYPE_DECL
+ || TREE_CODE (parameter) == TEMPLATE_DECL)
+ parm = TREE_TYPE (parameter);
+ else if (TREE_CODE (parameter) == PARM_DECL)
+ parm = DECL_INITIAL (parameter);
+ parm = parameter;
+ template_parm_level_and_index (parm, &l, &i);
Why not extend template_parm_level_and_index to handle these cases as well?
+ properly appends the descender of INDEX to that
+ if (*where == NULL_TREE)
+ TREE_VEC_ELT (TEMPLATE_PARM_DESCENDANTS (index),
+ TEMPLATE_PARM_LEVEL (descendant) - 1) = descendant;
Why not "*where = descendant"?
+ && (DECL_SOURCE_LOCATION (TEMPLATE_PARM_DECL (result))
+ != DECL_SOURCE_LOCATION (TEMPLATE_PARM_DECL (orig_index))))
+ /* We have gotten an equivalent index, that was reduced
+ from index from ORIG_INDEX, but which (location of)
+ DECL is different. This can lead to having error
+ messages pointing to the wrong location, so let's
+ build an equivalent TEMPLATE_PARM_INDEX with a DECL
+ pointing to the same location as ORIG_INDEX for
+ RESULT. */
How can this happen? Hmm, I guess it's because of
+ i = TEMPLATE_TYPE_PARM_INDEX (TYPE_CANONICAL (TREE_TYPE (i)));
Why do we want to go to the canonical type parameter (which has no name)
rather than just TYPE_MAIN_VARIANT?
I think it makes more sense to reduce the index we have, rather than
reduce the canonical index and then adjust the result to match the index
+ /* Template parms ought to be fixed-up from left to right. */
+ parms = nreverse (parms);
I'm a bit nervous about something called by fixup getting confused by
this change to the template parms before we change it back.
+/* Transform a template parameter into an argument, suitable to be
+ passed to tsubst as an element of its ARGS parameter. */
+template_parms_to_args (tree parms)
The comment seems to be talking about a single parm.
+ /* This can happen for template parms of a template template
+ parameter, e.g:
+ template<template<class T, class U> class TT> struct S;
+ Consider the level of the parms of TT; T and U both have
+ level 2; TT has no template parm of level 1. So in this case
+ the first element of full_template_args is NULL_TREE. If we
+ leave it like this TMPL_ARG_DEPTH on args returns 1 instead
+ of 2. This will make tsubst wrongly consider that T and U
+ have level 1. Instead, let's create a dummy vector as the
+ first element of full_template_args so that TMPL_ARG_DEPTH
+ returns the correct depth for args. */
Hmm, it seems odd that the parms wouldn't have level 1. I wonder if
changing that would also avoid needing to use structural equality for
template template parameters.
FIXME: This function does an approximation, as it only checks that
the levels of PARM_PACK/EXPANSION and ARG_PACK do match. For it to
be precise, I think the TEMPLATE_PARM_INDEX of PARM_PACK should
track its pre-fixup type, so that ARG_PACK could be compared with
that type instead. But that would increase the size of the
template_parm_index_s struct, as I don't see where else I could
store the pre-fixup type. */
Doesn't ...ORIG_INDEX work for this? Indeed, I'd think you could change
arg_from_parm_pack_p to compare ORIG_INDEX and then it would handle both
+ if (tinfo && TREE_CODE (TI_TEMPLATE (tinfo)) == TEMPLATE_DECL)
+ /* prepare possible partial instantiation of member
+ template by fixing-up template parms which level are
+ going to be reduced by the partial instantiation. */
+ tsubst_template_parms (DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo)),
+ args, tf_none);
This doesn't seem necessary for member functon templates, since we fix
up the parms first thing in tsubst_decl. Is it necessary for member
class templates? Can we handle it at a lower level there, too?
+ /* If T is a member template being partially instantiated,
+ fixup its template parmeters that are to be level-reduced,
+ upfront. */
+ tree parm_list =
+ tsubst_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t)),
+ args, complain);
This comment could be clearer; an UNBOUND_CLASS_TEMPLATE isn't a member
template, though it will eventually be replaced with one.