Hi again,
On 04/29/2012 11:42 AM, Paolo Carlini wrote:
This might just be a matter of calling for_each_template_parm and
returning 1 if we see any template parameter.
Good. Today I quickly tried something along these lines (see 'p'
attachment) and got some fails:

Ah, well. I guess for_each_template_parm doesn't look at the types of declarations.
Just a few moments ago I noticed something interesting: if a NULL FN is passed to for_each_template_parm, it assumes a function which always returns 1, what we want when just searching for the first occurrence. Now, in practice, *no* front-code calls it like this! Thus, if we want, it's safe to tweak / extend for_each_template_parm_r for our purposes when !fn

And indeed, the attached passes the testsuite with no regressions ;)

I also want to remark that there is this kind of comment:

    case INDIRECT_REF:
    case COMPONENT_REF:
      /* If there's no type, then this thing must be some expression
     involving template parameters.  */
      if (!fn && !TREE_TYPE (t))
    return error_mark_node;
+      else if (!fn && for_each_template_parm (TREE_TYPE (t), fn,
+                          data, pfd->visited,
+                          pfd->include_nondeduced_p))
+    return error_mark_node;

which, how can I say, appears to "support" the idea of tweaking / extending the code in the direction we like.

Thus, my question would be: is something like the below in the right direction? The alternate possibility I can see, would be basically redoing a slightly slimmed version of for_each_template_parm specialized for our needs (a few less conditionals)

Thanks!

Paolo.

////////////////////////////
Index: pt.c
===================================================================
--- pt.c        (revision 187001)
+++ pt.c        (working copy)
@@ -7861,6 +7861,10 @@ for_each_template_parm_r (tree *tp, int *walk_subt
          && for_each_template_parm (DECL_CONTEXT (t), fn, data,
                                     pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
+      if (!fn && TREE_TYPE (t)
+         && for_each_template_parm (TREE_TYPE(t), fn, data,
+                                    pfd->visited, pfd->include_nondeduced_p))
+       return error_mark_node;
       break;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
@@ -7905,6 +7909,11 @@ for_each_template_parm_r (tree *tp, int *walk_subt
                                     (TREE_TYPE (t)), fn, data,
                                     pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
+      else if (!fn && TREE_TYPE (t)
+              && for_each_template_parm (TREE_TYPE (t), fn,
+                                         data, pfd->visited, 
+                                         pfd->include_nondeduced_p))
+       return error_mark_node;
       break;
 
     case INDIRECT_REF:
@@ -7913,6 +7922,10 @@ for_each_template_parm_r (tree *tp, int *walk_subt
         involving template parameters.  */
       if (!fn && !TREE_TYPE (t))
        return error_mark_node;
+      else if (!fn && for_each_template_parm (TREE_TYPE (t), fn,
+                                             data, pfd->visited, 
+                                             pfd->include_nondeduced_p))
+       return error_mark_node;
       break;
 
     case MODOP_EXPR:
@@ -19744,6 +19757,29 @@ type_dependent_expression_p (tree expression)
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
+/* Returns TRUE if the EXPRESSION is instantiation-dependent, in the
+   sense defined by the ABI:
+
+   "An expression is instantiation-dependent if it is type-dependent
+   or value-dependent, or it has a subexpression that is type-dependent
+   or value-dependent."  */
+
+bool
+instantiation_dependent_expression_p (tree expression)
+{
+  if (!processing_template_decl)
+    return false;
+
+  if (expression == error_mark_node)
+    return false;
+
+  if (!TREE_TYPE (expression))
+    return true;
+
+  return for_each_template_parm (expression, NULL, NULL, NULL,
+                                /*include_nondeduced_p=*/true);
+}
+
 /* Like type_dependent_expression_p, but it also works while not processing
    a template definition, i.e. during substitution or mangling.  */
 
Index: semantics.c
===================================================================
--- semantics.c (revision 187001)
+++ semantics.c (working copy)
@@ -5168,8 +5168,7 @@ finish_decltype_type (tree expr, bool id_expressio
       return error_mark_node;
     }
 
-  /* FIXME instantiation-dependent  */
-  if (type_dependent_expression_p (expr)
+  if (instantiation_dependent_expression_p (expr)
       /* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
         if it isn't dependent, so that we can check access control at
         instantiation time, so defer the decltype as well (PR 42277).  */
Index: cp-tree.h
===================================================================
--- cp-tree.h   (revision 187001)
+++ cp-tree.h   (working copy)
@@ -5363,6 +5363,7 @@ extern bool any_type_dependent_arguments_p      (c
 extern bool any_type_dependent_elements_p       (const_tree);
 extern bool type_dependent_expression_p_push   (tree);
 extern bool value_dependent_expression_p       (tree);
+extern bool instantiation_dependent_expression_p(tree);
 extern bool any_value_dependent_elements_p      (const_tree);
 extern bool dependent_omp_for_p                        (tree, tree, tree, 
tree);
 extern tree resolve_typename_type              (tree, bool);

Reply via email to