decl.c (build_ptrmemfunc_type): Handle qualified pointer-to-member types here.
authorMark Mitchell <mark@codesourcery.com>
Tue, 10 Aug 1999 06:19:35 +0000 (06:19 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 10 Aug 1999 06:19:35 +0000 (06:19 +0000)
* 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

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

index 683277d9c0f36706632394714c124721b9992b4f..b6fd5428cf8775e430e8bb6f2084d4ae6307bedd 100644 (file)
@@ -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'.
index d976f19e5618cd77fd736d8596f356ff8a736491..c628ebf3eb2d600d0530f68b35f1b0c50dd6d1a1 100644 (file)
@@ -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;
 }
 
index b26548f98945be2e3f3f4dc6dacfa3d4e492bded..281e7a7eae9135bbb011ca9e83b0ca9e87c1c1ec 100644 (file)
@@ -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 (file)
index 0000000..9963a15
--- /dev/null
@@ -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;