aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorMuhammad Mahad <mahadtxt@gmail.com>2023-08-10 22:10:09 +0500
committerPhilip Herron <philip.herron@embecosm.com>2023-08-16 11:03:52 +0000
commitefa3041b4b19d598b919455ec1290ba899e54508 (patch)
tree6b9b5b05fb8f60da2344a1a53e34ae4d9e66a565 /gcc/rust
parent5545c75fa5574fcc96717ba1656653621204fca2 (diff)
downloadgcc-efa3041b4b19d598b919455ec1290ba899e54508.zip
gcc-efa3041b4b19d598b919455ec1290ba899e54508.tar.gz
gcc-efa3041b4b19d598b919455ec1290ba899e54508.tar.bz2
gccrs: Support for rich-loc & errorcode in parser error
Added method of binding ErrorCode & rich location to parser and expansion errors. Fixes https://github.com/Rust-GCC/gccrs/issues/2385 gcc/rust/ChangeLog: * rust-diagnostics.cc (va_constructor): Added constructor for all possible cases. (Error::Error): Updated error struct for all possible cases. * rust-diagnostics.h (struct Error): Updated error struct to support error code & rich location support. Signed-off-by: Muhammad Mahad <mahadtxt@gmail.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/rust-diagnostics.cc87
-rw-r--r--gcc/rust/rust-diagnostics.h77
2 files changed, 161 insertions, 3 deletions
diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
index fce10bd..eeb189e 100644
--- a/gcc/rust/rust-diagnostics.cc
+++ b/gcc/rust/rust-diagnostics.cc
@@ -379,10 +379,28 @@ namespace Rust {
/**
* This function takes ownership of `args` and calls `va_end` on it
*/
+
+// simple location
static Error
va_constructor (Error::Kind kind, location_t locus, const char *fmt,
va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);
+// simple location + error code
+static Error
+va_constructor (Error::Kind kind, location_t locus, const ErrorCode code,
+ const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
+
+// rich location
+static Error
+va_constructor (Error::Kind kind, rich_location *r_locus, const char *fmt,
+ va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);
+
+// rich location + error code
+static Error
+va_constructor (Error::Kind kind, rich_location *r_locus, const ErrorCode code,
+ const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
+
+// simple location
static Error
va_constructor (Error::Kind kind, location_t locus, const char *fmt,
va_list args)
@@ -394,6 +412,43 @@ va_constructor (Error::Kind kind, location_t locus, const char *fmt,
return Error (kind, locus, message);
}
+// simple location + error code
+static Error
+va_constructor (Error::Kind kind, location_t locus, const ErrorCode code,
+ const char *fmt, va_list args)
+{
+ std::string message = expand_message (fmt, args);
+ message.shrink_to_fit ();
+ va_end (args);
+
+ return Error (kind, locus, code, message);
+}
+
+// rich location
+static Error
+va_constructor (Error::Kind kind, rich_location *r_locus, const char *fmt,
+ va_list args)
+{
+ std::string message = expand_message (fmt, args);
+ message.shrink_to_fit ();
+ va_end (args);
+
+ return Error (kind, r_locus, message);
+}
+
+// rich location + error code
+static Error
+va_constructor (Error::Kind kind, rich_location *r_locus, const ErrorCode code,
+ const char *fmt, va_list args)
+{
+ std::string message = expand_message (fmt, args);
+ message.shrink_to_fit ();
+ va_end (args);
+
+ return Error (kind, r_locus, code, message);
+}
+
+// simple location
Error::Error (const location_t location, const char *fmt, ...)
: kind (Kind::Err), locus (location)
{
@@ -403,6 +458,38 @@ Error::Error (const location_t location, const char *fmt, ...)
*this = va_constructor (Kind::Err, location, fmt, ap);
}
+// simple location + error code
+Error::Error (const location_t location, const ErrorCode code, const char *fmt,
+ ...)
+ : kind (Kind::Err), locus (location), errorcode (code)
+{
+ va_list ap;
+ va_start (ap, fmt);
+
+ *this = va_constructor (Kind::Err, location, code, fmt, ap);
+}
+
+// rich location
+Error::Error (rich_location *r_locus, const char *fmt, ...)
+ : kind (Kind::Err), richlocus (r_locus)
+{
+ va_list ap;
+ va_start (ap, fmt);
+
+ *this = va_constructor (Kind::Err, r_locus, fmt, ap);
+}
+
+// rich location + error code
+Error::Error (rich_location *r_locus, const ErrorCode code, const char *fmt,
+ ...)
+ : kind (Kind::Err), richlocus (r_locus), errorcode (code)
+{
+ va_list ap;
+ va_start (ap, fmt);
+
+ *this = va_constructor (Kind::Err, r_locus, code, fmt, ap);
+}
+
Error
Error::Hint (const location_t location, const char *fmt, ...)
{
diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h
index d947212..7a9a6b8 100644
--- a/gcc/rust/rust-diagnostics.h
+++ b/gcc/rust/rust-diagnostics.h
@@ -23,6 +23,10 @@
#include "rust-linemap.h"
+// This macro is used to specify the position of format string & it's
+// arguments within the function's paramter list.
+// 'm' specifies the position of the format string parameter.
+// 'n' specifies the position of the first argument for the format string.
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define RUST_ATTRIBUTE_GCC_DIAG(m, n) \
__attribute__ ((__format__ (__gcc_tdiag__, m, n))) \
@@ -160,19 +164,60 @@ struct Error
Kind kind;
location_t locus;
+ rich_location *richlocus = nullptr;
+ ErrorCode errorcode;
std::string message;
- // TODO: store more stuff? e.g. node id?
+ bool is_errorcode = false;
+ // simple location
Error (Kind kind, location_t locus, std::string message)
: kind (kind), locus (locus), message (std::move (message))
{
message.shrink_to_fit ();
}
-
+ // simple location + error code
+ Error (Kind kind, location_t locus, ErrorCode code, std::string message)
+ : kind (kind), locus (locus), errorcode (std::move (code)),
+ message (std::move (message))
+ {
+ is_errorcode = true;
+ message.shrink_to_fit ();
+ }
+ // rich location
+ Error (Kind kind, rich_location *richlocus, std::string message)
+ : kind (kind), richlocus (richlocus), message (std::move (message))
+ {
+ message.shrink_to_fit ();
+ }
+ // rich location + error code
+ Error (Kind kind, rich_location *richlocus, ErrorCode code,
+ std::string message)
+ : kind (kind), richlocus (richlocus), errorcode (std::move (code)),
+ message (std::move (message))
+ {
+ is_errorcode = true;
+ message.shrink_to_fit ();
+ }
+ // simple location
Error (location_t locus, std::string message)
{
Error (Kind::Err, locus, std::move (message));
}
+ // simple location + error code
+ Error (location_t locus, ErrorCode code, std::string message)
+ {
+ Error (Kind::Err, locus, std::move (code), std::move (message));
+ }
+ // rich location
+ Error (rich_location *richlocus, std::string message)
+ {
+ Error (Kind::Err, richlocus, std::move (message));
+ }
+ // rich location + error code
+ Error (rich_location *richlocus, ErrorCode code, std::string message)
+ {
+ Error (Kind::Err, richlocus, std::move (code), std::move (message));
+ }
static Error Hint (location_t locus, std::string message)
{
@@ -185,9 +230,22 @@ struct Error
}
// TODO: the attribute part might be incorrect
+ // simple location
Error (location_t locus, const char *fmt,
...) /*RUST_ATTRIBUTE_GCC_DIAG (2, 3)*/ RUST_ATTRIBUTE_GCC_DIAG (3, 4);
+ // simple location + error code
+ Error (location_t locus, ErrorCode code, const char *fmt,
+ ...) /*RUST_ATTRIBUTE_GCC_DIAG (3, 4)*/ RUST_ATTRIBUTE_GCC_DIAG (4, 5);
+
+ // rich location
+ Error (rich_location *richlocus, const char *fmt,
+ ...) /*RUST_ATTRIBUTE_GCC_DIAG (2, 3)*/ RUST_ATTRIBUTE_GCC_DIAG (3, 4);
+
+ // rich location + error code
+ Error (rich_location *richlocus, ErrorCode code, const char *fmt,
+ ...) /*RUST_ATTRIBUTE_GCC_DIAG (3, 4)*/ RUST_ATTRIBUTE_GCC_DIAG (4, 5);
+
/**
* printf-like overload of Error::Hint
*/
@@ -208,7 +266,20 @@ struct Error
rust_inform (locus, "%s", message.c_str ());
break;
case Kind::Err:
- rust_error_at (locus, "%s", message.c_str ());
+ if (is_errorcode)
+ {
+ if (richlocus == nullptr)
+ rust_error_at (locus, errorcode, "%s", message.c_str ());
+ else
+ rust_error_at (*richlocus, errorcode, "%s", message.c_str ());
+ }
+ else
+ {
+ if (richlocus == nullptr)
+ rust_error_at (locus, "%s", message.c_str ());
+ else
+ rust_error_at (*richlocus, "%s", message.c_str ());
+ }
break;
case Kind::FatalErr:
rust_fatal_error (locus, "%s", message.c_str ());