cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
authorMark Mitchell <mark@codesourcery.com>
Wed, 28 Jun 2000 20:41:27 +0000 (20:41 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 28 Jun 2000 20:41:27 +0000 (20:41 +0000)
* cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
* class.c (update_vtable_entry_for_fn): Correct logic for deciding
where to emit thunks.
(build_vtt): Adjust call to build_vtt_inits.
(build_vtt_inits): Add parameter to indicate whether or not
sub-VTTs for virtual bases should be included.  Adjust handling of
construction vtables.
(get_matching_base): New function.
(dfs_build_vtt_inits): Rename to ...
(dfs_build_secondary_vptr_vtt_inits): Adjust handling of
construction vtables.
(dfs_fixup_binfo_vtbls): Likewise.
(build_ctor_vtbl_groups): Build construction vtables for virtual
bases, too.
(accumulate_vtbl_inits): Tweak logic for deciding whether or not
to build construction vtbls.
(dfs_accumulate_vtbl_inits): Adjust handling of
construction vtables.

* pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
types correctly.

From-SVN: r34765

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/pt.c

index e87c8ba..390bc1c 100644 (file)
@@ -1,3 +1,27 @@
+2000-06-28  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
+       * class.c (update_vtable_entry_for_fn): Correct logic for deciding
+       where to emit thunks.
+       (build_vtt): Adjust call to build_vtt_inits.
+       (build_vtt_inits): Add parameter to indicate whether or not
+       sub-VTTs for virtual bases should be included.  Adjust handling of
+       construction vtables.
+       (get_matching_base): New function.
+       (dfs_build_vtt_inits): Rename to ...
+       (dfs_build_secondary_vptr_vtt_inits): Adjust handling of
+       construction vtables.
+       (dfs_fixup_binfo_vtbls): Likewise.
+       (build_ctor_vtbl_groups): Build construction vtables for virtual
+       bases, too.
+       (accumulate_vtbl_inits): Tweak logic for deciding whether or not
+       to build construction vtbls.
+       (dfs_accumulate_vtbl_inits): Adjust handling of
+       construction vtables.
+
+       * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
+       types correctly.
+       
 2000-06-27  Mark Mitchell  <mark@codesourcery.com>
 
        * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
index 71a5aef..108e7d7 100644 (file)
@@ -190,10 +190,11 @@ static void update_vtable_entry_for_fn PARAMS ((tree, tree, tree, tree *));
 static tree copy_virtuals PARAMS ((tree));
 static void build_ctor_vtbl_group PARAMS ((tree, tree));
 static void build_vtt PARAMS ((tree));
-static tree *build_vtt_inits PARAMS ((tree, tree, tree *, tree *));
-static tree dfs_build_vtt_inits PARAMS ((tree, void *));
+static tree *build_vtt_inits PARAMS ((tree, tree, int, tree *, tree *));
+static tree dfs_build_secondary_vptr_vtt_inits PARAMS ((tree, void *));
 static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
 static int indirect_primary_base_p PARAMS ((tree, tree));
+static tree get_matching_base PARAMS ((tree, tree));
 
 /* Variables shared between class.c and call.c.  */
 
@@ -2643,7 +2644,7 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
 
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
-  virtual_base  = NULL_TREE;
+  virtual_base = NULL_TREE;
 
   /* Assume that we will always generate thunks with the vtables that
      reference them.  */
@@ -2659,7 +2660,8 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
          /* If we find BINFO, then the final overrider is in a class
             derived from BINFO, so the thunks can be generated with
             the final overrider.  */
-         if (same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
+         if (!virtual_base
+             && same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
            generate_thunk_with_vtable_p = 0;
 
          /* If we find the final overrider, then we can stop
@@ -6627,7 +6629,8 @@ build_vtt (t)
   /* Build up the initializers for the VTT.  */
   inits = NULL_TREE;
   index = size_zero_node;
-  build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
+  build_vtt_inits (TYPE_BINFO (t), t, /*virtual_vtts_p=*/1, 
+                  &inits, &index);
 
   /* If we didn't need a VTT, we're done.  */
   if (!inits)
@@ -6643,15 +6646,45 @@ build_vtt (t)
   initialize_array (vtt, inits);
 }
 
+/* The type corresponding to BINFO is a base class of T, but BINFO is
+   in the base class hierarchy of a class derived from T.  Return the
+   base, in T's hierarchy, that corresponds to BINFO.  */
+
+static tree
+get_matching_base (binfo, t)
+     tree binfo;
+     tree t;
+{
+  tree derived;
+  int i;
+
+  if (same_type_p (BINFO_TYPE (binfo), t))
+    return binfo;
+
+  if (TREE_VIA_VIRTUAL (binfo))
+    return binfo_for_vbase (BINFO_TYPE (binfo), t);
+
+  derived = get_matching_base (BINFO_INHERITANCE_CHAIN (binfo), t);
+  for (i = 0; i < BINFO_N_BASETYPES (derived); ++i)
+    if (same_type_p (BINFO_TYPE (BINFO_BASETYPE (derived, i)),
+                    BINFO_TYPE (binfo)))
+      return BINFO_BASETYPE (derived, i);
+
+  my_friendly_abort (20000628);
+  return NULL_TREE;
+}
+
 /* Recursively build the VTT-initializer for BINFO (which is in the
-   hierarchy dominated by T).  INITS points to the end of the
-   initializer list to date.  INDEX is the VTT index where the next
-   element will be placed.  */
+   hierarchy dominated by T).  If VIRTUAL_VTTS_P is non-zero, then
+   sub-VTTs for virtual bases are included.  INITS points to the end
+   of the initializer list to date.  INDEX is the VTT index where the
+   next element will be placed.  */
 
 static tree *
-build_vtt_inits (binfo, t, inits, index)
+build_vtt_inits (binfo, t, virtual_vtts_p, inits, index)
      tree binfo;
      tree t;
+     int virtual_vtts_p;
      tree *inits;
      tree *index;
 {
@@ -6679,7 +6712,7 @@ build_vtt_inits (binfo, t, inits, index)
   /* Add the address of the primary vtable for the complete object.  */
   init = BINFO_VTABLE (binfo);
   if (TREE_CODE (init) == TREE_LIST)
-    init = TREE_PURPOSE (init);
+    init = TREE_VALUE (init);
   *inits = build_tree_list (NULL_TREE, init);
   inits = &TREE_CHAIN (*inits);
   BINFO_VPTR_INDEX (binfo) = *index;
@@ -6690,23 +6723,23 @@ build_vtt_inits (binfo, t, inits, index)
     {
       b = BINFO_BASETYPE (binfo, i);
       if (!TREE_VIA_VIRTUAL (b))
-       inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t, inits,
-                                index);
+       inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t, 
+                                /*virtuals_vtts_p=*/0,
+                                inits, index);
     }
       
   /* Add secondary virtual pointers for all subobjects of BINFO with
      either virtual bases or virtual functions overridden along a
      virtual path between the declaration and D, except subobjects
      that are non-virtual primary bases.  */
