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]

[PR63240] generate debug info for defaulted member functions


This implements <http://dwarfstd.org/ShowIssue.php?issue=141215.3>, a
proposal already accepted for inclusion in DWARF-5, but using
DW_AT_GNU_defaulted instead of DW_AT_defaulted as the attribute name,
because the attribute id for DW_AT_defaulted is not yet publicly
available.

Regstrapped on x86_64-linux-gnu and i686-linux-gnu.  Ok to install?

for  include/ChangeLog

	PR debug/63240
	* dwarf2.def (DW_AT_GNU_defaulted): New.
	* dwarf2.h (enu dwarf_defaulted_attribute): New.

for  gcc/ChangeLog

	PR debug/63240
	* langhooks-def.h
	(LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P): Set default.
	(LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P): Likewise.
	(LANG_HOOKS_DECLS): Add them.
	* langhooks.h (struct lang_hooks_for_decls): Add
	function_decl_defaulted_inclass_p and
	function_decl_defaulted_outofclass_p.
	* dwarf2out.c (gen_subprogram_die): Add DW_AT_GNU_defaulted
	attribute.

for  gcc/cp/ChangeLog

	PR debug/63240
	* cp-objcp-common.c (cp_function_decl_defaulted_inclass_p,
	cp_function_decl_defaulted_outofclass_p): New.
	* cp-objcp-common.h (cp_function_decl_defaulted_inclass_p,
	cp_function_decl_defaulted_outofclass_p): Declare.
	(LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P): Redefine.
	(LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P): Redefine.

for  gcc/testsuite/ChangeLog

	PR debug/63240
	* g++.dg/debug/dwarf2/defaulted-member-function-1.C: New.
	* g++.dg/debug/dwarf2/defaulted-member-function-2.C: New.
	* g++.dg/debug/dwarf2/defaulted-member-function-3.C: New.
---
 gcc/cp/cp-objcp-common.c                           |   22 ++++++++++++++++++
 gcc/cp/cp-objcp-common.h                           |    8 +++++++
 gcc/dwarf2out.c                                    |   24 ++++++++++++++++++++
 gcc/langhooks-def.h                                |    4 +++
 gcc/langhooks.h                                    |    8 +++++++
 .../debug/dwarf2/defaulted-member-function-1.C     |   14 ++++++++++++
 .../debug/dwarf2/defaulted-member-function-2.C     |   16 +++++++++++++
 .../debug/dwarf2/defaulted-member-function-3.C     |   13 +++++++++++
 include/dwarf2.def                                 |    2 ++
 include/dwarf2.h                                   |    8 +++++++
 10 files changed, 119 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index f7ddb00..daa1b7e 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -150,6 +150,28 @@ cp_function_decl_deleted_p (tree decl)
 	  && DECL_DELETED_FN (decl));
 }
 
+/* Return true if DECL is a special member function defaulted within
+   the class body.  */
+
+bool
+cp_function_decl_defaulted_inclass_p (tree decl)
+{
+  return (decl
+	  && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+	  && DECL_DEFAULTED_IN_CLASS_P (decl));
+}
+
+/* Return true if DECL is a special member function defaulted outside
+   the class body.  */
+
+bool
+cp_function_decl_defaulted_outofclass_p (tree decl)
+{
+  return (decl
+	  && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+	  && DECL_DEFAULTED_OUTSIDE_CLASS_P (decl));
+}
+
 /* Stubs to keep c-opts.c happy.  */
 void
 push_file_scope (void)
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1bb19ee..7bba00d 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -28,6 +28,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 
 extern bool cp_function_decl_explicit_p (tree decl);
 extern bool cp_function_decl_deleted_p (tree decl);
+extern bool cp_function_decl_defaulted_inclass_p (tree decl);
+extern bool cp_function_decl_defaulted_outofclass_p (tree decl);
 extern void cp_common_init_ts (void);
 
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
@@ -134,6 +136,12 @@ extern void cp_common_init_ts (void);
 #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p
 #undef LANG_HOOKS_FUNCTION_DECL_DELETED_P
 #define LANG_HOOKS_FUNCTION_DECL_DELETED_P cp_function_decl_deleted_p
+#undef LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P \
+  cp_function_decl_defaulted_inclass_p
+#undef LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P \
+  cp_function_decl_defaulted_outofclass_p
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8d6eeed..71fa5ad 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20399,6 +20399,15 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 		add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
 				    TYPE_UNQUALIFIED, false, context_die);
 	    }
+
+	  /* When we process the method declaration, we haven't seen the
+	     out-of-class defaulted definition yet, so we have to recheck
+	     now.  */
+	  if (lang_hooks.decls.function_decl_defaulted_outofclass_p (decl)
+	      && (! dwarf_strict)
+	      && !get_AT (subr_die, DW_AT_GNU_defaulted))
+	    add_AT_unsigned (subr_die, DW_AT_GNU_defaulted,
+			     DW_DEFAULTED_out_of_class);
 	}
     }
   /* Create a fresh DIE for anything else.  */
