[PR63240] generate debug info for defaulted member functions
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 12 Aug 2016 07:11:50 +0000 (07:11 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 12 Aug 2016 07:11:50 +0000 (07:11 +0000)
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.

for  include/ChangeLog

PR debug/63240
* dwarf2.def (DW_AT_deleted, DW_AT_defaulted): New.
* dwarf2.h (enu dwarf_defaulted_attribute): New.

for  gcc/ChangeLog

PR debug/63240
* langhooks-def.h
(LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Const_tree-ify.
(LANG_HOOKS_FUNCTION_DECL_DELETED_P): Likewise.
(LANG_HOOKS_FUNCTION_DECL_DEFAULTED): Set default.
(LANG_HOOKS_DECLS): Add it.
* langhooks.h (struct lang_hooks_for_decls): Add
function_decl_defaulted.  Const_tree-ify
function_decl_explicit_p and function_decl_deleted_p.
* dwarf2out.c (gen_subprogram_die): Add DW_AT_defaulted
attribute.  Add DW_AT_deleted instead of DW_AT_GNU_deleted,
also at strict DWARF v5.

for  gcc/cp/ChangeLog

PR debug/63240
* cp-objcp-common.c (cp_function_decl_defaulted): New.
(cp_function_decl_explicit_p): Const_tree-ify.
(cp_function_decl_deleted_p): Likewise.
* cp-objcp-common.h (cp_function_decl_defaulted): Declare.
(cp_function_decl_explicit_p): Const_tree-ify.
(cp_function_decl_deleted_p): Likewise.
(LANG_HOOKS_FUNCTION_DECL_DEFAULTED): 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.
* g++.dg/debug/dwarf2/deleted-member-function.C: Expect
DW_AT_deleted.

From-SVN: r239403

15 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.c
gcc/cp/cp-objcp-common.h
gcc/dwarf2out.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
include/ChangeLog
include/dwarf2.def
include/dwarf2.h

index 59e4fcf0eac8a6cd040dabc3d71f5f82732f6403..11d6e548dba22bd2e1eebbc86d49ef4bf11fb6fb 100644 (file)
@@ -1,5 +1,18 @@
 2016-08-12  Alexandre Oliva <aoliva@redhat.com>
 
+       PR debug/63240
+       * langhooks-def.h
+       (LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Const_tree-ify.
+       (LANG_HOOKS_FUNCTION_DECL_DELETED_P): Likewise.
+       (LANG_HOOKS_FUNCTION_DECL_DEFAULTED): Set default.
+       (LANG_HOOKS_DECLS): Add it.
+       * langhooks.h (struct lang_hooks_for_decls): Add
+       function_decl_defaulted.  Const_tree-ify
+       function_decl_explicit_p and function_decl_deleted_p.
+       * dwarf2out.c (gen_subprogram_die): Add DW_AT_defaulted
+       attribute.  Add DW_AT_deleted instead of DW_AT_GNU_deleted,
+       also at strict DWARF v5.
+
        PR debug/55641
        * dwarf2out.c (decl_quals): Don't map TREE_READONLY to
        TYPE_QUAL_CONST in reference-typed decls.
index c0d246060856a7e66ee0b43fc4114a573114835f..4049c76bfebeeb77027d8386dff8db031b4dc7d8 100644 (file)
@@ -1,3 +1,14 @@
+2016-08-12  Alexandre Oliva <aoliva@redhat.com>
+
+       PR debug/63240
+       * cp-objcp-common.c (cp_function_decl_defaulted): New.
+       (cp_function_decl_explicit_p): Const_tree-ify.
+       (cp_function_decl_deleted_p): Likewise.
+       * cp-objcp-common.h (cp_function_decl_defaulted): Declare.
+       (cp_function_decl_explicit_p): Const_tree-ify.
+       (cp_function_decl_deleted_p): Likewise.
+       (LANG_HOOKS_FUNCTION_DECL_DEFAULTED): Redefine.
+
 2016-08-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/72868
index f7ddb00b02cb8ed2a931413bfdf825d8d2456025..9cb9dd780fb2e2b879d29315baf94a3220593c3c 100644 (file)
@@ -133,7 +133,7 @@ cxx_types_compatible_p (tree x, tree y)
 /* Return true if DECL is explicit member function.  */
 
 bool
-cp_function_decl_explicit_p (tree decl)
+cp_function_decl_explicit_p (const_tree decl)
 {
   return (decl
          && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
@@ -143,13 +143,34 @@ cp_function_decl_explicit_p (tree decl)
 /* Return true if DECL is deleted special member function.  */
 
 bool
-cp_function_decl_deleted_p (tree decl)
+cp_function_decl_deleted_p (const_tree decl)
 {
   return (decl
          && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
          && DECL_DELETED_FN (decl));
 }
 
+/* Returns 0 if DECL is NOT a C++11 defaulted special member function,
+   1 if it is explicitly defaulted within the class body, or 2 if it
+   is explicitly defaulted outside the class body.  */
+
+int
+cp_function_decl_defaulted (const_tree decl)
+{
+  if (decl
+      && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+      && DECL_DEFAULTED_FN (decl))
+    {
+      if (DECL_DEFAULTED_IN_CLASS_P (decl))
+       return 1;
+
+      if (DECL_DEFAULTED_OUTSIDE_CLASS_P (decl))
+       return 2;
+    }
+
+  return 0;
+}
+
 /* Stubs to keep c-opts.c happy.  */
 void
 push_file_scope (void)
index 1bb19ee04b9cd02e2f1a4cfe9c9c2f12be83be9f..3ad3eb64c0b4ff9b9893e21edb1d19c46a9c515c 100644 (file)
@@ -26,8 +26,9 @@ along with GCC; see the file COPYING3.  If not see
 extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
                                         tree, bool);
 
-extern bool cp_function_decl_explicit_p (tree decl);
-extern bool cp_function_decl_deleted_p (tree decl);
+extern bool cp_function_decl_explicit_p (const_tree decl);
+extern bool cp_function_decl_deleted_p (const_tree decl);
+extern int cp_function_decl_defaulted (const_tree decl);
 extern void cp_common_init_ts (void);
 
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
@@ -134,6 +135,8 @@ 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
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED cp_function_decl_defaulted
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
index 06dbadbd15f95b97d0a85ae59a2ba91a33b7323c..3b25358459dd93664f36649500a0436c385d0880 100644 (file)
@@ -20477,6 +20477,24 @@ 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.  */
+         int defaulted = lang_hooks.decls.function_decl_defaulted (decl);
+         if (defaulted && (dwarf_version >= 5 || ! dwarf_strict)
+             && !get_AT (subr_die, DW_AT_defaulted))
+           switch (defaulted)
+             {
+             case 2:
+               add_AT_unsigned (subr_die, DW_AT_defaulted,
+                                DW_DEFAULTED_out_of_class);
+               break;
+
+             case 1: /* This must have been handled before.  */
+             default:
+               gcc_unreachable ();
+             }
        }
     }
   /* Create a fresh DIE for anything else.  */
@@ -20524,10 +20542,35 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
            add_AT_flag (subr_die, DW_AT_explicit, 1);
 
          /* If this is a C++11 deleted special function member then generate
-            a DW_AT_GNU_deleted attribute.  */
+            a DW_AT_deleted attribute.  */
          if (lang_hooks.decls.function_decl_deleted_p (decl)
-             && (! dwarf_strict))
-           add_AT_flag (subr_die, DW_AT_GNU_deleted, 1);
+             && (dwarf_version >= 5 || ! dwarf_strict))
+           add_AT_flag (subr_die, DW_AT_deleted, 1);
+
+         /* If this is a C++11 defaulted special function member then
+            generate a DW_AT_GNU_defaulted attribute.  */
+         int defaulted = lang_hooks.decls.function_decl_defaulted (decl);
+         if (defaulted && (dwarf_version >= 5 || ! dwarf_strict))
+           switch (defaulted)
+             {
+             case 1:
+               add_AT_unsigned (subr_die, DW_AT_defaulted,
+                                DW_DEFAULTED_in_class);
+               break;
+
+               /* 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.  */
+             case 2:
+               add_AT_unsigned (subr_die, DW_AT_defaulted,
+                                DW_DEFAULTED_out_of_class);
+               break;
+
+             default:
+               gcc_unreachable ();
+             }
        }
     }
   /* Tag abstract instances with DW_AT_inline.  */
