From: Jason Merrill Date: Fri, 17 Dec 2021 10:45:02 +0000 (-0500) Subject: diagnostic: avoid repeating include path X-Git-Tag: basepoints/gcc-13~1671 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3a57993359c9759990fe8f2aa4088684ed82190;p=thirdparty%2Fgcc.git diagnostic: avoid repeating include path When a sequence of diagnostic messages bounces back and forth repeatedly between two includes, as with #include std::map 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 --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 58139427d019..5c02ff05882c 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; + + /* 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 6739028a9312..ccaa33b58172 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 *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 97cf398f64cd..364ad0e39318 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 :\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 :\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 2ffc44907a27..b254ae400419 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 :\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 :\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" }