Skip to content
Snippets Groups Projects
  • David Malcolm's avatar
    a5af2ec1
    diagnostics: add support for nested diagnostics [PR116253] · a5af2ec1
    David Malcolm authored
    
    Previously the diagnostic subsystem supported a one-deep
    hierarchy via auto_diagnostic_group, for associating
    notes with the warning/error they annotate; this only
    affects SARIF output, not text output.
    
    This patch adds support to the diagnostics subsystem for
    capturing arbitrarily deep nesting structure within
    diagnostic messages.
    
    This patch:
    * adds the ability to express nesting internally when
      building diagnostics
    * captures the nesting in SARIF output in the form documented
      in SG15's P3358R0 ("SARIF for Structured Diagnostics") via
      a "nestingLevel" property
    * adds a new experimental mode to text output to see the
      hierarchy, via:
      -fdiagnostics-set-output=text:experimental-nesting=yes
    * adds test coverage via a plugin, which with the above
      option emits:
      • note: child 0
        • note: grandchild 0 0
        • note: grandchild 0 1
        • note: grandchild 0 2
      • note: child 1
        • note: grandchild 1 0
        • note: grandchild 1 1
        • note: grandchild 1 2
      • note: child 2
        • note: grandchild 2 0
        • note: grandchild 2 1
        • note: grandchild 2 2
      using '*' rather than '•' if the text_art::theme is ascii-only.
    
    My hope is to eventually:
    (a) use this to improve C++'s template diagnostics
    (b) remove the "experimental" caveat from the the text output mode
    
    but this patch doesn't touch the C++ frontend, leaving both of these
    to followup work.
    
    gcc/c-family/ChangeLog:
    	PR other/116253
    	* c-opts.cc (c_diagnostic_text_finalizer): Use
    	text_output.build_indent_prefix for prefix to
    	diagnostic_show_locus.
    
    gcc/ChangeLog:
    	PR other/116253
    	* diagnostic-core.h (class auto_diagnostic_nesting_level): New.
    	* diagnostic-format-sarif.cc (class sarif_builder): Update leading
    	comment re nesting of diagnostics.
    	(sarif_result::on_nested_diagnostic): Add nestingLevel property.
    	* diagnostic-format-text.cc (on_report_diagnostic): If we're
    	showing nested diagnostics, then print changes of location on a
    	new line, indented, and update m_last_location.
    	(diagnostic_text_output_format::build_prefix): If m_show_nesting,
    	then potentially add indentation and a bullet point.
    	(get_bullet_point_unichar): New.
    	(use_unicode_p): New.
    	(diagnostic_text_output_format::build_indent_prefix): New.
    	* diagnostic-format-text.h
    	(diagnostic_text_output_format::diagnostic_text_output_format):
    	Initialize m_show_nesting and m_show_nesting_levels.
    	(diagnostic_text_output_format::build_indent_prefix): New decl.
    	(diagnostic_text_output_format::show_nesting_p): New accessor
    	(diagnostic_text_output_format::show_locations_in_nesting_p):
    	Likewise.
    	(diagnostic_text_output_format::set_show_nesting): New.
    	(diagnostic_text_output_format::set_show_locations_in_nesting):
    	New.
    	(diagnostic_text_output_format::set_show_nesting_levels): New.
    	(diagnostic_text_output_format::m_show_nesting): New field.
    	(diagnostic_text_output_format::m_show_locations_in_nesting): New
    	field.
    	(diagnostic_text_output_format::m_show_nesting_levels): New field.
    	* diagnostic-global-context.cc
    	(auto_diagnostic_nesting_level::auto_diagnostic_nesting_level):
    	New.
    	(auto_diagnostic_nesting_level::~auto_diagnostic_nesting_level):
    	New.
    	* diagnostic-show-locus.cc (layout_printer::print): Temporarily
    	set DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE.
    	* diagnostic.cc (diagnostic_context::initialize): Update for
    	renaming of m_nesting_depth to m_group_nesting_depth and
    	initialize m_diagnostic_nesting_level.
    	(diagnostic_context::finish): Update for renaming of
    	m_nesting_depth to m_group_nesting_depth.
    	(diagnostic_context::report_diagnostic): Likewise.
    	(diagnostic_context::begin_group): Likewise.
    	(diagnostic_context::end_group): Likewise.
    	(diagnostic_context::push_nesting_level): New.
    	(diagnostic_context::pop_nesting_level): New.
    	(diagnostic_context::set_diagnostic_buffer): Update for renaming
    	of m_nesting_depth to m_group_nesting_depth.  Assert that we don't
    	have nested diagnostics.
    	* diagnostic.h (diagnostic_context::push_nesting_level): New decl.
    	(diagnostic_context::pop_nesting_level): New decl.
    	(diagnostic_context::get_diagnostic_nesting_level): New accessor.
    	(diagnostic_context::build_indent_prefix): New decl.
    	(diagnostic_context::m_diagnostic_groups): Rename m_nesting_depth
    	to m_group_nesting_depth and add field m_diagnostic_nesting_level.
    	* doc/invoke.texi (fdiagnostics-add-output): Add note about
    	"experimental" schemes, keys, and values.  Add keys
    	"experimental-nesting", "experimental-nesting-show-locations",
    	and "experimental-nesting-show-levels" to text scheme.
    	* opts-diagnostic.cc (text_scheme_handler::make_sink): Add keys
    	"experimental-nesting", "experimental-nesting-show-locations",
    	and "experimental-nesting-show-levels".
    
    gcc/testsuite/ChangeLog:
    	PR other/116253
    	* gcc.dg/plugin/diagnostic-test-nesting-sarif.c: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-sarif.py: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c:
    	New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c:
    	New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented.c: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-plain.c: New test.
    	* gcc.dg/plugin/diagnostic_plugin_test_nesting.c: New test plugin.
    	* gcc.dg/plugin/plugin.exp: Add the above.
    
    Signed-off-by: default avatarDavid Malcolm <dmalcolm@redhat.com>
    a5af2ec1
    History
    diagnostics: add support for nested diagnostics [PR116253]
    David Malcolm authored
    
    Previously the diagnostic subsystem supported a one-deep
    hierarchy via auto_diagnostic_group, for associating
    notes with the warning/error they annotate; this only
    affects SARIF output, not text output.
    
    This patch adds support to the diagnostics subsystem for
    capturing arbitrarily deep nesting structure within
    diagnostic messages.
    
    This patch:
    * adds the ability to express nesting internally when
      building diagnostics
    * captures the nesting in SARIF output in the form documented
      in SG15's P3358R0 ("SARIF for Structured Diagnostics") via
      a "nestingLevel" property
    * adds a new experimental mode to text output to see the
      hierarchy, via:
      -fdiagnostics-set-output=text:experimental-nesting=yes
    * adds test coverage via a plugin, which with the above
      option emits:
      • note: child 0
        • note: grandchild 0 0
        • note: grandchild 0 1
        • note: grandchild 0 2
      • note: child 1
        • note: grandchild 1 0
        • note: grandchild 1 1
        • note: grandchild 1 2
      • note: child 2
        • note: grandchild 2 0
        • note: grandchild 2 1
        • note: grandchild 2 2
      using '*' rather than '•' if the text_art::theme is ascii-only.
    
    My hope is to eventually:
    (a) use this to improve C++'s template diagnostics
    (b) remove the "experimental" caveat from the the text output mode
    
    but this patch doesn't touch the C++ frontend, leaving both of these
    to followup work.
    
    gcc/c-family/ChangeLog:
    	PR other/116253
    	* c-opts.cc (c_diagnostic_text_finalizer): Use
    	text_output.build_indent_prefix for prefix to
    	diagnostic_show_locus.
    
    gcc/ChangeLog:
    	PR other/116253
    	* diagnostic-core.h (class auto_diagnostic_nesting_level): New.
    	* diagnostic-format-sarif.cc (class sarif_builder): Update leading
    	comment re nesting of diagnostics.
    	(sarif_result::on_nested_diagnostic): Add nestingLevel property.
    	* diagnostic-format-text.cc (on_report_diagnostic): If we're
    	showing nested diagnostics, then print changes of location on a
    	new line, indented, and update m_last_location.
    	(diagnostic_text_output_format::build_prefix): If m_show_nesting,
    	then potentially add indentation and a bullet point.
    	(get_bullet_point_unichar): New.
    	(use_unicode_p): New.
    	(diagnostic_text_output_format::build_indent_prefix): New.
    	* diagnostic-format-text.h
    	(diagnostic_text_output_format::diagnostic_text_output_format):
    	Initialize m_show_nesting and m_show_nesting_levels.
    	(diagnostic_text_output_format::build_indent_prefix): New decl.
    	(diagnostic_text_output_format::show_nesting_p): New accessor
    	(diagnostic_text_output_format::show_locations_in_nesting_p):
    	Likewise.
    	(diagnostic_text_output_format::set_show_nesting): New.
    	(diagnostic_text_output_format::set_show_locations_in_nesting):
    	New.
    	(diagnostic_text_output_format::set_show_nesting_levels): New.
    	(diagnostic_text_output_format::m_show_nesting): New field.
    	(diagnostic_text_output_format::m_show_locations_in_nesting): New
    	field.
    	(diagnostic_text_output_format::m_show_nesting_levels): New field.
    	* diagnostic-global-context.cc
    	(auto_diagnostic_nesting_level::auto_diagnostic_nesting_level):
    	New.
    	(auto_diagnostic_nesting_level::~auto_diagnostic_nesting_level):
    	New.
    	* diagnostic-show-locus.cc (layout_printer::print): Temporarily
    	set DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE.
    	* diagnostic.cc (diagnostic_context::initialize): Update for
    	renaming of m_nesting_depth to m_group_nesting_depth and
    	initialize m_diagnostic_nesting_level.
    	(diagnostic_context::finish): Update for renaming of
    	m_nesting_depth to m_group_nesting_depth.
    	(diagnostic_context::report_diagnostic): Likewise.
    	(diagnostic_context::begin_group): Likewise.
    	(diagnostic_context::end_group): Likewise.
    	(diagnostic_context::push_nesting_level): New.
    	(diagnostic_context::pop_nesting_level): New.
    	(diagnostic_context::set_diagnostic_buffer): Update for renaming
    	of m_nesting_depth to m_group_nesting_depth.  Assert that we don't
    	have nested diagnostics.
    	* diagnostic.h (diagnostic_context::push_nesting_level): New decl.
    	(diagnostic_context::pop_nesting_level): New decl.
    	(diagnostic_context::get_diagnostic_nesting_level): New accessor.
    	(diagnostic_context::build_indent_prefix): New decl.
    	(diagnostic_context::m_diagnostic_groups): Rename m_nesting_depth
    	to m_group_nesting_depth and add field m_diagnostic_nesting_level.
    	* doc/invoke.texi (fdiagnostics-add-output): Add note about
    	"experimental" schemes, keys, and values.  Add keys
    	"experimental-nesting", "experimental-nesting-show-locations",
    	and "experimental-nesting-show-levels" to text scheme.
    	* opts-diagnostic.cc (text_scheme_handler::make_sink): Add keys
    	"experimental-nesting", "experimental-nesting-show-locations",
    	and "experimental-nesting-show-levels".
    
    gcc/testsuite/ChangeLog:
    	PR other/116253
    	* gcc.dg/plugin/diagnostic-test-nesting-sarif.c: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-sarif.py: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented-show-levels.c:
    	New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented-unicode.c:
    	New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-indented.c: New test.
    	* gcc.dg/plugin/diagnostic-test-nesting-text-plain.c: New test.
    	* gcc.dg/plugin/diagnostic_plugin_test_nesting.c: New test plugin.
    	* gcc.dg/plugin/plugin.exp: Add the above.
    
    Signed-off-by: default avatarDavid Malcolm <dmalcolm@redhat.com>