index c17f9984184968dbc24af1597700cf608b070655..10d910c960d4cf12af4dc2654c7d4f4c73b9415a 100644 (file)
@@ -209,8 +209,9 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_GLOBAL_BINDINGS_P global_bindings_p
 #define LANG_HOOKS_PUSHDECL    pushdecl
 #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_EXPLICIT_P hook_bool_const_tree_false
+#define LANG_HOOKS_FUNCTION_DECL_DELETED_P hook_bool_const_tree_false
+#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED hook_int_const_tree_0
 #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
@@ -233,6 +234,7 @@ 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, \
   LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
   LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
   LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
index 169a6784b6abdf3f69ed32423a53c34235d2bf9d..44c258e963808c59a999a796b47c70f1672e2397 100644 (file)
@@ -181,10 +181,15 @@ struct lang_hooks_for_decls
   tree (*getdecls) (void);
 
   /* Returns true if DECL is explicit member function.  */
-  bool (*function_decl_explicit_p) (tree);
+  bool (*function_decl_explicit_p) (const_tree);
 
   /* Returns true if DECL is C++11 deleted special member function.  */
-  bool (*function_decl_deleted_p) (tree);
+  bool (*function_decl_deleted_p) (const_tree);
+
+  /* Returns 0 if DECL is NOT a C++11 defaulted special member
+     function, 1 if it is explicitly defaulted within the class body,
+     or 2 if it is explicitly defaulted outside the class body.  */
+  int (*function_decl_defaulted) (const_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.  */
index 1726157067ec6e59cbf969b2baead403dd1ad0ac..b2d0e64ec589741cf9cb3b8fe02ba05b726a76b0 100644 (file)
@@ -1,5 +1,12 @@
 2016-08-12  Alexandre Oliva <aoliva@redhat.com>
 
+       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.
+       * g++.dg/debug/dwarf2/deleted-member-function.C: Expect
+       DW_AT_deleted.
+
        PR debug/55641
        * g++.dg/debug/dwarf2/ref-1.C: New.
 
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 (file)
index 0000000..e798b49
--- /dev/null
@@ -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\]* DW_AT_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 (file)
index 0000000..5b56949
--- /dev/null
@@ -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\]* DW_AT_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 (file)
index 0000000..190fe50
--- /dev/null
@@ -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_defaulted" { xfail { powerpc-ibm-aix* } } } }
+
+struct Foo
+{
+};
+
+void
+bar ()
+{
+  Foo foo;
+}
index c0c36a977751327cb6813cf05dbddb17fb6055a6..7f42719d669c8c648eddd9a5052e76f398775a03 100644 (file)
@@ -1,6 +1,6 @@
 // { dg-do compile }
 // { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" }
