On 12/09/2011 03:26 PM, Dodji Seketeli wrote:

Two overall comments:

1) Yeah, let's hold this for 4.8.
2) TEMPLATE_ID_TYPE in this patch is too closely related to BOUND_TEMPLATE_TEMPLATE_PARM; I'd like to see all the BOUND_TEMPLATE_TEMPLATE_PARM_P checks go away so that things know how to handle TEMPLATE_ID_TYPE and they know how to handle TEMPLATE_TEMPLATE_PARM, but the combination of the two is not handled specially.

  #define TEMPLATE_TYPE_PARM_INDEX(NODE)                                        
\
    (TYPE_VALUES_RAW (TREE_CHECK3 ((NODE), TEMPLATE_TYPE_PARM,          \
                                 TEMPLATE_TEMPLATE_PARM,                \
-                                BOUND_TEMPLATE_TEMPLATE_PARM)))
+                                TEMPLATE_ID_TYPE)))

A TEMPLATE_ID_TYPE shouldn't have a parm index.

   /* Brings type template parameters to the canonical forms.  */
   if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
-      || code == BOUND_TEMPLATE_TEMPLATE_PARM)
+      || BOUND_TEMPLATE_TEMPLATE_PARM_P (parm))
     parm = TEMPLATE_TYPE_PARM_INDEX (parm);

Do we still need to handle this case here?

   /* Accept bound template template parameters.  */
   else if (allow_template_p
-          && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+          && BOUND_TEMPLATE_TEMPLATE_PARM_P (type))

Do we want to allow all TEMPLATE_ID_TYPE here?

       /* We can't apply any attributes to a completely unknown type until
         instantiation time.  */
       enum tree_code code = TREE_CODE (type);
-      if (code == TEMPLATE_TYPE_PARM
-         || code == BOUND_TEMPLATE_TEMPLATE_PARM
+      if (BOUND_TEMPLATE_TEMPLATE_PARM_P (type)
+         ||code == TEMPLATE_TYPE_PARM
          || code == TYPENAME_TYPE)

And here?

   /* Create lang_type structure.  */
   if (RECORD_OR_UNION_CODE_P (code)
-      || code == BOUND_TEMPLATE_TEMPLATE_PARM)
+      || code == TEMPLATE_ID_TYPE)

TEMPLATE_ID_TYPE doesn't need the whole 80 bytes of lang_type; it only needs one more tree outside of type_common. Since currently tree_code_size treats all types as being type_non_common, let's use TYPE_VALUES_RAW, TYPE_MINVAL, or TYPE_MAXVAL for TYPE_TEMPLATE_INFO of a TEMPLATE_ID_TYPE so it doesn't need TYPE_LANG_SPECIFIC at all.

 #define CLASSTYPE_TEMPLATE_ID_P(NODE)                                  \
   (TYPE_LANG_SPECIFIC (NODE) != NULL                                   \
-   && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM                        
\
+   && (BOUND_TEMPLATE_TEMPLATE_PARM_P (NODE)                           \
        || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL                      \
           && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))))

I think that with alias templates this should be renamed to TYPE_TEMPLATE_ID_P, and it should support all TEMPLATE_ID_TYPE. And the first use of CLASSTYPE_TEMPLATE_ID_P should drop the CLASS_TYPE_P check.

   /* Handle template parameters.  */
   if (code == TEMPLATE_TYPE_PARM
       || code == TEMPLATE_TEMPLATE_PARM
-      || code == BOUND_TEMPLATE_TEMPLATE_PARM
+      || BOUND_TEMPLATE_TEMPLATE_PARM_P (expr)
       || code == TEMPLATE_PARM_INDEX)
     write_template_param (expr);
   /* Handle literals.  */
