public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-6642] diagnostic: avoid repeating include path
@ 2022-01-17 16:59 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-01-17 16:59 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d3a57993359c9759990fe8f2aa4088684ed82190

commit r12-6642-gd3a57993359c9759990fe8f2aa4088684ed82190
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Dec 17 05:45:02 2021 -0500

    diagnostic: avoid repeating include path
    
    When a sequence of diagnostic messages bounces back and forth repeatedly
    between two includes, as with
    
     #include <map>
     std::map<const char*, const char*> m ("123", "456");
    
    The output is quite a bit longer than necessary because we dump the include
    path each time it changes.  I'd think we could print the include path once
    for each header file, and then expect that the user can look earlier in the
    output if they're wondering.
    
    gcc/ChangeLog:
    
            * diagnostic.h (struct diagnostic_context): Add includes_seen.
            * diagnostic.c (diagnostic_initialize): Initialize it.
            (diagnostic_finish): Clean it up.
            (includes_seen): New function.
            (diagnostic_report_current_module): Use it.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/cpp/line-2.c: Only expect includes once.
            * c-c++-common/cpp/line-3.c: Likewise.

Diff:
---
 gcc/diagnostic.h                        |  4 ++++
 gcc/diagnostic.c                        | 36 +++++++++++++++++++++++++++++++--
 gcc/testsuite/c-c++-common/cpp/line-2.c |  2 +-
 gcc/testsuite/c-c++-common/cpp/line-3.c |  2 +-
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 6739028a931..ccaa33b5817 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -387,6 +387,10 @@ struct diagnostic_context
      the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
      of a diagnostic's location.  */
   void (*set_locations_cb)(diagnostic_context *, diagnostic_info *);
+
+  /* Include files that diagnostic_report_current_module has already listed the
+     include path for.  */
+  hash_set<location_t, false, location_hash> *includes_seen;
 };
 
 static inline void
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 58139427d01..5c02ff05882 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -237,6 +237,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
   context->begin_group_cb = NULL;
   context->end_group_cb = NULL;
   context->final_cb = default_diagnostic_final_cb;
+  context->includes_seen = NULL;
 }
 
 /* Maybe initialize the color support. We require clients to do this
@@ -329,6 +330,12 @@ diagnostic_finish (diagnostic_context *context)
       delete context->edit_context_ptr;
       context->edit_context_ptr = NULL;
     }
+
+  if (context->includes_seen)
+    {
+      delete context->includes_seen;
+      context->includes_seen = nullptr;
+    }
 }
 
 /* Initialize DIAGNOSTIC, where the message MSG has already been
@@ -700,6 +707,31 @@ set_last_module (diagnostic_context *context, const line_map_ordinary *map)
   context->last_module = map;
 }
 
+/* Only dump the "In file included from..." stack once for each file.  */
+
+static bool
+includes_seen (diagnostic_context *context, const line_map_ordinary *map)
+{
+  /* No include path for main.  */
+  if (MAIN_FILE_P (map))
+    return true;
+
+  /* Always identify C++ modules, at least for now.  */
+  auto probe = map;
+  if (linemap_check_ordinary (map)->reason == LC_RENAME)
+    /* The module source file shows up as LC_RENAME inside LC_MODULE.  */
+    probe = linemap_included_from_linemap (line_table, map);
+  if (MAP_MODULE_P (probe))
+    return false;
+
+  if (!context->includes_seen)
+    context->includes_seen = new hash_set<location_t, false, location_hash>;
+
+  /* Hash the location of the #include directive to better handle files
+     that are included multiple times with different macros defined.  */
+  return context->includes_seen->add (linemap_included_from (map));
+}
+
 void
 diagnostic_report_current_module (diagnostic_context *context, location_t where)
 {
@@ -721,7 +753,7 @@ diagnostic_report_current_module (diagnostic_context *context, location_t where)
   if (map && last_module_changed_p (context, map))
     {
       set_last_module (context, map);
-      if (! MAIN_FILE_P (map))
+      if (!includes_seen (context, map))
 	{
 	  bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
 	  expanded_location s = {};
@@ -760,7 +792,7 @@ diagnostic_report_current_module (diagnostic_context *context, location_t where)
 			   "locus", s.file, line_col);
 	      first = false, need_inc = was_module, was_module = is_module;
 	    }
-	  while (! MAIN_FILE_P (map));
+	  while (!includes_seen (context, map));
 	  pp_verbatim (context->printer, ":");
 	  pp_newline (context->printer);
 	}
diff --git a/gcc/testsuite/c-c++-common/cpp/line-2.c b/gcc/testsuite/c-c++-common/cpp/line-2.c
index 97cf398f64c..364ad0e3931 100644
--- a/gcc/testsuite/c-c++-common/cpp/line-2.c
+++ b/gcc/testsuite/c-c++-common/cpp/line-2.c
@@ -8,4 +8,4 @@ int line4;
 
 // { dg-regexp {In file included from <command-line>:\n[^\n]*/line-2.h:4:2: error: #error wrong\n} }
 
-// { dg-regexp {[^\n]*/line-2.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\nIn file included from <command-line>:\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} }
+// { dg-regexp {[^\n]*/line-2.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} }
diff --git a/gcc/testsuite/c-c++-common/cpp/line-3.c b/gcc/testsuite/c-c++-common/cpp/line-3.c
index 2ffc44907a2..b254ae40041 100644
--- a/gcc/testsuite/c-c++-common/cpp/line-3.c
+++ b/gcc/testsuite/c-c++-common/cpp/line-3.c
@@ -15,6 +15,6 @@ int line4;
 
 // { dg-regexp {In file included from <command-line>:\n[^\n]*/line-2.h:4:2: error: #error wrong\n} }
 
-// { dg-regexp {[^\n]*/line-3.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\nIn file included from <command-line>:\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} }
+// { dg-regexp {[^\n]*/line-3.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} }
 
 // { dg-options "-fpreprocessed -fdirectives-only" }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-17 16:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-17 16:59 [gcc r12-6642] diagnostic: avoid repeating include path Jason Merrill

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