aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-12-17 05:45:02 -0500
committerJason Merrill <jason@redhat.com>2022-01-17 11:58:12 -0500
commitd3a57993359c9759990fe8f2aa4088684ed82190 (patch)
tree82399b3aeabcffc665f0808ade49811306a04557 /gcc
parent450c85b81f4dd67bf6211d307afdc0f3c07ef44f (diff)
downloadgcc-d3a57993359c9759990fe8f2aa4088684ed82190.zip
gcc-d3a57993359c9759990fe8f2aa4088684ed82190.tar.gz
gcc-d3a57993359c9759990fe8f2aa4088684ed82190.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/diagnostic.c36
-rw-r--r--gcc/diagnostic.h4
-rw-r--r--gcc/testsuite/c-c++-common/cpp/line-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/cpp/line-3.c2
4 files changed, 40 insertions, 4 deletions
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 5813942..5c02ff0 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/diagnostic.h b/gcc/diagnostic.h
index 6739028..ccaa33b 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/testsuite/c-c++-common/cpp/line-2.c b/gcc/testsuite/c-c++-common/cpp/line-2.c
index 97cf398..364ad0e 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 2ffc449..b254ae4 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" }