aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2016-08-12 07:11:50 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2016-08-12 07:11:50 +0000
commite366d7d807f8d06dc35570871ba2b723b78975af (patch)
tree471d9088fd063b9813bc17c068db09d41e6775d3
parent71e1a6a4c799e27be77f593c82b1575e094ea548 (diff)
downloadgcc-e366d7d807f8d06dc35570871ba2b723b78975af.zip
gcc-e366d7d807f8d06dc35570871ba2b723b78975af.tar.gz
gcc-e366d7d807f8d06dc35570871ba2b723b78975af.tar.bz2
[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. 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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-objcp-common.c25
-rw-r--r--gcc/cp/cp-objcp-common.h7
-rw-r--r--gcc/dwarf2out.c49
-rw-r--r--gcc/langhooks-def.h6
-rw-r--r--gcc/langhooks.h9
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C14
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C16
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C13
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C2
-rw-r--r--include/ChangeLog6
-rw-r--r--include/dwarf2.def2
-rw-r--r--include/dwarf2.h8
15 files changed, 176 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59e4fcf..11d6e54 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c0d2460..4049c76 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index f7ddb00..9cb9dd7 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -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)
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1bb19ee..3ad3eb6 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 06dbadb..3b25358 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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. */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index c17f998..10d910c 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -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, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 169a678..44c258e 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1726157..b2d0e64 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..e798b49
--- /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\]* 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
index 0000000..5b56949
--- /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\]* 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
index 0000000..190fe50
--- /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_defaulted" { xfail { powerpc-ibm-aix* } } } }
+
+struct Foo
+{
+};
+
+void
+bar ()
+{
+ Foo foo;
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
index c0c36a9..7f42719 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
@@ -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
{
diff --git a/include/ChangeLog b/include/ChangeLog
index 06be028..5a3843b 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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.
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 2dfee56..67b2a5b 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -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. */
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
{