Line data Source code
1 : /* Various declarations for language-independent diagnostics subroutines.
2 : Copyright (C) 2000-2026 Free Software Foundation, Inc.
3 : Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef GCC_DIAGNOSTIC_H
22 : #define GCC_DIAGNOSTIC_H
23 :
24 : #include "rich-location.h"
25 : #include "pretty-print.h"
26 : #include "diagnostic-core.h"
27 :
28 : #include "diagnostics/diagnostic-info.h"
29 : #include "diagnostics/context.h"
30 :
31 : /* Extension hooks for client. */
32 : #define diagnostic_context_auxiliary_data(DC) (DC)->m_client_aux_data
33 : #define diagnostic_info_auxiliary_data(DI) (DI)->m_x_data
34 :
35 : /* This diagnostics::context is used by front-ends that directly output
36 : diagnostic messages without going through `error', `warning',
37 : and similar functions. */
38 : extern diagnostics::context *global_dc;
39 :
40 : /* The number of errors that have been issued so far. Ideally, these
41 : would take a diagnostics::context as an argument. */
42 : #define errorcount global_dc->diagnostic_count (diagnostics::kind::error)
43 : /* Similarly, but for warnings. */
44 : #define warningcount global_dc->diagnostic_count (diagnostics::kind::warning)
45 : /* Similarly, but for warnings promoted to errors. */
46 : #define werrorcount global_dc->diagnostic_count (diagnostics::kind::werror)
47 : /* Similarly, but for sorrys. */
48 : #define sorrycount global_dc->diagnostic_count (diagnostics::kind::sorry)
49 :
50 : /* Returns nonzero if warnings should be emitted. */
51 : #define diagnostic_report_warnings_p(DC, LOC) \
52 : (!(DC)->m_inhibit_warnings \
53 : && !(in_system_header_at (LOC) && !(DC)->m_warn_system_headers))
54 :
55 : /* Override the option index to be used for reporting a
56 : diagnostic. */
57 :
58 : inline void
59 142871 : diagnostic_set_option_id (diagnostics::diagnostic_info *info,
60 : diagnostics::option_id opt_id)
61 : {
62 142871 : info->m_option_id = opt_id;
63 : }
64 :
65 : /* Diagnostic related functions. */
66 :
67 : inline void
68 705442 : diagnostic_initialize (diagnostics::context *context, int n_opts)
69 : {
70 705442 : context->initialize (n_opts);
71 : }
72 :
73 : inline void
74 1400680 : diagnostic_color_init (diagnostics::context *context, int value = -1)
75 : {
76 1400680 : context->color_init (value);
77 542692 : }
78 :
79 : inline void
80 1391074 : diagnostic_urls_init (diagnostics::context *context, int value = -1)
81 : {
82 1391074 : context->urls_init (value);
83 537476 : }
84 :
85 : inline void
86 304383 : diagnostic_finish (diagnostics::context *context)
87 : {
88 304383 : context->finish ();
89 : }
90 :
91 : inline void
92 370183 : diagnostic_show_locus (diagnostics::context *context,
93 : const diagnostics::source_printing_options &opts,
94 : rich_location *richloc,
95 : enum diagnostics::kind diagnostic_kind,
96 : pretty_printer *pp,
97 : diagnostics::source_effect_info *effect_info = nullptr)
98 : {
99 370183 : gcc_assert (context);
100 370183 : gcc_assert (richloc);
101 370183 : gcc_assert (pp);
102 370183 : context->maybe_show_locus (*richloc, opts, diagnostic_kind, *pp, effect_info);
103 370183 : }
104 :
105 : inline void
106 6 : diagnostic_show_locus_as_html (diagnostics::context *context,
107 : const diagnostics::source_printing_options &opts,
108 : rich_location *richloc,
109 : enum diagnostics::kind diagnostic_kind,
110 : xml::printer &xp,
111 : diagnostics::source_effect_info *effect_info = nullptr,
112 : diagnostics::html_label_writer *label_writer = nullptr)
113 : {
114 6 : gcc_assert (context);
115 6 : gcc_assert (richloc);
116 6 : context->maybe_show_locus_as_html (*richloc, opts, diagnostic_kind, xp,
117 : effect_info, label_writer);
118 6 : }
119 :
120 : /* Because we read source files a second time after the frontend did it the
121 : first time, we need to know how the frontend handled things like character
122 : set conversion and UTF-8 BOM stripping, in order to make everything
123 : consistent. This function needs to be called by each frontend that requires
124 : non-default behavior, to inform the diagnostics infrastructure how input is
125 : to be processed. The default behavior is to do no conversion and not to
126 : strip a UTF-8 BOM.
127 :
128 : The callback should return the input charset to be used to convert the given
129 : file's contents to UTF-8, or it should return NULL if no conversion is needed
130 : for this file. SHOULD_SKIP_BOM only applies in case no conversion was
131 : performed, and if true, it will cause a UTF-8 BOM to be skipped at the
132 : beginning of the file. (In case a conversion was performed, the BOM is
133 : rather skipped as part of the conversion process.) */
134 :
135 : inline void
136 209535 : diagnostic_initialize_input_context (diagnostics::context *context,
137 : diagnostic_input_charset_callback ccb,
138 : bool should_skip_bom)
139 : {
140 209535 : context->initialize_input_context (ccb, should_skip_bom);
141 : }
142 :
143 : /* Force diagnostics controlled by OPTIDX to be kind KIND. */
144 : inline diagnostics::kind
145 5108092 : diagnostic_classify_diagnostic (diagnostics::context *context,
146 : diagnostics::option_id opt_id,
147 : enum diagnostics::kind kind,
148 : location_t where)
149 : {
150 5108092 : return context->classify_diagnostic (opt_id, kind, where);
151 : }
152 :
153 : inline void
154 4352841 : diagnostic_push_diagnostics (diagnostics::context *context,
155 : location_t where)
156 : {
157 4352841 : context->push_diagnostics (where);
158 4271912 : }
159 : inline void
160 4352198 : diagnostic_pop_diagnostics (diagnostics::context *context,
161 : location_t where)
162 : {
163 4352198 : context->pop_diagnostics (where);
164 4271269 : }
165 :
166 : /* Report a diagnostic message (an error or a warning) as specified by
167 : DC. This function is *the* subroutine in terms of which front-ends
168 : should implement their specific diagnostic handling modules. The
169 : front-end independent format specifiers are exactly those described
170 : in the documentation of output_format.
171 : Return true if a diagnostic was printed, false otherwise. */
172 :
173 : inline bool
174 5026911 : diagnostic_report_diagnostic (diagnostics::context *context,
175 : diagnostics::diagnostic_info *diagnostic)
176 : {
177 5026911 : context->begin_group ();
178 5026911 : bool warned = context->report_diagnostic (diagnostic);
179 5026533 : context->end_group ();
180 5026533 : return warned;
181 : }
182 :
183 : #ifdef ATTRIBUTE_GCC_DIAG
184 : extern void diagnostic_set_info (diagnostics::diagnostic_info *,
185 : const char *, va_list *,
186 : rich_location *,
187 : enum diagnostics::kind)
188 : ATTRIBUTE_GCC_DIAG(2,0);
189 : extern void diagnostic_set_info_translated (diagnostics::diagnostic_info *,
190 : const char *, va_list *,
191 : rich_location *,
192 : enum diagnostics::kind)
193 : ATTRIBUTE_GCC_DIAG(2,0);
194 : #endif
195 :
196 : namespace diagnostics {
197 :
198 : void default_text_starter (diagnostics::text_sink &,
199 : const diagnostics::diagnostic_info *);
200 : template <typename TextOrHtml>
201 : void default_start_span_fn (const diagnostics::location_print_policy &,
202 : TextOrHtml &text_or_html,
203 : expanded_location);
204 : void default_text_finalizer (diagnostics::text_sink &,
205 : const diagnostics::diagnostic_info *,
206 : enum diagnostics::kind);
207 : } // namespace diagnostics
208 :
209 : int get_terminal_width (void);
210 :
211 : /* Return the location associated to this diagnostic. Parameter WHICH
212 : specifies which location. By default, expand the first one. */
213 :
214 : inline location_t
215 104486619 : diagnostic_location (const diagnostics::diagnostic_info *diagnostic,
216 : int which = 0)
217 : {
218 104486619 : return diagnostic->m_message.get_location (which);
219 : }
220 :
221 : /* Return the number of locations to be printed in DIAGNOSTIC. */
222 :
223 : inline unsigned int
224 : diagnostic_num_locations (const diagnostics::diagnostic_info *diagnostic)
225 : {
226 : return diagnostic->m_message.m_richloc->get_num_locations ();
227 : }
228 :
229 : /* Expand the location of this diagnostic. Use this function for
230 : consistency. Parameter WHICH specifies which location. By default,
231 : expand the first one. */
232 :
233 : inline expanded_location
234 1573627 : diagnostic_expand_location (const diagnostics::diagnostic_info *diagnostic,
235 : int which = 0)
236 : {
237 1573627 : return diagnostic->m_richloc->get_expanded_location (which);
238 : }
239 :
240 : /* This is somehow the right-side margin of a caret line, that is, we
241 : print at least these many characters after the position pointed at
242 : by the caret. */
243 : const int CARET_LINE_MARGIN = 10;
244 :
245 : /* Return true if the two locations can be represented within the same
246 : caret line. This is used to build a prefix and also to determine
247 : whether to print one or two caret lines. */
248 :
249 : inline bool
250 555 : diagnostic_same_line (const diagnostics::context *context,
251 : expanded_location s1, expanded_location s2)
252 : {
253 549 : return (s2.column && s1.line == s2.line
254 555 : && ((context->get_source_printing_options ().max_width
255 213 : - CARET_LINE_MARGIN)
256 213 : > abs (s1.column - s2.column)));
257 : }
258 :
259 : /* Pure text formatting support functions. */
260 :
261 : extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
262 :
263 : inline bool
264 1299522 : warning_enabled_at (location_t loc, diagnostics::option_id opt_id)
265 : {
266 1299522 : return global_dc->warning_enabled_at (loc, opt_id);
267 : }
268 :
269 : inline bool
270 590788 : option_unspecified_p (diagnostics::option_id opt_id)
271 : {
272 590788 : return global_dc->option_unspecified_p (opt_id);
273 : }
274 :
275 : namespace diagnostics {
276 :
277 : /* Compute the number of digits in the decimal representation of an integer. */
278 : extern int num_digits (uint64_t);
279 :
280 : } // namespace diagnostics
281 :
282 : #endif /* ! GCC_DIAGNOSTIC_H */
|