@@ -2995,9 +2995,10 @@ write_template_param (const tree parm)

   switch (TREE_CODE (parm))
     {
+    case TEMPLATE_ID_TYPE:
+      gcc_assert (BOUND_TEMPLATE_TEMPLATE_PARM_P (parm));
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
-    case BOUND_TEMPLATE_TEMPLATE_PARM:
       parm_index = TEMPLATE_TYPE_IDX (parm);
       break;

We shouldn't need to handle TEMPLATE_ID_TYPE at all here; our normal handling of TEMPLATE_ID_TYPE should look through to the underlying TEMPLATE_TEMPLATE_PARM, and then that comes here.

-  if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+  if (BOUND_TEMPLATE_TEMPLATE_PARM_P (parm))
     {
-      templ
-       = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
+      templ = TI_TEMPLATE (TYPE_TEMPLATE_INFO (parm));
       if (find_substitution (templ))
        return;
     }

Likewise.

@@ -5330,7 +5330,7 @@ arg_assoc_type (struct arg_lookup *k, tree type)
       /* Associate the return type.  */
       return arg_assoc_type (k, TREE_TYPE (type));
     case TEMPLATE_TYPE_PARM:
-    case BOUND_TEMPLATE_TEMPLATE_PARM:
+    case TEMPLATE_ID_TYPE:
       return false;

This code was already wrong; as in arg_assoc_class, we should look at the associated namespaces of the template arguments.

-    case BOUND_TEMPLATE_TEMPLATE_PARM:
+    case TEMPLATE_ID_TYPE:
       /* Record template parameters such as `T' inside `TT<T>'.  */
       if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
                                  pfd->include_nondeduced_p))
        return error_mark_node;
+
+      if (!BOUND_TEMPLATE_TEMPLATE_PARM_P (t))
+       break;
+
       /* Fall through.  */

Instead of falling through, the handling of TEMPLATE_ID_TYPE should walk into TYPE_TI_TEMPLATE.

     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
-    case BOUND_TEMPLATE_TEMPLATE_PARM:
+    case TEMPLATE_ID_TYPE:
     case TEMPLATE_PARM_INDEX:

TEMPLATE_ID_TYPE should get its own case, and we should be able to handle template template parms and other uses the same way.

@@ -15851,7 +15891,7 @@ template_parm_level_and_index (tree parm, int* level, 
int* index)
 {
   if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
       || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
-      || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+      || BOUND_TEMPLATE_TEMPLATE_PARM_P (parm))

And we shouldn't need to handle it here.

@@ -16216,9 +16256,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
         within the nested-name-specifier.  */
       return unify_success (explain_p);

+    case TEMPLATE_ID_TYPE:
+      gcc_assert (BOUND_TEMPLATE_TEMPLATE_PARM_P (parm));

And it should get its own code here, since presumably we can deduce template arguments from the non-bound-template-template-parm usage as well.

+    case TEMPLATE_ID_TYPE:
+      if (BOUND_TEMPLATE_TEMPLATE_PARM_P (node))
+       /* Fall through.  */;
+      else
+       break;

Own code.

   if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
-      || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+      || BOUND_TEMPLATE_TEMPLATE_PARM_P (type)
       || TREE_CODE (type) == TYPENAME_TYPE)

This should allow all TEMPLATE_ID_TYPE.

@@ -1129,7 +1129,7 @@ comp_template_parms_position (tree t1, tree t2)
   tree index1, index2;
   gcc_assert (t1 && t2
              && TREE_CODE (t1) == TREE_CODE (t2)
-             && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
+             && (BOUND_TEMPLATE_TEMPLATE_PARM_P (t1)
                  || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
                  || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));

Shouldn't need to handle any TEMPLATE_ID_TYPE.

+    case TEMPLATE_ID_TYPE:
+      if (!BOUND_TEMPLATE_TEMPLATE_PARM_P (t1))
+       {
+         if (!cp_tree_equal (TYPE_TI_TEMPLATE (t1),
+                             TYPE_TI_TEMPLATE (t2)))
+           return false;
+         return comp_template_args (TYPE_TI_ARGS (t1),
+                                    TYPE_TI_ARGS (t2));
+       }
+      else
+       {
+         /* Fall through.  */;
+       }

Should handle all TEMPLATE_ID_TYPE the same.

     case UNION_TYPE:
       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
          && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
-             || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
+             || BOUND_TEMPLATE_TEMPLATE_PARM_P (t1))
          && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))

Should handle all TEMPLATE_ID_TYPE.

Jason

Reply via email to