-  secondary_vptrs = build_tree_list (BINFO_TYPE (binfo), NULL_TREE);
+  secondary_vptrs = tree_cons (t, NULL_TREE, BINFO_TYPE (binfo));
   TREE_TYPE (secondary_vptrs) = *index;
   dfs_walk_real (binfo,
-                dfs_build_vtt_inits,
+                dfs_build_secondary_vptr_vtt_inits,
                 NULL,
                 dfs_unmarked_real_bases_queue_p,
                 secondary_vptrs);
-  dfs_walk (binfo, dfs_fixup_binfo_vtbls, dfs_marked_real_bases_queue_p,
-           BINFO_TYPE (binfo));
+  dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
   *index = TREE_TYPE (secondary_vptrs);
 
   /* The secondary vptrs come back in reverse order.  After we reverse
@@ -6721,16 +6754,22 @@ build_vtt_inits (binfo, t, inits, index)
     }
 
   /* Add the secondary VTTs for virtual bases.  */
-  for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
-    {
-      tree vbase;
-
-      if (!TREE_VIA_VIRTUAL (b))
-       continue;
+  if (virtual_vtts_p)
+    for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
+      {
+       tree vbase;
+       
+       if (!TREE_VIA_VIRTUAL (b))
+         continue;
+       
+       vbase = binfo_for_vbase (BINFO_TYPE (b), t);
+       inits = build_vtt_inits (vbase, t, /*virtual_vtts_p=*/0, 
+                                inits, index);
+      }
 
-      vbase = binfo_for_vbase (BINFO_TYPE (b), t);
-      inits = build_vtt_inits (vbase, t, inits, index);
-    }
+  dfs_walk (binfo, dfs_fixup_binfo_vtbls,
+           dfs_unmarked_real_bases_queue_p,
+           build_tree_list (t, binfo));
 
   return inits;
 }
