aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-08-10 06:19:35 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-08-10 06:19:35 +0000
commit46cbda4ad4c9e664c04ba2b159d0ea426e03323c (patch)
tree9dab6d3fd3ce567ec4e322811b19662edf17837b
parent7941ceabf0f14279e93443a63ca4d355f3a88830 (diff)
downloadgcc-46cbda4ad4c9e664c04ba2b159d0ea426e03323c.zip
gcc-46cbda4ad4c9e664c04ba2b159d0ea426e03323c.tar.gz
gcc-46cbda4ad4c9e664c04ba2b159d0ea426e03323c.tar.bz2
decl.c (build_ptrmemfunc_type): Handle qualified pointer-to-member types here.
* decl.c (build_ptrmemfunc_type): Handle qualified pointer-to-member types here. * tree.c (cp_build_qualified_type_real): Simplify handling here. From-SVN: r28642
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c22
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ptrmem9.C6
4 files changed, 35 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 683277d..b6fd542 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+1999-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (build_ptrmemfunc_type): Handle qualified
+ pointer-to-member types here.
+ * tree.c (cp_build_qualified_type_real): Simplify handling here.
+
1999-08-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl.c: Remove redundant prototype for `print_error_function'.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d976f19..c628ebf 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8810,6 +8810,7 @@ build_ptrmemfunc_type (type)
tree fields[4];
tree t;
tree u;
+ tree unqualified_variant = NULL_TREE;
/* If a canonical type already exists for this type, use it. We use
this method instead of type_hash_canon, because it only does a
@@ -8818,6 +8819,12 @@ build_ptrmemfunc_type (type)
if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type)))
return t;
+ /* Make sure that we always have the unqualified pointer-to-member
+ type first. */
+ if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)
+ unqualified_variant
+ = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
+
push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
u = make_lang_type (UNION_TYPE);
@@ -8848,10 +8855,25 @@ build_ptrmemfunc_type (type)
information for this anonymous RECORD_TYPE. */
TYPE_NAME (t) = NULL_TREE;
+ /* If this is not the unqualified form of this pointer-to-member
+ type, set the TYPE_MAIN_VARIANT for this type to be the
+ unqualified type. Since they are actually RECORD_TYPEs that are
+ not variants of each other, we must do this manually. */
+ if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)
+ {
+ t = build_qualified_type (t, CP_TYPE_QUALS (type));
+ TYPE_MAIN_VARIANT (t) = unqualified_variant;
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
+ TYPE_NEXT_VARIANT (unqualified_variant) = t;
+ }
+
+ /* Cache this pointer-to-member type so that we can find it again
+ later. */
TYPE_SET_PTRMEMFUNC_TYPE (type, t);
/* Seems to be wanted. */
CLASSTYPE_GOT_SEMICOLON (t) = 1;
+
return t;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b26548f..281e7a7 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -583,7 +583,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
t = TYPE_PTRMEMFUNC_FN_TYPE (type);
t = cp_build_qualified_type_real (t, type_quals, complain);
- return build_qualified_type (build_ptrmemfunc_type (t), type_quals);
+ return build_ptrmemfunc_type (t);
}
/* Retrieve (or create) the appropriately qualified variant. */
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem9.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem9.C
new file mode 100644
index 0000000..9963a15
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem9.C
@@ -0,0 +1,6 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+struct A;
+template <class T> void f (void (A::* const)(T)) {}
+void (*p)(void (A::* const)(int)) = f;