cp-tree.h (get_template_base): Don't declare.
authorMark Mitchell <mark@markmitchell.com>
Wed, 10 Feb 1999 10:28:07 +0000 (10:28 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 10 Feb 1999 10:28:07 +0000 (10:28 +0000)
* cp-tree.h (get_template_base): Don't declare.
(dfs_walk): Declare.
(dfs_unmark): Likewise.
(markedp): Likewise.
* pt.c (unify): Remove duplicate declaration.  Pass tparms and
targs to get_template_base.
(get_template_base_recursive): Move here from search.c.  Check to
see that the base found can be instantiated to form the desired
type.
(get_template_base): Likewise.
(get_class_bindings): Simplify.
* search.c (get_template_base_recursive): Move to pt.c.
(get_template_base): Likewise.
(markedp): Make it global.
(dfs_walk): Likewise.
(dfs_unmark): Likewise.

From-SVN: r25126

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/search.c
gcc/testsuite/g++.old-deja/g++.pt/deduct1.C [new file with mode: 0644]

index 975769f..1eb28f0 100644 (file)
@@ -1,3 +1,22 @@
+1999-02-09  Mark Mitchell  <mark@markmitchell.com>
+
+       * cp-tree.h (get_template_base): Don't declare.
+       (dfs_walk): Declare.
+       (dfs_unmark): Likewise.
+       (markedp): Likewise.
+       * pt.c (unify): Remove duplicate declaration.  Pass tparms and
+       targs to get_template_base.
+       (get_template_base_recursive): Move here from search.c.  Check to
+       see that the base found can be instantiated to form the desired
+       type.
+       (get_template_base): Likewise.
+       (get_class_bindings): Simplify.
+       * search.c (get_template_base_recursive): Move to pt.c.
+       (get_template_base): Likewise.
+       (markedp): Make it global.
+       (dfs_walk): Likewise.
+       (dfs_unmark): Likewise.
+       
 1999-02-07  Jason Merrill  <jason@yorick.cygnus.com>
 
        * pt.c (maybe_process_partial_specialization): Complain about
index 6bed0bc..1bc67cf 100644 (file)
@@ -3147,8 +3147,10 @@ extern void init_search_processing               PROTO((void));
 extern void reinit_search_statistics           PROTO((void));
 extern tree current_scope                      PROTO((void));
 extern tree lookup_conversions                 PROTO((tree));
-extern tree get_template_base                  PROTO((tree, tree));
 extern tree binfo_for_vtable                   PROTO((tree));
+extern void dfs_walk                            PROTO((tree, void (*) (tree), int (*) (tree)));
+extern void dfs_unmark                          PROTO((tree));
+extern int  markedp                             PROTO((tree));
 
 /* in semantics.c */
 extern void finish_expr_stmt                    PROTO((tree));
index 72cf9d0..5b2e3a2 100644 (file)
@@ -77,7 +77,6 @@ static tree saved_trees;
 #define UNIFY_ALLOW_DERIVED 4
 #define UNIFY_ALLOW_INTEGER 8
 
-static int unify PROTO((tree, tree, tree, tree, int, int*));
 static int resolve_overloaded_unification PROTO((tree, tree, tree, tree,
                                                 unification_kind_t, int,
                                                 int*));
@@ -137,6 +136,9 @@ static tree process_partial_specialization PROTO((tree));
 static void set_current_access_from_decl PROTO((tree));
 static void check_default_tmpl_args PROTO((tree, tree, int, int));
 static tree tsubst_call_declarator_parms PROTO((tree, tree, tree));
+static tree get_template_base_recursive PROTO((tree, tree, int *, tree, tree,
+                                              tree, int)); 
+static tree get_template_base PROTO((tree, tree, int *, tree, tree));
 
 /* We use TREE_VECs to hold template arguments.  If there is only one
    level of template arguments, then the TREE_VEC contains the
@@ -7360,6 +7362,120 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
   return 1;
 }
 
+/* Subroutine of get_template_base.  */
+
+static tree
+get_template_base_recursive (tparms, targs, explicit_mask,
+                            binfo, rval, template,
+                            via_virtual)
+     tree tparms;
+     tree targs;
+     int *explicit_mask;
+     tree binfo;
+     tree rval;
+     tree template;
+     int via_virtual;
+{
+  tree binfos;
+  int i, n_baselinks;
+  tree type = BINFO_TYPE (binfo);
+  tree tmpl = CLASSTYPE_TI_TEMPLATE (template);
+
+  if (CLASSTYPE_TEMPLATE_INFO (type)
+      && CLASSTYPE_TI_TEMPLATE (type) == tmpl)
+    {
+      /* Copy the TPARMS and TARGS since we're only doing a
+        speculative unification here.  */
+      tree copy_of_tparms;
+      tree copy_of_targs;
+      
+      push_momentary ();
+      push_expression_obstack ();
+      copy_of_tparms = copy_node (tparms);
+      copy_of_targs = copy_node (targs);
+      pop_obstacks ();
+      
+      i = unify (copy_of_tparms,
+                copy_of_targs,
+                CLASSTYPE_TI_ARGS (template),
+                CLASSTYPE_TI_ARGS (type),
+                UNIFY_ALLOW_NONE, explicit_mask);
+
+      pop_momentary ();
+
+      if (i == 0)
+       {
+         if (rval == NULL_TREE || rval == type)
+           return type;
+         else
+           return error_mark_node;
+       }
+    }
+
+  binfos = BINFO_BASETYPES (binfo);
+  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
+  /* Process base types.  */
+  for (i = 0; i < n_baselinks; i++)
+    {
+      tree base_binfo = TREE_VEC_ELT (binfos, i);
+
+      /* Find any specific instance of a virtual base, when searching with
+        a binfo...  */
+      if (BINFO_MARKED (base_binfo) == 0)
+       {
+         int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
+
+         /* When searching for a non-virtual, we cannot mark
+            virtually found binfos.  */
+         if (! this_virtual)
+           SET_BINFO_MARKED (base_binfo);
+
+         rval = get_template_base_recursive (tparms, targs, explicit_mask,
+                                             base_binfo, rval,
+                                             template, this_virtual);
+         if (rval == error_mark_node)
+           return rval;
+       }
+    }
+
+  return rval;
+}
+
+/* Given a template type TEMPLATE and a class type or binfo node BINFO,
+   find the unique base type in BINFO that is an instance of TEMPLATE.
+   If there are more than one, return error_mark_node.  TEMPLATE may
+   be the type of a partial specialization, as well as a plain
+   template type.  Used by unify.  */
+
+static tree
+get_template_base (tparms, targs, explicit_mask, template, binfo)
+     tree tparms;
+     tree targs;
+     int *explicit_mask;
+     tree template;
+     tree binfo;
+{
+  tree type = NULL_TREE, rval;
+
+  if (TREE_CODE (binfo) == TREE_VEC)
+    type = BINFO_TYPE (binfo);
+  else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
+    {
+      type = complete_type (binfo);
+      binfo = TYPE_BINFO (type);
+    }
+  else
+    my_friendly_abort (92);
+
+  rval = get_template_base_recursive (tparms, targs, explicit_mask,
+                                     binfo, NULL_TREE,
+                                     template, 0); 
+  dfs_walk (binfo, dfs_unmark, markedp);
+
+  return rval;
+}
+
 /* Returns the level of DECL, which declares a template parameter.  */
 
 int
@@ -7766,7 +7882,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
               The call to get_template_base also handles the case
               where PARM and ARG are the same type, i.e., where no
               derivation is involved.  */
-           t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg);
+           t = get_template_base (tparms, targs, explicit_mask,
+                                  parm, arg);
          else if (CLASSTYPE_TEMPLATE_INFO (arg) 
                   && (CLASSTYPE_TI_TEMPLATE (parm) 
                       == CLASSTYPE_TI_TEMPLATE (arg)))