@@ -6738,7 +6777,7 @@ build_vtt_inits (binfo, t, inits, index)
 /* Called from build_vtt_inits via dfs_walk.  */
 
 static tree
-dfs_build_vtt_inits (binfo, data)
+dfs_build_secondary_vptr_vtt_inits (binfo, data)
      tree binfo;
      void *data;
 {
@@ -6748,7 +6787,7 @@ dfs_build_vtt_inits (binfo, data)
   tree index;
 
   l = (tree) data;
-  t = TREE_PURPOSE (l);
+  t = TREE_CHAIN (l);
 
   SET_BINFO_MARKED (binfo);
 
@@ -6769,7 +6808,7 @@ dfs_build_vtt_inits (binfo, data)
      virtual path.  The point is that given:
 
        struct V { virtual void f(); int i; };
-       struct C : public V { void f (); };
+       struct C : public virtual V { void f (); };
 
      when we constrct C we need a secondary vptr for V-in-C because we
      don't know what the vcall offset for `f' should be.  If `V' ends
@@ -6777,7 +6816,7 @@ dfs_build_vtt_inits (binfo, data)
      different vcall offset than that present in the normal V-in-C
      vtable.  */
   if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))
-      && !BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P (binfo))
+      && !BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P (get_matching_base (binfo, t)))
     return NULL_TREE;
 
   /* Record the index where this secondary vptr can be found.  */
@@ -6789,7 +6828,7 @@ dfs_build_vtt_inits (binfo, data)
   /* Add the initializer for the secondary vptr itself.  */
   init = BINFO_VTABLE (binfo);
   if (TREE_CODE (init) == TREE_LIST)
-    init = TREE_PURPOSE (init);
+    init = TREE_VALUE (init);
   TREE_VALUE (l) = tree_cons (NULL_TREE, init, TREE_VALUE (l));
 
   return NULL_TREE;
@@ -6800,7 +6839,7 @@ dfs_build_vtt_inits (binfo, data)
 static tree
 dfs_fixup_binfo_vtbls (binfo, data)
      tree binfo;
-     void *data ATTRIBUTE_UNUSED;
+     void *data;
 {
   CLEAR_BINFO_MARKED (binfo);
 
@@ -6810,8 +6849,10 @@ dfs_fixup_binfo_vtbls (binfo, data)
 
   /* If we scribbled the construction vtable vptr into BINFO, clear it
      out now.  */
-  if (TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST)
-    BINFO_VTABLE (binfo) = TREE_VALUE (BINFO_VTABLE (binfo));
+  if (TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST
+      && (TREE_PURPOSE (BINFO_VTABLE (binfo)) 
+         == TREE_VALUE ((tree) data)))
+    BINFO_VTABLE (binfo) = TREE_CHAIN (BINFO_VTABLE (binfo));
 
   return NULL_TREE;
 }
@@ -6829,6 +6870,7 @@ build_ctor_vtbl_group (binfo, t)
   tree vtbl;
   tree inits;
   tree id;
+  tree vbase;
 
   /* See if we've already create this construction vtable group.  */
   if (flag_new_abi)
@@ -6845,6 +6887,19 @@ build_ctor_vtbl_group (binfo, t)
   list = build_tree_list (vtbl, NULL_TREE);
   accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
                         binfo, t, list);
+  for (vbase = TYPE_BINFO (TREE_TYPE (binfo)); 
+       vbase; 
+       vbase = TREE_CHAIN (vbase))
+    {
+      tree b;
+
+      if (!TREE_VIA_VIRTUAL (vbase))
+       continue;
+
+      b = binfo_for_vbase (BINFO_TYPE (vbase), t);
+      accumulate_vtbl_inits (b, vbase, binfo, t, list);
+    }
+
   inits = TREE_VALUE (list);
 
   /* Figure out the type of the construction vtable.  */
@@ -6886,7 +6941,9 @@ accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
   /* If we're building a construction vtable, we're not interested in
      subobjects that don't require construction vtables.  */
   if (ctor_vtbl_p 
-      && !TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
+      && !TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))
+      && !(BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P 
+          (get_matching_base (binfo, BINFO_TYPE (rtti_binfo)))))
     return;
 
   /* Build the initializers for the BINFO-in-T vtable.  */
@@ -6929,16 +6986,8 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
      tree l;
 {
   tree inits = NULL_TREE;
-  int ctor_vtbl_p;
-
-  /* This is a construction vtable if the RTTI type is not the most
-     derived type in the hierarchy.  */
-  ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
 
-  if (BINFO_NEW_VTABLE_MARKED (binfo, t)
-      /* We need a new vtable, even for a primary base, when we're
-        building a construction vtable.  */
-      || (ctor_vtbl_p && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))))
+  if (BINFO_NEW_VTABLE_MARKED (orig_binfo, t))
     {
       tree vtbl;
       tree index;
@@ -6963,14 +7012,14 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
       TREE_CONSTANT (vtbl) = 1;
 
       /* For an ordinary vtable, set BINFO_VTABLE.  */
-      if (!ctor_vtbl_p)
+      if (same_type_p (BINFO_TYPE (rtti_binfo), t))
        BINFO_VTABLE (binfo) = vtbl;
       /* For a construction vtable, we can't overwrite BINFO_VTABLE.
         So, we make a TREE_LIST.  Later, dfs_fixup_binfo_vtbls will
         straighten this out.  */
       else
-       BINFO_VTABLE (binfo) = build_tree_list (vtbl,
-                                               BINFO_VTABLE (binfo));
+       BINFO_VTABLE (binfo) = 
+         tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
     }
 
   return inits;
index f7e3b07..9f8ba20 100644 (file)
@@ -1781,8 +1781,6 @@ struct lang_type
    my_friendly_assert (!BINFO_PRIMARY_MARKED_P (B), 20000517),          \
    my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE,  \
                       20000517))
-#define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
-  (BINFO_NEW_VTABLE_MARKED (B, C) = 0)
 
 /* Nonzero means this class has done dfs_pushdecls.  */
 #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
index 8da3dd5..e36d51b 100644 (file)
@@ -6361,25 +6361,34 @@ tsubst (t, args, complain, in_decl)
          {
          case TEMPLATE_TYPE_PARM:
          case TEMPLATE_TEMPLATE_PARM:
-           r = copy_node (t);
-           TEMPLATE_TYPE_PARM_INDEX (r)
-             = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
-                                           r, levels);
-           TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
-           TYPE_MAIN_VARIANT (r) = r;
-           TYPE_POINTER_TO (r) = NULL_TREE;
-           TYPE_REFERENCE_TO (r) = NULL_TREE;
-
-           if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
-               && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
+           if (CP_TYPE_QUALS (t))
              {
-               tree argvec = tsubst (TYPE_TI_ARGS (t), args,
-                                     complain, in_decl); 
-               if (argvec == error_mark_node)
-                 return error_mark_node;
+               r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
+               r = cp_build_qualified_type_real (r, CP_TYPE_QUALS (t),
+                                                 complain);
+             }
+           else
+             {
+               r = copy_node (t);
+               TEMPLATE_TYPE_PARM_INDEX (r)
+                 = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
+                                               r, levels);
+               TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
+               TYPE_MAIN_VARIANT (r) = r;
+               TYPE_POINTER_TO (r) = NULL_TREE;
+               TYPE_REFERENCE_TO (r) = NULL_TREE;
+
+               if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+                   && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
+                 {
+                   tree argvec = tsubst (TYPE_TI_ARGS (t), args,
+                                         complain, in_decl); 
+                   if (argvec == error_mark_node)
+                     return error_mark_node;
 
-               TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
-                 = tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
+                   TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
+                     = tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
+                 }
              }
            break;