Files
gcc-reflection/gcc/auto-obstack.h
David Malcolm 2a521eee58 libgdiagnostics: add diagnostic_message_buffer [PR120792]
This patch extends libgdiagnostics to provide a way to capture
the pp tokens making up a message string, so that SARIF and
HTML sinks can retain information such as event IDs and URLs.
As well as richer output, this improves the round-tripping of such
information through sarif-replay.

This also allows diagnostic messages to be built up in pieces,
with a drop-in replacement for fprintf, which I've found useful when
attempting to port "ld" to use libgdiagnostics.

gcc/ChangeLog:
	PR sarif-replay/120792
	* auto-obstack.h: New file, based on material taken from
	pretty-print.cc.
	* diagnostic-digraphs.h
	(diagnostics::digraphs::digraph::set_description): New.
	(diagnostics::digraphs::node::set_label): New.
	* doc/libgdiagnostics/topics/compatibility.rst: Add
	LIBGDIAGNOSTICS_ABI_4.
	* doc/libgdiagnostics/topics/diagnostics.rst
	(diagnostic_finish_via_msg_buf): Document new entrypoint.
	* doc/libgdiagnostics/topics/execution-paths.rst
	(diagnostic_execution_path_add_event_via_msg_buf): Document new
	entrypoint.
	* doc/libgdiagnostics/topics/index.rst: Add message-buffers.rst.
	* doc/libgdiagnostics/topics/message-buffers.rst: New file.
	* doc/libgdiagnostics/topics/message-formatting.rst: Add note
	about message buffers.
	* doc/libgdiagnostics/topics/physical-locations.rst
	(diagnostic_add_location_with_label_via_msg_buf): Add.
	* doc/libgdiagnostics/tutorial/07-execution-paths.rst: Link to
	next section.
	* doc/libgdiagnostics/tutorial/08-message-buffers.rst: New file.
	* doc/libgdiagnostics/tutorial/index.rst: Add
	08-message-buffers.rst.
	* libgdiagnostics++.h (libgdiagnostics::message_buffer): New
	class.
	(libgdiagnostics::execution_path::add_event_via_msg_buf): New.
	(libgdiagnostics::diagnostic::add_location_with_label): New.
	(libgdiagnostics::diagnostic::finish_via_msg_buf): New.
	(libgdiagnostics::graph::set_description): New overload.
	(libgdiagnostics::graph::add_edge): New overload.
	(libgdiagnostics::node::set_label): New overload.
	* libgdiagnostics-private.h
	(private_diagnostic_execution_path_add_event_2): Drop decl.
	(private_diagnostic_execution_path_add_event_3): New decl.
	* libgdiagnostics.cc:  Include "pretty-print-format-impl.h",
	"pretty-print-markup.h", and "auto-obstack.h".
	(class copying_token_printer): New.
	(struct diagnostic_message_buffer): New.
	(class pp_element_message_buffer): New.
	(libgdiagnostics_path_event::libgdiagnostics_path_event): Replace
	params "gmsgid" and "args" with "msg_buf".
	(libgdiagnostics_path_event::print_desc): Reimplement using
	pp_element_message_buffer to replay m_msg_buf into "pp".
	(libgdiagnostics_path_event::m_desc_uncolored): Drop field.
	(libgdiagnostics_path_event::m_desc_colored): Drop field.
	(libgdiagnostics_path_event::msg_buf): New field.
	(diagnostic_execution_path::add_event_va): Reimplement.
	(diagnostic_execution_path::add_event_via_msg_buf): New.
	(diagnostic::add_location_with_label): New overload, using
	msg_buf.
	(diagnostic_manager::emit): Reimplement with...
	(diagnostic_manager::emit_va): ...this.
	(diagnostic_manager::emit_msg_buf): New.
	(FAIL_IF_NULL): Rename "p" to "ptr_arg".
	(diagnostic_finish_va): Update to use diagnostic_manager::emit_va.
	(diagnostic_graph::add_node_with_id): Rename "id" to "node_id".
	(diagnostic_graph_add_node): Likewise.
	(diagnostic_graph_add_edge): Rename "id" to "edge_id".
	(diagnostic_graph_get_node_by_id): Rename "id" to "node_id".
	(diagnostic_graph_get_edge_by_id): Rename "id" to "edge_id".
	(private_diagnostic_execution_path_add_event_2): Delete.
	(diagnostic_message_buffer_new): New public entrypoint.
	(diagnostic_message_buffer_release): Likewise.
	(diagnostic_message_buffer_append_str): Likewise.
	(diagnostic_message_buffer_append_text): Likewise.
	(diagnostic_message_buffer_append_byte): Likewise.
	(diagnostic_message_buffer_append_printf): Likewise.
	(diagnostic_message_buffer_append_event_id): Likewise.
	(diagnostic_message_buffer_begin_url): Likewise.
	(diagnostic_message_buffer_end_url): Likewise.
	(diagnostic_message_buffer_begin_quote): Likewise.
	(diagnostic_message_buffer_end_quote): Likewise.
	(diagnostic_message_buffer_begin_color): Likewise.
	(diagnostic_message_buffer_end_color): Likewise.
	(diagnostic_message_buffer_dump): Likewise.
	(diagnostic_finish_via_msg_buf): Likewise.
	(diagnostic_add_location_with_label_via_msg_buf): Likewise.
	(diagnostic_execution_path_add_event_via_msg_buf): Likewise.
	(diagnostic_graph_set_description_via_msg_buf): Likewise.
	(diagnostic_graph_add_edge_via_msg_buf): Likewise.
	(diagnostic_node_set_label_via_msg_buf): Likewise.
	(private_diagnostic_execution_path_add_event_3): New private
	entrypoint.
	* libgdiagnostics.h (LIBGDIAGNOSTICS_PARAM_FORMAT_STRING): New macro.
	(LIBGDIAGNOSTICS_PARAM_PRINTF_FORMAT_STRING): New macro.
	(diagnostic_message_buffer): New typedef.
	(LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer): New define.
	(diagnostic_message_buffer_new): New decl.
	(diagnostic_message_buffer_release): New decl.
	(diagnostic_message_buffer_append_str): New decl.
	(diagnostic_message_buffer_append_text): New decl.
	(diagnostic_message_buffer_append_byte): New decl.
	(diagnostic_message_buffer_append_printf): New decl.
	(diagnostic_message_buffer_append_event_id): New decl.
	(diagnostic_message_buffer_begin_url): New decl.
	(diagnostic_message_buffer_end_url): New decl.
	(diagnostic_message_buffer_begin_quote): New decl.
	(diagnostic_message_buffer_end_quote): New decl.
	(diagnostic_message_buffer_begin_color): New decl.
	(diagnostic_message_buffer_end_color): New decl.
	(diagnostic_message_buffer_dump): New decl.
	(diagnostic_finish_via_msg_buf): New decl.
	(diagnostic_add_location_with_label_via_msg_buf): New decl.
	(diagnostic_execution_path_add_event_via_msg_buf): New decl.
	(diagnostic_graph_set_description_via_msg_buf): New decl.
	(diagnostic_graph_add_edge_via_msg_buf): New decl.
	(diagnostic_node_set_label_via_msg_buf): New decl.
	* libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_3): Drop
	private_diagnostic_execution_path_add_event_2.
	(LIBGDIAGNOSTICS_ABI_4): New.
	* libsarifreplay.cc (class annotation): Use
	libgdiagnostics::message_buffer rather than label_text.
	(add_any_annotations): Likewise.
	(sarif_replayer::handle_result_obj): Likewise.
	(make_plain_text_within_result_message): Likewise.
	(handle_thread_flow_location_object): Likewise.
	(handle_location_object): Likewise.
	(sarif_replayer::handle_graph_object): Likewise.
	(sarif_replayer::handle_node_object): Likewise.
	(sarif_replayer::handle_edge_object): Likewise.
	* pretty-print-format-impl.h (pp_token_list::push_back_byte): New
	decl.
	* pretty-print-markup.h (pp_markup::context::begin_url): New decl.
	(pp_markup::context::end_url): New decl.
	(pp_markup::context::add_event_id): New decl.
	* pretty-print.cc: Include "auto-obstack.h".
	(pp_token_list::push_back_byte): New.
	(struct auto_obstack): Move to auto-obstack.h.
	(default_token_printer): Make non-static.
	(pp_markup::context::begin_url): New.
	(pp_markup::context::end_url): New.
	(pp_markup::context::add_event_id): New.