@@ -8059,18 +8176,8 @@ get_class_bindings (tparms, parms, args)
 
   args = innermost_args (args);
 
-  for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
-    {
-      switch (unify (tparms, vec, 
-                    TREE_VEC_ELT (parms, i), TREE_VEC_ELT (args, i),
-                    UNIFY_ALLOW_NONE, 0))
-       {
-       case 0:
-         break;
-       case 1:
-         return NULL_TREE;
-       }
-    }
+  if (unify (tparms, vec, parms, args, UNIFY_ALLOW_NONE, 0))
+    return NULL_TREE;
 
   for (i =  0; i < ntparms; ++i)
     if (! TREE_VEC_ELT (vec, i))
index 8b15764..1edfdf8 100644 (file)
@@ -86,9 +86,6 @@ static int lookup_fnfields_here PROTO((tree, tree));
 static int is_subobject_of_p PROTO((tree, tree));
 static int hides PROTO((tree, tree));
 static tree virtual_context PROTO((tree, tree, tree));
-static tree get_template_base_recursive
-       PROTO((tree, tree, tree, int));
-static void dfs_walk PROTO((tree, void (*) (tree), int (*) (tree)));
 static void dfs_check_overlap PROTO((tree));
 static int dfs_no_overlap_yet PROTO((tree));
 static void envelope_add_decl PROTO((tree, tree, tree *));
@@ -100,7 +97,6 @@ static void expand_upcast_fixups
 static void fixup_virtual_upcast_offsets
        PROTO((tree, tree, int, int, tree, tree, tree, tree,
               tree *));
-static int markedp PROTO((tree));
 static int unmarkedp PROTO((tree));
 static int marked_vtable_pathp PROTO((tree));
 static int unmarked_vtable_pathp PROTO((tree));
