This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] cdtor naming


This patch changes the way we name cdtors internally. Currently both in-charge ctor and dtor get the DECL_NAME naming the class they are a member of. That's the same DECL_NAME as the class's self-reference TYPE_DECL. (The specialized base/complete/deleting cdtors get special names already.)

Not only is this confusing when looking inside the compiler, but we end up having to frob the name in a few places when trying to do lookups. We already check for cdtorness when emitting a user-readable name (except in one place, which this patch addresses).

This patch changes things so that ctors use ctor_identifer and dtors use dtor_identifier. This makes it clearer when debugging the compiler and avoids the need to frob the name. We do now have two ways to check cdtorness -- look at the DECL_CONSTRUCTOR_P of the DECL, or look at the IDENTIFIER_CTOR_P flag of the IDENTIFIER. The former is used by the language-agnostic middle-end, and the latter is used by the C++ FE to determine if we lazily need to synthesize things. It doesn't seem useful, (at the moment), to just have one mechanism.

The testcase change is in the introspection plugin, where the plugin prints the raw name. It now sees the special name, rather than the class name (which was only 'right' for the ctor anyway). This seems better to me.

nathan
--
Nathan Sidwell
2017-06-30  Nathan Sidwell  <nathan@acm.org>

	* call.c (build_new_method_call_1): Use constructo_name to get
	ctor name.  Move argument processing earlier to merge cdtor
	handling blocks.
	* decl.c (grokfndecl): Cdtors have special names.
	* method.c (implicitly_declare_fn): Likewise. Simplify flag setting.
	* pt.c (check_explicit_specialization): Cdtor name is already
	special.
	* search.c (class_method_index_for_fn): Likewise.

	* g++.dg/plugin/decl-plugin-test.C: Expect special ctor name.

Index: cp/call.c
===================================================================
--- cp/call.c	(revision 249835)
+++ cp/call.c	(working copy)
@@ -8994,6 +8994,7 @@ build_new_method_call_1 (tree instance,
       if (! (complain & tf_error))
 	return error_mark_node;
 
+      name = constructor_name (basetype);
       if (permerror (input_location,
 		     "cannot call constructor %<%T::%D%> directly",
 		     basetype, name))
@@ -9004,6 +9005,19 @@ build_new_method_call_1 (tree instance,
       return call;
     }
 
+  /* Process the argument list.  */
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args, complain);
+      if (*args == NULL)
+	return error_mark_node;
+    }
+
+  /* Consider the object argument to be used even if we end up selecting a
+     static member function.  */
+  instance = mark_type_use (instance);
+
+
   /* Figure out whether to skip the first argument for the error
      message we will display to users if an error occurs.  We don't
      want to display any compiler-generated arguments.  The "this"
@@ -9013,35 +9027,18 @@ build_new_method_call_1 (tree instance,
   skip_first_for_error = false;
   if (IDENTIFIER_CDTOR_P (name))
     {
-      /* Callers should explicitly indicate whether they want to construct
+      /* Callers should explicitly indicate whether they want to ctor
 	 the complete object or just the part without virtual bases.  */
       gcc_assert (name != ctor_identifier);
-      /* Similarly for destructors.  */
-      gcc_assert (name != dtor_identifier);
+
       /* Remove the VTT pointer, if present.  */
       if ((name == base_ctor_identifier || name == base_dtor_identifier)
 	  && CLASSTYPE_VBASECLASSES (basetype))
 	skip_first_for_error = true;
-    }
-
-  /* Process the argument list.  */
-  if (args != NULL && *args != NULL)
-    {
-      *args = resolve_args (*args, complain);
-      if (*args == NULL)
-	return error_mark_node;
-    }
 
