From bc3597635a708cd91d742c91c6050829cfb4062a Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 29 Nov 2024 18:13:22 -0500 Subject: Rename "libdiagnostics" to "libgdiagnostics" "libdiagnostics" clashes with an existing soname in Debian, as per: https://gcc.gnu.org/pipermail/gcc/2024-November/245175.html Rename it to "libgdiagnostics" for uniqueness. I am being deliberately vague about what the "g" stands for: it could be "gnu", "gcc", or "gpl-licensed" as the reader desires. ChangeLog: * configure.ac: Rename "libdiagnostics" to "libgdiagnostics". * configure: Regenerate. gcc/ChangeLog: * Makefile.in: Rename "libdiagnostics" to "libgdiagnostics". * configure.ac: Likewise. * configure: Regenerate. * doc/install.texi: Rename "libdiagnostics" to "libgdiagnostics". * doc/libdiagnostics/*: Rename to doc/libgdiagnostics, renaming "libdiagnostics" to "libgdiagnostics" throughout. * libdiagnostics++.h: Rename to... * libgdiagnostics++.h: ...this, renaming "libdiagnostics" to "libgdiagnostics" throughout. * libdiagnostics.cc: Rename to... * libgdiagnostics.cc: ...this, renaming "libdiagnostics" to "libgdiagnostics" throughout. * libdiagnostics.h: Rename to... * libgdiagnostics.h: ...this, renaming "libdiagnostics" to "libgdiagnostics" throughout. * libdiagnostics.map: Rename to... * libgdiagnostics.map: ...this, renaming "libdiagnostics" to "libgdiagnostics" throughout. * libsarifreplay.cc: Update for renaming of "libdiagnostics" to "libgdiagnostics". * libsarifreplay.h: Likewise. * sarif-replay.cc: Likewise. gcc/testsuite/ChangeLog: * libdiagnostics.dg/*: Rename to libgdiagnostics.dg, renaming "libdiagnostics" to "libgdiagnostics" throughout. Signed-off-by: David Malcolm --- gcc/doc/install.texi | 6 +- gcc/doc/libdiagnostics/Makefile | 20 -- gcc/doc/libdiagnostics/conf.py | 27 -- gcc/doc/libdiagnostics/index.rst | 113 --------- gcc/doc/libdiagnostics/make.bat | 35 --- .../libdiagnostics/topics/diagnostic-manager.rst | 58 ----- gcc/doc/libdiagnostics/topics/diagnostics.rst | 127 ---------- gcc/doc/libdiagnostics/topics/execution-paths.rst | 93 ------- gcc/doc/libdiagnostics/topics/fix-it-hints.rst | 135 ---------- gcc/doc/libdiagnostics/topics/index.rst | 38 --- .../libdiagnostics/topics/logical-locations.rst | 109 -------- .../libdiagnostics/topics/message-formatting.rst | 224 ---------------- gcc/doc/libdiagnostics/topics/metadata.rst | 149 ----------- .../libdiagnostics/topics/physical-locations.rst | 281 --------------------- gcc/doc/libdiagnostics/topics/retrofitting.rst | 23 -- gcc/doc/libdiagnostics/topics/sarif.rst | 51 ---- gcc/doc/libdiagnostics/topics/text-output.rst | 87 ------- gcc/doc/libdiagnostics/topics/ux.rst | 26 -- gcc/doc/libdiagnostics/tutorial/01-hello-world.rst | 173 ------------- .../tutorial/02-physical-locations.rst | 260 ------------------- .../tutorial/03-logical-locations.rst | 60 ----- gcc/doc/libdiagnostics/tutorial/04-notes.rst | 66 ----- gcc/doc/libdiagnostics/tutorial/05-warnings.rst | 44 ---- .../libdiagnostics/tutorial/06-fix-it-hints.rst | 61 ----- .../libdiagnostics/tutorial/07-execution-paths.rst | 141 ----------- gcc/doc/libdiagnostics/tutorial/example-1.png | Bin 5646 -> 0 bytes gcc/doc/libdiagnostics/tutorial/index.rst | 32 --- gcc/doc/libgdiagnostics/Makefile | 20 ++ gcc/doc/libgdiagnostics/conf.py | 27 ++ gcc/doc/libgdiagnostics/index.rst | 113 +++++++++ gcc/doc/libgdiagnostics/make.bat | 35 +++ .../libgdiagnostics/topics/diagnostic-manager.rst | 58 +++++ gcc/doc/libgdiagnostics/topics/diagnostics.rst | 127 ++++++++++ gcc/doc/libgdiagnostics/topics/execution-paths.rst | 93 +++++++ gcc/doc/libgdiagnostics/topics/fix-it-hints.rst | 135 ++++++++++ gcc/doc/libgdiagnostics/topics/index.rst | 38 +++ .../libgdiagnostics/topics/logical-locations.rst | 109 ++++++++ .../libgdiagnostics/topics/message-formatting.rst | 224 ++++++++++++++++ gcc/doc/libgdiagnostics/topics/metadata.rst | 149 +++++++++++ .../libgdiagnostics/topics/physical-locations.rst | 281 +++++++++++++++++++++ gcc/doc/libgdiagnostics/topics/retrofitting.rst | 23 ++ gcc/doc/libgdiagnostics/topics/sarif.rst | 51 ++++ gcc/doc/libgdiagnostics/topics/text-output.rst | 87 +++++++ gcc/doc/libgdiagnostics/topics/ux.rst | 26 ++ .../libgdiagnostics/tutorial/01-hello-world.rst | 173 +++++++++++++ .../tutorial/02-physical-locations.rst | 260 +++++++++++++++++++ .../tutorial/03-logical-locations.rst | 60 +++++ gcc/doc/libgdiagnostics/tutorial/04-notes.rst | 66 +++++ gcc/doc/libgdiagnostics/tutorial/05-warnings.rst | 44 ++++ .../libgdiagnostics/tutorial/06-fix-it-hints.rst | 61 +++++ .../tutorial/07-execution-paths.rst | 141 +++++++++++ gcc/doc/libgdiagnostics/tutorial/example-1.png | Bin 0 -> 5646 bytes gcc/doc/libgdiagnostics/tutorial/index.rst | 32 +++ 53 files changed, 2436 insertions(+), 2436 deletions(-) delete mode 100644 gcc/doc/libdiagnostics/Makefile delete mode 100644 gcc/doc/libdiagnostics/conf.py delete mode 100644 gcc/doc/libdiagnostics/index.rst delete mode 100644 gcc/doc/libdiagnostics/make.bat delete mode 100644 gcc/doc/libdiagnostics/topics/diagnostic-manager.rst delete mode 100644 gcc/doc/libdiagnostics/topics/diagnostics.rst delete mode 100644 gcc/doc/libdiagnostics/topics/execution-paths.rst delete mode 100644 gcc/doc/libdiagnostics/topics/fix-it-hints.rst delete mode 100644 gcc/doc/libdiagnostics/topics/index.rst delete mode 100644 gcc/doc/libdiagnostics/topics/logical-locations.rst delete mode 100644 gcc/doc/libdiagnostics/topics/message-formatting.rst delete mode 100644 gcc/doc/libdiagnostics/topics/metadata.rst delete mode 100644 gcc/doc/libdiagnostics/topics/physical-locations.rst delete mode 100644 gcc/doc/libdiagnostics/topics/retrofitting.rst delete mode 100644 gcc/doc/libdiagnostics/topics/sarif.rst delete mode 100644 gcc/doc/libdiagnostics/topics/text-output.rst delete mode 100644 gcc/doc/libdiagnostics/topics/ux.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/01-hello-world.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/02-physical-locations.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/03-logical-locations.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/04-notes.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/05-warnings.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/06-fix-it-hints.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/07-execution-paths.rst delete mode 100644 gcc/doc/libdiagnostics/tutorial/example-1.png delete mode 100644 gcc/doc/libdiagnostics/tutorial/index.rst create mode 100644 gcc/doc/libgdiagnostics/Makefile create mode 100644 gcc/doc/libgdiagnostics/conf.py create mode 100644 gcc/doc/libgdiagnostics/index.rst create mode 100644 gcc/doc/libgdiagnostics/make.bat create mode 100644 gcc/doc/libgdiagnostics/topics/diagnostic-manager.rst create mode 100644 gcc/doc/libgdiagnostics/topics/diagnostics.rst create mode 100644 gcc/doc/libgdiagnostics/topics/execution-paths.rst create mode 100644 gcc/doc/libgdiagnostics/topics/fix-it-hints.rst create mode 100644 gcc/doc/libgdiagnostics/topics/index.rst create mode 100644 gcc/doc/libgdiagnostics/topics/logical-locations.rst create mode 100644 gcc/doc/libgdiagnostics/topics/message-formatting.rst create mode 100644 gcc/doc/libgdiagnostics/topics/metadata.rst create mode 100644 gcc/doc/libgdiagnostics/topics/physical-locations.rst create mode 100644 gcc/doc/libgdiagnostics/topics/retrofitting.rst create mode 100644 gcc/doc/libgdiagnostics/topics/sarif.rst create mode 100644 gcc/doc/libgdiagnostics/topics/text-output.rst create mode 100644 gcc/doc/libgdiagnostics/topics/ux.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/01-hello-world.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/02-physical-locations.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/03-logical-locations.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/04-notes.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/05-warnings.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/06-fix-it-hints.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/07-execution-paths.rst create mode 100644 gcc/doc/libgdiagnostics/tutorial/example-1.png create mode 100644 gcc/doc/libgdiagnostics/tutorial/index.rst (limited to 'gcc/doc') diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 03575c2..97d9aaf 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1231,8 +1231,8 @@ virtual calls in verifiable mode at all. However the libvtv library will still be built (see @option{--disable-libvtv} to turn off building libvtv). @option{--disable-vtable-verify} is the default. -@item --enable-libdiagnostics -Specify whether to build @code{libdiagnostics}, a shared library exposing +@item --enable-libgdiagnostics +Specify whether to build @code{libgdiagnostics}, a shared library exposing GCC's diagnostics capabilities via a C API, and a C++ wrapper API adding ``syntactic sugar''. @@ -1241,7 +1241,7 @@ This option requires @option{--enable-host-shared} on non-Windows hosts. This option also enables @code{sarif-replay}, a command-line tool for viewing @uref{https://sarif.info/,,SARIF files}. @code{sarif-replay} takes one or more @code{.sarif} files as input and attempts to replay any -diagnostics within them to stderr (via @code{libdiagnostics}) in the style +diagnostics within them to stderr (via @code{libgdiagnostics}) in the style of GCC's diagnostics. @item --disable-gcov diff --git a/gcc/doc/libdiagnostics/Makefile b/gcc/doc/libdiagnostics/Makefile deleted file mode 100644 index d4bb2cb..0000000 --- a/gcc/doc/libdiagnostics/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/gcc/doc/libdiagnostics/conf.py b/gcc/doc/libdiagnostics/conf.py deleted file mode 100644 index 1ff7552..0000000 --- a/gcc/doc/libdiagnostics/conf.py +++ /dev/null @@ -1,27 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'libdiagnostics' -copyright = '2024, David Malcolm' -author = 'David Malcolm' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [] - -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = 'alabaster' -html_static_path = ['_static'] diff --git a/gcc/doc/libdiagnostics/index.rst b/gcc/doc/libdiagnostics/index.rst deleted file mode 100644 index a05eb4e..0000000 --- a/gcc/doc/libdiagnostics/index.rst +++ /dev/null @@ -1,113 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -libdiagnostics -============== - -This document describes `libdiagnostics `_, -an API for programs to use to emit diagnostics (such as for "lint"-style checker -tools), supporting: - -* text output similar to GCC's errors and warnings:: - - test-typo.c:19:13: error: unknown field 'colour' - 19 | return p->colour; - | ^~~~~~ - - quoting pertinent source code (with a cache), and underlining - :doc:`points and ranges in the files being tested `, - possibly with labels:: - - test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' - 19 | 42 + "foo" - | ~~ ^ ~~~~~ - | | | - | int const char * - -* emitting :doc:`fix-it hints `:: - - test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color' - 19 | return p->colour; - | ^~~~~~ - | color - - and generating patches from them:: - - @@ -16,7 +16,7 @@ - struct rgb - get_color (struct object *p) - { - - return p->colour; - + return p->color; - } - -* capturing :doc:`execution paths` through code:: - - In function 'make_a_list_of_random_ints_badly': - test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter" - 30 | PyList_Append(list, item); - | ^~~~~~~~~~~~~~~~~~~~~~~~~ - make_a_list_of_random_ints_badly': events 1-3 - 26 | list = PyList_New(0); - | ^~~~~~~~~~~~~ - | | - | (1) when 'PyList_New' fails, returning NULL - 27 | - 28 | for (i = 0; i < count; i++) { - | ~~~~~~~~~ - | | - | (2) when 'i < count' - 29 | item = PyLong_FromLong(random()); - 30 | PyList_Append(list, item); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 - -* support for emitting machine-readable representations of the above - using the :doc:`SARIF file format ` - -There are actually two APIs for the library: - -* a pure C API: ``libdiagnostics.h`` - -* a C++ wrapper API: ``libdiagnostics+.h``. This is a header-only - collection of wrapper classes around the C API to give a less - verbose API. - -This documentation covers the C API. - -Contents -******** - -.. toctree:: - :maxdepth: 2 - - tutorial/index.rst - topics/index.rst - -libdiagnostics 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 of the License, or -(at your option) any later version. - - -Indices and tables -****************** - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/gcc/doc/libdiagnostics/make.bat b/gcc/doc/libdiagnostics/make.bat deleted file mode 100644 index 954237b..0000000 --- a/gcc/doc/libdiagnostics/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/gcc/doc/libdiagnostics/topics/diagnostic-manager.rst b/gcc/doc/libdiagnostics/topics/diagnostic-manager.rst deleted file mode 100644 index 7f86f6b..0000000 --- a/gcc/doc/libdiagnostics/topics/diagnostic-manager.rst +++ /dev/null @@ -1,58 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Diagnostic Managers -=================== - -.. type:: diagnostic_manager; - -A :type:`diagnostic_manager` is an opaque bundle of state for a client of -libdiagnostics. - -It has zero of more "output sinks" to which diagnostics are emitted. - -Responsibilities include: - -* location-management - -* caching of source file content - -* patch generation - -.. function:: diagnostic_manager *diagnostic_manager_new (void) - - Create a new diagnostic_manager. - The caller will need to call :func:`diagnostic_release_manager` - on it at some point. - - .. note:: No output sinks are created by default; so you will want - to create one with something like: - - .. code-block:: - - diagnostic_manager_add_text_sink (diag_mgr, stderr, - DIAGNOSTIC_COLORIZE_IF_TTY); - -.. function:: void diagnostic_manager_release (diagnostic_manager *diag_mgr) - - Release a diagnostic_manager. - - This will flush output to all of the output sinks, and clean up. - - The parameter must be non-NULL. diff --git a/gcc/doc/libdiagnostics/topics/diagnostics.rst b/gcc/doc/libdiagnostics/topics/diagnostics.rst deleted file mode 100644 index 66f0a25..0000000 --- a/gcc/doc/libdiagnostics/topics/diagnostics.rst +++ /dev/null @@ -1,127 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Diagnostics -=========== - -.. type:: diagnostic - -A :type:`diagnostic` is an opaque bundle of state for a particular -diagnostic that is being constructed in memory. - - -Lifecycle of a diagnostic -************************* - -Diagnostics are - -* *created* from a :type:`diagnostic_manager` by using - :func:`diagnostic_begin`, then - -* *populated* with data, such as physical locations, logical locations, - metadata, execution paths, or fix-it hints, then - -* *finished*, in which a formatting string and arguments are given, - via a call to :func:`diagnostic_finish` or :func:`diagnostic_finish_va`. - The :type:`diagnostic_manager` will emit the diagnostic to all of the - manager's output sinks (either immediately, or at some later time, - depending on the sink). - - Once a :type:`diagnostic` has had one of these "finish" functions called - on it, it is freed, and is no longer valid for use. - - The formatting strings use their own syntax; see :doc:`message-formatting`. - -.. function:: diagnostic *diagnostic_begin (diagnostic_manager *diag_mgr, \ - enum diagnostic_level level) - - Create a new :type:`diagnostic` associated with the given - :type:`diagnostic_manager`. - - The parameter ``diag_mgr`` must be non-NULL. - - The parameter ``level`` describes the severity of the diagnostic. - -.. enum:: diagnostic_level - - This enum describes the severity of a particular diagnostic. - - .. macro:: DIAGNOSTIC_LEVEL_ERROR - - A problem sufficiently severe that the program cannot successfully - complete, or where the input being analyzed is definitely wrong - (e.g. malformed). - - .. macro:: DIAGNOSTIC_LEVEL_WARNING - - A problem where the input is technically correct, but is likely - not what the user intended, such as common mistakes, or other - unusual conditions that *may* indicate trouble, such as use of - obsolete features. - - .. macro:: DIAGNOSTIC_LEVEL_NOTE - - A supplementary message added to another :type:`diagnostic`, giving - extra information that may help the user understand it. - - .. macro:: DIAGNOSTIC_LEVEL_SORRY - - A problem where the input is valid, but the tool isn't - able to handle it. - -.. function:: void diagnostic_finish (diagnostic *diag, const char *fmt, ...) - - Emit ``diag`` to all sinks of its manager, and release ``diag``. It is not - valid to use ``diag`` after this call. - - Use parameter ``fmt`` for the message. - Note that this uses gcc's pretty-print format, which is *not* printf. - See :doc:`message-formatting`. - - Both ``diag`` and ``fmt`` must be non-NULL. - - TODO: who is responsible for putting FMT through gettext? - -.. function:: void diagnostic_finish_va (diagnostic *diag, const char *fmt, va_list *args) - - This is equivalent to :func:`diagnostic_finish`, but using a - :type:`va_list` rather than directly taking variadic arguments. - - All three parameters must be non-NULL. - - -Diagnostic groups -***************** - -See :doc:`the "adding notes" section of the tutorial <../tutorial/04-notes>` -for an example of a diagnostic group. - -.. function:: void diagnostic_manager_begin_group (diagnostic_manager *diag_mgr) - - Begin a diagnostic group. All diagnostics emitted within - ``diag_mgr`` after the first one will be treated as additional information - relating to the initial diagnostic. - - The parameter ``diag_mgr`` must be non-NULL. - -.. function:: void diagnostic_manager_end_group (diagnostic_manager *diag_mgr) - - Finish a diagnostic group. - - The parameter ``diag_mgr`` must be non-NULL. diff --git a/gcc/doc/libdiagnostics/topics/execution-paths.rst b/gcc/doc/libdiagnostics/topics/execution-paths.rst deleted file mode 100644 index 3f4109c..0000000 --- a/gcc/doc/libdiagnostics/topics/execution-paths.rst +++ /dev/null @@ -1,93 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Execution paths -=============== - -.. type:: diagnostic_execution_path - -A :type:`diagnostic` can optionally contain a :type:`diagnostic_execution_path` -describing a path of execution through code. - -.. function:: diagnostic_execution_path * diagnostic_add_execution_path (diagnostic *diag) - - Create and borrow a pointer to an execution path for ``diag``. - - The path is automatically cleaned up when ``diag`` is finished. - - ``diag`` must be non-NULL. - -.. function:: diagnostic_execution_path * diagnostic_manager_new_execution_path (diagnostic_manager *diag_mgr) - - Create a new execution path. This is owned by the caller and must have either - :func:`diagnostic_take_execution_path` or - :func:`diagnostic_execution_path_release` called on it. - - ``diag_mgr`` must be non-NULL. - -.. function:: void diagnostic_take_execution_path (diagnostic *diag, diagnostic_execution_path *path) - - Set ``diag`` to use ``path`` as its execution path, taking ownership of ``path``. - - Both parameters must be non-NULL. - -.. function:: void diagnostic_execution_path_release (diagnostic_execution_path *path) - - Release ownership of ``path``, which must not have been taken by a diagnostic. - -.. type:: diagnostic_event_id - -A :type:`diagnostic_event_id` identifies a particular event within a -:type:`diagnostic_execution_path` and can be used for expressing -cross-references between events. In particular FIXME - -.. function:: diagnostic_event_id diagnostic_execution_path_add_event (diagnostic_execution_path *path, \ - const diagnostic_physical_location *physical_loc, \ - const diagnostic_logical_location *logical_loc, \ - unsigned stack_depth, \ - const char *fmt, ...) - - Append an event to the end of ``path``, which must be non-NULL. - - ``physical_loc`` can be NULL, or non-NULL to associate the event - with a :type:`diagnostic_physical_location`. - - ``logical_loc`` can be NULL, or non-NULL to associate the event - with a :type:`diagnostic_logical_location`. - - ``stack_depth`` is for use in interprocedural paths and identifies the - depth of the stack at the event. Purely intraprocedural paths should - use a stack depth of 1 for their events - - ``fmt`` must be non-NULL. See :doc:`message-formatting` for details of - how to use it. - -.. function:: diagnostic_event_id diagnostic_execution_path_add_event_va (diagnostic_execution_path *path, \ - const diagnostic_physical_location *physical_loc, \ - const diagnostic_logical_location *logical_loc, \ - unsigned stack_depth, \ - const char *fmt, \ - va_list *args) - - Equivalent to :func:`diagnostic_execution_path_add_event`, but using a - :type:`va_list` rather than directly taking variadic arguments. - -Paths are printed to text sinks, and for SARIF sinks each path is added as -a ``codeFlow`` object (see SARIF 2.1.0 -`3.36 codeFlow object `_). diff --git a/gcc/doc/libdiagnostics/topics/fix-it-hints.rst b/gcc/doc/libdiagnostics/topics/fix-it-hints.rst deleted file mode 100644 index 08acb71..0000000 --- a/gcc/doc/libdiagnostics/topics/fix-it-hints.rst +++ /dev/null @@ -1,135 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Fix-it hints -============ - -Adding fix-it hints to a diagnostic -*********************************** - -A :type:`diagnostic` can contain "fix-it hints", giving suggestions -for the user on how to edit their code to fix a problem. These -can be expressed as insertions, replacements, and removals of text. - -There is only limited support for newline characters in fix-it hints: -only hints with newlines which insert an entire new line are permitted, -inserting at the start of a line, and finishing with a newline -(with no interior newline characters). Other attempts to add -fix-it hints containing newline characters will fail. -Similarly, attempts to delete or replace a range *affecting* multiple -lines will fail. - -The API handles these failures gracefully, so that diagnostics can attempt -to add fix-it hints without each needing extensive checking. - -Fix-it hints are printed to text sinks, and are emitted by SARIF sinks -as ``fix`` objects (see SARIF 2.1.0 -`3.55 fix object `_). - -Fix-it hints within a :type:`diagnostic` are "atomic": if any hints can't -be applied, none of them will be, and no fix-its hints will be displayed -for that diagnostic. This implies that diagnostic messages need to be worded -in such a way that they make sense whether or not the fix-it hints -are displayed. - -All fix-it hints within one :type:`diagnostic` must affect the same -:type:`diagnostic_file`. - -.. function:: void diagnostic_add_fix_it_hint_insert_before (diagnostic *diag, \ - const diagnostic_physical_location *loc, \ - const char *addition) - - Add a fix-it hint to ``diag`` suggesting the insertion of the string - ``addition`` before ``LOC``. - - For example:: - - ptr = arr[0]; - ^~~~~~ - & - - This :type:`diagnostic` has a single location covering ``arr[0]``, - with the caret at the start. It has a single insertion fix-it hint, - inserting ``&`` before the start of ``loc``. - -.. function:: void diagnostic_add_fix_it_hint_insert_after (diagnostic *diag, \ - const diagnostic_physical_location *loc, \ - const char *addition) - - Add a fix-it hint to ``diag`` suggesting the insertion of the string - ``addition`` after the end of ``LOC``. - - For example, in:: - - #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2) - ^~~~ ^~~~ ^~~~ - ( ) ( ) ( ) - - - the :type:`diagnostic` has three physical locations, covering ``ARG0``, - ``ARG1``, and ``ARG2``, and 6 insertion fix-it hints: each arg - has a pair of insertion fix-it hints, suggesting wrapping - them with parentheses: one a '(' inserted before, - the other a ')' inserted after. - -.. function:: void diagnostic_add_fix_it_hint_replace (diagnostic *diag, \ - const diagnostic_physical_location *loc, \ - const char *replacement) - - Add a fix-it hint to ``diag`` suggesting the replacement of the text - at ``LOC`` with the string ``replacement``. - - For example, in:: - - c = s.colour; - ^~~~~~ - color - - This :type:`diagnostic` has a single physical location covering ``colour``, - and a single "replace" fix-it hint, covering the same range, suggesting - replacing it with ``color``. - -.. function:: void diagnostic_add_fix_it_hint_delete (diagnostic *diag, \ - const diagnostic_physical_location *loc) - - Add a fix-it hint to ``diag`` suggesting the deletion of the text - at ``LOC``. - - - For example, in:: - - struct s {int i};; - ^ - - - - This :type:`diagnostic` has a single physical location at the stray - trailing semicolon, along with a single removal fix-it hint, covering - the same location. - - -Generating patches -****************** - -.. function:: void diagnostic_manager_write_patch (diagnostic_manager *diag_mgr, \ - FILE *dst_stream) - - Write a patch to ``dst_stream`` consisting of the effect of all fix-it hints - on all diagnostics that have been finished on ``diag_mgr``. - - Both parameters must be non-NULL. diff --git a/gcc/doc/libdiagnostics/topics/index.rst b/gcc/doc/libdiagnostics/topics/index.rst deleted file mode 100644 index 064340b..0000000 --- a/gcc/doc/libdiagnostics/topics/index.rst +++ /dev/null @@ -1,38 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - - -Topic reference -=============== - -.. toctree:: - :maxdepth: 2 - - retrofitting.rst - diagnostic-manager.rst - diagnostics.rst - message-formatting.rst - physical-locations.rst - logical-locations.rst - metadata.rst - fix-it-hints.rst - execution-paths.rst - text-output.rst - sarif.rst - ux.rst diff --git a/gcc/doc/libdiagnostics/topics/logical-locations.rst b/gcc/doc/libdiagnostics/topics/logical-locations.rst deleted file mode 100644 index 85900b6..0000000 --- a/gcc/doc/libdiagnostics/topics/logical-locations.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Logical locations -================= - -A "logical" location is a location expressed in terms of -construct in a programming language, such as ``within function 'foo'`` -(as opposed to a :doc:`"physical" location `, which -refers to a specific file, and line(s) and/or column(s)) - -Creating location information -***************************** - -.. type:: diagnostic_logical_location - -A :type:`diagnostic_logical_location` is an opaque type describing a "logical" -source location - -.. function:: const diagnostic_logical_location * diagnostic_manager_new_logical_location (diagnostic_manager *diag_mgr, \ - enum diagnostic_logical_location_kind_t kind, \ - const diagnostic_logical_location *parent, \ - const char *short_name, \ - const char *fully_qualified_name, \ - const char *decorated_name) - - Create a :type:`diagnostic_logical_location`. - - ``diag_mgr`` must be non-NULL. - - ``kind`` describes the kind of logical location: - - .. enum:: diagnostic_logical_location_kind_t - - This roughly corresponds to the ``kind`` property in SARIF v2.1.0 - (`§3.33.7 `_). - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER - - .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE - - ``parent`` can be NULL; if non-NULL it can be used to express tree-like - nesting of logical locations, such as in:: - - namespace foo { namespace bar { class baz { baz (); }; } } - - where a diagnostic within ``baz``'s constructor could be reported - as being within ``foo::bar::baz::baz`` where the logical locations - are two namespaces, a type, and a member, respectively. - - ``short_name`` can be NULL, or else a string suitable for use by - the SARIF logicalLocation ``name`` property - (SARIF v2.1.0 `§3.33.4 `_). - - ``fully_qualified_name`` can be NULL or else a string suitable for use by - the SARIF logicalLocation ``fullyQualifiedName`` property - (SARIF v2.1.0 `§3.33.5 `_). - - ``decorated_name`` can be NULL or else a string suitable for use by - the SARIF logicalLocation ``decoratedName`` property - (SARIF v2.1.0 `§3.33.6 `_). - -.. function:: void diagnostic_manager_debug_dump_logical_location (const diagnostic_manager *diag_mgr, \ - const diagnostic_logical_location *loc, \ - FILE *out) - - Write a representation of ``file`` to ``out``, for debugging. - Both ``diag_mgr`` and ``out`` must be non-NULL. - ``file`` may be NULL. - - TODO: example of output - -Associating diagnostics with locations -************************************** - -.. function:: void diagnostic_set_logical_location (diagnostic *diag, \ - const diagnostic_logical_location *logical_loc) - - Set the logical location of ``diag``. - - ``diag`` must be non-NULL; ``logical_loc`` can be NULL. diff --git a/gcc/doc/libdiagnostics/topics/message-formatting.rst b/gcc/doc/libdiagnostics/topics/message-formatting.rst deleted file mode 100644 index 9d42f89..0000000 --- a/gcc/doc/libdiagnostics/topics/message-formatting.rst +++ /dev/null @@ -1,224 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Message formatting -================== - -Various libdiagnostics entrypoints take a format string and -variadic arguments. - -The format strings take codes prefixed by ``%``, or ``%q`` to put -the result in quotes. For example:: - - "hello %s", "world" - -would print:: - - hello world - -whereas:: - - "hello %qs", "world" - -would print:: - - hello `world' - -where ```world'`` would be displayed in bold if colorization were enabled -in the terminal. - -The following format specifiers are accepted: - - -Numbers -******* - -``d`` and ``i`` (``signed int``), ``u`` (``unsigned int``) - ``%d``, ``%i``, and ``%u`` print integers in base ten. For example:: - - "the answer is %i", 42 - - would print:: - - the answer is 42 - -``o`` (``unsigned int``) - Print the integer in base eight - -``x`` (``unsigned int``) - Print the integer in base sixteen - -The above can be prefixed with ``l`` and ``ll`` prefixes to take -``long`` and ``long long`` values of the appropriate signedness. - -For example:: - - "address: %lx", (unsigned long)0x108b516 - -would print:: - - address: 108b516 - -Similarly, the prefix ``z`` can be used for ``size_t``:: - - "size: %zd", sizeof(struct foo) - size: 32 - -and ``t`` for ptrdiff_t. - -``f`` (``double``) - ``%f`` prints a floating-point value. For example:: - - "value: %f", 1.0 - - might print:: - - value: 1.000000 - - -Strings -******* - -``c`` (``char``) - ``%c`` prints a single character. - -``s`` (``const char *``) - ``%s`` prints a string. - - Note that if the string refers to something that might - appear in the input file (such as the name of a function), it's better - to quote the value; for example:: - - "unrecognized identifier: %qs", "foo" - - might print:: - - unrecognized identifier: `foo' - -``m`` (no argument) - Prints ``strerror(errno)``, for example:: - - "can't open %qs: %m" - - might print:: - - can't open `foo.txt': No such file or directory - -``%`` (no argument) - ``%%`` prints a `%` character, for example:: - - "8%% of 75 is 75%% of 8, and is thus 6" - - prints:: - - 8% of 75 is 75% of 8, and is thus 6 - -``'`` (no argument) - ``%'`` prints an apostrophe. This should only be used in untranslated messages; - translations should use appropriate punctuation directly. - - -Other format specifiers -*********************** - -``p`` (pointer) - ``%p`` prints a pointer, although the precise format is - implementation-defined. - -``r`` (``const char *``) - ``%r`` starts colorization on suitable text sinks, where the argument - specifies the name of the kind of entity to be colored, such as ``error``. - -``R`` (no argument) - ``%R`` stops colorization - -``<`` and ``>`` (no arguments) - ``%<`` adds an opening quote and ``%>`` a closing quote, such as:: - - "missing element %<%s:%s%>", ns, name - - which might be printed as:: - - missing element `xhtml:head' - - If the thing to be quoted can be handled with another format specifier, - then it's simpler to use ``q`` with it. For example, it's much - simpler to print a ``const char *`` in quotes via:: - - "%qs", str - - rather than the error-prone:: - - "%<%s%>", str - -``{`` (``const char *``) - ``%{`` starts a link; the argument is the URL. This will be displayed - in a suitably-capable terminal if a text sink is directly connected to - a tty, and will be captured in SARIF output. - -``}`` (no argument) - ``%}`` stops a link started with ``%{``. - - For example:: - - "for more information see %{the documentation%}", "https://example.com" - - would be printed as:: - - for more information see the documentation - - with the URL emitted in suitable output sinks. - -``@`` (``diagnostic_event_id *``) - ``%@`` prints a reference to an event in a - :type:`diagnostic_execution_path`, where the :type:`diagnostic_event_id` - is passed by pointer. - - For example, if ``event_id`` refers to the first event in a path, then:: - - "double-%qs of %qs; first %qs was at %@", - function, ptr, function, &event_id - - might print:: - - double-`free' of `p'; first `free` was at (1) - -.. : - - TODO: - - %.*s: a substring the length of which is specified by an argument - integer. - %Ns: likewise, but length specified as constant in the format string. - %Z: Requires two arguments - array of int, and len. Prints elements - of the array. - - %e: Consumes a pp_element * argument. - - Arguments can be used sequentially, or through %N$ resp. *N$ - notation Nth argument after the format string. If %N$ / *N$ - notation is used, it must be used for all arguments, except %m, %%, - %<, %>, %} and %', which may not have a number, as they do not consume - an argument. When %M$.*N$s is used, M must be N + 1. (This may - also be written %M$.*s, provided N is not otherwise used.) The - format string must have conversion specifiers with argument numbers - 1 up to highest argument; each argument may only be used once. - A format string can have at most 30 arguments. */ - - diff --git a/gcc/doc/libdiagnostics/topics/metadata.rst b/gcc/doc/libdiagnostics/topics/metadata.rst deleted file mode 100644 index c62792a..0000000 --- a/gcc/doc/libdiagnostics/topics/metadata.rst +++ /dev/null @@ -1,149 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Adding metadata -=============== - -Tool metadata -************* - -It's possible to set up various metadata on the :type:`diagnostic_manager` -as a whole, describing the program creating the diagnostics. - -.. note:: - - It's not required to set up any of this up on a - :type:`diagnostic_manager`. However, if you are doing - :doc:`SARIF output `, then you need to at least call - :func:`diagnostic_manager_set_tool_name` or the generated ``.sarif`` - file will not validate against the schema. - -.. function:: void diagnostic_manager_set_tool_name (diagnostic_manager *diag_mgr, \ - const char *value) - - Set a string for the name of the tool emitting the diagnostics. - - Both parameters must be non-NULL. - - If set, this string will be used - - * by :doc:`text output sinks ` as a prefix for output - when no physical location is available, replacing ``progname`` - in the following: - - .. code-block:: console - - $ ./tut01-hello-world - progname: error: I'm sorry Dave, I'm afraid I can't do that - - * by :doc:`SARIF output sinks ` as the value for the - ``name`` property of the ``driver`` - (`SARIF v2.1.0 §3.19.8 `_). - -.. function:: void diagnostic_manager_set_full_name (diagnostic_manager *diag_mgr, \ - const char *value) - - Set a string giving the name of the tool along with the its version and - other useful information:: - - diagnostic_manager_set_full_name (diag_mgr, "FooChecker 0.1 (en_US)"); - - If set, this string will be used by :doc:`SARIF output sinks ` as - the value for the ``fullName`` property of the ``driver`` - (`SARIF v2.1.0 §3.19.9 `_). - - Both parameters must be non-NULL. - -.. function:: void diagnostic_manager_set_version_string (diagnostic_manager *diag_mgr, \ - const char *value) - - Set a string suitable for use as the value of the SARIF ``version`` property - of the ``driver``. - (`SARIF v2.1.0 §3.19.13 `_):: - - diagnostic_manager_set_version_string (diag_mgr, "0.1"); - - Both parameters must be non-NULL. - -.. function:: void diagnostic_manager_set_version_url (diagnostic_manager *diag_mgr, \ - const char *value) - - Set a string suitable for use as the value of the SARIF ``informationUri`` - property of the ``driver``. - (`SARIF v2.1.0 §3.19.17 `_):: - - diagnostic_manager_set_version_url (diag_mgr, - "https://www.example.com/foo-checker/releases/0.1/"); - - Both parameters must be non-NULL. - -Adding metadata to a diagnostic -******************************* - -.. function:: void diagnostic_set_cwe (diagnostic *diag, \ - unsigned cwe_id) - - Associate ``diag`` with the given ID within - the `Common Weakness Enumeration `_:: - - /* CWE-242: Use of Inherently Dangerous Function. */ - diagnostic_set_cwe (d, 242); - - ``diag`` must be non-NULL. - - The CWE value will be printed by text sinks after the message:: - - test-metadata.c:21:3: warning: never use 'gets' [CWE-242] - - and in a sufficiently-capable terminal will be a link to - documentation about the CWE. - -.. function:: void diagnostic_add_rule (diagnostic *diag, \ - const char *title, \ - const char *url) - - Associate this :type:`diagnostic` with a particular rule that has been - violated (such as in a coding standard, or within a specification). - - A diagnostic can be associated with zero or more rules. - - ``diag`` must be non-NULL. The rule must have at least one of a - title and a URL, but these can be NULL. - - For example, given:: - - diagnostic_add_rule (d, - "MSC24-C", - "https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions"); - - the rule name will be printed by text sinks after the message:: - - test-metadata.c:21:3: warning: never use 'gets' [MSC24-C] - 21 | gets (buf); - | ^~~~~~~~~~ - - and if so, the URL will be available in a sufficiently capable - terminal. - - This can be used in conjunction with :func:`diagnostic_set_cwe`, - giving output like this:: - - test-metadata.c:21:3: warning: never use 'gets' [CWE-242] [MSC24-C] - 21 | gets (buf); - | ^~~~~~~~~~ diff --git a/gcc/doc/libdiagnostics/topics/physical-locations.rst b/gcc/doc/libdiagnostics/topics/physical-locations.rst deleted file mode 100644 index bad2b8d..0000000 --- a/gcc/doc/libdiagnostics/topics/physical-locations.rst +++ /dev/null @@ -1,281 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Physical locations -================== - -A "physical" source location is a location expressed in terms of -a specific file, and line(s) and column(s) (as opposed to a -:doc:`"logical" location `, -which refers to semantic constructs in a programming language). - -Creating location information -***************************** - -The :type:`diagnostic_manager` manages various objects relating to -locations. - -.. type:: diagnostic_file - - A :type:`diagnostic_file` is an opaque type describing a particular input file. - -.. function:: const diagnostic_file * diagnostic_manager_new_file (diagnostic_manager *diag_mgr, \ - const char *name, \ - const char *sarif_source_language) - - Create a new :type:`diagnostic_file` for file ``name``. Repeated calls - with strings that match ``name`` will return the same object. - - Both ``diag_mgr`` and ``name`` must be non-NULL. - - If ``sarif_source_language`` is non-NULL, it specifies a - ``sourceLanguage`` value for the file for use when writing - :doc:`SARIF ` - (`SARIF v2.1.0 §3.24.10 `_). - See - `SARIF v2.1.0 Appendix J `_ - for suggested values for various programmming languages. - - For example, this creates a :type:`diagnostic_file` for ``foo.c`` - and identifies it as C source code:: - - foo_c = diagnostic_manager_new_file (diag_mgr, - "foo.c", - "c" /* source_language */); - -.. function:: void diagnostic_manager_debug_dump_file (diagnostic_manager *diag_mgr, \ - const diagnostic_file *file, \ - FILE *out) - - Write a representation of ``file`` to ``out``, for debugging. - Both ``diag_mgr`` and ``out`` must be non-NULL. - `file`` may be NULL. - - For example:: - - diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr); - - might lead to this output:: - - file(name="foo.c", sarif_source_language="c") - -.. type:: diagnostic_line_num_t - -A :type:`diagnostic_line_num_t` is used for representing line numbers -within text files. libdiagnostics treats the first line of a text file -as line 1. - -.. type:: diagnostic_column_num_t - -A :type:`diagnostic_column_num_t` is used for representing column numbers -within text files. libdiagnostics treats the first column of a text line -as column 1, **not** column 0. - -.. note:: - - Both libdiagnostics and Emacs number source *lines* starting at 1, but - they have differing conventions for *columns*. - - libdiagnostics uses a 1-based convention for source columns, - whereas Emacs's ``M-x column-number-mode`` uses a 0-based convention. - - For example, an error in the initial, left-hand - column of source line 3 is reported by libdiagnostics as:: - - some-file.c:3:1: error: ...etc... - - On navigating to the location of that error in Emacs - (e.g. via ``next-error``), - the locus is reported in the Mode Line - (assuming ``M-x column-number-mode``) as:: - - some-file.c 10% (3, 0) - - i.e. ``3:1:`` in libdiagnostics corresponds to ``(3, 0)`` in Emacs. - -.. type:: diagnostic_physical_location - -A :type:`diagnostic_physical_location` is an opaque type representing a -key into a database of source locations within a :type:`diagnostic_manager`. - -:type:`diagnostic_physical_location` instances are created by various API -calls into the :type:`diagnostic_manager` expressing source code points -and ranges. - -They persist until the :type:`diagnostic_manager` is released, which -cleans them up. - -A ``NULL`` value means "unknown", and can be returned by the -:type:`diagnostic_manager` as a fallback when a problem occurs -(e.g. too many locations). - -A :type:`diagnostic_physical_location` can be a single point within the -source code, such as here (at the the '"' at the start of the string literal):: - - int i = "foo"; - ^ - -or be a range with a start and finish, and a "caret" location:: - - a = (foo && bar) - ~~~~~^~~~~~~ - -where the caret here is at the first "&", and the start and finish -are at the parentheses. - -.. function:: const diagnostic_physical_location *diagnostic_manager_new_location_from_file_and_line (diagnostic_manager *diag_mgr, \ - const diagnostic_file *file, \ - diagnostic_line_num_t line_num) - - Attempt to create a :type:`diagnostic_physical_location` representing - ``FILENAME:LINE_NUM``, with no column information (thus representing - the whole of the given line. - - Both ``diag_mgr`` and ``file`` must be non-NULL. - -.. function:: const diagnostic_physical_location * diagnostic_manager_new_location_from_file_line_column (diagnostic_manager *diag_mgr, \ - const diagnostic_file *file, \ - diagnostic_line_num_t line_num, \ - diagnostic_column_num_t column_num) - - Attempt to create a :type:`diagnostic_physical_location` for - ``FILENAME:LINE_NUM:COLUMN_NUM`` representing a particular point - in the source file. - - Both ``diag_mgr`` and ``file`` must be non-NULL. - -.. function:: const diagnostic_physical_location *diagnostic_manager_new_location_from_range (diagnostic_manager *diag_mgr,\ - const diagnostic_physical_location *loc_caret,\ - const diagnostic_physical_location *loc_start,\ - const diagnostic_physical_location *loc_end) - - Attempt to create a diagnostic_physical_location representing a - range within a source file, with a highlighted "caret" location. - - All must be within the same file, but they can be on different lines. - - For example, consider the location of the binary expression below:: - - ...|__________1111111112222222 - ...|12345678901234567890123456 - ...| - 521|int sum (int foo, int bar) - 522|{ - 523| return foo + bar; - ...| ~~~~^~~~~ - 524|} - - The location's caret is at the "+", line 523 column 15, but starts - earlier, at the "f" of "foo" at column 11. The finish is at the "r" - of "bar" at column 19. - - ``diag_mgr`` must be non-NULL. - -.. function:: void diagnostic_manager_debug_dump_location (const diagnostic_manager *diag_mgr,\ - const diagnostic_physical_location *loc, \ - FILE *out) - - Write a representation of ``loc`` to ``out``, for debugging. - - Both ``diag_mgr`` and ``out`` must be non-NULL. - `loc`` may be NULL. - - TODO: example of output - -Associating diagnostics with locations -************************************** - -A :type:`diagnostic` has an optional primary physical location -and zero or more secondary physical locations. For example:: - - a = (foo && bar) - ~~~~~^~~~~~~ - -This diagnostic has a single :type:`diagnostic_physical_location`, -with the caret at the first "&", and the start/finish at the parentheses. - -Contrast with:: - - a = (foo && bar) - ~~~ ^~ ~~~ - -This diagnostic has three locations - -* The primary location (at "&&") has its caret and start location at - the first "&" and end at the second "&. - -* The secondary location for "foo" has its start and finish at the "f" - and "o" of "foo"; the caret is not displayed, but is perhaps at - the "f" of "foo". - -* Similarly, the other secondary location (for "bar") has its start and - finish at the "b" and "r" of "bar"; the caret is not displayed, but - is perhaps at the"b" of "bar". - -.. function:: void diagnostic_set_location (diagnostic *diag, \ - const diagnostic_physical_location * loc) - - Set the primary location of ``diag``. - - ``diag`` must be non-NULL; ``loc`` can be NULL. - -.. function:: void diagnostic_set_location_with_label (diagnostic *diag, \ - const diagnostic_physical_location *loc, \ - const char *fmt, ...) - - Set the primary location of ``diag``, with a label. The label is - formatted as per the rules FIXME - - ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL. - - See :doc:`message-formatting` for details of how to use ``fmt``. - - TODO: example of use - -.. function:: void diagnostic_add_location (diagnostic *diag, \ - const diagnostic_physical_location * loc) - - Add a secondary location to ``diag``. - - ``diag`` must be non-NULL; ``loc`` can be NULL. - - -.. function:: void diagnostic_add_location_with_label (diagnostic *diag, \ - const diagnostic_physical_location *loc, \ - const char *text) - - Add a secondary location to ``diag``, with a label. The label is - formatted as per the rules FIXME - - ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL. - - For example, - - .. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-labelled-ranges.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - - might give this text output:: - - test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' - 19 | 42 + "foo" - | ~~ ^ ~~~~~ - | | | - | int const char * diff --git a/gcc/doc/libdiagnostics/topics/retrofitting.rst b/gcc/doc/libdiagnostics/topics/retrofitting.rst deleted file mode 100644 index d034057..0000000 --- a/gcc/doc/libdiagnostics/topics/retrofitting.rst +++ /dev/null @@ -1,23 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Adding libdiagnostics to an existing project -============================================ - -TODO diff --git a/gcc/doc/libdiagnostics/topics/sarif.rst b/gcc/doc/libdiagnostics/topics/sarif.rst deleted file mode 100644 index 3fd75ed..0000000 --- a/gcc/doc/libdiagnostics/topics/sarif.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -SARIF support -============= - -`SARIF `_ is a machine-readable format, originally -designed for the output of static analysis tools, but which can be used -for diagnostics in general. - -.. function:: void diagnostic_manager_add_sarif_sink (diagnostic_manager *diag_mgr, \ - FILE *dst_stream, \ - const diagnostic_file *main_input_file, \ - enum diagnostic_sarif_version version) - - Add a new output sink to ``diag_mgr``, which writes SARIF of the given - version to ``dst_stream``. - - The output is not written until ``diag_mgr`` is released. - - ``dst_stream`` is borrowed, and must outlive ``diag_mgr``. - - For the result to be a valid SARIF file according to the schema, - ``diag_mgr`` must have had :func:`diagnostic_manager_set_tool_name` - called on it. - - ``diag_mgr``, ``dst_stream``, and ``main_input_file`` must all be non-NULL. - - .. enum:: diagnostic_sarif_version - - An enum for choosing the SARIF version for a SARIF output sink. - - .. macro:: DIAGNOSTIC_SARIF_VERSION_2_1_0 - - .. macro:: DIAGNOSTIC_SARIF_VERSION_2_2_PRERELEASE diff --git a/gcc/doc/libdiagnostics/topics/text-output.rst b/gcc/doc/libdiagnostics/topics/text-output.rst deleted file mode 100644 index 32b2a54..0000000 --- a/gcc/doc/libdiagnostics/topics/text-output.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Text output -=========== - -.. type:: diagnostic_text_sink - -.. function:: diagnostic_text_sink * diagnostic_manager_add_text_sink (diagnostic_manager *diag_mgr,\ - FILE *dst_stream, \ - enum diagnostic_colorize colorize) - - Add a new output sink to ``diag_mgr``, which writes GCC-style diagnostics - to ``dst_stream``. - Return a borrowed pointer to the sink, which is cleaned up when ``diag_mgr`` - is released. - - ``diag_mgr`` must be non-NULL. - - ``dst_stream`` must be non-NULL. It is borrowed and must outlive ``DIAG_MGR``. - - The output for each diagnostic is written and flushed as each - :type:`diagnostic` is finished. - - .. enum:: diagnostic_colorize - - An enum for determining if we should colorize a text output sink. - - .. macro:: DIAGNOSTIC_COLORIZE_IF_TTY - - Diagnostics should be colorized if the destination stream is - directly connected to a tty. - - .. macro:: DIAGNOSTIC_COLORIZE_NO - - Diagnostics should not be colorized. - - .. macro:: DIAGNOSTIC_COLORIZE_YES - - Diagnostics should be colorized. - -.. function:: void diagnostic_text_sink_set_source_printing_enabled (diagnostic_text_sink *text_sink, \ - int value) - - Enable or disable printing of source text in the text sink. - - ``text_sink`` must be non-NULL. - - Default: enabled. - -.. function:: void diagnostic_text_sink_set_colorize (diagnostic_text_sink *text_sink, \ - enum diagnostic_colorize colorize) - - Update colorization of text sink. - - ``text_sink`` must be non-NULL. - -.. function:: void diagnostic_text_sink_set_labelled_source_colorization_enabled (diagnostic_text_sink *text_sink, \ - int value) - - ``text_sink`` must be non-NULL. - - Enable or disable colorization of the characters of source text - that are underlined. - - This should be true for clients that generate range information - (so that the ranges of code are colorized), and false for clients that - merely specify points within the source code (to avoid e.g. colorizing - just the first character in a token, which would look strange). - - Default: enabled. diff --git a/gcc/doc/libdiagnostics/topics/ux.rst b/gcc/doc/libdiagnostics/topics/ux.rst deleted file mode 100644 index fc96e17..0000000 --- a/gcc/doc/libdiagnostics/topics/ux.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -User Experience -=============== - -Refer to -`GCC's user experience guidelines `_ -for notes on -`what makes a good diagnostic `_. diff --git a/gcc/doc/libdiagnostics/tutorial/01-hello-world.rst b/gcc/doc/libdiagnostics/tutorial/01-hello-world.rst deleted file mode 100644 index 4635687..0000000 --- a/gcc/doc/libdiagnostics/tutorial/01-hello-world.rst +++ /dev/null @@ -1,173 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 1: "Hello world" -============================== - -Before we look at the details of the API, let's look at building and -running programs that use the library. - -Here's a toy program that uses libdiagnostics to emit an error message -to stderr. - - .. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-example-1.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -Copy the above to `tut01-hello-world.c`. - -Assuming you have libdiagnostics installed, build the test program -using: - -.. code-block:: console - - $ gcc \ - tut01-hello-world.c \ - -o tut01-hello-world \ - -ldiagnostics - -You should then be able to run the built program: - -.. code-block:: console - - $ ./tut01-hello-world - progname: error: I'm sorry Dave, I'm afraid I can't do that - -If stderr is connected to a terminal, you should get colorized output -(using `SGR control codes `_). - -.. image:: example-1.png - -Otherwise, the output will be plain text. - -Obviously a trivial example like the above could be done using ``fprintf`` -on stderr, and it's fairly easy to colorize text at the terminal. - -In :doc:`the next part of the tutorial <02-physical-locations>` we'll add -file/location information to our error messages, and libdiagnostics will -quote the pertinent parts of the file, underlining them, which is less trivial -to reimplement. libdiagnostics gives us many other such abilities, such as -fix-it hints and execution paths, which we'll cover in the following -tutorials. Also, once a program's diagnostics are using libdiagnostics, -it is trivial to add support for outputting them in -machine-readable form as :doc:`SARIF <../topics/sarif>`. - - -Structure -********* - -The above example shows the typical structure of a program using -libdiagnostics: - -* **initialization**: create a :type:`diagnostic_manager` instance, - and create an output sink for it, and other one-time initialization - -* **emission**: create various :type:`diagnostic` instances, populating - them with data, and calling "finish" once they're ready to be emitted. - :doc:`Text sinks <../topics/text-output>` emit their diagnostics as soon - as "finish" is called on them. - -* **cleanup**: call :func:`diagnostic_manager_release` on the - :type:`diagnostic_manager` to finish and free up resources. - :doc:`SARIF sinks <../topics/sarif>` write their output when - :func:`diagnostic_manager_release` is called on the manager. - -For non-trivial examples we'll also want to create location information, -which could happen during initialization, or during a parsing phase of -the program using libdiagnostics. See :doc:`02-physical-locations` for -more information. - - -Formatted messages -****************** - -The above example uses :func:`diagnostic_finish`, which takes a format -string and arguments. libdiagnostics has its own style of format -string arguments used for :func:`diagnostic_finish` and some other -entrypoints. - -.. note:: The format syntax is *not* the same as ``printf``; see - :doc:`supported formatting options <../topics/message-formatting>`. - -You can use the ``q`` modifier on arguments -to quote them, so, for example ``%qs`` is a quoted string, consuming a -``const char *`` argument:: - - diagnostic_finish (d, "can't find %qs", "foo"); - -This gives output like this: - -.. code-block:: console - - progname: error: can't find ‘foo’ - -where the quoted string will appear in bold in a suitably-capable -terminal, and the quotes will be internationalized, so that e.g. with -``LANG=fr_FR.UTF8`` we might get: - -.. code-block:: console - - progname: erreur: can't find « free » - -Note that: - -* the string ``error`` has been localized by libdiagnostics to - ``erreur``, - -* locale-specific quoting has been used (``«`` and ``»`` rather than - ``‘`` and ``’``), - -* ``foo`` hasn't been localized - you would typically use quoted strings - for referring to identifiers in the input language (such as function names - in code, property names in JSON, etc), - -* the message itself hasn't been localized: you are responsible for - passing a translated format string to :func:`diagnostic_finish` if you - want to internationalize the output. - -There are many :doc:`supported formatting options <../topics/message-formatting>`. - - -Naming the program -****************** - -In the above output the message was preceded with ``progname``. This -appears for diagnostics that don't have any location information associated -with them. We'll look at setting up location information in the -:doc:`next tutorial <02-physical-locations>`, but we can override this -default name via :func:`diagnostic_manager_set_tool_name`:: - - diagnostic_manager_set_tool_name (diag_mgr, "my-awesome-checker"); - -leading to output like this:: - - my-awesome-checker: error: can't find ‘foo’ - -There are various other functions for -:doc:`supplying metadata to libdiagnostics <../../topics/metadata>`. - - -Moving beyond trivial examples -****************************** - -Obviously it's not very useful if we can't refer to specific files and -specific locations in those files in our diagnostics, so read -:doc:`part 2 of the tutorial <02-physical-locations>` for information on -how to do this. diff --git a/gcc/doc/libdiagnostics/tutorial/02-physical-locations.rst b/gcc/doc/libdiagnostics/tutorial/02-physical-locations.rst deleted file mode 100644 index 2e429de..0000000 --- a/gcc/doc/libdiagnostics/tutorial/02-physical-locations.rst +++ /dev/null @@ -1,260 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 2: physical locations -=================================== - -libdiagnostics has two kinds of location: - -* *physical locations* expressed in terms of a specific file, and line(s) - and perhaps column(s), such as ``some-file.c:3:1``, or a range of - columns, such as in:: - - test-typo.c:19:13: error: unknown field 'colour' - 19 | return p->colour; - | ^~~~~~ - - or even a range spanning multiple lines of a file. - - All of these are instances of :type:`diagnostic_physical_location`. - -* *logical locations* which refers to semantic constructs - in the input, such as ``within function 'foo'``, or within - namespace ``foo``'s class ``bar``'s member function ``get_color``. - - These are instances of :type:`diagnostic_logical_location`, - -A :type:`diagnostic` can have zero or more physical locations, -and optionally have a logical location. - -Let's extend the previous example to add a physical location to the -:type:`diagnostic`; we'll cover logical locations in the -:doc:`next section <03-logical-locations>`. - - -Source files -************ - -Given these declarations:: - - static diagnostic_manager *diag_mgr; - static const diagnostic_file *main_file; - -we can create a :type:`diagnostic_file` describing an input file ``foo.c`` -via :func:`diagnostic_manager_new_file`:: - - foo_c = diagnostic_manager_new_file (diag_mgr, - "foo.c", - "c" /* source_language */); - -You can use :func:`diagnostic_manager_debug_dump_file` to print a -representation of a :type:`diagnostic_file` for debugging. -For example:: - - diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr); - -might lead to this output on ``stderr``:: - - file(name="foo.c", sarif_source_language="c") - -Once we have a :type:`diagnostic_file` we can use it to create instances -of :type:`diagnostic_physical_location` within the :type:`diagnostic_manager`. -These are owned by the :type:`diagnostic_manager` and cleaned up -automatically when :func:`diagnostic_manager_release` is called. - -Instances of :type:`diagnostic_physical_location` can refer to - -* a source line as a whole, created via - :func:`diagnostic_manager_new_location_from_file_and_line`. - -* a particular point within a source file (line/column), created via - :func:`diagnostic_manager_new_location_from_file_line_column`. - -* a range of text within of source file, created via - :func:`diagnostic_manager_new_location_from_range`. - - -Diagnostics affecting a whole source line -***************************************** - -If we want a diagnostic to refer to an entire source line, -we can use :func:`diagnostic_manager_new_location_from_file_and_line`. - -For example, given this example input where the tool can't find the header:: - - #include - -we could complain about it via libdiagnostics via: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-no-column.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -leading to output like this:: - - foo.c:17: error: can't find 'foo.h'" - 17 | #include - -where libdiagnostics will attempt to load the source file and -quote the pertinent line. - -If libdiagnostics cannot open the file, it will merely print:: - - foo.c:17: error: can't find 'foo.h' - -You can use :func:`diagnostic_manager_debug_dump_location` to dump a -:type:`diagnostic_physical_location`. For the above example:: - - diagnostic_manager_debug_dump_location (diag_mgr, loc, stderr); - -might print:: - - foo.c:17 - -to stderr. - - -Columns and ranges -****************** - -If we want to generate output like this:: - - foo.c:17:11: error: can't find 'foo'" - 17 | #include - | ^~~~~ - -where the diagnostic is marked as relating to the above range of -characters in line 17, we need to express the range of characters -within the line of interest. - -We can do this by creating a :type:`diagnostic_physical_location` for the -start of the range, another one for the end of the range, and then using -these two to create a :type:`diagnostic_physical_location` for the -range as a whole: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-error.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -On compiling and running the program, we should get this output:: - - foo.c:17:11: error: can't find 'foo.h' - 17 | #include - | ^~~~~ - -where libdiagnostics will attempt to load the source file and -underling the pertinent part of the given line. - -If libdiagnostics cannot open the file, it will merely print:: - - foo.c:17:8: error: can't find 'foo' - -A range can span multiple lines within the same file. - -As before, you can use :func:`diagnostic_manager_debug_dump_location` to -dump the locations. For the above example:: - - diagnostic_manager_debug_dump_location (diag_mgr, loc_start, stderr); - -and:: - - diagnostic_manager_debug_dump_location (diag_mgr, loc_range, stderr); - -might print:: - - foo.c:17:11 - -to stderr, whereas:: - - diagnostic_manager_debug_dump_location (diag_mgr, loc_end, stderr); - -might print:: - - foo.c:17:15 - - -Multiple locations -****************** - -As well as the primary physical location seen above, a :type:`diagnostic` -can have additional physical locations. You can add these secondary -locations via :func:`diagnostic_add_location`. - -For example, for this valid but suspicious-looking C code:: - - const char *strs[3] = {"foo", - "bar" - "baz"}; - -the following :type:`diagnostic` has its primary location where the missing -comma should be, and secondary locations for each of the string literals -``"foo"``, ``"bar"``, and ``"baz"``, added via :func:`diagnostic_add_location`: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-multiple-lines.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -where the text output might be:: - - test-multiple-lines.c:23:29: warning: missing comma - 22 | const char *strs[3] = {"foo", - | ~~~~~ - 23 | "bar" - | ~~~~~^ - 24 | "baz"}; - | ~~~~~ - - -Labelling locations -******************* - -You can give the locations labels using -:func:`diagnostic_set_location_with_label` and -:func:`diagnostic_add_location_with_label`. - -Consider emitting a "type mismatch" diagnostic for:: - - 42 + "foo" - -where the primary location is on the ``+``, with secondary locations on the``42`` -and the ``"foo"``: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-labelled-ranges.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -giving this text output:: - - test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' - 19 | 42 + "foo" - | ~~ ^ ~~~~~ - | | | - | int const char * - - -More on locations -***************** - -For more details on the above, see :doc:`../topics/physical-locations`. -Otherwise the :doc:`next part of the tutorial <03-logical-locations>` -covers logical locations. diff --git a/gcc/doc/libdiagnostics/tutorial/03-logical-locations.rst b/gcc/doc/libdiagnostics/tutorial/03-logical-locations.rst deleted file mode 100644 index d36ac09..0000000 --- a/gcc/doc/libdiagnostics/tutorial/03-logical-locations.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 3: logical locations -================================== - -Let's extend the previous example to add a -:doc:`logical location <../topics/logical-locations>` to the -:type:`diagnostic`. - -First we create a :type:`diagnostic_logical_location` representing a -particular function:: - - const diagnostic_logical_location *logical_loc - = diagnostic_manager_new_logical_location (diag_mgr, - DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION, - NULL, /* parent */ - "foo", - NULL, - NULL); - -In this simple example we specify that it is a function, and just give -it a name (``foo``). For more complicated cases we can set up tree-like -hierarchies of logical locations, set qualified names, "mangled" names, -and so on; see :func:`diagnostic_manager_new_logical_location` for details. - -Once we have :type:`diagnostic_logical_location` we can associate it with -a :type:`diagnostic` with :func:`diagnostic_set_logical_location`:: - - diagnostic_set_logical_location (d, logical_loc); - -The logical location will be printed by text output sinks like this:: - - In function 'foo': - -and will be captured in :doc:`SARIF <../topics/sarif>` output. - - -Find out more -************* - -For more details on the above, see :doc:`../topics/logical-locations`. -Otherwise the :doc:`next part of the tutorial <04-notes>` covers adding -supplementary "notes" to a :type:`diagnostic`. diff --git a/gcc/doc/libdiagnostics/tutorial/04-notes.rst b/gcc/doc/libdiagnostics/tutorial/04-notes.rst deleted file mode 100644 index 117eb6f..0000000 --- a/gcc/doc/libdiagnostics/tutorial/04-notes.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 4: adding notes -============================= - -Let's further extend the previous example to add a "note" to it. - -We want to generate output like this:: - - test-with-note.c:17:11: error: can't find 'foo' - 17 | #include - | ^~~~~ - test-with-note.c:17:11: note: have you looked behind the couch? - -The "error" and "note" are both instances of :type:`diagnostic`. -We want to let libdiagnostics know that they are grouped together. -The way to do this is to use :func:`diagnostic_manager_begin_group` -and :func:`diagnostic_manager_end_group` around the "finish" calls -to the diagnostics. - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-error-with-note.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -On compiling and running the program, we should get the desired output:: - - test-with-note.c:17:11: error: can't find 'foo' - 17 | #include - | ^~~~~ - test-with-note.c:17:11: note: have you looked behind the couch? - -The grouping doesn't affect text output sinks, but a -:doc:`SARIF sink <../topics/sarif>` will group the note within the error -(via the ``relatedLocations`` property of ``result`` objects; see SARIF v2.1.0 -`§3.27.22 `_). - -In the above, the note had the same physical location as the error -(``loc_range``). This can be useful for splitting up a message into two -parts to make localization easier, but they could have different locations, such -as in:: - - test.xml:10:2: error: 'foo' is not valid here - test.xml:5:1: note: within element 'bar' - -where each :type:`diagnostic` had its own :type:`diagnostic_physical_location`. - -In :doc:`the next tutorial <05-warnings>` we'll look at issuing warnings, -rather than errors. diff --git a/gcc/doc/libdiagnostics/tutorial/05-warnings.rst b/gcc/doc/libdiagnostics/tutorial/05-warnings.rst deleted file mode 100644 index 1512ae7..0000000 --- a/gcc/doc/libdiagnostics/tutorial/05-warnings.rst +++ /dev/null @@ -1,44 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 5: warnings -========================= - -So far we've only emitted errors, but other kinds of diagnostic are possible, -such as warnings. - -We can select different kinds of diagnostic via :enum:`diagnostic_level` -when calling :func:`diagnostic_begin`: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-warning.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -On compiling and running the program, we should get output similar to:: - - test-warning.c:17:11: warning: this is a warning - 17 | #include - | ^~~~~ - -Various severities are possible, see :enum:`diagnostic_level` for more -information. - -In :doc:`the next section of the tutorial <06-fix-it-hints>` we'll look -at adding fix-it hints to diagnostics. diff --git a/gcc/doc/libdiagnostics/tutorial/06-fix-it-hints.rst b/gcc/doc/libdiagnostics/tutorial/06-fix-it-hints.rst deleted file mode 100644 index 9486ab7..0000000 --- a/gcc/doc/libdiagnostics/tutorial/06-fix-it-hints.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 6: fix-it hints -============================= - -libdiagnostics supports adding "fix-it hints" to a :type:`diagnostic`: -suggestions for the user on how to edit their code to fix a problem. These -can be expressed as insertions, replacements, and removals of text. - -For example, here we add a replacement fix-it hint to a diagnostic: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-fix-it-hint.c - :language: c - :start-after: /* begin quoted source */ - :end-before: /* end quoted source */ - -On compiling and running the program, we should get output similar to:: - - test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color' - 19 | return p->colour; - | ^~~~~~ - | color - -We can also add a call to :func:`diagnostic_manager_write_patch` to the -program cleanup code:: - - diagnostic_manager_write_patch (diag_mgr, stderr); - -This will write a patch to the stream (here ``stderr``) giving the effect -of all fix-it hints on all diagnostics emitted by the -:type:`diagnostic_manager`, giving something like:: - - @@ -16,7 +16,7 @@ - struct rgb - get_color (struct object *p) - { - - return p->colour; - + return p->color; - } - - -See the :doc:`guide to fix-it hints <../topics/fix-it-hints>` -for more information, or go on to -:doc:`the next section of the tutorial <07-execution-paths>`. diff --git a/gcc/doc/libdiagnostics/tutorial/07-execution-paths.rst b/gcc/doc/libdiagnostics/tutorial/07-execution-paths.rst deleted file mode 100644 index 0fbbed2..0000000 --- a/gcc/doc/libdiagnostics/tutorial/07-execution-paths.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -.. default-domain:: c - -Tutorial part 7: execution paths -================================ - -A :type:`diagnostic` can optionally have a :type:`diagnostic_execution_path` -describing a path of execution through code. - -For example, let's pretend we're writing a static analyis tool for finding -bugs in `CPython extension code `_. - -Let's say we're analyzing this code: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-warning-with-path.c - :language: c - :start-after: begin fake source - :end-before: end fake source - -This code attempts to take an Python integer parameter and then build a -list of that length, containing random integers. However, there are -**numerous bugs** in this code: a type mismatch, mistakes in -reference-counting, and an almost total lack of error-handling. - -For example, ``PyList_Append`` requires a non-NULL first parameter (``list``), -but ``PyList_New`` can fail, returning NULL, and this isn't checked for, -which would lead to a segfault if ``PyList_New`` fails. - -We can add a :type:`diagnostic_execution_path` to the :type:`diagnostic` -via :func:`diagnostic_add_execution_path`, and then add events to it -using :func:`diagnostic_execution_path_add_event`. - -For example, with:: - - diagnostic_event_id alloc_event_id - = diagnostic_execution_path_add_event (path, - loc_call_to_PyList_New, - logical_loc, 0, - "when %qs fails, returning NULL", - "PyList_New"); - -we create an event that will be worded as:: - - (1) when `PyList_New' fails, returning NULL - -Note that :func:`diagnostic_execution_path_add_event` returns a -:type:`diagnostic_event_id`. We can use this to refer to this event -in another event using the ``%@`` format code in its message, which -takes the address of a :type:`diagnostic_event_id`:: - - diagnostic_execution_path_add_event (path, - loc_call_to_PyList_Append, - logical_loc, 0, - "when calling %qs, passing NULL from %@ as argument %i", - "PyList_Append", &alloc_event_id, 1); - -where the latter event will be worded as:: - - (2) when calling `PyList_Append', passing NULL from (1) as argument 1 - -where the ``%@`` reference to the other event has been printed as ``(1)``. -In SARIF output the text "(1)" will have a embedded link referring within the sarif -log to the ``threadFlowLocation`` object for the other event, via JSON -pointer (see `§3.10.3 "URIs that use the sarif scheme" `_). - -Let's add an event between these describing control flow, creating three -events in all: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-warning-with-path.c - :language: c - :start-after: begin path creation - :end-before: end path creation - -Assuming we also gave it :type:`diagnostic_logical_location` with: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-warning-with-path.c - :language: c - :start-after: begin create logical locs - :end-before: end create logical locs - -and finish the :type:`diagnostic` with :func:`diagnostic_finish` like this:: - - diagnostic_finish (d, - "passing NULL as argument %i to %qs" - " which requires a non-NULL parameter", - 1, "PyList_Append"); - -then we should get output to text sinks similar to the following:: - - In function 'make_a_list_of_random_ints_badly': - test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter" - 30 | PyList_Append(list, item); - | ^~~~~~~~~~~~~~~~~~~~~~~~~ - make_a_list_of_random_ints_badly': events 1-3 - 26 | list = PyList_New(0); - | ^~~~~~~~~~~~~ - | | - | (1) when 'PyList_New' fails, returning NULL - 27 | - 28 | for (i = 0; i < count; i++) { - | ~~~~~~~~~ - | | - | (2) when 'i < count' - 29 | item = PyLong_FromLong(random()); - 30 | PyList_Append(list, item); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 - -and for SARIF sinks the path will be added as a ``codeFlow`` object -(see SARIF 2.1.0 `3.36 codeFlow object `_). - -Here's the above example in full: - -.. literalinclude:: ../../../testsuite/libdiagnostics.dg/test-warning-with-path.c - :language: c - :start-after: begin full example - :end-before: end full example - - -Moving on -********* - -That's the end of the tutorial. For more information on libdiagnostics, see -the :doc:`topic guide <../topics/index>`. diff --git a/gcc/doc/libdiagnostics/tutorial/example-1.png b/gcc/doc/libdiagnostics/tutorial/example-1.png deleted file mode 100644 index d637103..0000000 Binary files a/gcc/doc/libdiagnostics/tutorial/example-1.png and /dev/null differ diff --git a/gcc/doc/libdiagnostics/tutorial/index.rst b/gcc/doc/libdiagnostics/tutorial/index.rst deleted file mode 100644 index 6ea6866..0000000 --- a/gcc/doc/libdiagnostics/tutorial/index.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. Copyright (C) 2024 Free Software Foundation, Inc. - Originally contributed by David Malcolm - - This 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 of the License, or - (at your option) any later version. - - This program 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 this program. If not, see - . - -Tutorial -======== - -The following tutorial gives an overview of how to use libdiagnostics. - -.. toctree:: - :maxdepth: 2 - - 01-hello-world.rst - 02-physical-locations.rst - 03-logical-locations.rst - 04-notes.rst - 05-warnings.rst - 06-fix-it-hints.rst - 07-execution-paths.rst diff --git a/gcc/doc/libgdiagnostics/Makefile b/gcc/doc/libgdiagnostics/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/gcc/doc/libgdiagnostics/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/gcc/doc/libgdiagnostics/conf.py b/gcc/doc/libgdiagnostics/conf.py new file mode 100644 index 0000000..8e92e12 --- /dev/null +++ b/gcc/doc/libgdiagnostics/conf.py @@ -0,0 +1,27 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'libgdiagnostics' +copyright = '2024, David Malcolm' +author = 'David Malcolm' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/gcc/doc/libgdiagnostics/index.rst b/gcc/doc/libgdiagnostics/index.rst new file mode 100644 index 0000000..853331d --- /dev/null +++ b/gcc/doc/libgdiagnostics/index.rst @@ -0,0 +1,113 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +libgdiagnostics +=============== + +This document describes `libgdiagnostics `_, +an API for programs to use to emit diagnostics (such as for "lint"-style checker +tools), supporting: + +* text output similar to GCC's errors and warnings:: + + test-typo.c:19:13: error: unknown field 'colour' + 19 | return p->colour; + | ^~~~~~ + + quoting pertinent source code (with a cache), and underlining + :doc:`points and ranges in the files being tested `, + possibly with labels:: + + test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' + 19 | 42 + "foo" + | ~~ ^ ~~~~~ + | | | + | int const char * + +* emitting :doc:`fix-it hints `:: + + test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color' + 19 | return p->colour; + | ^~~~~~ + | color + + and generating patches from them:: + + @@ -16,7 +16,7 @@ + struct rgb + get_color (struct object *p) + { + - return p->colour; + + return p->color; + } + +* capturing :doc:`execution paths` through code:: + + In function 'make_a_list_of_random_ints_badly': + test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter" + 30 | PyList_Append(list, item); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + make_a_list_of_random_ints_badly': events 1-3 + 26 | list = PyList_New(0); + | ^~~~~~~~~~~~~ + | | + | (1) when 'PyList_New' fails, returning NULL + 27 | + 28 | for (i = 0; i < count; i++) { + | ~~~~~~~~~ + | | + | (2) when 'i < count' + 29 | item = PyLong_FromLong(random()); + 30 | PyList_Append(list, item); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 + +* support for emitting machine-readable representations of the above + using the :doc:`SARIF file format ` + +There are actually two APIs for the library: + +* a pure C API: ``libgdiagnostics.h`` + +* a C++ wrapper API: ``libgdiagnostics+.h``. This is a header-only + collection of wrapper classes around the C API to give a less + verbose API. + +This documentation covers the C API. + +Contents +******** + +.. toctree:: + :maxdepth: 2 + + tutorial/index.rst + topics/index.rst + +libgdiagnostics 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 of the License, or +(at your option) any later version. + + +Indices and tables +****************** + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/gcc/doc/libgdiagnostics/make.bat b/gcc/doc/libgdiagnostics/make.bat new file mode 100644 index 0000000..954237b --- /dev/null +++ b/gcc/doc/libgdiagnostics/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/gcc/doc/libgdiagnostics/topics/diagnostic-manager.rst b/gcc/doc/libgdiagnostics/topics/diagnostic-manager.rst new file mode 100644 index 0000000..e370cfc --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/diagnostic-manager.rst @@ -0,0 +1,58 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Diagnostic Managers +=================== + +.. type:: diagnostic_manager; + +A :type:`diagnostic_manager` is an opaque bundle of state for a client of +libgdiagnostics. + +It has zero of more "output sinks" to which diagnostics are emitted. + +Responsibilities include: + +* location-management + +* caching of source file content + +* patch generation + +.. function:: diagnostic_manager *diagnostic_manager_new (void) + + Create a new diagnostic_manager. + The caller will need to call :func:`diagnostic_release_manager` + on it at some point. + + .. note:: No output sinks are created by default; so you will want + to create one with something like: + + .. code-block:: + + diagnostic_manager_add_text_sink (diag_mgr, stderr, + DIAGNOSTIC_COLORIZE_IF_TTY); + +.. function:: void diagnostic_manager_release (diagnostic_manager *diag_mgr) + + Release a diagnostic_manager. + + This will flush output to all of the output sinks, and clean up. + + The parameter must be non-NULL. diff --git a/gcc/doc/libgdiagnostics/topics/diagnostics.rst b/gcc/doc/libgdiagnostics/topics/diagnostics.rst new file mode 100644 index 0000000..66f0a25 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/diagnostics.rst @@ -0,0 +1,127 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Diagnostics +=========== + +.. type:: diagnostic + +A :type:`diagnostic` is an opaque bundle of state for a particular +diagnostic that is being constructed in memory. + + +Lifecycle of a diagnostic +************************* + +Diagnostics are + +* *created* from a :type:`diagnostic_manager` by using + :func:`diagnostic_begin`, then + +* *populated* with data, such as physical locations, logical locations, + metadata, execution paths, or fix-it hints, then + +* *finished*, in which a formatting string and arguments are given, + via a call to :func:`diagnostic_finish` or :func:`diagnostic_finish_va`. + The :type:`diagnostic_manager` will emit the diagnostic to all of the + manager's output sinks (either immediately, or at some later time, + depending on the sink). + + Once a :type:`diagnostic` has had one of these "finish" functions called + on it, it is freed, and is no longer valid for use. + + The formatting strings use their own syntax; see :doc:`message-formatting`. + +.. function:: diagnostic *diagnostic_begin (diagnostic_manager *diag_mgr, \ + enum diagnostic_level level) + + Create a new :type:`diagnostic` associated with the given + :type:`diagnostic_manager`. + + The parameter ``diag_mgr`` must be non-NULL. + + The parameter ``level`` describes the severity of the diagnostic. + +.. enum:: diagnostic_level + + This enum describes the severity of a particular diagnostic. + + .. macro:: DIAGNOSTIC_LEVEL_ERROR + + A problem sufficiently severe that the program cannot successfully + complete, or where the input being analyzed is definitely wrong + (e.g. malformed). + + .. macro:: DIAGNOSTIC_LEVEL_WARNING + + A problem where the input is technically correct, but is likely + not what the user intended, such as common mistakes, or other + unusual conditions that *may* indicate trouble, such as use of + obsolete features. + + .. macro:: DIAGNOSTIC_LEVEL_NOTE + + A supplementary message added to another :type:`diagnostic`, giving + extra information that may help the user understand it. + + .. macro:: DIAGNOSTIC_LEVEL_SORRY + + A problem where the input is valid, but the tool isn't + able to handle it. + +.. function:: void diagnostic_finish (diagnostic *diag, const char *fmt, ...) + + Emit ``diag`` to all sinks of its manager, and release ``diag``. It is not + valid to use ``diag`` after this call. + + Use parameter ``fmt`` for the message. + Note that this uses gcc's pretty-print format, which is *not* printf. + See :doc:`message-formatting`. + + Both ``diag`` and ``fmt`` must be non-NULL. + + TODO: who is responsible for putting FMT through gettext? + +.. function:: void diagnostic_finish_va (diagnostic *diag, const char *fmt, va_list *args) + + This is equivalent to :func:`diagnostic_finish`, but using a + :type:`va_list` rather than directly taking variadic arguments. + + All three parameters must be non-NULL. + + +Diagnostic groups +***************** + +See :doc:`the "adding notes" section of the tutorial <../tutorial/04-notes>` +for an example of a diagnostic group. + +.. function:: void diagnostic_manager_begin_group (diagnostic_manager *diag_mgr) + + Begin a diagnostic group. All diagnostics emitted within + ``diag_mgr`` after the first one will be treated as additional information + relating to the initial diagnostic. + + The parameter ``diag_mgr`` must be non-NULL. + +.. function:: void diagnostic_manager_end_group (diagnostic_manager *diag_mgr) + + Finish a diagnostic group. + + The parameter ``diag_mgr`` must be non-NULL. diff --git a/gcc/doc/libgdiagnostics/topics/execution-paths.rst b/gcc/doc/libgdiagnostics/topics/execution-paths.rst new file mode 100644 index 0000000..3f4109c --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/execution-paths.rst @@ -0,0 +1,93 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Execution paths +=============== + +.. type:: diagnostic_execution_path + +A :type:`diagnostic` can optionally contain a :type:`diagnostic_execution_path` +describing a path of execution through code. + +.. function:: diagnostic_execution_path * diagnostic_add_execution_path (diagnostic *diag) + + Create and borrow a pointer to an execution path for ``diag``. + + The path is automatically cleaned up when ``diag`` is finished. + + ``diag`` must be non-NULL. + +.. function:: diagnostic_execution_path * diagnostic_manager_new_execution_path (diagnostic_manager *diag_mgr) + + Create a new execution path. This is owned by the caller and must have either + :func:`diagnostic_take_execution_path` or + :func:`diagnostic_execution_path_release` called on it. + + ``diag_mgr`` must be non-NULL. + +.. function:: void diagnostic_take_execution_path (diagnostic *diag, diagnostic_execution_path *path) + + Set ``diag`` to use ``path`` as its execution path, taking ownership of ``path``. + + Both parameters must be non-NULL. + +.. function:: void diagnostic_execution_path_release (diagnostic_execution_path *path) + + Release ownership of ``path``, which must not have been taken by a diagnostic. + +.. type:: diagnostic_event_id + +A :type:`diagnostic_event_id` identifies a particular event within a +:type:`diagnostic_execution_path` and can be used for expressing +cross-references between events. In particular FIXME + +.. function:: diagnostic_event_id diagnostic_execution_path_add_event (diagnostic_execution_path *path, \ + const diagnostic_physical_location *physical_loc, \ + const diagnostic_logical_location *logical_loc, \ + unsigned stack_depth, \ + const char *fmt, ...) + + Append an event to the end of ``path``, which must be non-NULL. + + ``physical_loc`` can be NULL, or non-NULL to associate the event + with a :type:`diagnostic_physical_location`. + + ``logical_loc`` can be NULL, or non-NULL to associate the event + with a :type:`diagnostic_logical_location`. + + ``stack_depth`` is for use in interprocedural paths and identifies the + depth of the stack at the event. Purely intraprocedural paths should + use a stack depth of 1 for their events + + ``fmt`` must be non-NULL. See :doc:`message-formatting` for details of + how to use it. + +.. function:: diagnostic_event_id diagnostic_execution_path_add_event_va (diagnostic_execution_path *path, \ + const diagnostic_physical_location *physical_loc, \ + const diagnostic_logical_location *logical_loc, \ + unsigned stack_depth, \ + const char *fmt, \ + va_list *args) + + Equivalent to :func:`diagnostic_execution_path_add_event`, but using a + :type:`va_list` rather than directly taking variadic arguments. + +Paths are printed to text sinks, and for SARIF sinks each path is added as +a ``codeFlow`` object (see SARIF 2.1.0 +`3.36 codeFlow object `_). diff --git a/gcc/doc/libgdiagnostics/topics/fix-it-hints.rst b/gcc/doc/libgdiagnostics/topics/fix-it-hints.rst new file mode 100644 index 0000000..08acb71 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/fix-it-hints.rst @@ -0,0 +1,135 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Fix-it hints +============ + +Adding fix-it hints to a diagnostic +*********************************** + +A :type:`diagnostic` can contain "fix-it hints", giving suggestions +for the user on how to edit their code to fix a problem. These +can be expressed as insertions, replacements, and removals of text. + +There is only limited support for newline characters in fix-it hints: +only hints with newlines which insert an entire new line are permitted, +inserting at the start of a line, and finishing with a newline +(with no interior newline characters). Other attempts to add +fix-it hints containing newline characters will fail. +Similarly, attempts to delete or replace a range *affecting* multiple +lines will fail. + +The API handles these failures gracefully, so that diagnostics can attempt +to add fix-it hints without each needing extensive checking. + +Fix-it hints are printed to text sinks, and are emitted by SARIF sinks +as ``fix`` objects (see SARIF 2.1.0 +`3.55 fix object `_). + +Fix-it hints within a :type:`diagnostic` are "atomic": if any hints can't +be applied, none of them will be, and no fix-its hints will be displayed +for that diagnostic. This implies that diagnostic messages need to be worded +in such a way that they make sense whether or not the fix-it hints +are displayed. + +All fix-it hints within one :type:`diagnostic` must affect the same +:type:`diagnostic_file`. + +.. function:: void diagnostic_add_fix_it_hint_insert_before (diagnostic *diag, \ + const diagnostic_physical_location *loc, \ + const char *addition) + + Add a fix-it hint to ``diag`` suggesting the insertion of the string + ``addition`` before ``LOC``. + + For example:: + + ptr = arr[0]; + ^~~~~~ + & + + This :type:`diagnostic` has a single location covering ``arr[0]``, + with the caret at the start. It has a single insertion fix-it hint, + inserting ``&`` before the start of ``loc``. + +.. function:: void diagnostic_add_fix_it_hint_insert_after (diagnostic *diag, \ + const diagnostic_physical_location *loc, \ + const char *addition) + + Add a fix-it hint to ``diag`` suggesting the insertion of the string + ``addition`` after the end of ``LOC``. + + For example, in:: + + #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2) + ^~~~ ^~~~ ^~~~ + ( ) ( ) ( ) + + + the :type:`diagnostic` has three physical locations, covering ``ARG0``, + ``ARG1``, and ``ARG2``, and 6 insertion fix-it hints: each arg + has a pair of insertion fix-it hints, suggesting wrapping + them with parentheses: one a '(' inserted before, + the other a ')' inserted after. + +.. function:: void diagnostic_add_fix_it_hint_replace (diagnostic *diag, \ + const diagnostic_physical_location *loc, \ + const char *replacement) + + Add a fix-it hint to ``diag`` suggesting the replacement of the text + at ``LOC`` with the string ``replacement``. + + For example, in:: + + c = s.colour; + ^~~~~~ + color + + This :type:`diagnostic` has a single physical location covering ``colour``, + and a single "replace" fix-it hint, covering the same range, suggesting + replacing it with ``color``. + +.. function:: void diagnostic_add_fix_it_hint_delete (diagnostic *diag, \ + const diagnostic_physical_location *loc) + + Add a fix-it hint to ``diag`` suggesting the deletion of the text + at ``LOC``. + + + For example, in:: + + struct s {int i};; + ^ + - + + This :type:`diagnostic` has a single physical location at the stray + trailing semicolon, along with a single removal fix-it hint, covering + the same location. + + +Generating patches +****************** + +.. function:: void diagnostic_manager_write_patch (diagnostic_manager *diag_mgr, \ + FILE *dst_stream) + + Write a patch to ``dst_stream`` consisting of the effect of all fix-it hints + on all diagnostics that have been finished on ``diag_mgr``. + + Both parameters must be non-NULL. diff --git a/gcc/doc/libgdiagnostics/topics/index.rst b/gcc/doc/libgdiagnostics/topics/index.rst new file mode 100644 index 0000000..064340b --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/index.rst @@ -0,0 +1,38 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + + +Topic reference +=============== + +.. toctree:: + :maxdepth: 2 + + retrofitting.rst + diagnostic-manager.rst + diagnostics.rst + message-formatting.rst + physical-locations.rst + logical-locations.rst + metadata.rst + fix-it-hints.rst + execution-paths.rst + text-output.rst + sarif.rst + ux.rst diff --git a/gcc/doc/libgdiagnostics/topics/logical-locations.rst b/gcc/doc/libgdiagnostics/topics/logical-locations.rst new file mode 100644 index 0000000..85900b6 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/logical-locations.rst @@ -0,0 +1,109 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Logical locations +================= + +A "logical" location is a location expressed in terms of +construct in a programming language, such as ``within function 'foo'`` +(as opposed to a :doc:`"physical" location `, which +refers to a specific file, and line(s) and/or column(s)) + +Creating location information +***************************** + +.. type:: diagnostic_logical_location + +A :type:`diagnostic_logical_location` is an opaque type describing a "logical" +source location + +.. function:: const diagnostic_logical_location * diagnostic_manager_new_logical_location (diagnostic_manager *diag_mgr, \ + enum diagnostic_logical_location_kind_t kind, \ + const diagnostic_logical_location *parent, \ + const char *short_name, \ + const char *fully_qualified_name, \ + const char *decorated_name) + + Create a :type:`diagnostic_logical_location`. + + ``diag_mgr`` must be non-NULL. + + ``kind`` describes the kind of logical location: + + .. enum:: diagnostic_logical_location_kind_t + + This roughly corresponds to the ``kind`` property in SARIF v2.1.0 + (`§3.33.7 `_). + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER + + .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE + + ``parent`` can be NULL; if non-NULL it can be used to express tree-like + nesting of logical locations, such as in:: + + namespace foo { namespace bar { class baz { baz (); }; } } + + where a diagnostic within ``baz``'s constructor could be reported + as being within ``foo::bar::baz::baz`` where the logical locations + are two namespaces, a type, and a member, respectively. + + ``short_name`` can be NULL, or else a string suitable for use by + the SARIF logicalLocation ``name`` property + (SARIF v2.1.0 `§3.33.4 `_). + + ``fully_qualified_name`` can be NULL or else a string suitable for use by + the SARIF logicalLocation ``fullyQualifiedName`` property + (SARIF v2.1.0 `§3.33.5 `_). + + ``decorated_name`` can be NULL or else a string suitable for use by + the SARIF logicalLocation ``decoratedName`` property + (SARIF v2.1.0 `§3.33.6 `_). + +.. function:: void diagnostic_manager_debug_dump_logical_location (const diagnostic_manager *diag_mgr, \ + const diagnostic_logical_location *loc, \ + FILE *out) + + Write a representation of ``file`` to ``out``, for debugging. + Both ``diag_mgr`` and ``out`` must be non-NULL. + ``file`` may be NULL. + + TODO: example of output + +Associating diagnostics with locations +************************************** + +.. function:: void diagnostic_set_logical_location (diagnostic *diag, \ + const diagnostic_logical_location *logical_loc) + + Set the logical location of ``diag``. + + ``diag`` must be non-NULL; ``logical_loc`` can be NULL. diff --git a/gcc/doc/libgdiagnostics/topics/message-formatting.rst b/gcc/doc/libgdiagnostics/topics/message-formatting.rst new file mode 100644 index 0000000..086e894 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/message-formatting.rst @@ -0,0 +1,224 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Message formatting +================== + +Various libgdiagnostics entrypoints take a format string and +variadic arguments. + +The format strings take codes prefixed by ``%``, or ``%q`` to put +the result in quotes. For example:: + + "hello %s", "world" + +would print:: + + hello world + +whereas:: + + "hello %qs", "world" + +would print:: + + hello `world' + +where ```world'`` would be displayed in bold if colorization were enabled +in the terminal. + +The following format specifiers are accepted: + + +Numbers +******* + +``d`` and ``i`` (``signed int``), ``u`` (``unsigned int``) + ``%d``, ``%i``, and ``%u`` print integers in base ten. For example:: + + "the answer is %i", 42 + + would print:: + + the answer is 42 + +``o`` (``unsigned int``) + Print the integer in base eight + +``x`` (``unsigned int``) + Print the integer in base sixteen + +The above can be prefixed with ``l`` and ``ll`` prefixes to take +``long`` and ``long long`` values of the appropriate signedness. + +For example:: + + "address: %lx", (unsigned long)0x108b516 + +would print:: + + address: 108b516 + +Similarly, the prefix ``z`` can be used for ``size_t``:: + + "size: %zd", sizeof(struct foo) + size: 32 + +and ``t`` for ptrdiff_t. + +``f`` (``double``) + ``%f`` prints a floating-point value. For example:: + + "value: %f", 1.0 + + might print:: + + value: 1.000000 + + +Strings +******* + +``c`` (``char``) + ``%c`` prints a single character. + +``s`` (``const char *``) + ``%s`` prints a string. + + Note that if the string refers to something that might + appear in the input file (such as the name of a function), it's better + to quote the value; for example:: + + "unrecognized identifier: %qs", "foo" + + might print:: + + unrecognized identifier: `foo' + +``m`` (no argument) + Prints ``strerror(errno)``, for example:: + + "can't open %qs: %m" + + might print:: + + can't open `foo.txt': No such file or directory + +``%`` (no argument) + ``%%`` prints a `%` character, for example:: + + "8%% of 75 is 75%% of 8, and is thus 6" + + prints:: + + 8% of 75 is 75% of 8, and is thus 6 + +``'`` (no argument) + ``%'`` prints an apostrophe. This should only be used in untranslated messages; + translations should use appropriate punctuation directly. + + +Other format specifiers +*********************** + +``p`` (pointer) + ``%p`` prints a pointer, although the precise format is + implementation-defined. + +``r`` (``const char *``) + ``%r`` starts colorization on suitable text sinks, where the argument + specifies the name of the kind of entity to be colored, such as ``error``. + +``R`` (no argument) + ``%R`` stops colorization + +``<`` and ``>`` (no arguments) + ``%<`` adds an opening quote and ``%>`` a closing quote, such as:: + + "missing element %<%s:%s%>", ns, name + + which might be printed as:: + + missing element `xhtml:head' + + If the thing to be quoted can be handled with another format specifier, + then it's simpler to use ``q`` with it. For example, it's much + simpler to print a ``const char *`` in quotes via:: + + "%qs", str + + rather than the error-prone:: + + "%<%s%>", str + +``{`` (``const char *``) + ``%{`` starts a link; the argument is the URL. This will be displayed + in a suitably-capable terminal if a text sink is directly connected to + a tty, and will be captured in SARIF output. + +``}`` (no argument) + ``%}`` stops a link started with ``%{``. + + For example:: + + "for more information see %{the documentation%}", "https://example.com" + + would be printed as:: + + for more information see the documentation + + with the URL emitted in suitable output sinks. + +``@`` (``diagnostic_event_id *``) + ``%@`` prints a reference to an event in a + :type:`diagnostic_execution_path`, where the :type:`diagnostic_event_id` + is passed by pointer. + + For example, if ``event_id`` refers to the first event in a path, then:: + + "double-%qs of %qs; first %qs was at %@", + function, ptr, function, &event_id + + might print:: + + double-`free' of `p'; first `free` was at (1) + +.. : + + TODO: + + %.*s: a substring the length of which is specified by an argument + integer. + %Ns: likewise, but length specified as constant in the format string. + %Z: Requires two arguments - array of int, and len. Prints elements + of the array. + + %e: Consumes a pp_element * argument. + + Arguments can be used sequentially, or through %N$ resp. *N$ + notation Nth argument after the format string. If %N$ / *N$ + notation is used, it must be used for all arguments, except %m, %%, + %<, %>, %} and %', which may not have a number, as they do not consume + an argument. When %M$.*N$s is used, M must be N + 1. (This may + also be written %M$.*s, provided N is not otherwise used.) The + format string must have conversion specifiers with argument numbers + 1 up to highest argument; each argument may only be used once. + A format string can have at most 30 arguments. */ + + diff --git a/gcc/doc/libgdiagnostics/topics/metadata.rst b/gcc/doc/libgdiagnostics/topics/metadata.rst new file mode 100644 index 0000000..c62792a --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/metadata.rst @@ -0,0 +1,149 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Adding metadata +=============== + +Tool metadata +************* + +It's possible to set up various metadata on the :type:`diagnostic_manager` +as a whole, describing the program creating the diagnostics. + +.. note:: + + It's not required to set up any of this up on a + :type:`diagnostic_manager`. However, if you are doing + :doc:`SARIF output `, then you need to at least call + :func:`diagnostic_manager_set_tool_name` or the generated ``.sarif`` + file will not validate against the schema. + +.. function:: void diagnostic_manager_set_tool_name (diagnostic_manager *diag_mgr, \ + const char *value) + + Set a string for the name of the tool emitting the diagnostics. + + Both parameters must be non-NULL. + + If set, this string will be used + + * by :doc:`text output sinks ` as a prefix for output + when no physical location is available, replacing ``progname`` + in the following: + + .. code-block:: console + + $ ./tut01-hello-world + progname: error: I'm sorry Dave, I'm afraid I can't do that + + * by :doc:`SARIF output sinks ` as the value for the + ``name`` property of the ``driver`` + (`SARIF v2.1.0 §3.19.8 `_). + +.. function:: void diagnostic_manager_set_full_name (diagnostic_manager *diag_mgr, \ + const char *value) + + Set a string giving the name of the tool along with the its version and + other useful information:: + + diagnostic_manager_set_full_name (diag_mgr, "FooChecker 0.1 (en_US)"); + + If set, this string will be used by :doc:`SARIF output sinks ` as + the value for the ``fullName`` property of the ``driver`` + (`SARIF v2.1.0 §3.19.9 `_). + + Both parameters must be non-NULL. + +.. function:: void diagnostic_manager_set_version_string (diagnostic_manager *diag_mgr, \ + const char *value) + + Set a string suitable for use as the value of the SARIF ``version`` property + of the ``driver``. + (`SARIF v2.1.0 §3.19.13 `_):: + + diagnostic_manager_set_version_string (diag_mgr, "0.1"); + + Both parameters must be non-NULL. + +.. function:: void diagnostic_manager_set_version_url (diagnostic_manager *diag_mgr, \ + const char *value) + + Set a string suitable for use as the value of the SARIF ``informationUri`` + property of the ``driver``. + (`SARIF v2.1.0 §3.19.17 `_):: + + diagnostic_manager_set_version_url (diag_mgr, + "https://www.example.com/foo-checker/releases/0.1/"); + + Both parameters must be non-NULL. + +Adding metadata to a diagnostic +******************************* + +.. function:: void diagnostic_set_cwe (diagnostic *diag, \ + unsigned cwe_id) + + Associate ``diag`` with the given ID within + the `Common Weakness Enumeration `_:: + + /* CWE-242: Use of Inherently Dangerous Function. */ + diagnostic_set_cwe (d, 242); + + ``diag`` must be non-NULL. + + The CWE value will be printed by text sinks after the message:: + + test-metadata.c:21:3: warning: never use 'gets' [CWE-242] + + and in a sufficiently-capable terminal will be a link to + documentation about the CWE. + +.. function:: void diagnostic_add_rule (diagnostic *diag, \ + const char *title, \ + const char *url) + + Associate this :type:`diagnostic` with a particular rule that has been + violated (such as in a coding standard, or within a specification). + + A diagnostic can be associated with zero or more rules. + + ``diag`` must be non-NULL. The rule must have at least one of a + title and a URL, but these can be NULL. + + For example, given:: + + diagnostic_add_rule (d, + "MSC24-C", + "https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions"); + + the rule name will be printed by text sinks after the message:: + + test-metadata.c:21:3: warning: never use 'gets' [MSC24-C] + 21 | gets (buf); + | ^~~~~~~~~~ + + and if so, the URL will be available in a sufficiently capable + terminal. + + This can be used in conjunction with :func:`diagnostic_set_cwe`, + giving output like this:: + + test-metadata.c:21:3: warning: never use 'gets' [CWE-242] [MSC24-C] + 21 | gets (buf); + | ^~~~~~~~~~ diff --git a/gcc/doc/libgdiagnostics/topics/physical-locations.rst b/gcc/doc/libgdiagnostics/topics/physical-locations.rst new file mode 100644 index 0000000..cf10f53 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/physical-locations.rst @@ -0,0 +1,281 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Physical locations +================== + +A "physical" source location is a location expressed in terms of +a specific file, and line(s) and column(s) (as opposed to a +:doc:`"logical" location `, +which refers to semantic constructs in a programming language). + +Creating location information +***************************** + +The :type:`diagnostic_manager` manages various objects relating to +locations. + +.. type:: diagnostic_file + + A :type:`diagnostic_file` is an opaque type describing a particular input file. + +.. function:: const diagnostic_file * diagnostic_manager_new_file (diagnostic_manager *diag_mgr, \ + const char *name, \ + const char *sarif_source_language) + + Create a new :type:`diagnostic_file` for file ``name``. Repeated calls + with strings that match ``name`` will return the same object. + + Both ``diag_mgr`` and ``name`` must be non-NULL. + + If ``sarif_source_language`` is non-NULL, it specifies a + ``sourceLanguage`` value for the file for use when writing + :doc:`SARIF ` + (`SARIF v2.1.0 §3.24.10 `_). + See + `SARIF v2.1.0 Appendix J `_ + for suggested values for various programmming languages. + + For example, this creates a :type:`diagnostic_file` for ``foo.c`` + and identifies it as C source code:: + + foo_c = diagnostic_manager_new_file (diag_mgr, + "foo.c", + "c" /* source_language */); + +.. function:: void diagnostic_manager_debug_dump_file (diagnostic_manager *diag_mgr, \ + const diagnostic_file *file, \ + FILE *out) + + Write a representation of ``file`` to ``out``, for debugging. + Both ``diag_mgr`` and ``out`` must be non-NULL. + `file`` may be NULL. + + For example:: + + diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr); + + might lead to this output:: + + file(name="foo.c", sarif_source_language="c") + +.. type:: diagnostic_line_num_t + +A :type:`diagnostic_line_num_t` is used for representing line numbers +within text files. libgdiagnostics treats the first line of a text file +as line 1. + +.. type:: diagnostic_column_num_t + +A :type:`diagnostic_column_num_t` is used for representing column numbers +within text files. libgdiagnostics treats the first column of a text line +as column 1, **not** column 0. + +.. note:: + + Both libgdiagnostics and Emacs number source *lines* starting at 1, but + they have differing conventions for *columns*. + + libgdiagnostics uses a 1-based convention for source columns, + whereas Emacs's ``M-x column-number-mode`` uses a 0-based convention. + + For example, an error in the initial, left-hand + column of source line 3 is reported by libgdiagnostics as:: + + some-file.c:3:1: error: ...etc... + + On navigating to the location of that error in Emacs + (e.g. via ``next-error``), + the locus is reported in the Mode Line + (assuming ``M-x column-number-mode``) as:: + + some-file.c 10% (3, 0) + + i.e. ``3:1:`` in libgdiagnostics corresponds to ``(3, 0)`` in Emacs. + +.. type:: diagnostic_physical_location + +A :type:`diagnostic_physical_location` is an opaque type representing a +key into a database of source locations within a :type:`diagnostic_manager`. + +:type:`diagnostic_physical_location` instances are created by various API +calls into the :type:`diagnostic_manager` expressing source code points +and ranges. + +They persist until the :type:`diagnostic_manager` is released, which +cleans them up. + +A ``NULL`` value means "unknown", and can be returned by the +:type:`diagnostic_manager` as a fallback when a problem occurs +(e.g. too many locations). + +A :type:`diagnostic_physical_location` can be a single point within the +source code, such as here (at the the '"' at the start of the string literal):: + + int i = "foo"; + ^ + +or be a range with a start and finish, and a "caret" location:: + + a = (foo && bar) + ~~~~~^~~~~~~ + +where the caret here is at the first "&", and the start and finish +are at the parentheses. + +.. function:: const diagnostic_physical_location *diagnostic_manager_new_location_from_file_and_line (diagnostic_manager *diag_mgr, \ + const diagnostic_file *file, \ + diagnostic_line_num_t line_num) + + Attempt to create a :type:`diagnostic_physical_location` representing + ``FILENAME:LINE_NUM``, with no column information (thus representing + the whole of the given line. + + Both ``diag_mgr`` and ``file`` must be non-NULL. + +.. function:: const diagnostic_physical_location * diagnostic_manager_new_location_from_file_line_column (diagnostic_manager *diag_mgr, \ + const diagnostic_file *file, \ + diagnostic_line_num_t line_num, \ + diagnostic_column_num_t column_num) + + Attempt to create a :type:`diagnostic_physical_location` for + ``FILENAME:LINE_NUM:COLUMN_NUM`` representing a particular point + in the source file. + + Both ``diag_mgr`` and ``file`` must be non-NULL. + +.. function:: const diagnostic_physical_location *diagnostic_manager_new_location_from_range (diagnostic_manager *diag_mgr,\ + const diagnostic_physical_location *loc_caret,\ + const diagnostic_physical_location *loc_start,\ + const diagnostic_physical_location *loc_end) + + Attempt to create a diagnostic_physical_location representing a + range within a source file, with a highlighted "caret" location. + + All must be within the same file, but they can be on different lines. + + For example, consider the location of the binary expression below:: + + ...|__________1111111112222222 + ...|12345678901234567890123456 + ...| + 521|int sum (int foo, int bar) + 522|{ + 523| return foo + bar; + ...| ~~~~^~~~~ + 524|} + + The location's caret is at the "+", line 523 column 15, but starts + earlier, at the "f" of "foo" at column 11. The finish is at the "r" + of "bar" at column 19. + + ``diag_mgr`` must be non-NULL. + +.. function:: void diagnostic_manager_debug_dump_location (const diagnostic_manager *diag_mgr,\ + const diagnostic_physical_location *loc, \ + FILE *out) + + Write a representation of ``loc`` to ``out``, for debugging. + + Both ``diag_mgr`` and ``out`` must be non-NULL. + `loc`` may be NULL. + + TODO: example of output + +Associating diagnostics with locations +************************************** + +A :type:`diagnostic` has an optional primary physical location +and zero or more secondary physical locations. For example:: + + a = (foo && bar) + ~~~~~^~~~~~~ + +This diagnostic has a single :type:`diagnostic_physical_location`, +with the caret at the first "&", and the start/finish at the parentheses. + +Contrast with:: + + a = (foo && bar) + ~~~ ^~ ~~~ + +This diagnostic has three locations + +* The primary location (at "&&") has its caret and start location at + the first "&" and end at the second "&. + +* The secondary location for "foo" has its start and finish at the "f" + and "o" of "foo"; the caret is not displayed, but is perhaps at + the "f" of "foo". + +* Similarly, the other secondary location (for "bar") has its start and + finish at the "b" and "r" of "bar"; the caret is not displayed, but + is perhaps at the"b" of "bar". + +.. function:: void diagnostic_set_location (diagnostic *diag, \ + const diagnostic_physical_location * loc) + + Set the primary location of ``diag``. + + ``diag`` must be non-NULL; ``loc`` can be NULL. + +.. function:: void diagnostic_set_location_with_label (diagnostic *diag, \ + const diagnostic_physical_location *loc, \ + const char *fmt, ...) + + Set the primary location of ``diag``, with a label. The label is + formatted as per the rules FIXME + + ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL. + + See :doc:`message-formatting` for details of how to use ``fmt``. + + TODO: example of use + +.. function:: void diagnostic_add_location (diagnostic *diag, \ + const diagnostic_physical_location * loc) + + Add a secondary location to ``diag``. + + ``diag`` must be non-NULL; ``loc`` can be NULL. + + +.. function:: void diagnostic_add_location_with_label (diagnostic *diag, \ + const diagnostic_physical_location *loc, \ + const char *text) + + Add a secondary location to ``diag``, with a label. The label is + formatted as per the rules FIXME + + ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL. + + For example, + + .. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-labelled-ranges.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + + might give this text output:: + + test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' + 19 | 42 + "foo" + | ~~ ^ ~~~~~ + | | | + | int const char * diff --git a/gcc/doc/libgdiagnostics/topics/retrofitting.rst b/gcc/doc/libgdiagnostics/topics/retrofitting.rst new file mode 100644 index 0000000..3c7198d --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/retrofitting.rst @@ -0,0 +1,23 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Adding libgdiagnostics to an existing project +============================================= + +TODO diff --git a/gcc/doc/libgdiagnostics/topics/sarif.rst b/gcc/doc/libgdiagnostics/topics/sarif.rst new file mode 100644 index 0000000..3fd75ed --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/sarif.rst @@ -0,0 +1,51 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +SARIF support +============= + +`SARIF `_ is a machine-readable format, originally +designed for the output of static analysis tools, but which can be used +for diagnostics in general. + +.. function:: void diagnostic_manager_add_sarif_sink (diagnostic_manager *diag_mgr, \ + FILE *dst_stream, \ + const diagnostic_file *main_input_file, \ + enum diagnostic_sarif_version version) + + Add a new output sink to ``diag_mgr``, which writes SARIF of the given + version to ``dst_stream``. + + The output is not written until ``diag_mgr`` is released. + + ``dst_stream`` is borrowed, and must outlive ``diag_mgr``. + + For the result to be a valid SARIF file according to the schema, + ``diag_mgr`` must have had :func:`diagnostic_manager_set_tool_name` + called on it. + + ``diag_mgr``, ``dst_stream``, and ``main_input_file`` must all be non-NULL. + + .. enum:: diagnostic_sarif_version + + An enum for choosing the SARIF version for a SARIF output sink. + + .. macro:: DIAGNOSTIC_SARIF_VERSION_2_1_0 + + .. macro:: DIAGNOSTIC_SARIF_VERSION_2_2_PRERELEASE diff --git a/gcc/doc/libgdiagnostics/topics/text-output.rst b/gcc/doc/libgdiagnostics/topics/text-output.rst new file mode 100644 index 0000000..32b2a54 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/text-output.rst @@ -0,0 +1,87 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Text output +=========== + +.. type:: diagnostic_text_sink + +.. function:: diagnostic_text_sink * diagnostic_manager_add_text_sink (diagnostic_manager *diag_mgr,\ + FILE *dst_stream, \ + enum diagnostic_colorize colorize) + + Add a new output sink to ``diag_mgr``, which writes GCC-style diagnostics + to ``dst_stream``. + Return a borrowed pointer to the sink, which is cleaned up when ``diag_mgr`` + is released. + + ``diag_mgr`` must be non-NULL. + + ``dst_stream`` must be non-NULL. It is borrowed and must outlive ``DIAG_MGR``. + + The output for each diagnostic is written and flushed as each + :type:`diagnostic` is finished. + + .. enum:: diagnostic_colorize + + An enum for determining if we should colorize a text output sink. + + .. macro:: DIAGNOSTIC_COLORIZE_IF_TTY + + Diagnostics should be colorized if the destination stream is + directly connected to a tty. + + .. macro:: DIAGNOSTIC_COLORIZE_NO + + Diagnostics should not be colorized. + + .. macro:: DIAGNOSTIC_COLORIZE_YES + + Diagnostics should be colorized. + +.. function:: void diagnostic_text_sink_set_source_printing_enabled (diagnostic_text_sink *text_sink, \ + int value) + + Enable or disable printing of source text in the text sink. + + ``text_sink`` must be non-NULL. + + Default: enabled. + +.. function:: void diagnostic_text_sink_set_colorize (diagnostic_text_sink *text_sink, \ + enum diagnostic_colorize colorize) + + Update colorization of text sink. + + ``text_sink`` must be non-NULL. + +.. function:: void diagnostic_text_sink_set_labelled_source_colorization_enabled (diagnostic_text_sink *text_sink, \ + int value) + + ``text_sink`` must be non-NULL. + + Enable or disable colorization of the characters of source text + that are underlined. + + This should be true for clients that generate range information + (so that the ranges of code are colorized), and false for clients that + merely specify points within the source code (to avoid e.g. colorizing + just the first character in a token, which would look strange). + + Default: enabled. diff --git a/gcc/doc/libgdiagnostics/topics/ux.rst b/gcc/doc/libgdiagnostics/topics/ux.rst new file mode 100644 index 0000000..fc96e17 --- /dev/null +++ b/gcc/doc/libgdiagnostics/topics/ux.rst @@ -0,0 +1,26 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +User Experience +=============== + +Refer to +`GCC's user experience guidelines `_ +for notes on +`what makes a good diagnostic `_. diff --git a/gcc/doc/libgdiagnostics/tutorial/01-hello-world.rst b/gcc/doc/libgdiagnostics/tutorial/01-hello-world.rst new file mode 100644 index 0000000..67f54c0 --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/01-hello-world.rst @@ -0,0 +1,173 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 1: "Hello world" +============================== + +Before we look at the details of the API, let's look at building and +running programs that use the library. + +Here's a toy program that uses libgdiagnostics to emit an error message +to stderr. + + .. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-example-1.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +Copy the above to `tut01-hello-world.c`. + +Assuming you have libgdiagnostics installed, build the test program +using: + +.. code-block:: console + + $ gcc \ + tut01-hello-world.c \ + -o tut01-hello-world \ + -ldiagnostics + +You should then be able to run the built program: + +.. code-block:: console + + $ ./tut01-hello-world + progname: error: I'm sorry Dave, I'm afraid I can't do that + +If stderr is connected to a terminal, you should get colorized output +(using `SGR control codes `_). + +.. image:: example-1.png + +Otherwise, the output will be plain text. + +Obviously a trivial example like the above could be done using ``fprintf`` +on stderr, and it's fairly easy to colorize text at the terminal. + +In :doc:`the next part of the tutorial <02-physical-locations>` we'll add +file/location information to our error messages, and libgdiagnostics will +quote the pertinent parts of the file, underlining them, which is less trivial +to reimplement. libgdiagnostics gives us many other such abilities, such as +fix-it hints and execution paths, which we'll cover in the following +tutorials. Also, once a program's diagnostics are using libgdiagnostics, +it is trivial to add support for outputting them in +machine-readable form as :doc:`SARIF <../topics/sarif>`. + + +Structure +********* + +The above example shows the typical structure of a program using +libgdiagnostics: + +* **initialization**: create a :type:`diagnostic_manager` instance, + and create an output sink for it, and other one-time initialization + +* **emission**: create various :type:`diagnostic` instances, populating + them with data, and calling "finish" once they're ready to be emitted. + :doc:`Text sinks <../topics/text-output>` emit their diagnostics as soon + as "finish" is called on them. + +* **cleanup**: call :func:`diagnostic_manager_release` on the + :type:`diagnostic_manager` to finish and free up resources. + :doc:`SARIF sinks <../topics/sarif>` write their output when + :func:`diagnostic_manager_release` is called on the manager. + +For non-trivial examples we'll also want to create location information, +which could happen during initialization, or during a parsing phase of +the program using libgdiagnostics. See :doc:`02-physical-locations` for +more information. + + +Formatted messages +****************** + +The above example uses :func:`diagnostic_finish`, which takes a format +string and arguments. libgdiagnostics has its own style of format +string arguments used for :func:`diagnostic_finish` and some other +entrypoints. + +.. note:: The format syntax is *not* the same as ``printf``; see + :doc:`supported formatting options <../topics/message-formatting>`. + +You can use the ``q`` modifier on arguments +to quote them, so, for example ``%qs`` is a quoted string, consuming a +``const char *`` argument:: + + diagnostic_finish (d, "can't find %qs", "foo"); + +This gives output like this: + +.. code-block:: console + + progname: error: can't find ‘foo’ + +where the quoted string will appear in bold in a suitably-capable +terminal, and the quotes will be internationalized, so that e.g. with +``LANG=fr_FR.UTF8`` we might get: + +.. code-block:: console + + progname: erreur: can't find « free » + +Note that: + +* the string ``error`` has been localized by libgdiagnostics to + ``erreur``, + +* locale-specific quoting has been used (``«`` and ``»`` rather than + ``‘`` and ``’``), + +* ``foo`` hasn't been localized - you would typically use quoted strings + for referring to identifiers in the input language (such as function names + in code, property names in JSON, etc), + +* the message itself hasn't been localized: you are responsible for + passing a translated format string to :func:`diagnostic_finish` if you + want to internationalize the output. + +There are many :doc:`supported formatting options <../topics/message-formatting>`. + + +Naming the program +****************** + +In the above output the message was preceded with ``progname``. This +appears for diagnostics that don't have any location information associated +with them. We'll look at setting up location information in the +:doc:`next tutorial <02-physical-locations>`, but we can override this +default name via :func:`diagnostic_manager_set_tool_name`:: + + diagnostic_manager_set_tool_name (diag_mgr, "my-awesome-checker"); + +leading to output like this:: + + my-awesome-checker: error: can't find ‘foo’ + +There are various other functions for +:doc:`supplying metadata to libgdiagnostics <../../topics/metadata>`. + + +Moving beyond trivial examples +****************************** + +Obviously it's not very useful if we can't refer to specific files and +specific locations in those files in our diagnostics, so read +:doc:`part 2 of the tutorial <02-physical-locations>` for information on +how to do this. diff --git a/gcc/doc/libgdiagnostics/tutorial/02-physical-locations.rst b/gcc/doc/libgdiagnostics/tutorial/02-physical-locations.rst new file mode 100644 index 0000000..71d836ed --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/02-physical-locations.rst @@ -0,0 +1,260 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 2: physical locations +=================================== + +libgdiagnostics has two kinds of location: + +* *physical locations* expressed in terms of a specific file, and line(s) + and perhaps column(s), such as ``some-file.c:3:1``, or a range of + columns, such as in:: + + test-typo.c:19:13: error: unknown field 'colour' + 19 | return p->colour; + | ^~~~~~ + + or even a range spanning multiple lines of a file. + + All of these are instances of :type:`diagnostic_physical_location`. + +* *logical locations* which refers to semantic constructs + in the input, such as ``within function 'foo'``, or within + namespace ``foo``'s class ``bar``'s member function ``get_color``. + + These are instances of :type:`diagnostic_logical_location`, + +A :type:`diagnostic` can have zero or more physical locations, +and optionally have a logical location. + +Let's extend the previous example to add a physical location to the +:type:`diagnostic`; we'll cover logical locations in the +:doc:`next section <03-logical-locations>`. + + +Source files +************ + +Given these declarations:: + + static diagnostic_manager *diag_mgr; + static const diagnostic_file *main_file; + +we can create a :type:`diagnostic_file` describing an input file ``foo.c`` +via :func:`diagnostic_manager_new_file`:: + + foo_c = diagnostic_manager_new_file (diag_mgr, + "foo.c", + "c" /* source_language */); + +You can use :func:`diagnostic_manager_debug_dump_file` to print a +representation of a :type:`diagnostic_file` for debugging. +For example:: + + diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr); + +might lead to this output on ``stderr``:: + + file(name="foo.c", sarif_source_language="c") + +Once we have a :type:`diagnostic_file` we can use it to create instances +of :type:`diagnostic_physical_location` within the :type:`diagnostic_manager`. +These are owned by the :type:`diagnostic_manager` and cleaned up +automatically when :func:`diagnostic_manager_release` is called. + +Instances of :type:`diagnostic_physical_location` can refer to + +* a source line as a whole, created via + :func:`diagnostic_manager_new_location_from_file_and_line`. + +* a particular point within a source file (line/column), created via + :func:`diagnostic_manager_new_location_from_file_line_column`. + +* a range of text within of source file, created via + :func:`diagnostic_manager_new_location_from_range`. + + +Diagnostics affecting a whole source line +***************************************** + +If we want a diagnostic to refer to an entire source line, +we can use :func:`diagnostic_manager_new_location_from_file_and_line`. + +For example, given this example input where the tool can't find the header:: + + #include + +we could complain about it via libgdiagnostics via: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-no-column.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +leading to output like this:: + + foo.c:17: error: can't find 'foo.h'" + 17 | #include + +where libgdiagnostics will attempt to load the source file and +quote the pertinent line. + +If libgdiagnostics cannot open the file, it will merely print:: + + foo.c:17: error: can't find 'foo.h' + +You can use :func:`diagnostic_manager_debug_dump_location` to dump a +:type:`diagnostic_physical_location`. For the above example:: + + diagnostic_manager_debug_dump_location (diag_mgr, loc, stderr); + +might print:: + + foo.c:17 + +to stderr. + + +Columns and ranges +****************** + +If we want to generate output like this:: + + foo.c:17:11: error: can't find 'foo'" + 17 | #include + | ^~~~~ + +where the diagnostic is marked as relating to the above range of +characters in line 17, we need to express the range of characters +within the line of interest. + +We can do this by creating a :type:`diagnostic_physical_location` for the +start of the range, another one for the end of the range, and then using +these two to create a :type:`diagnostic_physical_location` for the +range as a whole: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-error.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +On compiling and running the program, we should get this output:: + + foo.c:17:11: error: can't find 'foo.h' + 17 | #include + | ^~~~~ + +where libgdiagnostics will attempt to load the source file and +underling the pertinent part of the given line. + +If libgdiagnostics cannot open the file, it will merely print:: + + foo.c:17:8: error: can't find 'foo' + +A range can span multiple lines within the same file. + +As before, you can use :func:`diagnostic_manager_debug_dump_location` to +dump the locations. For the above example:: + + diagnostic_manager_debug_dump_location (diag_mgr, loc_start, stderr); + +and:: + + diagnostic_manager_debug_dump_location (diag_mgr, loc_range, stderr); + +might print:: + + foo.c:17:11 + +to stderr, whereas:: + + diagnostic_manager_debug_dump_location (diag_mgr, loc_end, stderr); + +might print:: + + foo.c:17:15 + + +Multiple locations +****************** + +As well as the primary physical location seen above, a :type:`diagnostic` +can have additional physical locations. You can add these secondary +locations via :func:`diagnostic_add_location`. + +For example, for this valid but suspicious-looking C code:: + + const char *strs[3] = {"foo", + "bar" + "baz"}; + +the following :type:`diagnostic` has its primary location where the missing +comma should be, and secondary locations for each of the string literals +``"foo"``, ``"bar"``, and ``"baz"``, added via :func:`diagnostic_add_location`: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-multiple-lines.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +where the text output might be:: + + test-multiple-lines.c:23:29: warning: missing comma + 22 | const char *strs[3] = {"foo", + | ~~~~~ + 23 | "bar" + | ~~~~~^ + 24 | "baz"}; + | ~~~~~ + + +Labelling locations +******************* + +You can give the locations labels using +:func:`diagnostic_set_location_with_label` and +:func:`diagnostic_add_location_with_label`. + +Consider emitting a "type mismatch" diagnostic for:: + + 42 + "foo" + +where the primary location is on the ``+``, with secondary locations on the``42`` +and the ``"foo"``: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-labelled-ranges.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +giving this text output:: + + test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *' + 19 | 42 + "foo" + | ~~ ^ ~~~~~ + | | | + | int const char * + + +More on locations +***************** + +For more details on the above, see :doc:`../topics/physical-locations`. +Otherwise the :doc:`next part of the tutorial <03-logical-locations>` +covers logical locations. diff --git a/gcc/doc/libgdiagnostics/tutorial/03-logical-locations.rst b/gcc/doc/libgdiagnostics/tutorial/03-logical-locations.rst new file mode 100644 index 0000000..d36ac09 --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/03-logical-locations.rst @@ -0,0 +1,60 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 3: logical locations +================================== + +Let's extend the previous example to add a +:doc:`logical location <../topics/logical-locations>` to the +:type:`diagnostic`. + +First we create a :type:`diagnostic_logical_location` representing a +particular function:: + + const diagnostic_logical_location *logical_loc + = diagnostic_manager_new_logical_location (diag_mgr, + DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION, + NULL, /* parent */ + "foo", + NULL, + NULL); + +In this simple example we specify that it is a function, and just give +it a name (``foo``). For more complicated cases we can set up tree-like +hierarchies of logical locations, set qualified names, "mangled" names, +and so on; see :func:`diagnostic_manager_new_logical_location` for details. + +Once we have :type:`diagnostic_logical_location` we can associate it with +a :type:`diagnostic` with :func:`diagnostic_set_logical_location`:: + + diagnostic_set_logical_location (d, logical_loc); + +The logical location will be printed by text output sinks like this:: + + In function 'foo': + +and will be captured in :doc:`SARIF <../topics/sarif>` output. + + +Find out more +************* + +For more details on the above, see :doc:`../topics/logical-locations`. +Otherwise the :doc:`next part of the tutorial <04-notes>` covers adding +supplementary "notes" to a :type:`diagnostic`. diff --git a/gcc/doc/libgdiagnostics/tutorial/04-notes.rst b/gcc/doc/libgdiagnostics/tutorial/04-notes.rst new file mode 100644 index 0000000..81755b2 --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/04-notes.rst @@ -0,0 +1,66 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 4: adding notes +============================= + +Let's further extend the previous example to add a "note" to it. + +We want to generate output like this:: + + test-with-note.c:17:11: error: can't find 'foo' + 17 | #include + | ^~~~~ + test-with-note.c:17:11: note: have you looked behind the couch? + +The "error" and "note" are both instances of :type:`diagnostic`. +We want to let libgdiagnostics know that they are grouped together. +The way to do this is to use :func:`diagnostic_manager_begin_group` +and :func:`diagnostic_manager_end_group` around the "finish" calls +to the diagnostics. + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-error-with-note.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +On compiling and running the program, we should get the desired output:: + + test-with-note.c:17:11: error: can't find 'foo' + 17 | #include + | ^~~~~ + test-with-note.c:17:11: note: have you looked behind the couch? + +The grouping doesn't affect text output sinks, but a +:doc:`SARIF sink <../topics/sarif>` will group the note within the error +(via the ``relatedLocations`` property of ``result`` objects; see SARIF v2.1.0 +`§3.27.22 `_). + +In the above, the note had the same physical location as the error +(``loc_range``). This can be useful for splitting up a message into two +parts to make localization easier, but they could have different locations, such +as in:: + + test.xml:10:2: error: 'foo' is not valid here + test.xml:5:1: note: within element 'bar' + +where each :type:`diagnostic` had its own :type:`diagnostic_physical_location`. + +In :doc:`the next tutorial <05-warnings>` we'll look at issuing warnings, +rather than errors. diff --git a/gcc/doc/libgdiagnostics/tutorial/05-warnings.rst b/gcc/doc/libgdiagnostics/tutorial/05-warnings.rst new file mode 100644 index 0000000..8362318 --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/05-warnings.rst @@ -0,0 +1,44 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 5: warnings +========================= + +So far we've only emitted errors, but other kinds of diagnostic are possible, +such as warnings. + +We can select different kinds of diagnostic via :enum:`diagnostic_level` +when calling :func:`diagnostic_begin`: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +On compiling and running the program, we should get output similar to:: + + test-warning.c:17:11: warning: this is a warning + 17 | #include + | ^~~~~ + +Various severities are possible, see :enum:`diagnostic_level` for more +information. + +In :doc:`the next section of the tutorial <06-fix-it-hints>` we'll look +at adding fix-it hints to diagnostics. diff --git a/gcc/doc/libgdiagnostics/tutorial/06-fix-it-hints.rst b/gcc/doc/libgdiagnostics/tutorial/06-fix-it-hints.rst new file mode 100644 index 0000000..f3c32ad --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/06-fix-it-hints.rst @@ -0,0 +1,61 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 6: fix-it hints +============================= + +libgdiagnostics supports adding "fix-it hints" to a :type:`diagnostic`: +suggestions for the user on how to edit their code to fix a problem. These +can be expressed as insertions, replacements, and removals of text. + +For example, here we add a replacement fix-it hint to a diagnostic: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-fix-it-hint.c + :language: c + :start-after: /* begin quoted source */ + :end-before: /* end quoted source */ + +On compiling and running the program, we should get output similar to:: + + test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color' + 19 | return p->colour; + | ^~~~~~ + | color + +We can also add a call to :func:`diagnostic_manager_write_patch` to the +program cleanup code:: + + diagnostic_manager_write_patch (diag_mgr, stderr); + +This will write a patch to the stream (here ``stderr``) giving the effect +of all fix-it hints on all diagnostics emitted by the +:type:`diagnostic_manager`, giving something like:: + + @@ -16,7 +16,7 @@ + struct rgb + get_color (struct object *p) + { + - return p->colour; + + return p->color; + } + + +See the :doc:`guide to fix-it hints <../topics/fix-it-hints>` +for more information, or go on to +:doc:`the next section of the tutorial <07-execution-paths>`. diff --git a/gcc/doc/libgdiagnostics/tutorial/07-execution-paths.rst b/gcc/doc/libgdiagnostics/tutorial/07-execution-paths.rst new file mode 100644 index 0000000..3c0ba71 --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/07-execution-paths.rst @@ -0,0 +1,141 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +.. default-domain:: c + +Tutorial part 7: execution paths +================================ + +A :type:`diagnostic` can optionally have a :type:`diagnostic_execution_path` +describing a path of execution through code. + +For example, let's pretend we're writing a static analyis tool for finding +bugs in `CPython extension code `_. + +Let's say we're analyzing this code: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c + :language: c + :start-after: begin fake source + :end-before: end fake source + +This code attempts to take an Python integer parameter and then build a +list of that length, containing random integers. However, there are +**numerous bugs** in this code: a type mismatch, mistakes in +reference-counting, and an almost total lack of error-handling. + +For example, ``PyList_Append`` requires a non-NULL first parameter (``list``), +but ``PyList_New`` can fail, returning NULL, and this isn't checked for, +which would lead to a segfault if ``PyList_New`` fails. + +We can add a :type:`diagnostic_execution_path` to the :type:`diagnostic` +via :func:`diagnostic_add_execution_path`, and then add events to it +using :func:`diagnostic_execution_path_add_event`. + +For example, with:: + + diagnostic_event_id alloc_event_id + = diagnostic_execution_path_add_event (path, + loc_call_to_PyList_New, + logical_loc, 0, + "when %qs fails, returning NULL", + "PyList_New"); + +we create an event that will be worded as:: + + (1) when `PyList_New' fails, returning NULL + +Note that :func:`diagnostic_execution_path_add_event` returns a +:type:`diagnostic_event_id`. We can use this to refer to this event +in another event using the ``%@`` format code in its message, which +takes the address of a :type:`diagnostic_event_id`:: + + diagnostic_execution_path_add_event (path, + loc_call_to_PyList_Append, + logical_loc, 0, + "when calling %qs, passing NULL from %@ as argument %i", + "PyList_Append", &alloc_event_id, 1); + +where the latter event will be worded as:: + + (2) when calling `PyList_Append', passing NULL from (1) as argument 1 + +where the ``%@`` reference to the other event has been printed as ``(1)``. +In SARIF output the text "(1)" will have a embedded link referring within the sarif +log to the ``threadFlowLocation`` object for the other event, via JSON +pointer (see `§3.10.3 "URIs that use the sarif scheme" `_). + +Let's add an event between these describing control flow, creating three +events in all: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c + :language: c + :start-after: begin path creation + :end-before: end path creation + +Assuming we also gave it :type:`diagnostic_logical_location` with: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c + :language: c + :start-after: begin create logical locs + :end-before: end create logical locs + +and finish the :type:`diagnostic` with :func:`diagnostic_finish` like this:: + + diagnostic_finish (d, + "passing NULL as argument %i to %qs" + " which requires a non-NULL parameter", + 1, "PyList_Append"); + +then we should get output to text sinks similar to the following:: + + In function 'make_a_list_of_random_ints_badly': + test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter" + 30 | PyList_Append(list, item); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + make_a_list_of_random_ints_badly': events 1-3 + 26 | list = PyList_New(0); + | ^~~~~~~~~~~~~ + | | + | (1) when 'PyList_New' fails, returning NULL + 27 | + 28 | for (i = 0; i < count; i++) { + | ~~~~~~~~~ + | | + | (2) when 'i < count' + 29 | item = PyLong_FromLong(random()); + 30 | PyList_Append(list, item); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1 + +and for SARIF sinks the path will be added as a ``codeFlow`` object +(see SARIF 2.1.0 `3.36 codeFlow object `_). + +Here's the above example in full: + +.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c + :language: c + :start-after: begin full example + :end-before: end full example + + +Moving on +********* + +That's the end of the tutorial. For more information on libgdiagnostics, see +the :doc:`topic guide <../topics/index>`. diff --git a/gcc/doc/libgdiagnostics/tutorial/example-1.png b/gcc/doc/libgdiagnostics/tutorial/example-1.png new file mode 100644 index 0000000..d637103 Binary files /dev/null and b/gcc/doc/libgdiagnostics/tutorial/example-1.png differ diff --git a/gcc/doc/libgdiagnostics/tutorial/index.rst b/gcc/doc/libgdiagnostics/tutorial/index.rst new file mode 100644 index 0000000..0bad00e --- /dev/null +++ b/gcc/doc/libgdiagnostics/tutorial/index.rst @@ -0,0 +1,32 @@ +.. Copyright (C) 2024 Free Software Foundation, Inc. + Originally contributed by David Malcolm + + This 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 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see + . + +Tutorial +======== + +The following tutorial gives an overview of how to use libgdiagnostics. + +.. toctree:: + :maxdepth: 2 + + 01-hello-world.rst + 02-physical-locations.rst + 03-logical-locations.rst + 04-notes.rst + 05-warnings.rst + 06-fix-it-hints.rst + 07-execution-paths.rst -- cgit v1.1