From 7ac05dd75c071e92632fa8d7b44fda5292d20576 Mon Sep 17 00:00:00 2001
From: mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 18 Apr 2000 20:21:39 +0000
Subject: [PATCH] 	* cp-tree.h (lang_decl_flags): Remove const_memfunc
 and 	volatile_memfunc.  Add destructor_attr.  Adjust dummy. 
 (DECL_DESTRUCTOR_P): Use destructor_attr. 	(DECL_CONST_MEMFUNC_P):
 Reimplement. 	(DECL_VOLATILE_MEMFUNC_P): Remove. 	* class.c
 (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS. 	(overrides): Use
 DECL_DESTRUCTOR_P. 	(check_for_override): Likewise. 	* decl.c
 (start_function): Likewise. 	* decl2.c (grokfclassfn): Likewise. 
 (check_classfn): Likewise. 	(grok_function_init): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33235 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                              | 15 +++++++++++++
 gcc/cp/class.c                                | 11 ++++------
 gcc/cp/cp-tree.h                              | 19 +++++++---------
 gcc/cp/decl.c                                 |  3 +--
 gcc/cp/decl2.c                                |  7 +++---
 .../g++.old-deja/g++.other/externC1.C         | 22 +++++++++++++++++++
 6 files changed, 54 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/g++.old-deja/g++.other/externC1.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5f3c8fb7aa5e..5d60aa017c25 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2000-04-18  Mark Mitchell  <mark@codesourcery.com>
+
+	* cp-tree.h (lang_decl_flags): Remove const_memfunc and
+	volatile_memfunc.  Add destructor_attr.  Adjust dummy.
+	(DECL_DESTRUCTOR_P): Use destructor_attr.
+	(DECL_CONST_MEMFUNC_P): Reimplement.
+	(DECL_VOLATILE_MEMFUNC_P): Remove.
+	* class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
+	(overrides): Use DECL_DESTRUCTOR_P.
+	(check_for_override): Likewise.
+	* decl.c (start_function): Likewise.
+	* decl2.c (grokfclassfn): Likewise.
+	(check_classfn): Likewise.
+	(grok_function_init): Likewise.
+
 2000-04-17  Mark Mitchell  <mark@codesourcery.com>
 
 	* decl2.c (grokfield): Issue error on illegal data member
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a850a2790c3e..b5d3f3e7b227 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2155,7 +2155,7 @@ finish_struct_methods (t)
     /* Clear out this flag.  */
     DECL_IN_AGGR_P (fn_fields) = 0;
 
-  if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1))
+  if (TYPE_HAS_DESTRUCTOR (t) && !CLASSTYPE_DESTRUCTORS (t))
     /* We thought there was a destructor, but there wasn't.  Some
        parse errors cause this anomalous situation.  */
     TYPE_HAS_DESTRUCTOR (t) = 0;
@@ -2285,11 +2285,9 @@ overrides (fndecl, base_fndecl)
      tree fndecl, base_fndecl;
 {
   /* Destructors have special names.  */
-  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
-      && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+  if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl))
     return 1;
