]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
lower: Add base for lowering FormatArgs nodes
authorArthur Cohen <arthur.cohen@embecosm.com>
Thu, 22 Feb 2024 13:59:17 +0000 (14:59 +0100)
committerCohenArthur <arthur.cohen@embecosm.com>
Fri, 1 Mar 2024 15:42:36 +0000 (15:42 +0000)
gcc/rust/ChangeLog:

* Make-lang.in: Compile the new source file.
* ast/rust-ast-collector.cc (TokenCollector::visit): Error out when
visiting FormatArgs nodes.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
* ast/rust-ast.cc (FormatArgs::get_locus): New.
* ast/rust-builtin-ast-nodes.h: Improve FormatArgs API.
* ast/rust-fmt.cc (Pieces::~Pieces): Cleanup.
(Pieces::Pieces): Likewise.
* ast/rust-fmt.h (struct Pieces): Add pieces_vector member.
* hir/rust-ast-lower-format-args.cc: New file.
* hir/rust-ast-lower-format-args.h: New file.

gcc/rust/Make-lang.in
gcc/rust/ast/rust-ast-collector.cc
gcc/rust/ast/rust-ast.cc
gcc/rust/ast/rust-builtin-ast-nodes.h
gcc/rust/ast/rust-fmt.cc
gcc/rust/ast/rust-fmt.h
gcc/rust/hir/rust-ast-lower-expr.cc
gcc/rust/hir/rust-ast-lower-format-args.cc [new file with mode: 0644]
gcc/rust/hir/rust-ast-lower-format-args.h [new file with mode: 0644]
gcc/rust/resolve/rust-ast-resolve-base.cc

index 9974930d04baa3fa29c555f67cc20a64f0e38d5a..8a324c8c07929c1862060821cad882b1e92c0a92 100644 (file)
@@ -118,6 +118,7 @@ GRS_OBJS = \
     rust/rust-ast-lower-expr.o \
     rust/rust-ast-lower-type.o \
     rust/rust-ast-lower-stmt.o \
+    rust/rust-ast-lower-format-args.o \
     rust/rust-rib.o \
     rust/rust-name-resolution-context.o \
     rust/rust-default-resolver.o \
index b8ec62367bcf69e4bfc42037e963b883e213e15b..c0e8e774824ad1d7ce151256e5a7a5f29c098ac2 100644 (file)
@@ -2810,7 +2810,8 @@ TokenCollector::visit (BareFunctionType &type)
 void
 TokenCollector::visit (AST::FormatArgs &fmt)
 {
-  rust_sorry_at (0, "unimplemented format_args!() visitor");
+  rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
+                __FILE__, __LINE__);
 }
 
 } // namespace AST
index f3dabc6cd0fe19f54eb5fa93297926408a896284..fbd795f671803381f8593d9e1ae00a427b38e87c 100644 (file)
@@ -5065,7 +5065,7 @@ FormatArgs::as_string () const
 location_t
 FormatArgs::get_locus () const
 {
-  rust_unreachable ();
+  return loc;
 }
 
 bool
index 6e267173a557bff6bf9dc49e3c2d56311d240664..780d1a9d4e948aca377c57ba86d2b968d5b7b328 100644 (file)
@@ -184,48 +184,32 @@ public:
 
   FormatArgs (location_t loc, Fmt::Pieces &&template_str,
              FormatArguments &&arguments)
-    : loc (loc), template_str (std::move (template_str)),
+    : loc (loc), template_pieces (std::move (template_str)),
       arguments (std::move (arguments))
   {}
 
