On Thu, 2022-01-13 at 17:08 -0500, Jason Merrill wrote:
> 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.
> 
> Tested x86_64-pc-linux-gnu, OK for trunk?
> 
> gcc/ChangeLog:
> 
>         * diagnostic.c (includes_seen): New.
>         (diagnostic_report_current_module): Use it.
> ---
>  gcc/diagnostic.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
> index 58139427d01..e56441a2dbf 100644
> --- a/gcc/diagnostic.c
> +++ b/gcc/diagnostic.c
> @@ -700,6 +700,16 @@ 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 (const line_map_ordinary *map)
> +{
> +  using hset = hash_set<const line_map_ordinary *>;
> +  static hset *set = new hset;
> +  return set->add (map);
> +}

Overall, I like the idea, but...

- the patch works at the level of line_map_ordinary instances, rather
than header files.  There are various ways in which a single header
file can have multiple line maps e.g. due to very long lines, or
including another file, etc.  I think it makes sense to do it at the
per-file level, assuming we aren't in a horrible situation where a
header is being included repeatedly, with different effects.  So maybe
this ought to look at what include directive led to this map, i.e.
looking at the ord_map->included_from field, and having a
hash_set<location_t> ?

- there's no test coverage, but it's probably not feasible to write
DejaGnu tests for this, given the way prune.exp's prune_gcc_output
strips these strings.  Maybe a dg directive to selectively disable the
pertinent pruning operations in prune_gcc_output???  Gah...

- global state is a pet peeve of mine; can the above state be put
inside the diagnostic_context instead?   (perhaps via a pointer to a
wrapper class to avoid requiring all users of diagnostic.h to include
hash-set.h?).

Hope this is constructive
Dave

> +
>  void
>  diagnostic_report_current_module (diagnostic_context *context,
> location_t where)
>  {
> @@ -721,7 +731,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 (! MAIN_FILE_P (map) && !includes_seen (map))
>         {
>           bool first = true, need_inc = true, was_module =
> MAP_MODULE_P (map);
>           expanded_location s = {};
> 
> base-commit: b8ffa71e4271ae562c2d315b9b24c4979bbf8227
> prerequisite-patch-id: e45065ef320968d982923dd44da7bed07e3326ef


Reply via email to