public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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

             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).