diff mbox series

[051/125] gccrs: format-args: Only pass the format string to the parser.

Message ID 20240801145809.366388-53-arthur.cohen@embecosm.com
State New
Headers show
Series [001/125] Rust: Make 'tree'-level 'MAIN_NAME_P' work | expand

Commit Message

Arthur Cohen Aug. 1, 2024, 2:56 p.m. UTC
This fixes an issue we had where the generated code ended with more static
pieces than its rustc counterpart.

gcc/rust/ChangeLog:

	* expand/rust-macro-builtins.cc (struct FormatArgsInput): Store the format_str
	as a string instead of an AST::Expr.
	(format_args_parse_arguments): Transform format_expr into a format string
	properly - add note for handling eager macro invocations later on.
	(MacroBuiltin::format_args_handler): Parse the correct input, append
	newline to format_str if necessary.
---
 gcc/rust/expand/rust-macro-builtins.cc | 37 +++++++++++++++-----------
 1 file changed, 22 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 112713a4f97..a33a57752da 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -18,6 +18,7 @@ 
 
 #include "expected.h"
 #include "libproc_macro_internal/tokenstream.h"
+#include "optional.h"
 #include "rust-ast-full-decls.h"
 #include "rust-builtin-ast-nodes.h"
 #include "rust-expand-format-args.h"
@@ -961,7 +962,7 @@  MacroBuiltin::stringify_handler (location_t invoc_locus,
 
 struct FormatArgsInput
 {
-  std::unique_ptr<AST::Expr> format_str;
+  std::string format_str;
   AST::FormatArguments args;
   // bool is_literal?
 };
@@ -985,12 +986,18 @@  format_args_parse_arguments (AST::MacroInvocData &invoc)
 
   auto args = AST::FormatArguments ();
   auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
-  std::unique_ptr<AST::Expr> format_str = nullptr;
+  std::unique_ptr<AST::Expr> format_expr = nullptr;
 
   // TODO: Handle the case where we're not parsing a string literal (macro
   // invocation for e.g.)
   if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
-    format_str = parser.parse_literal_expr ();
+    format_expr = parser.parse_literal_expr ();
+
+  // TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
+  // macro invocation, what do we do here? return a tl::unexpected?
+  auto format_str = static_cast<AST::LiteralExpr &> (*format_expr)
+		      .get_literal ()
+		      .as_string ();
 
   // TODO: Allow implicit captures ONLY if the the first arg is a string literal
   // and not a macro invocation
@@ -1053,6 +1060,13 @@  MacroBuiltin::format_args_handler (location_t invoc_locus,
 {
   auto input = format_args_parse_arguments (invoc);
 
+  if (!input)
+    {
+      rust_error_at (invoc_locus,
+		     "could not parse arguments to %<format_args!()%>");
+      return tl::nullopt;
+    }
+
   // TODO(Arthur): We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
   // if (!fmt_expr->is_literal ())
@@ -1080,20 +1094,13 @@  MacroBuiltin::format_args_handler (location_t invoc_locus,
   //     rust_unreachable ();
   //   }
 
-  // Remove the delimiters from the macro invocation:
-  // the invoc data for `format_args!(fmt, arg1, arg2)` is `(fmt, arg1, arg2)`,
-  // so we pop the front and back to remove the parentheses (or curly brackets,
-  // or brackets)
-  auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
-  tokens.erase (tokens.begin ());
-  tokens.pop_back ();
+  bool append_newline = nl == AST::FormatArgs::Newline::Yes;
 
-  std::stringstream stream;
-  for (const auto &tok : tokens)
-    stream << tok->as_string () << ' ';
+  auto fmt_str = std::move (input->format_str);
+  if (append_newline)
+    fmt_str += '\n';
 
-  auto append_newline = nl == AST::FormatArgs::Newline::Yes ? true : false;
-  auto pieces = Fmt::Pieces::collect (stream.str (), append_newline);
+  auto pieces = Fmt::Pieces::collect (fmt_str, append_newline);
 
   // TODO:
   // do the transformation into an AST::FormatArgs node