aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1999-02-17 18:58:59 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-02-17 18:58:59 +0000
commit3fd71a527ef1afd65299554c36d47e509b824abe (patch)
tree69172dce38299462c22bab09dc1cd5670fa31869
parent176c720e2ca8694601e36568f5b8baa60848cdb3 (diff)
downloadgcc-3fd71a527ef1afd65299554c36d47e509b824abe.zip
gcc-3fd71a527ef1afd65299554c36d47e509b824abe.tar.gz
gcc-3fd71a527ef1afd65299554c36d47e509b824abe.tar.bz2
decl.c (xref_basetypes): Comment.
* decl.c (xref_basetypes): Comment. * pt.c (instantiate_class_template): Use xref_basetypes. From-SVN: r25272
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/pt.c91
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/inherit1.C25
4 files changed, 87 insertions, 40 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a0a3a8f..d7dc235 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3b6917c..c5ffd2b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a951a8b..49d948c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..6ae70c1
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/inherit1.C
@@ -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;
+}