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