@@ -110,7 +106,6 @@ static int dfs_debug_unmarkedp PROTO((tree));
 static void dfs_debug_mark PROTO((tree));
 static void dfs_find_vbases PROTO((tree));
 static void dfs_clear_vbase_slots PROTO((tree));
-static void dfs_unmark PROTO((tree));
 static void dfs_init_vbase_pointers PROTO((tree));
 static void dfs_get_vbase_types PROTO((tree));
 static void dfs_pushdecls PROTO((tree));
@@ -2102,7 +2097,7 @@ convert_pointer_to_single_level (to_type, expr)
    dfs_init_vbase_pointers is the work function, as otherwise there
    would be no record.  */
 
-static void
+void
 dfs_walk (binfo, fn, qfn)
      tree binfo;
      void (*fn) PROTO((tree));
@@ -2201,7 +2196,7 @@ dfs_search (binfo, fn, start)
   return fn (binfo);
 }
 
-static int markedp (binfo) tree binfo;
+int markedp (binfo) tree binfo;
 { return BINFO_MARKED (binfo); }
 static int unmarkedp (binfo) tree binfo;
 { return BINFO_MARKED (binfo) == 0; }
@@ -2252,7 +2247,7 @@ dfs_mark (binfo) tree binfo;
 { SET_BINFO_MARKED (binfo); }
 #endif
 
-static void
+void
 dfs_unmark (binfo) tree binfo;
 { CLEAR_BINFO_MARKED (binfo); }
 
@@ -3347,85 +3342,6 @@ lookup_conversions (type)
   return conversions;
 }
 
-/* Subroutine of get_template_base.  */
-
-static tree
-get_template_base_recursive (binfo, rval, template, via_virtual)
-     tree binfo, template, rval;
-     int via_virtual;
-{
-  tree binfos;
-  int i, n_baselinks;
-  tree type = BINFO_TYPE (binfo);
-
-  if (CLASSTYPE_TEMPLATE_INFO (type)
-      && CLASSTYPE_TI_TEMPLATE (type) == template)
-    {
-      if (rval == NULL_TREE || rval == type)
-       return type;
-      else
-       return error_mark_node;
-    }
-
-  binfos = BINFO_BASETYPES (binfo);
-  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
-  /* Process base types.  */
-  for (i = 0; i < n_baselinks; i++)
-    {
-      tree base_binfo = TREE_VEC_ELT (binfos, i);
-
-      /* Find any specific instance of a virtual base, when searching with
-        a binfo...  */
-      if (BINFO_MARKED (base_binfo) == 0)
-       {
-         int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
-
-         /* When searching for a non-virtual, we cannot mark
-            virtually found binfos.  */
-         if (! this_virtual)
-           SET_BINFO_MARKED (base_binfo);
-
-         rval = get_template_base_recursive
-           (base_binfo, rval, template, this_virtual);
-         if (rval == error_mark_node)
-           return rval;
-       }
-    }
-
-  return rval;
-}
-
-/* Given a class template TEMPLATE and a class type or binfo node BINFO,
-   find the unique base type in BINFO that is an instance of TEMPLATE.
-   If there are more than one, return error_mark_node.  Used by unify.  */
-
-tree
-get_template_base (template, binfo)
-     register tree template, binfo;
-{
-  tree type = NULL_TREE, rval;
-
-  if (TREE_CODE (binfo) == TREE_VEC)
-    type = BINFO_TYPE (binfo);
-  else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
-    {
-      type = complete_type (binfo);
-      binfo = TYPE_BINFO (type);
-    }
-  else
-    my_friendly_abort (92);
-
-  if (CLASSTYPE_TEMPLATE_INFO (type)
-      && CLASSTYPE_TI_TEMPLATE (type) == template)
-    return type;
-
-  rval = get_template_base_recursive (binfo, NULL_TREE, template, 0);
-  dfs_walk (binfo, dfs_unmark, markedp);
-
-  return rval;
-}
-
 /* Check whether the empty class indicated by EMPTY_BINFO is also present
    at offset 0 in COMPARE_TYPE, and set found_overlap if so.  */
 
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/deduct1.C b/gcc/testsuite/g++.old-deja/g++.pt/deduct1.C
new file mode 100644 (file)
index 0000000..a87b2a7
--- /dev/null
@@ -0,0 +1,27 @@
+// Build don't link:
+
+template<class CoordinateSystem, class MeshTag>
+struct Mesh { };
+
+struct RectGrid { };
+
+struct RectMesh { };
+
+struct Cartesian { };
+
+template<class CS>
+struct Mesh<CS, RectGrid> { };
+
+template<class CS>
+struct Mesh<CS, RectMesh> : public Mesh<CS, RectGrid> { };
+
+template<class CS>
+void foo(const Mesh<CS, RectGrid> &)
+{
+}
+
+int main()
+{
+  Mesh<Cartesian, RectMesh> m;
+  foo(m);
+}