aboutsummaryrefslogtreecommitdiff
path: root/gcc/doc/libgdiagnostics/topics/diagnostics.rst
blob: 3d24da0164c42424cd334cf551140410a3b4b489 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.. Copyright (C) 2024-2025 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   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
   <https://www.gnu.org/licenses/>.

.. 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.