Branch data Line data Source code
1 : : /* Various declarations for language-independent diagnostics subroutines.
2 : : Copyright (C) 2000-2025 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 : 146868 : diagnostic_set_option_id (diagnostics::diagnostic_info *info,
60 : : diagnostics::option_id opt_id)
61 : : {
62 : 146868 : info->m_option_id = opt_id;
63 : : }
64 : :
65 : : /* Diagnostic related functions. */
66 : :
67 : : inline void
68 : 712169 : diagnostic_initialize (diagnostics::context *context, int n_opts)
69 : : {
70 : 712169 : context->initialize (n_opts);
71 : : }
72 : :
73 : : inline void
74 : 1420186 : diagnostic_color_init (diagnostics::context *context, int value = -1)
75 : : {
76 : 1420186 : context->color_init (value);
77 : 550694 : }
78 : :
79 : : inline void
80 : 1404991 : diagnostic_urls_init (diagnostics::context *context, int value = -1)
81 : : {
82 : 1404991 : context->urls_init (value);
83 : 542688 : }
84 : :
85 : : inline void
86 : 305757 : diagnostic_finish (diagnostics::context *context)
87 : : {
88 : 305757 : context->finish ();
89 : : }
90 : :
91 : : inline void
92 : 366809 : 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 : 366809 : gcc_assert (context);
100 : 366809 : gcc_assert (richloc);
101 : 366809 : gcc_assert (pp);
102 : 366809 : context->maybe_show_locus (*richloc, opts, diagnostic_kind, *pp, effect_info);
103 : 366809 : }
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 : 209330 : diagnostic_initialize_input_context (diagnostics::context *context,
137 : : diagnostic_input_charset_callback ccb,
138 : : bool should_skip_bom)
139 : : {
140 : 209330 : 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 : 4540588 : diagnostic_classify_diagnostic (diagnostics::context *context,
146 : : diagnostics::option_id opt_id,
147 : : enum diagnostics::kind kind,
148 : : location_t where)
149 : : {
150 : 4540588 : return context->classify_diagnostic (opt_id, kind, where);
151 : : }
152 : :
153 : : inline void
154 : 3861155 : diagnostic_push_diagnostics (diagnostics::context *context,
155 : : location_t where)
156 : : {
157 : 3861155 : context->push_diagnostics (where);
158 : 3794329 : }
159 : : inline void
160 : 3860572 : diagnostic_pop_diagnostics (diagnostics::context *context,
161 : : location_t where)
162 : : {
163 : 3860572 : context->pop_diagnostics (where);
164 : 3793746 : }
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 : 4993315 : diagnostic_report_diagnostic (diagnostics::context *context,
175 : : diagnostics::diagnostic_info *diagnostic)
176 : : {
177 : 4993315 : context->begin_group ();
178 : 4993315 : bool warned = context->report_diagnostic (diagnostic);
179 : 4992942 : context->end_group ();
180 : 4992942 : 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 : 93837157 : diagnostic_location (const diagnostics::diagnostic_info *diagnostic,
216 : : int which = 0)
217 : : {
218 : 93837157 : 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 : 1542167 : diagnostic_expand_location (const diagnostics::diagnostic_info *diagnostic,
235 : : int which = 0)
236 : : {
237 : 1542167 : 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 : 510 : diagnostic_same_line (const diagnostics::context *context,
251 : : expanded_location s1, expanded_location s2)
252 : : {
253 : 504 : return (s2.column && s1.line == s2.line
254 : 510 : && ((context->get_source_printing_options ().max_width
255 : 173 : - CARET_LINE_MARGIN)
256 : 173 : > 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 : 300635 : warning_enabled_at (location_t loc, diagnostics::option_id opt_id)
265 : : {
266 : 300635 : return global_dc->warning_enabled_at (loc, opt_id);
267 : : }
268 : :
269 : : inline bool
270 : 593310 : option_unspecified_p (diagnostics::option_id opt_id)
271 : : {
272 : 593310 : 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 (int);
279 : :
280 : : } // namespace diagnostics
281 : :
282 : : #endif /* ! GCC_DIAGNOSTIC_H */
|