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 as index?
+ else + { + 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); + else + 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
descendant
+ 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 we have.
+ /* 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. */ + +static tree +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 cases.
+ if (tinfo && TREE_CODE (TI_TEMPLATE (tinfo)) == TEMPLATE_DECL) + { + ++processing_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); + --processing_template_decl; + }
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?
case UNBOUND_CLASS_TEMPLATE: { + /* 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.
Jason