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