@@ -20450,6 +20459,21 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 	  if (lang_hooks.decls.function_decl_deleted_p (decl)
 	      && (! dwarf_strict))
 	    add_AT_flag (subr_die, DW_AT_GNU_deleted, 1);
+
+	  /* If this is a C++11 defaulted special function member then
+	     generate a DW_AT_GNU_defaulted attribute.  */
+	  if (lang_hooks.decls.function_decl_defaulted_inclass_p (decl)
+	      && (! dwarf_strict))
+	    add_AT_unsigned (subr_die, DW_AT_GNU_defaulted,
+			     DW_DEFAULTED_in_class);
+	  /* It is likely that this will never hit, since we don't
+	     have the out-of-class definition yet when we process the
+	     class definition and the method declaration.  We recheck
+	     elsewhere, but leave it here just in case.  */
+	  else if (lang_hooks.decls.function_decl_defaulted_outofclass_p (decl)
+		   && (! dwarf_strict))
+	    add_AT_unsigned (subr_die, DW_AT_GNU_defaulted,
+			     DW_DEFAULTED_out_of_class);
 	}
     }
   /* Tag abstract instances with DW_AT_inline.  */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 034b3b7..23e1c74 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -210,6 +210,8 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_GETDECLS	getdecls
 #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
 #define LANG_HOOKS_FUNCTION_DECL_DELETED_P hook_bool_tree_false
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P hook_bool_tree_false
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P hook_bool_tree_false
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
 #define LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS NULL
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL	lhd_decl_ok_for_sibcall
@@ -232,6 +234,8 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_GETDECLS, \
   LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
   LANG_HOOKS_FUNCTION_DECL_DELETED_P, \
+  LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P, \
+  LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P, \
   LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
   LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
   LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 0593424..7e6eb9c 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -186,6 +186,14 @@ struct lang_hooks_for_decls
   /* Returns true if DECL is C++11 deleted special member function.  */
   bool (*function_decl_deleted_p) (tree);
 
+  /* Returns true if DECL is C++11 defaulted special member function
+     that is explicitly defaulted within the class body.  */
+  bool (*function_decl_defaulted_inclass_p) (tree);
+
+  /* Returns true if DECL is C++11 defaulted special member function
+     that is explicitly defaulted outside the class body.  */
+  bool (*function_decl_defaulted_outofclass_p) (tree);
+
   /* Returns True if the parameter is a generic parameter decl
      of a generic type, e.g a template template parameter for the C++ FE.  */
   bool (*generic_generic_parameter_decl_p) (const_tree);
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C
new file mode 100644
index 0000000..c1d107c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" }
+// { dg-final { scan-assembler-times "0x1\[ \t\]\[^\n\]*\[ \t\]DW_AT_GNU_defaulted" 1 { xfail { powerpc-ibm-aix* } } } }
+
+struct Foo
+{
+  Foo () = default;
+};
+
+void
+bar ()
+{
+  Foo foo;
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C
new file mode 100644
index 0000000..29a08de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" }
+// { dg-final { scan-assembler-times "0x2\[ \t\]\[^\n\]*\[ \t\]DW_AT_GNU_defaulted" 1 { xfail { powerpc-ibm-aix* } } } }
+
+struct Foo
+{
+  Foo ();
+};
+
+Foo::Foo () = default;
+
+void
+bar ()
+{
+  Foo foo;
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C
new file mode 100644
index 0000000..95cf7d2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" }
+// { dg-final { scan-assembler-not " DW_AT_GNU_defaulted" { xfail { powerpc-ibm-aix* } } } }
+
+struct Foo
+{
+};
+
+void
+bar ()
+{
+  Foo foo;
+}
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 2dfee56..4d06ce8 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -387,6 +387,8 @@ DW_AT (DW_AT_GNU_all_source_call_sites, 0x2118)
 DW_AT (DW_AT_GNU_macros, 0x2119)
 /* Attribute for C++ deleted special member functions (= delete;).  */
 DW_AT (DW_AT_GNU_deleted, 0x211a)
+/* Attribute for C++ defaulted special member functions (= default;).  */
+DW_AT (DW_AT_GNU_defaulted, 0x211b)
 /* Extensions for Fission.  See http://gcc.gnu.org/wiki/DebugFission.  */
 DW_AT (DW_AT_GNU_dwo_name, 0x2130)
 DW_AT (DW_AT_GNU_dwo_id, 0x2131)
diff --git a/include/dwarf2.h b/include/dwarf2.h
index 1a145aa..d166a96 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -342,6 +342,14 @@ enum dwarf_macinfo_record_type
     DW_MACINFO_vendor_ext = 255
   };
 
+/* DW_TAG_GNU_defaulted/DW_TAG_defaulted attributes.  */
+enum dwarf_defaulted_attribute
+  {
+    DW_DEFAULTED_no = 0x00,
+    DW_DEFAULTED_in_class = 0x01,
+    DW_DEFAULTED_out_of_class = 0x02
+  };
+
 /* Names and codes for new style macro information.  */
 enum dwarf_macro_record_type
   {


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer


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