https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120792
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by David Malcolm <dmalc...@gcc.gnu.org>: https://gcc.gnu.org/g:2a521eee58da7c0d0f2262181b804aa148e60aaf commit r16-2274-g2a521eee58da7c0d0f2262181b804aa148e60aaf Author: David Malcolm <dmalc...@redhat.com> Date: Tue Jul 15 16:19:42 2025 -0400 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 <dmalc...@redhat.com>