Skip to content

Commit

Permalink
gccrs: Support for rich-loc & errorcode in parser error
Browse files Browse the repository at this point in the history
Added method of binding ErrorCode & rich location to
parser and expansion errors.
Fixes #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>
  • Loading branch information
MahadMuhammad committed Aug 11, 2023
1 parent ebd449c commit b1eee3f
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 3 deletions.
87 changes: 87 additions & 0 deletions gcc/rust/rust-diagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,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)
Expand All @@ -399,6 +417,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)
{
Expand All @@ -408,6 +463,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, ...)
{
Expand Down
77 changes: 74 additions & 3 deletions gcc/rust/rust-diagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))) \
Expand Down Expand Up @@ -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)
{
Expand All @@ -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
*/
Expand All @@ -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 ());
Expand Down

0 comments on commit b1eee3f

Please sign in to comment.