From: Mark Mitchell Date: Tue, 10 Aug 1999 06:19:35 +0000 (+0000) Subject: decl.c (build_ptrmemfunc_type): Handle qualified pointer-to-member types here. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=46cbda4ad4c9e664c04ba2b159d0ea426e03323c;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 683277d9c0f..b6fd5428cf8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +1999-08-09 Mark Mitchell + + * 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 * decl.c: Remove redundant prototype for `print_error_function'. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d976f19e561..c628ebf3eb2 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 b26548f9894..281e7a7eae9 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 00000000000..9963a15ab6f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem9.C @@ -0,0 +1,6 @@ +// Build don't link: +// Origin: Jason Merrill + +struct A; +template void f (void (A::* const)(T)) {} +void (*p)(void (A::* const)(int)) = f;