-  /* Consider the object argument to be used even if we end up selecting a
-     static member function.  */
-  instance = mark_type_use (instance);
-
-  /* It's OK to call destructors and constructors on cv-qualified objects.
-     Therefore, convert the INSTANCE to the unqualified type, if
-     necessary.  */
-  if (DECL_DESTRUCTOR_P (fn)
-      || DECL_CONSTRUCTOR_P (fn))
-    {
+      /* It's OK to call destructors and constructors on cv-qualified
+	 objects.  Therefore, convert the INSTANCE to the unqualified
+	 type, if necessary.  */
       if (!same_type_p (basetype, TREE_TYPE (instance)))
 	{
 	  instance = build_this (instance);
@@ -9049,8 +9046,8 @@ build_new_method_call_1 (tree instance,
 	  instance = build_fold_indirect_ref (instance);
 	}
     }
-  if (DECL_DESTRUCTOR_P (fn))
-    name = complete_dtor_identifier;
+  else
+    gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn));
 
   /* For the overload resolution we need to find the actual `this`
      that would be captured if the call turns out to be to a
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 249835)
+++ cp/decl.c	(working copy)
@@ -8518,9 +8518,11 @@ grokfndecl (tree ctype,
     case sfk_copy_constructor:
     case sfk_move_constructor:
       DECL_CONSTRUCTOR_P (decl) = 1;
+      DECL_NAME (decl) = ctor_identifier;
       break;
     case sfk_destructor:
       DECL_DESTRUCTOR_P (decl) = 1;
+      DECL_NAME (decl) = dtor_identifier;
       break;
     default:
       break;
Index: cp/method.c
===================================================================
--- cp/method.c	(revision 249835)
+++ cp/method.c	(working copy)
@@ -1968,12 +1968,12 @@ implicitly_declare_fn (special_function_
     {
     case sfk_destructor:
       /* Destructor.  */
-      name = constructor_name (type);
+      name = dtor_identifier;
       break;
 
     case sfk_constructor:
       /* Default constructor.  */
-      name = constructor_name (type);
+      name = ctor_identifier;
       break;
 
     case sfk_copy_constructor:
@@ -1989,7 +1989,7 @@ implicitly_declare_fn (special_function_
 	  name = cp_assignment_operator_id (NOP_EXPR);
 	}
       else
-	name = constructor_name (type);
+	name = ctor_identifier;
 
       if (kind == sfk_inheriting_constructor)
 	parameter_types = inherited_parms;
@@ -2053,13 +2053,14 @@ implicitly_declare_fn (special_function_
   fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
   if (kind != sfk_inheriting_constructor)
     DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
-  if (kind == sfk_constructor || kind == sfk_copy_constructor
-      || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
-    DECL_CONSTRUCTOR_P (fn) = 1;
-  else if (kind == sfk_destructor)
-    DECL_DESTRUCTOR_P (fn) = 1;
-  else
+
+  if (!IDENTIFIER_CDTOR_P (name))
+    /* Assignment operator.  */
     SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+  else if (IDENTIFIER_CTOR_P (name))
+    DECL_CONSTRUCTOR_P (fn) = true;
+  else
+    DECL_DESTRUCTOR_P (fn) = true;
 
   SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
 
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 249835)
+++ cp/pt.c	(working copy)
@@ -2881,9 +2881,8 @@ check_explicit_specialization (tree decl
 
 	  if (constructor_name_p (name, ctype))
 	    {
-	      int is_constructor = DECL_CONSTRUCTOR_P (decl);
-
-	      if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
+	      if (DECL_CONSTRUCTOR_P (decl)
+		  ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
 		  : !CLASSTYPE_DESTRUCTOR (ctype))
 		{
 		  /* From [temp.expl.spec]:
@@ -2898,7 +2897,7 @@ check_explicit_specialization (tree decl
 		  return error_mark_node;
 		}
 
-	      name = is_constructor ? ctor_identifier : dtor_identifier;
+	      name = DECL_NAME (decl);
 	    }
 
 	  if (!DECL_CONV_FN_P (decl))
Index: cp/search.c
===================================================================
--- cp/search.c	(revision 249835)
+++ cp/search.c	(working copy)
@@ -1713,10 +1713,7 @@ class_method_index_for_fn (tree class_ty
 {
   gcc_assert (DECL_DECLARES_FUNCTION_P (function));
 
-  return lookup_fnfields_1 (class_type,
-			    DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
-			    DECL_DESTRUCTOR_P (function) ? dtor_identifier :
-			    DECL_NAME (function));
+  return lookup_fnfields_1 (class_type, DECL_NAME (function));
 }
 
 
Index: testsuite/g++.dg/plugin/decl-plugin-test.C
===================================================================
--- testsuite/g++.dg/plugin/decl-plugin-test.C	(revision 249835)
+++ testsuite/g++.dg/plugin/decl-plugin-test.C	(working copy)
@@ -17,7 +17,7 @@ class test_class {
   int class_field1; // { dg-warning "Decl Field class_field1" }
   int class_field2; // { dg-warning "Decl Field class_field2" }
 
-  test_class() // { dg-warning "Decl Function test_class" }
+  test_class() // { dg-warning "Decl Function __ct" }
     : class_field1(0), class_field2(0)
   {}
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]