1 // rust-diagnostics.cc -- GCC implementation of rust diagnostics interface.
2 // Copyright (C) 2016-2023 Free Software Foundation, Inc.
3 // Contributed by Than McIntosh, Google.
5 // This file is part of GCC.
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
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
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/>.
21 #include "rust-system.h"
22 #include "rust-diagnostics.h"
27 return std::string (xstrerror (errno
));
30 // Rewrite a format string to expand any extensions not
31 // supported by sprintf(). See comments in rust-diagnostics.h
32 // for list of supported format specifiers.
35 expand_format (const char *fmt
)
38 for (const char *c
= fmt
; *c
; ++c
)
49 // malformed format string
57 ss
<< mformat_value ();
61 ss
<< rust_open_quote ();
65 ss
<< rust_close_quote ();
69 ss
<< rust_open_quote ();
73 ss
<< mformat_value ();
79 ss
<< rust_close_quote ();
90 // Expand message format specifiers, using a combination of
91 // expand_format above to handle extensions (ex: %m, %q) and vasprintf()
92 // to handle regular printf-style formatting. A pragma is being used here to
93 // suppress this warning:
95 // warning: function ‘std::__cxx11::string expand_message(const char*,
96 // __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute
97 // [-Wsuggest-attribute=format]
99 // What appears to be happening here is that the checker is deciding that
100 // because of the call to vasprintf() (which has attribute gnu_printf), the
101 // calling function must need to have attribute gnu_printf as well, even
102 // though there is already an attribute declaration for it.
105 expand_message (const char *fmt
, va_list ap
) RUST_ATTRIBUTE_GCC_DIAG (1, 0);
107 #pragma GCC diagnostic push
108 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
111 expand_message (const char *fmt
, va_list ap
)
114 std::string expanded_fmt
= expand_format (fmt
);
115 int nwr
= vasprintf (&mbuf
, expanded_fmt
.c_str (), ap
);
118 // memory allocation failed
119 rust_be_error_at (Linemap::unknown_location (),
120 "memory allocation failed in vasprintf");
123 std::string rval
= std::string (mbuf
);
128 #pragma GCC diagnostic pop
130 static const char *cached_open_quote
= NULL
;
131 static const char *cached_close_quote
= NULL
;
136 if (cached_open_quote
== NULL
)
137 rust_be_get_quotechars (&cached_open_quote
, &cached_close_quote
);
138 return cached_open_quote
;
144 if (cached_close_quote
== NULL
)
145 rust_be_get_quotechars (&cached_open_quote
, &cached_close_quote
);
146 return cached_close_quote
;
150 rust_internal_error_at (const Location location
, const char *fmt
, ...)
155 rust_be_internal_error_at (location
, expand_message (fmt
, ap
));
160 rust_error_at (const Location location
, const char *fmt
, ...)
165 rust_be_error_at (location
, expand_message (fmt
, ap
));
170 rust_warning_at (const Location location
, int opt
, const char *fmt
, ...)
175 rust_be_warning_at (location
, opt
, expand_message (fmt
, ap
));
180 rust_fatal_error (const Location location
, const char *fmt
, ...)
185 rust_be_fatal_error (location
, expand_message (fmt
, ap
));
190 rust_inform (const Location location
, const char *fmt
, ...)
195 rust_be_inform (location
, expand_message (fmt
, ap
));
201 rust_error_at (const RichLocation
&location
, const char *fmt
, ...)
206 rust_be_error_at (location
, expand_message (fmt
, ap
));
211 rust_debug_loc (const Location location
, const char *fmt
, ...)
213 if (!rust_be_debug_p ())
220 int nwr
= vasprintf (&mbuf
, fmt
, ap
);
224 rust_be_error_at (Linemap::unknown_location (),
225 "memory allocation failed in vasprintf");
228 std::string rval
= std::string (mbuf
);
230 rust_be_inform (location
, rval
);
236 * This function takes ownership of `args` and calls `va_end` on it
239 va_constructor (Error::Kind kind
, Location locus
, const char *fmt
, va_list args
)
240 RUST_ATTRIBUTE_GCC_DIAG (3, 0);
243 va_constructor (Error::Kind kind
, Location locus
, const char *fmt
, va_list args
)
245 std::string message
= expand_message (fmt
, args
);
246 message
.shrink_to_fit ();
249 return Error (kind
, locus
, message
);
252 Error::Error (const Location location
, const char *fmt
, ...)
253 : kind (Kind::Err
), locus (location
)
258 *this = va_constructor (Kind::Err
, location
, fmt
, ap
);
262 Error::Hint (const Location location
, const char *fmt
, ...)
267 return va_constructor (Kind::Hint
, location
, fmt
, ap
);
271 Error::Fatal (const Location location
, const char *fmt
, ...)
276 return va_constructor (Kind::FatalErr
, location
, fmt
, ap
);