-  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
-      || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+  if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
     return 0;
   if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
     {
@@ -2744,8 +2742,7 @@ check_for_override (decl, ctype)
       if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
 	{
 	  tree tmp = get_matching_virtual
-	    (base_binfo, decl,
-	     DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
+	    (base_binfo, decl, DECL_DESTRUCTOR_P (decl));
 
 	  if (tmp && !found_overriden_fn)
 	    {
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f63cb6b5da1e..d419e26027ff 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1861,12 +1861,12 @@ struct lang_decl_flags
 
   unsigned operator_attr : 1;
   unsigned constructor_attr : 1;
+  unsigned destructor_attr : 1;
   unsigned friend_attr : 1;
   unsigned static_function : 1;
-  unsigned const_memfunc : 1;
-  unsigned volatile_memfunc : 1;
   unsigned pure_virtual : 1;
   unsigned has_in_charge_parm_p : 1;
+  unsigned pretty_function_p : 1;
 
   unsigned mutable_flag : 1;
   unsigned deferred : 1;
@@ -1881,8 +1881,7 @@ struct lang_decl_flags
   unsigned pending_inline_p : 1;
   unsigned global_ctor_p : 1;
   unsigned global_dtor_p : 1;
-  unsigned pretty_function_p : 1;
-  unsigned dummy : 2;
+  unsigned dummy : 3;
 
   tree context;
 
@@ -1969,8 +1968,7 @@ struct lang_decl
 /* There ought to be a better way to find out whether or not something is
    a destructor.  */
 #define DECL_DESTRUCTOR_P(NODE)				\
-  (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE))	\
-   && DECL_LANGUAGE (NODE) == lang_cplusplus)
+  (DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr)
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
    specialized in-charge constructor, in-charge deleting constructor,
@@ -2078,11 +2076,10 @@ struct lang_decl
 
 /* Nonzero for FUNCTION_DECL means that this member function
    has `this' as const X *const.  */
-#define DECL_CONST_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.const_memfunc)
-
-/* Nonzero for FUNCTION_DECL means that this member function
-   has `this' as volatile X *const.  */
-#define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc)
+#define DECL_CONST_MEMFUNC_P(NODE)					 \
+  (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
+   && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE 				 \
+				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
 
 /* Nonzero for a DECL means that this member is a non-static member.  */
 #define DECL_NONSTATIC_MEMBER_P(NODE) 		\
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2760ea5605b3..f667fd520715 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13551,8 +13551,7 @@ start_function (declspecs, declarator, attrs, flags)
 
   ++function_depth;
 
-  if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1))
-      && DECL_LANGUAGE (decl1) == lang_cplusplus)
+  if (DECL_DESTRUCTOR_P (decl1))
     {
       dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
       DECL_CONTEXT (dtor_label) = current_function_decl;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e9b1b1fb4a89..3be90dcbd760 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1037,6 +1037,7 @@ grokclassfn (ctype, function, flags, quals)
 
   if (flags == DTOR_FLAG)
     {
+      DECL_DESTRUCTOR_P (function) = 1;
       DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype);
       TYPE_HAS_DESTRUCTOR (ctype) = 1;
     }
@@ -1389,7 +1390,7 @@ check_classfn (ctype, function)
 	  && DECL_CONSTRUCTOR_P (function))
 	goto got_it;
       if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
-	  && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
+	  && DECL_DESTRUCTOR_P (function))
 	goto got_it;
 
       while (++methods != end && *methods)
@@ -1410,7 +1411,7 @@ check_classfn (ctype, function)
 		     we can't use this short-cut for them, either.
 		     (It's not legal to declare arguments for a
 		     destructor, but some people try.)  */
-		  if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+		  if (!DECL_DESTRUCTOR_P (function)
 		      && (DECL_ASSEMBLER_NAME (function)
 			  != DECL_NAME (function))
 		      && (DECL_ASSEMBLER_NAME (fndecl)
@@ -1909,7 +1910,7 @@ grok_function_init (decl, init)
       /* pure virtual destructors must be defined.  */
       /* pure virtual needs to be defined (as abort) only when put in 
 	 vtbl. For wellformed call, it should be itself. pr4737 */
-      if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+      if (!DECL_DESTRUCTOR_P (decl)))
 	{
 	  /* Give this node rtl from `abort'.  */
 	  DECL_RTL (decl) = DECL_RTL (abort_fndecl);
diff --git a/gcc/testsuite/g++.old-deja/g++.other/externC1.C b/gcc/testsuite/g++.old-deja/g++.other/externC1.C
new file mode 100644
index 000000000000..ca60b0217541
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/externC1.C
@@ -0,0 +1,22 @@
+// Build don't link:
+// Origin: Mark Mitchell <mitchell@codesourcery.com>
+
+extern "C"
+{
+  struct T
+  {
+    ~T ();
+  };
+
+  struct S
+  {
+    T t;
+  };
+}
+
+S* s;
+
+void f ()
+{
+  delete s;
+}
-- 
GitLab