xref: /netbsd-src/external/gpl3/gcc/dist/libcpp/errors.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Default error handlers for CPP Library.
2    Copyright (C) 1986-2022 Free Software Foundation, Inc.
3    Written by Per Bothner, 1994.
4    Based on CCCP program by Paul Rubin, June 1986
5    Adapted to ANSI C, Richard Stallman, Jan 1987
6 
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.
20 
21  In other words, you are welcome to use, share and improve this program.
22  You are forbidden to forbid anyone else to use, share and improve
23  what you give them.   Help stamp out software-hoarding!  */
24 
25 #include "config.h"
26 #include "system.h"
27 #include "cpplib.h"
28 #include "internal.h"
29 
30 /* Get a location_t for the current location in PFILE,
31    generally that of the previously lexed token.  */
32 
33 location_t
cpp_diagnostic_get_current_location(cpp_reader * pfile)34 cpp_diagnostic_get_current_location (cpp_reader *pfile)
35 {
36   if (CPP_OPTION (pfile, traditional))
37     {
38       if (pfile->state.in_directive)
39 	return pfile->directive_line;
40       else
41 	return pfile->line_table->highest_line;
42     }
43   /* We don't want to refer to a token before the beginning of the
44      current run -- that is invalid.  */
45   else if (pfile->cur_token == pfile->cur_run->base)
46     {
47       return 0;
48     }
49   else
50     {
51       return pfile->cur_token[-1].src_loc;
52     }
53 }
54 
55 /* Print a diagnostic at the given location.  */
56 
57 ATTRIBUTE_FPTR_PRINTF(5,0)
58 static bool
cpp_diagnostic_at(cpp_reader * pfile,enum cpp_diagnostic_level level,enum cpp_warning_reason reason,rich_location * richloc,const char * msgid,va_list * ap)59 cpp_diagnostic_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
60 		   enum cpp_warning_reason reason, rich_location *richloc,
61 		   const char *msgid, va_list *ap)
62 {
63   bool ret;
64 
65   if (!pfile->cb.diagnostic)
66     abort ();
67   ret = pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap);
68 
69   return ret;
70 }
71 
72 /* Print a diagnostic at the location of the previously lexed token.  */
73 
74 ATTRIBUTE_FPTR_PRINTF(4,0)
75 static bool
cpp_diagnostic(cpp_reader * pfile,enum cpp_diagnostic_level level,enum cpp_warning_reason reason,const char * msgid,va_list * ap)76 cpp_diagnostic (cpp_reader * pfile, enum cpp_diagnostic_level level,
77 		enum cpp_warning_reason reason,
78 		const char *msgid, va_list *ap)
79 {
80   location_t src_loc = cpp_diagnostic_get_current_location (pfile);
81   rich_location richloc (pfile->line_table, src_loc);
82   return cpp_diagnostic_at (pfile, level, reason, &richloc, msgid, ap);
83 }
84 
85 /* Print a warning or error, depending on the value of LEVEL.  */
86 
87 bool
cpp_error(cpp_reader * pfile,enum cpp_diagnostic_level level,const char * msgid,...)88 cpp_error (cpp_reader * pfile, enum cpp_diagnostic_level level,
89 	   const char *msgid, ...)
90 {
91   va_list ap;
92   bool ret;
93 
94   va_start (ap, msgid);
95 
96   ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap);
97 
98   va_end (ap);
99   return ret;
100 }
101 
102 /* Print a warning.  The warning reason may be given in REASON.  */
103 
104 bool
cpp_warning(cpp_reader * pfile,enum cpp_warning_reason reason,const char * msgid,...)105 cpp_warning (cpp_reader * pfile, enum cpp_warning_reason reason,
106 	     const char *msgid, ...)
107 {
108   va_list ap;
109   bool ret;
110 
111   va_start (ap, msgid);
112 
113   ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap);
114 
115   va_end (ap);
116   return ret;
117 }
118 
119 /* Print a pedantic warning.  The warning reason may be given in REASON.  */
120 
121 bool
cpp_pedwarning(cpp_reader * pfile,enum cpp_warning_reason reason,const char * msgid,...)122 cpp_pedwarning (cpp_reader * pfile, enum cpp_warning_reason reason,
123 		const char *msgid, ...)
124 {
125   va_list ap;
126   bool ret;
127 
128   va_start (ap, msgid);
129 
130   ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap);
131 
132   va_end (ap);
133   return ret;
134 }
135 
136 /* Print a warning, including system headers.  The warning reason may be
137    given in REASON.  */
138 
139 bool
cpp_warning_syshdr(cpp_reader * pfile,enum cpp_warning_reason reason,const char * msgid,...)140 cpp_warning_syshdr (cpp_reader * pfile, enum cpp_warning_reason reason,
141 		    const char *msgid, ...)
142 {
143   va_list ap;
144   bool ret;
145 
146   va_start (ap, msgid);
147 
148   ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap);
149 
150   va_end (ap);
151   return ret;
152 }
153 
154 /* As cpp_warning above, but use RICHLOC as the location of the diagnostic.  */
155 
cpp_warning_at(cpp_reader * pfile,enum cpp_warning_reason reason,rich_location * richloc,const char * msgid,...)156 bool cpp_warning_at (cpp_reader *pfile, enum cpp_warning_reason reason,
157 		     rich_location *richloc, const char *msgid, ...)
158 {
159   va_list ap;
160   bool ret;
161 
162   va_start (ap, msgid);
163 
164   ret = cpp_diagnostic_at (pfile, CPP_DL_WARNING, reason, richloc,
165 			   msgid, &ap);
166 
167   va_end (ap);
168   return ret;
169 
170 }
171 
172 /* As cpp_pedwarning above, but use RICHLOC as the location of the
173    diagnostic.  */
174 
175 bool
cpp_pedwarning_at(cpp_reader * pfile,enum cpp_warning_reason reason,rich_location * richloc,const char * msgid,...)176 cpp_pedwarning_at (cpp_reader * pfile, enum cpp_warning_reason reason,
177 		   rich_location *richloc, const char *msgid, ...)
178 {
179   va_list ap;
180   bool ret;
181 
182   va_start (ap, msgid);
183 
184   ret = cpp_diagnostic_at (pfile, CPP_DL_PEDWARN, reason, richloc,
185 			   msgid, &ap);
186 
187   va_end (ap);
188   return ret;
189 }
190 
191 /* Print a diagnostic at a specific location.  */
192 
193 ATTRIBUTE_FPTR_PRINTF(6,0)
194 static bool
cpp_diagnostic_with_line(cpp_reader * pfile,enum cpp_diagnostic_level level,enum cpp_warning_reason reason,location_t src_loc,unsigned int column,const char * msgid,va_list * ap)195 cpp_diagnostic_with_line (cpp_reader * pfile, enum cpp_diagnostic_level level,
196 			  enum cpp_warning_reason reason,
197 			  location_t src_loc, unsigned int column,
198 			  const char *msgid, va_list *ap)
199 {
200   bool ret;
201 
202   if (!pfile->cb.diagnostic)
203     abort ();
204   rich_location richloc (pfile->line_table, src_loc);
205   if (column)
206     richloc.override_column (column);
207   ret = pfile->cb.diagnostic (pfile, level, reason, &richloc, _(msgid), ap);
208 
209   return ret;
210 }
211 
212 /* Print a warning or error, depending on the value of LEVEL.  */
213 
214 bool
cpp_error_with_line(cpp_reader * pfile,enum cpp_diagnostic_level level,location_t src_loc,unsigned int column,const char * msgid,...)215 cpp_error_with_line (cpp_reader *pfile, enum cpp_diagnostic_level level,
216 		     location_t src_loc, unsigned int column,
217 		     const char *msgid, ...)
218 {
219   va_list ap;
220   bool ret;
221 
222   va_start (ap, msgid);
223 
224   ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc,
225                                   column, msgid, &ap);
226 
227   va_end (ap);
228   return ret;
229 }
230 
231 /* Print a warning.  The warning reason may be given in REASON.  */
232 
233 bool
cpp_warning_with_line(cpp_reader * pfile,enum cpp_warning_reason reason,location_t src_loc,unsigned int column,const char * msgid,...)234 cpp_warning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
235 		       location_t src_loc, unsigned int column,
236 		       const char *msgid, ...)
237 {
238   va_list ap;
239   bool ret;
240 
241   va_start (ap, msgid);
242 
243   ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc,
244                                   column, msgid, &ap);
245 
246   va_end (ap);
247   return ret;
248 }
249 
250 /* Print a pedantic warning.  The warning reason may be given in REASON.  */
251 
252 bool
cpp_pedwarning_with_line(cpp_reader * pfile,enum cpp_warning_reason reason,location_t src_loc,unsigned int column,const char * msgid,...)253 cpp_pedwarning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
254 			  location_t src_loc, unsigned int column,
255 			  const char *msgid, ...)
256 {
257   va_list ap;
258   bool ret;
259 
260   va_start (ap, msgid);
261 
262   ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc,
263                                   column, msgid, &ap);
264 
265   va_end (ap);
266   return ret;
267 }
268 
269 /* Print a warning, including system headers.  The warning reason may be
270    given in REASON.  */
271 
272 bool
cpp_warning_with_line_syshdr(cpp_reader * pfile,enum cpp_warning_reason reason,location_t src_loc,unsigned int column,const char * msgid,...)273 cpp_warning_with_line_syshdr (cpp_reader *pfile, enum cpp_warning_reason reason,
274 			      location_t src_loc, unsigned int column,
275 			      const char *msgid, ...)
276 {
277   va_list ap;
278   bool ret;
279 
280   va_start (ap, msgid);
281 
282   ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc,
283                                   column, msgid, &ap);
284 
285   va_end (ap);
286   return ret;
287 }
288 
289 /* As cpp_error, but use SRC_LOC as the location of the error, without
290    a column override.  */
291 
292 bool
cpp_error_at(cpp_reader * pfile,enum cpp_diagnostic_level level,location_t src_loc,const char * msgid,...)293 cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
294 	      location_t src_loc, const char *msgid, ...)
295 {
296   va_list ap;
297   bool ret;
298 
299   va_start (ap, msgid);
300 
301   rich_location richloc (pfile->line_table, src_loc);
302   ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, &richloc,
303 			   msgid, &ap);
304 
305   va_end (ap);
306   return ret;
307 }
308 
309 /* As cpp_error, but use RICHLOC as the location of the error, without
310    a column override.  */
311 
312 bool
cpp_error_at(cpp_reader * pfile,enum cpp_diagnostic_level level,rich_location * richloc,const char * msgid,...)313 cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
314 	      rich_location *richloc, const char *msgid, ...)
315 {
316   va_list ap;
317   bool ret;
318 
319   va_start (ap, msgid);
320 
321   ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, richloc,
322 			   msgid, &ap);
323 
324   va_end (ap);
325   return ret;
326 }
327 
328 /* Print a warning or error, depending on the value of LEVEL.  Include
329    information from errno.  */
330 
331 bool
cpp_errno(cpp_reader * pfile,enum cpp_diagnostic_level level,const char * msgid)332 cpp_errno (cpp_reader *pfile, enum cpp_diagnostic_level level,
333 	   const char *msgid)
334 {
335   return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno));
336 }
337 
338 /* Print a warning or error, depending on the value of LEVEL.  Include
339    information from errno.  Unlike cpp_errno, the argument is a filename
340    that is not localized, but "" is replaced with localized "stdout".  */
341 
342 bool
cpp_errno_filename(cpp_reader * pfile,enum cpp_diagnostic_level level,const char * filename,location_t loc)343 cpp_errno_filename (cpp_reader *pfile, enum cpp_diagnostic_level level,
344 		    const char *filename,
345 		    location_t loc)
346 {
347   if (filename[0] == '\0')
348     filename = _("stdout");
349 
350   return cpp_error_at (pfile, level, loc, "%s: %s", filename,
351 		       xstrerror (errno));
352 }
353