[gcc r14-7923] gccrs: Support for rich-loc & errorcode in parser error

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 18:07:40 GMT 2024


https://gcc.gnu.org/g:4ad44eae61457754cb0249bb6df24cc33f684163

commit r14-7923-g4ad44eae61457754cb0249bb6df24cc33f684163
Author: Muhammad Mahad <mahadtxt@gmail.com>
Date:   Thu Aug 10 22:10:09 2023 +0500

    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>

Diff:
---
 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 683fc531140..a90b9603bd7 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 a38dd0d42a8..7c5894a2df2 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 ());


More information about the Gcc-cvs mailing list