-// { dg-final { scan-assembler-times " DW_AT_GNU_deleted" 2 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_deleted" 2 { xfail { powerpc-ibm-aix* } } } }
 
 struct Foo
 {
index 06be0281e26c051eadc0742e5a6fe4de191179b8..5a3843bde1c6f30d718ecbb1e748a102939c7741 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-12  Alexandre Oliva <aoliva@redhat.com>
+
+       PR debug/63240
+       * dwarf2.def (DW_AT_deleted, DW_AT_defaulted): New.
+       * dwarf2.h (enu dwarf_defaulted_attribute): New.
+
 2016-07-29  Aldy Hernandez  <aldyh@redhat.com>
 
        * libiberty.h (MAX_ALLOCA_SIZE): New macro.
index 2dfee5666dea68d8292f04c5100c93e1f1fcf4f4..67b2a5bd39d610995a1f8b24e757e8e86c6d81c7 100644 (file)
@@ -310,6 +310,8 @@ DW_AT (DW_AT_enum_class, 0x6d)
 DW_AT (DW_AT_linkage_name, 0x6e)
 /* DWARF 5.  */
 DW_AT (DW_AT_noreturn, 0x87)
+DW_AT (DW_AT_deleted, 0x8a)
+DW_AT (DW_AT_defaulted, 0x8b)
 
 DW_AT_DUP (DW_AT_lo_user, 0x2000) /* Implementation-defined range start.  */
 DW_AT_DUP (DW_AT_hi_user, 0x3fff) /* Implementation-defined range end.  */
index 1a145aa48f7f42f702b591a9153e0298a311750a..d166a965db5cdd706f23aa6e7c5a65d511719fad 100644 (file)
@@ -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
   {