diff mbox

[C++] cdtor naming

Message ID 2cb4fef2-452a-276d-110d-2eedfeb674d3@acm.org
State New
Headers show

Commit Message

Nathan Sidwell June 30, 2017, 1:20 p.m. UTC
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
diff mbox

Patch

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)
   {}