From efa3041b4b19d598b919455ec1290ba899e54508 Mon Sep 17 00:00:00 2001 From: Muhammad Mahad Date: Thu, 10 Aug 2023 22:10:09 +0500 Subject: [PATCH] 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 --- gcc/rust/rust-diagnostics.cc | 87 ++++++++++++++++++++++++++++++++++++ gcc/rust/rust-diagnostics.h | 77 +++++++++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 3 deletions(-) diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc index fce10bd67364..eeb189e7fa81 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 d94721275bc4..7a9a6b8af284 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 ());