-  FormatArgs (FormatArgs &&other)
-    : loc (std::move (other.loc)),
-      template_str (std::move (other.template_str)),
-      arguments (std::move (other.arguments))
-  {
-    std::cerr << "[ARTHUR] moving FormatArgs" << std::endl;
-  }
-
-  // FIXME: This might be invalid - we are reusing the same memory allocated
-  // on the Rust side for `other`. This is probably valid as long as we only
-  // ever read that memory and never write to it.
-  FormatArgs (const FormatArgs &other)
-    : loc (other.loc), template_str (other.template_str),
-      arguments (other.arguments)
-  {
-    std::cerr << "[ARTHUR] copying FormatArgs" << std::endl;
-  }
-
-  // FormatArgs &operator= (const FormatArgs &other) = default;
-  //   : template_str (other.template_str), arguments (other.arguments)
-  // {}
+  FormatArgs (FormatArgs &&other) = default;
+  FormatArgs (const FormatArgs &other) = default;
+  FormatArgs &operator= (const FormatArgs &other) = default;
 
   void accept_vis (AST::ASTVisitor &vis) override;
 
+  const Fmt::Pieces &get_template () const { return template_pieces; }
+  virtual location_t get_locus () const override;
+
 private:
   location_t loc;
   // FIXME: This probably needs to be a separate type - it is one in rustc's
   // expansion of format_args!(). There is extra handling associated with it.
   // we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
   // transformation into something we can handle better
-  Fmt::Pieces template_str;
+  Fmt::Pieces template_pieces;
   FormatArguments arguments;
 
   bool marked_for_strip = false;
 
 protected:
   virtual std::string as_string () const override;
-  virtual location_t get_locus () const override;
   virtual bool is_expr_without_block () const override;
   virtual void mark_for_strip () override;
   virtual bool is_marked_for_strip () const override;
index c367e30d5460cec3e24bb655e9131d682045a3f0..b82e089fc41d258245d04f7debdc845efd6de301 100644 (file)
@@ -27,30 +27,23 @@ Pieces::collect (std::string &&to_parse, bool append_newline)
 {
   auto piece_slice = collect_pieces (to_parse.c_str (), append_newline);
 
-  rust_debug ("[ARTHUR] %p, %lu", (const void *) piece_slice.base_ptr,
-             piece_slice.len);
-
   // this performs multiple copies, can we avoid them maybe?
-  // auto pieces = std::vector<Piece> (piece_slice.base_ptr,
-  //        piece_slice.base_ptr + piece_slice.len);
-
-  return Pieces (piece_slice, std::move (to_parse));
+  // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
+  // should transform them into the proper C++ type which we can work with. so
+  // transform all the strings into C++ strings? all the Option<T> into
+  // tl::optional<T>?
+  auto pieces = std::vector<Piece> (piece_slice.base_ptr,
+                                   piece_slice.base_ptr + piece_slice.len);
+
+  return Pieces (std::move (pieces), piece_slice, std::move (to_parse));
 }
 
-Pieces::~Pieces ()
-{
-  std::cerr << "Arthur: destoying pieces. this: " << (void *) this
-           << " slice: " << slice.base_ptr << std::endl;
-  destroy_pieces (slice);
-}
+Pieces::~Pieces () { destroy_pieces (slice); }
 
-Pieces::Pieces (const Pieces &other) : to_parse (other.to_parse)
+Pieces::Pieces (const Pieces &other)
+  : pieces_vector (other.pieces_vector), to_parse (other.to_parse)
 {
   slice = clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap);
-  std::cerr << "Arthur: copying pieces: other.to_parse: "
-           << (void *) other.to_parse.c_str ()
-           << " ours to_parse: " << (void *) to_parse.c_str () << std::endl;
-  // auto pieces = std::vector (slice.base_ptr, slice.base_ptr + slice.len);
 }
 
 Pieces &
@@ -63,13 +56,11 @@ Pieces::operator= (const Pieces &other)
 }
 
 Pieces::Pieces (Pieces &&other)
-  : slice (
-    clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
+  : pieces_vector (std::move (other.pieces_vector)),
+    slice (
+      clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
     to_parse (std::move (other.to_parse))
-{
-  std::cerr << "Arthur: moving pieces. to_parse: " << (void *) to_parse.c_str ()
-           << " base_ptr/slice: " << (void *) slice.base_ptr << std::endl;
-}
+{}
 
 } // namespace Fmt
 } // namespace Rust