gcc/testsuite/ChangeLog:
	PR sarif-replay/120792
	* libgdiagnostics.dg/sarif.py: Delete duplicate script.
	* libgdiagnostics.dg/test-message-buffer-c.py: New test script.
	* libgdiagnostics.dg/test-message-buffer.c: New test.
	* libgdiagnostics.dg/test-warning-with-path-c.py: Update expected
	output to reflect that SARIF for event messages now contains JSON
	pointers when referring to other events by ID.
	* sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif: Add
	HTML and SARIF output, and call out to Python scripts to verify
	the output.  Add example of a result with a link in its message.
	* sarif-replay.dg/2.1.0-valid/embedded-links-check-html.py: New
	test script.
	* sarif-replay.dg/2.1.0-valid/embedded-links-check-sarif-roundtrip.py:
	New test script.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2025-07-15 16:19:42 -04:00

59 lines
1.3 KiB
C

/* RAII wrapper around obstack.
Copyright (C) 2024-2025 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_AUTO_OBSTACK_H
#define GCC_AUTO_OBSTACK_H
/* RAII wrapper around obstack. */
struct auto_obstack
{
auto_obstack ()
{
obstack_init (&m_obstack);
}
~auto_obstack ()
{
obstack_free (&m_obstack, NULL);
}
operator obstack & () { return m_obstack; }
void grow (const void *src, size_t length)
{
obstack_grow (&m_obstack, src, length);
}
void *object_base () const
{
return m_obstack.object_base;
}
size_t object_size () const
{
return obstack_object_size (&m_obstack);
}
obstack m_obstack;
};
#endif /* GCC_AUTO_OBSTACK_H */