From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Marek Polacek <polacek@redhat.com>
Subject: [PATCH] Emit DWARF5 DW_AT_export_symbols for namespaces
Date: Fri, 21 Jul 2017 20:33:00 -0000 [thread overview]
Message-ID: <20170721203312.GL2123@tucnak> (raw)
Hi!
DWARF5 introduced DW_AT_export_symbols that may be preset on
DW_TAG_namespace or DW_TAG_{structure,union,class}_type to signalize
inline or anonymous namespaces or anonymous structures/unions/classes.
What we were emitting instead is an implicit DW_TAG_imported_module
in the outer namespace.
The following patch changes nothing for -gdwarf-4 and below with
-gstrict-dwarf, for -gdwarf-4 and below -gno-strict-dwarf it
just adds DW_AT_export_symbols to inline namespaces (so that interested
consumers can find out it is inline namespace, but consumers not knowing
about DW_AT_export_symbols still have the implicit DW_TAG_imported_module).
In that mode, no changes for anonymous namespaces, because those
are already easily detectable by the consumers (missing DW_AT_name).
For -gdwarf-5 it emits DW_AT_export_symbols on both inline namespaces
and anonymous namespaces and doesn't emit the implicit
DW_TAG_imported_module, which is shorter.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
This patch doesn't do anything about anon struct/union/class, I've tried
to handle it, the problem is that ANON_AGGR_TYPE_P flag is set too late,
after the debug hook adds the type DIE. Any thoughts on how to handle that?
And I wonder what is the counterpart of ANON_AGGR_TYPE_P in the C FE, CCing
Marek on that.
2017-07-21 Jakub Jelinek <jakub@redhat.com>
* debug.h (struct gcc_debug_hooks): Add IMPLICIT argument
to imported_module_or_decl hook.
(debug_nothing_tree_tree_tree_bool): Remove.
(debug_nothing_tree_tree_tree_bool_bool): New declaration.
* debug.c (do_nothing_debug_hooks): Use
debug_nothing_tree_tree_tree_bool_bool instead of
debug_nothing_tree_tree_tree_bool.
* vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Likewise.
* sdbout.c (sdb_debug_hooks): Likewise.
* dwarf2out.c (dwarf2_lineno_debug_hooks): Likewise.
(gen_namespace_die): Add DW_AT_export_symbols attribute if
langhook wants it.
(dwarf2out_imported_module_or_decl): Add IMPLICIT argument,
if true, -gdwarf-5 and decl will have DW_AT_export_symbols
attribute, don't add anything.
cp/
* cp-objcp-common.c (cp_decl_dwarf_attribute): Handle
DW_AT_export_symbols.
* name-lookup.c (emit_debug_info_using_namespace): Add IMPLICIT
argument, pass it through to the debug hook.
(finish_namespace_using_directive): Adjust
emit_debug_info_using_namespace caller.
(push_namespace): Likewise. Call it after setting
DECL_NAMESPACE_INLINE_P.
(cp_emit_debug_info_for_using): Pass false as new argument to
the imported_module_or_decl debug hook.
fortran/
* trans-decl.c (gfc_trans_use_stmts): Pass false as new argument to
the imported_module_or_decl debug hook.
ada/
* gcc-interface/utils.c (gnat_write_global_declarations): Pass false
as new argument to the imported_module_or_decl debug hook.
testsuite/
* g++.dg/debug/dwarf2/inline-ns-1.C: New test.
* g++.dg/debug/dwarf2/inline-ns-2.C: New test.
--- gcc/debug.h.jj 2017-02-18 17:11:18.000000000 +0100
+++ gcc/debug.h 2017-07-21 12:19:09.486576092 +0200
@@ -145,7 +145,8 @@ struct gcc_debug_hooks
/* Debug information for imported modules and declarations. */
void (* imported_module_or_decl) (tree decl, tree name,
- tree context, bool child);
+ tree context, bool child,
+ bool implicit);
/* DECL is an inline function, whose body is present, but which is
not being output at this point. */
@@ -206,7 +207,8 @@ extern void debug_nothing_int_int (unsig
extern void debug_nothing_tree (tree);
extern void debug_nothing_tree_tree (tree, tree);
extern void debug_nothing_tree_int (tree, int);
-extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
+extern void debug_nothing_tree_tree_tree_bool_bool (tree, tree, tree,
+ bool, bool);
extern bool debug_true_const_tree (const_tree);
extern void debug_nothing_rtx_insn (rtx_insn *);
extern void debug_nothing_rtx_code_label (rtx_code_label *);
--- gcc/debug.c.jj 2017-02-18 17:11:18.000000000 +0100
+++ gcc/debug.c 2017-07-21 11:53:45.452383785 +0200
@@ -47,7 +47,7 @@ const struct gcc_debug_hooks do_nothing_
debug_nothing_tree, /* early_global_decl */
debug_nothing_tree, /* late_global_decl */
debug_nothing_tree_int, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
debug_nothing_rtx_code_label, /* label */
@@ -80,10 +80,11 @@ debug_nothing_tree_tree (tree t1 ATTRIBU
}
void
-debug_nothing_tree_tree_tree_bool (tree t1 ATTRIBUTE_UNUSED,
- tree t2 ATTRIBUTE_UNUSED,
- tree t3 ATTRIBUTE_UNUSED,
- bool b1 ATTRIBUTE_UNUSED)
+debug_nothing_tree_tree_tree_bool_bool (tree t1 ATTRIBUTE_UNUSED,
+ tree t2 ATTRIBUTE_UNUSED,
+ tree t3 ATTRIBUTE_UNUSED,
+ bool b1 ATTRIBUTE_UNUSED,
+ bool b2 ATTRIBUTE_UNUSED)
{
}
--- gcc/vmsdbgout.c.jj 2017-02-18 17:11:18.000000000 +0100
+++ gcc/vmsdbgout.c 2017-07-21 11:54:50.757609629 +0200
@@ -197,7 +197,7 @@ const struct gcc_debug_hooks vmsdbg_debu
vmsdbgout_early_global_decl,
vmsdbgout_late_global_decl,
vmsdbgout_type_decl, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool, /* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
vmsdbgout_abstract_function,
debug_nothing_rtx_code_label, /* label */
--- gcc/dbxout.c.jj 2017-07-21 10:28:12.000000000 +0200
+++ gcc/dbxout.c 2017-07-21 11:54:03.115174403 +0200
@@ -371,7 +371,7 @@ const struct gcc_debug_hooks dbx_debug_h
dbxout_early_global_decl, /* early_global_decl */
dbxout_late_global_decl, /* late_global_decl */
dbxout_type_decl, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
debug_nothing_rtx_code_label, /* label */
@@ -411,7 +411,7 @@ const struct gcc_debug_hooks xcoff_debug
dbxout_early_global_decl, /* early_global_decl */
dbxout_late_global_decl, /* late_global_decl */
dbxout_type_decl, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
debug_nothing_rtx_code_label, /* label */
--- gcc/sdbout.c.jj 2017-02-18 17:11:18.000000000 +0100
+++ gcc/sdbout.c 2017-07-21 11:54:32.259828909 +0200
@@ -301,7 +301,7 @@ const struct gcc_debug_hooks sdb_debug_h
sdbout_early_global_decl, /* early_global_decl */
sdbout_late_global_decl, /* late_global_decl */
sdbout_symbol, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
sdbout_label, /* label */
--- gcc/dwarf2out.c.jj 2017-07-21 10:28:12.659136982 +0200
+++ gcc/dwarf2out.c 2017-07-21 12:01:14.052065893 +0200
@@ -2680,7 +2680,7 @@ static bool dwarf2out_ignore_block (cons
static void dwarf2out_early_global_decl (tree);
static void dwarf2out_late_global_decl (tree);
static void dwarf2out_type_decl (tree, int);
-static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool);
+static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool, bool);
static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
dw_die_ref);
static void dwarf2out_abstract_function (tree);
@@ -2764,7 +2764,7 @@ const struct gcc_debug_hooks dwarf2_line
debug_nothing_tree, /* early_global_decl */
debug_nothing_tree, /* late_global_decl */
debug_nothing_tree_int, /* type_decl */
- debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
+ debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
debug_nothing_rtx_code_label, /* label */
@@ -25166,6 +25172,11 @@ gen_namespace_die (tree decl, dw_die_ref
add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
equate_decl_number_to_die (decl, namespace_die);
}
+ if ((dwarf_version >= 5 || !dwarf_strict)
+ && lang_hooks.decls.decl_dwarf_attribute (decl,
+ DW_AT_export_symbols) == 1)
+ add_AT_flag (namespace_die, DW_AT_export_symbols, 1);
+
/* Bypass dwarf2_name's check for DECL_NAMELESS. */
if (want_pubnames ())
add_pubname_string (lang_hooks.dwarf_name (decl, 1), namespace_die);
@@ -25579,11 +25590,13 @@ dwarf2out_imported_module_or_decl_1 (tre
/* Output debug information for imported module or decl DECL.
NAME is non-NULL name in context if the decl has been renamed.
CHILD is true if decl is one of the renamed decls as part of
- importing whole module. */
+ importing whole module.
+ IMPLICIT is set if this hook is called for an implicit import
+ such as inline namespace. */
static void
dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
- bool child)
+ bool child, bool implicit)
{
/* dw_die_ref at_import_die; */
dw_die_ref scope_die;
@@ -25593,6 +25606,16 @@ dwarf2out_imported_module_or_decl (tree
gcc_assert (decl);
+ /* For DWARF5, just DW_AT_export_symbols on the DW_TAG_namespace
+ should be enough, for DWARF4 and older even if we emit as extension
+ DW_AT_export_symbols add the implicit DW_TAG_imported_module anyway
+ for the benefit of consumers unaware of DW_AT_export_symbols. */
+ if (implicit
+ && dwarf_version >= 5
+ && lang_hooks.decls.decl_dwarf_attribute (decl,
+ DW_AT_export_symbols) == 1)
+ return;
+
set_early_dwarf s;
/* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
--- gcc/cp/cp-objcp-common.c.jj 2017-07-19 14:01:18.866064325 +0200
+++ gcc/cp/cp-objcp-common.c 2017-07-21 12:18:28.031066986 +0200
@@ -212,6 +212,13 @@ cp_decl_dwarf_attribute (const_tree decl
}
break;
+ case DW_AT_export_symbols:
+ if (TREE_CODE (decl) == NAMESPACE_DECL
+ && (DECL_NAMESPACE_INLINE_P (decl)
+ || (DECL_NAME (decl) == NULL_TREE && dwarf_version >= 5)))
+ return 1;
+ break;
+
default:
break;
}
--- gcc/cp/name-lookup.c.jj 2017-07-19 14:01:18.887064085 +0200
+++ gcc/cp/name-lookup.c 2017-07-21 12:06:27.525349847 +0200
@@ -6045,11 +6045,12 @@ add_using_namespace (vec<tree, va_gc> *&
/* Tell the debug system of a using directive. */
static void
-emit_debug_info_using_namespace (tree from, tree target)
+emit_debug_info_using_namespace (tree from, tree target, bool implicit)
{
/* Emit debugging info. */
tree context = from != global_namespace ? from : NULL_TREE;
- debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false);
+ debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false,
+ implicit);
}
/* Process a namespace-scope using directive. */
@@ -6064,7 +6065,7 @@ finish_namespace_using_directive (tree t
add_using_namespace (DECL_NAMESPACE_USING (current_namespace),
ORIGINAL_NAMESPACE (target));
emit_debug_info_using_namespace (current_namespace,
- ORIGINAL_NAMESPACE (target));
+ ORIGINAL_NAMESPACE (target), false);
if (attribs == error_mark_node)
return;
@@ -6223,14 +6224,14 @@ push_namespace (tree name, bool make_inl
else if (TREE_PUBLIC (current_namespace))
TREE_PUBLIC (ns) = 1;
- if (name == anon_identifier || make_inline)
- emit_debug_info_using_namespace (current_namespace, ns);
-
if (make_inline)
{
DECL_NAMESPACE_INLINE_P (ns) = true;
vec_safe_push (DECL_NAMESPACE_INLINEES (current_namespace), ns);
}
+
+ if (name == anon_identifier || make_inline)
+ emit_debug_info_using_namespace (current_namespace, ns, true);
}
}
@@ -6358,8 +6359,8 @@ cp_emit_debug_info_for_using (tree t, tr
if (building_stmt_list_p ())
add_stmt (build_stmt (input_location, USING_STMT, fn));
else
- debug_hooks->imported_module_or_decl (fn,
- NULL_TREE, context, false);
+ debug_hooks->imported_module_or_decl (fn, NULL_TREE, context,
+ false, false);
}
}
}
--- gcc/fortran/trans-decl.c.jj 2017-05-12 14:34:55.000000000 +0200
+++ gcc/fortran/trans-decl.c 2017-07-21 12:11:53.917733772 +0200
@@ -4875,7 +4875,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
(*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
NULL_TREE,
ns->proc_name->backend_decl,
- false);
+ false, false);
for (rent = use_stmt->rename; rent; rent = rent->next)
{
tree decl, local_name;
@@ -4952,7 +4952,8 @@ gfc_trans_use_stmts (gfc_namespace * ns)
gfc_set_backend_locus (&rent->where);
(*debug_hooks->imported_module_or_decl) (decl, local_name,
ns->proc_name->backend_decl,
- !use_stmt->only_flag);
+ !use_stmt->only_flag,
+ false);
}
}
}
--- gcc/ada/gcc-interface/utils.c.jj 2017-06-21 16:53:37.000000000 +0200
+++ gcc/ada/gcc-interface/utils.c 2017-07-21 12:12:22.569394503 +0200
@@ -5553,7 +5553,7 @@ gnat_write_global_declarations (void)
FOR_EACH_VEC_SAFE_ELT (global_decls, i, iter)
if (TREE_CODE (iter) == IMPORTED_DECL && !DECL_IGNORED_P (iter))
debug_hooks->imported_module_or_decl (iter, DECL_NAME (iter),
- DECL_CONTEXT (iter), 0);
+ DECL_CONTEXT (iter), false, false);
}
/* ************************************************************************
--- gcc/testsuite/g++.dg/debug/dwarf2/inline-ns-1.C.jj 2017-07-21 13:36:41.589158999 +0200
+++ gcc/testsuite/g++.dg/debug/dwarf2/inline-ns-1.C 2017-07-21 13:51:34.353524052 +0200
@@ -0,0 +1,23 @@
+// { dg-options "-O2 -gdwarf-4 -dA -gno-strict-dwarf" }
+// { dg-final { scan-assembler-times " DW_AT_export_symbols" 1 } }
+// { dg-final { scan-assembler-times "DIE \\(\[^\n\r\]*\\) DW_TAG_imported_module" 2 } }
+
+namespace A
+{
+ int i = 5;
+ inline namespace B
+ {
+ int j = 6;
+ namespace C
+ {
+ int k = 7;
+ };
+ };
+};
+int l = A::i + A::j + A::C::k;
+int m = A::i + A::B::j + A::B::C::k;
+namespace
+{
+ int n = 8;
+};
+int o = n;
--- gcc/testsuite/g++.dg/debug/dwarf2/inline-ns-2.C.jj 2017-07-21 13:40:16.689595957 +0200
+++ gcc/testsuite/g++.dg/debug/dwarf2/inline-ns-2.C 2017-07-21 13:52:20.043981081 +0200
@@ -0,0 +1,23 @@
+// { dg-options "-O2 -gdwarf-5 -dA" }
+// { dg-final { scan-assembler-times " DW_AT_export_symbols" 2 } }
+// { dg-final { scan-assembler-not "DIE \\(\[^\n\r\]*\\) DW_TAG_imported_module" } }
+
+namespace A
+{
+ int i = 5;
+ inline namespace B
+ {
+ int j = 6;
+ namespace C
+ {
+ int k = 7;
+ };
+ };
+};
+int l = A::i + A::j + A::C::k;
+int m = A::i + A::B::j + A::B::C::k;
+namespace
+{
+ int n = 8;
+};
+int o = n;
Jakub
next reply other threads:[~2017-07-21 20:33 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-21 20:33 Jakub Jelinek [this message]
2017-07-25 11:46 ` Marek Polacek
2017-07-25 12:11 ` Jakub Jelinek
2017-07-28 19:44 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170721203312.GL2123@tucnak \
--to=jakub@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
--cc=polacek@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).