index 22447c4eba071c1f7f323a277726e473a6b1dc3c..ba412f9958c5040d4b5b2eef803be2fc9ed228bc 100644 (file)
@@ -262,6 +262,8 @@ struct Pieces
 
   Pieces (Pieces &&other);
 
+  const std::vector<Piece> &get_pieces () const { return pieces_vector; }
+
   // {
   //   slice = clone_pieces (&other.slice);
   //   to_parse = other.to_parse;
@@ -270,10 +272,17 @@ struct Pieces
   // }
 
 private:
-  Pieces (PieceSlice slice, std::string &&to_parse)
-    : slice (slice), to_parse (std::move (to_parse))
+  Pieces (std::vector<Piece> &&pieces_vector, PieceSlice slice,
+         std::string &&to_parse)
+    : pieces_vector (std::move (pieces_vector)), slice (slice),
+      to_parse (std::move (to_parse))
   {}
 
+  std::vector<Piece> pieces_vector;
+
+  // this memory is held for FFI reasons - it needs to be released and cloned
+  // precisely, so try to not access it/modify it if possible. you should
+  // instead work with `pieces_vector`
   PieceSlice slice;
   std::string to_parse;
 };
index 8e07b19df4c870fa0ee8dac9cd1f6044feae0626..ece15529b5fda0de988db291ff29437490a24844 100644 (file)
@@ -19,6 +19,7 @@
 #include "rust-ast-lower-expr.h"
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-block.h"
+#include "rust-ast-lower-format-args.h"
 #include "rust-ast-lower-struct-field-expr.h"
 #include "rust-ast-lower-pattern.h"
 #include "rust-ast-lower-type.h"
@@ -833,7 +834,11 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
 void
 ASTLoweringExpr::visit (AST::FormatArgs &fmt)
 {
-  rust_sorry_at (0, "unimplemented format_args!() visitor");
+  // Lowering FormatArgs is complex, and this file is already very long
+  translated = FormatArgsLowering ().go (fmt);
+
+  rust_sorry_at (fmt.get_locus (),
+                "FormatArgs lowering is not implemented yet");
 }
 
 } // namespace HIR
diff --git a/gcc/rust/hir/rust-ast-lower-format-args.cc b/gcc/rust/hir/rust-ast-lower-format-args.cc
new file mode 100644 (file)
index 0000000..fcae55a
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-lower-format-args.h"
+#include "rust-ast-full.h"
+#include "rust-hir-full.h"
+
+namespace Rust {
+namespace HIR {
+
+FormatArgsLowering::FormatArgsLowering () {}
+
+HIR::Expr *
+FormatArgsLowering::go (AST::FormatArgs &fmt)
+{
+  // Eventually, we will ned to perform format_args!() expansion as part of HIR
+  // lowering - this enables a couple of interesting optimizations such as
+  // format_args flattening and the inlining of constants into the format
+  // strings. However, this is not a priority at the moment and it is easier to
+  // do "regular" macro expansion for `format_arsg!()`
+
+  return nullptr;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-format-args.h b/gcc/rust/hir/rust-ast-lower-format-args.h
new file mode 100644 (file)
index 0000000..f21635c
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_LOWER_FORMAT_ARGS
+#define RUST_AST_LOWER_FORMAT_ARGS
+
+#include "rust-ast-full-decls.h"
+#include "rust-hir-full-decls.h"
+
+namespace Rust {
+namespace HIR {
+
+class FormatArgsLowering
+{
+public:
+  FormatArgsLowering ();
+  HIR::Expr *go (AST::FormatArgs &fmt);
+
+private:
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif // ! RUST_AST_LOWER_FORMAT_ARGS
index 04a0bb65ec2adb4c528b932c7acb356a00dae709..5a9f54fc7f14bde9437fe711715f451a9017254d 100644 (file)
@@ -653,7 +653,8 @@ ResolverBase::visit (AST::FunctionParam &)
 void
 ResolverBase::visit (AST::FormatArgs &fmt)
 {
-  rust_sorry_at (0, "unimplemented format_args!() visitor");
+  rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
+                __FILE__, __LINE__);
 }
 
 } // namespace Resolver