]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Support for rich-loc & errorcode in parser error
authorMuhammad Mahad <mahadtxt@gmail.com>
Thu, 10 Aug 2023 17:10:09 +0000 (22:10 +0500)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:00:31 +0000 (19:00 +0100)
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>
gcc/rust/rust-diagnostics.cc
gcc/rust/rust-diagnostics.h

index 683fc531140593a873bdd91eb1e6919b3cce9c47..a90b9603bd772d8750676ba9afc52a77d73e1adb 100644 (file)
@@ -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, ...)
 {
index a38dd0d42a81dca894f9681c700a34ceb8f48853..7c5894a2df2dc40d6c9bb8a27224d987f45223e6 100644 (file)
 
 #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 ());