decl.c (xref_basetypes): Comment.
authorMark Mitchell <mark@markmitchell.com>
Wed, 17 Feb 1999 18:58:59 +0000 (18:58 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 17 Feb 1999 18:58:59 +0000 (18:58 +0000)
* decl.c (xref_basetypes): Comment.
* pt.c (instantiate_class_template): Use xref_basetypes.

From-SVN: r25272

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/inherit1.C [new file with mode: 0644]

index a0a3a8fab5e28d55df0cb84cdb9306ba8a37d31d..d7dc23563cdd8149a1a3d9a88a6c45493b156bff 100644 (file)
@@ -1,3 +1,8 @@
+1999-02-17  Mark Mitchell  <mark@markmitchell.com>
+
+       * decl.c (xref_basetypes): Comment.
+       * pt.c (instantiate_class_template): Use xref_basetypes.
+
 1999-02-16  Mark Mitchell  <mark@markmitchell.com>
 
        * cp-tree.h (tsubst): Change prototype.
index 3b6917cc1d909c2069f8e7341a64cc4026e1913e..c5ffd2b8cf18322cd9aa9e705a2f0da1bf8ed45a 100644 (file)
@@ -12357,6 +12357,12 @@ xref_tag_from_type (old, id, globalize)
   return xref_tag (code_type_node, id, globalize);
 }
 
+/* REF is a type (named NAME), for which we have just seen some
+   baseclasses.  BINFO is a list of those baseclasses; the
+   TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of
+   the base-class.  CODE_TYPE_NODE indicates whether REF is a class,
+   struct, or union.  */
+
 void
 xref_basetypes (code_type_node, name, ref, binfo)
      tree code_type_node;
index a951a8bb8e7210063d3cce088513867676d79e3a..49d948c68be2a4de29163b055e12af12aa7da019 100644 (file)
@@ -4688,53 +4688,64 @@ instantiate_class_template (type)
      DECL_TI_ARGS of some instantiated member template.  */
   args = copy_to_permanent (args);
 
-  {
-    tree binfo = TYPE_BINFO (type);
-    tree pbases = TYPE_BINFO_BASETYPES (pattern);
+  if (TYPE_BINFO_BASETYPES (pattern))
+    {
+      tree base_list = NULL_TREE;
+      tree pbases = TYPE_BINFO_BASETYPES (pattern);
+      int i;
 
-    if (pbases)
-      {
-       tree bases;
-       int i;
-       int len = TREE_VEC_LENGTH (pbases);
-       bases = make_tree_vec (len);
-       for (i = 0; i < len; ++i)
-         {
-           tree elt, basetype;
+      /* Substitute into each of the bases to determine the actual
+        basetypes.  */
+      for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
+       {
+         tree base;
+         tree access;
+         tree pbase;
 
-           TREE_VEC_ELT (bases, i) = elt
-             = tsubst (TREE_VEC_ELT (pbases, i), args,
-                       /*complain=*/1, NULL_TREE);
-           BINFO_INHERITANCE_CHAIN (elt) = binfo;
+         pbase = TREE_VEC_ELT (pbases, i);
 
-           basetype = TREE_TYPE (elt);
+         /* Substitue to figure out the base class.  */
+         base = tsubst (BINFO_TYPE (pbase), args, 
+                        /*complain=*/1, NULL_TREE);
+         if (base == error_mark_node)
+           continue;
 
-           if (! IS_AGGR_TYPE (basetype))
-             cp_error
-               ("base type `%T' of `%T' fails to be a struct or class type",
-                basetype, type);
-           else if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE)
-             cp_error ("base class `%T' of `%T' has incomplete type",
-                       basetype, type);
+         /* Calculate the correct access node.  */
+         if (TREE_VIA_VIRTUAL (pbase)) 
+           {
+             if (TREE_VIA_PUBLIC (pbase))
+               access = access_public_virtual_node;
+             else if (TREE_VIA_PROTECTED (pbase))
+               access = access_protected_virtual_node;
+             else if (TREE_VIA_PRIVATE (pbase))
+               access = access_private_virtual_node;
+           }
+         else
+           {
+             if (TREE_VIA_PUBLIC (pbase))
+               access = access_public_node;
+             else if (TREE_VIA_PROTECTED (pbase))
+               access = access_protected_node;
+             else if (TREE_VIA_PRIVATE (pbase))
+               access = access_private_node;
+           }
 
-           /* These are set up in xref_basetypes for normal classes, so
-              we have to handle them here for template bases.  */
+         base_list = tree_cons (access, base, base_list);
+       }
 
-           unshare_base_binfos (elt);
+      /* The list is now in reverse order; correct that.  */
+      base_list = nreverse (base_list);
 
-           if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
-             {
-               TYPE_USES_VIRTUAL_BASECLASSES (type) = 1;
-               TYPE_USES_COMPLEX_INHERITANCE (type) = 1;
-             }
-           TYPE_GETS_NEW (type) |= TYPE_GETS_NEW (basetype);
-           TYPE_GETS_DELETE (type) |= TYPE_GETS_DELETE (basetype);
-         }
-       /* Don't initialize this until the vector is filled out, or
-          lookups will crash.  */
-       BINFO_BASETYPES (binfo) = bases;
-      }
-  }
+      /* Now call xref_basetypes to set up all the base-class
+        information.  */
+      xref_basetypes (TREE_CODE (pattern) == RECORD_TYPE
+                     ? (CLASSTYPE_DECLARED_CLASS (pattern)
+                        ? class_type_node : record_type_node)
+                     : union_type_node,
+                     DECL_NAME (TYPE_NAME (pattern)),
+                     type,
+                     base_list);
+    }
 
   for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
     {
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/inherit1.C b/gcc/testsuite/g++.old-deja/g++.pt/inherit1.C
new file mode 100644 (file)
index 0000000..6ae70c1
--- /dev/null
@@ -0,0 +1,25 @@
+// Origin: Wolfgang Bangerth <wolf@gaia.iwr.uni-heidelberg.de>
+
+int i = 1;
+
+struct Base1 {  int local1;  };
+struct Base2 {  int local2;  };
+
+template <int dim> class Derived;
+
+template <>
+class Derived<1> : public Base1, public Base2 {};
+
+template <int dim>
+class FinalClass :  public Derived<dim> {
+public:
+  FinalClass () {
+    if (&local1 != &local2)
+      i = 0;
+  }
+};
+
+int main () {
+  FinalClass<1> a1;
+  return i;
+}