Skip to content

Commit afed72d

Browse files
committed
format-args: Fix Rust interface and add input parsing.
gcc/rust/ChangeLog: * Make-lang.in: Do not build Rust library in release mode. * ast/rust-ast.cc: Make FormatArgs inherit from AST::Expr * ast/rust-builtin-ast-nodes.h: Improve FormatArg* nodes and helpers. * ast/rust-fmt.cc (Pieces::collect): Fix interface to match FFI function. * ast/rust-fmt.h (collect_pieces): Likewise. (struct Pieces): Add append_newline parameter. * expand/rust-macro-builtins.cc: Add proper parsing of format_args input. * hir/rust-ast-lower-base.cc: Include diagnostics header. libgrust/ChangeLog: * libformat_parser/src/lib.rs: Switch interface to use more parser parameters. * libformat_parser/src/bin.rs: Use new interface.
1 parent 38e3cff commit afed72d

File tree

9 files changed

+418
-80
lines changed

9 files changed

+418
-80
lines changed

gcc/rust/Make-lang.in

+2-2
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ rust/%.o: rust/lex/%.cc
409409
echo $@
410410

411411
rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml $(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
412-
cargo build --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always release, right?
413-
cp $(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
412+
cargo build --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml # FIXME: Not always release, right?
413+
cp $(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a $@
414414

415415
# build all rust/parse files in rust folder, add cross-folder includes
416416
rust/%.o: rust/parse/%.cc

gcc/rust/ast/rust-ast.cc

+51
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
1919

2020
#include "rust-ast.h"
2121
#include "optional.h"
22+
#include "rust-builtin-ast-nodes.h"
2223
#include "rust-system.h"
2324
#include "rust-ast-full.h"
2425
#include "rust-diagnostics.h"
@@ -5054,6 +5055,56 @@ FormatArgs::accept_vis (ASTVisitor &vis)
50545055
vis.visit (*this);
50555056
}
50565057

5058+
std::string
5059+
FormatArgs::as_string () const
5060+
{
5061+
// FIXME(Arthur): Improve
5062+
return "FormatArgs";
5063+
}
5064+
5065+
location_t
5066+
FormatArgs::get_locus () const
5067+
{
5068+
rust_unreachable ();
5069+
}
5070+
5071+
bool
5072+
FormatArgs::is_expr_without_block () const
5073+
{
5074+
return false;
5075+
}
5076+
5077+
void
5078+
FormatArgs::mark_for_strip ()
5079+
{
5080+
marked_for_strip = true;
5081+
}
5082+
5083+
bool
5084+
FormatArgs::is_marked_for_strip () const
5085+
{
5086+
return marked_for_strip;
5087+
}
5088+
5089+
std::vector<Attribute> &
5090+
FormatArgs::get_outer_attrs ()
5091+
{
5092+
rust_unreachable ();
5093+
}
5094+
5095+
void FormatArgs::set_outer_attrs (std::vector<Attribute>)
5096+
{
5097+
rust_unreachable ();
5098+
}
5099+
5100+
Expr *
5101+
FormatArgs::clone_expr_impl () const
5102+
{
5103+
std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
5104+
5105+
return new FormatArgs (*this);
5106+
}
5107+
50575108
} // namespace AST
50585109

50595110
std::ostream &

gcc/rust/ast/rust-builtin-ast-nodes.h

+122-11
Original file line numberDiff line numberDiff line change
@@ -59,35 +59,108 @@ namespace AST {
5959
// └─┘ └─┘
6060
// positions (could be names, numbers, empty, or `*`)
6161

62+
// FIXME: Merge with the class below this one?
6263
class FormatArgumentKind
6364
{
6465
public:
66+
enum class Kind
67+
{
68+
Normal,
69+
Named,
70+
Captured,
71+
} kind;
72+
6573
Identifier &get_ident ()
6674
{
6775
rust_assert (kind == Kind::Captured || kind == Kind::Named);
6876

6977
return ident.value ();
7078
}
7179

72-
private:
73-
enum class Kind
80+
FormatArgumentKind (Kind kind, tl::optional<Identifier> ident)
81+
: kind (kind), ident (ident)
82+
{}
83+
84+
FormatArgumentKind (const FormatArgumentKind &other)
7485
{
75-
Normal,
76-
Named,
77-
Captured,
78-
} kind;
86+
kind = other.kind;
87+
ident = other.ident;
88+
}
89+
90+
FormatArgumentKind operator= (const FormatArgumentKind &other)
91+
{
92+
kind = other.kind;
93+
ident = other.ident;
7994

95+
return *this;
96+
}
97+
98+
private:
8099
tl::optional<Identifier> ident;
81100
};
82101

83102
class FormatArgument
84103
{
104+
public:
105+
static FormatArgument normal (std::unique_ptr<Expr> expr)
106+
{
107+
return FormatArgument (FormatArgumentKind::Kind::Normal, tl::nullopt,
108+
std::move (expr));
109+
}
110+
111+
static FormatArgument named (Identifier ident, std::unique_ptr<Expr> expr)
112+
{
113+
return FormatArgument (FormatArgumentKind::Kind::Named, ident,
114+
std::move (expr));
115+
}
116+
117+
static FormatArgument captured (Identifier ident, std::unique_ptr<Expr> expr)
118+
{
119+
return FormatArgument (FormatArgumentKind::Kind::Captured, ident,
120+
std::move (expr));
121+
}
122+
123+
FormatArgument (const FormatArgument &other)
124+
: kind (other.kind), expr (other.expr->clone_expr ())
125+
{}
126+
127+
FormatArgument operator= (const FormatArgument &other)
128+
{
129+
kind = other.kind;
130+
expr = other.expr->clone_expr ();
131+
132+
return *this;
133+
}
134+
135+
private:
136+
FormatArgument (FormatArgumentKind::Kind kind, tl::optional<Identifier> ident,
137+
std::unique_ptr<Expr> expr)
138+
: kind (FormatArgumentKind (kind, ident)), expr (std::move (expr))
139+
{}
140+
85141
FormatArgumentKind kind;
86142
std::unique_ptr<Expr> expr;
87143
};
88144

89145
class FormatArguments
90146
{
147+
public:
148+
FormatArguments () {}
149+
FormatArguments (FormatArguments &&) = default;
150+
FormatArguments (const FormatArguments &other)
151+
{
152+
args = std::vector<FormatArgument> ();
153+
args.reserve (other.args.size ());
154+
155+
for (const auto &arg : other.args)
156+
args.emplace_back (arg);
157+
};
158+
159+
FormatArguments &operator= (const FormatArguments &other) = default;
160+
161+
void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); }
162+
163+
private:
91164
std::vector<FormatArgument> args;
92165
};
93166

@@ -100,7 +173,7 @@ class FormatArguments
100173
// format_args!("result: {}", some_result))` -> `format_args!("heyo result: {}",
101174
// some_result)`
102175
// FIXME: Move to rust-macro.h
103-
class FormatArgs : public Visitable
176+
class FormatArgs : public Expr
104177
{
105178
public:
106179
enum class Newline
@@ -109,18 +182,56 @@ class FormatArgs : public Visitable
109182
No
110183
};
111184

112-
FormatArgs (location_t loc, Fmt::PieceSlice template_str,
113-
FormatArguments arguments)
185+
FormatArgs (location_t loc, Fmt::Pieces &&template_str,
186+
FormatArguments &&arguments)
114187
: loc (loc), template_str (std::move (template_str)),
115188
arguments (std::move (arguments))
116189
{}
117190

118-
void accept_vis (AST::ASTVisitor &vis);
191+
FormatArgs (FormatArgs &&other)
192+
: loc (std::move (other.loc)),
193+
template_str (std::move (other.template_str)),
194+
arguments (std::move (other.arguments))
195+
{
196+
std::cerr << "[ARTHUR] moving FormatArgs" << std::endl;
197+
}
198+
199+
// FIXME: This might be invalid - we are reusing the same memory allocated
200+
// on the Rust side for `other`. This is probably valid as long as we only
201+
// ever read that memory and never write to it.
202+
FormatArgs (const FormatArgs &other)
203+
: loc (other.loc), template_str (other.template_str),
204+
arguments (other.arguments)
205+
{
206+
std::cerr << "[ARTHUR] copying FormatArgs" << std::endl;
207+
}
208+
209+
// FormatArgs &operator= (const FormatArgs &other) = default;
210+
// : template_str (other.template_str), arguments (other.arguments)
211+
// {}
212+
213+
void accept_vis (AST::ASTVisitor &vis) override;
119214

120215
private:
121216
location_t loc;
122-
Fmt::PieceSlice template_str;
217+
// FIXME: This probably needs to be a separate type - it is one in rustc's
218+
// expansion of format_args!(). There is extra handling associated with it.
219+
// we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
220+
// transformation into something we can handle better
221+
Fmt::Pieces template_str;
123222
FormatArguments arguments;
223+
224+
bool marked_for_strip = false;
225+
226+
protected:
227+
virtual std::string as_string () const override;
228+
virtual location_t get_locus () const override;
229+
virtual bool is_expr_without_block () const override;
230+
virtual void mark_for_strip () override;
231+
virtual bool is_marked_for_strip () const override;
232+
virtual std::vector<Attribute> &get_outer_attrs () override;
233+
virtual void set_outer_attrs (std::vector<Attribute>) override;
234+
virtual Expr *clone_expr_impl () const override;
124235
};
125236

126237
} // namespace AST

gcc/rust/ast/rust-fmt.cc

+35-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ namespace Rust {
2323
namespace Fmt {
2424

2525
Pieces
26-
Pieces::collect (std::string &&to_parse)
26+
Pieces::collect (std::string &&to_parse, bool append_newline)
2727
{
28-
auto piece_slice = collect_pieces (to_parse.c_str ());
28+
auto piece_slice = collect_pieces (to_parse.c_str (), append_newline);
2929

3030
rust_debug ("[ARTHUR] %p, %lu", (const void *) piece_slice.base_ptr,
3131
piece_slice.len);
@@ -37,7 +37,39 @@ Pieces::collect (std::string &&to_parse)
3737
return Pieces (piece_slice, std::move (to_parse));
3838
}
3939

40-
Pieces::~Pieces () { destroy_pieces (slice); }
40+
Pieces::~Pieces ()
41+
{
42+
std::cerr << "Arthur: destoying pieces. this: " << (void *) this
43+
<< " slice: " << slice.base_ptr << std::endl;
44+
destroy_pieces (slice);
45+
}
46+
47+
Pieces::Pieces (const Pieces &other) : to_parse (other.to_parse)
48+
{
49+
slice = clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap);
50+
std::cerr << "Arthur: copying pieces: other.to_parse: "
51+
<< (void *) other.to_parse.c_str ()
52+
<< " ours to_parse: " << (void *) to_parse.c_str () << std::endl;
53+
// auto pieces = std::vector (slice.base_ptr, slice.base_ptr + slice.len);
54+
}
55+
56+
Pieces &
57+
Pieces::operator= (const Pieces &other)
58+
{
59+
slice = clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap);
60+
to_parse = other.to_parse;
61+
62+
return *this;
63+
}
64+
65+
Pieces::Pieces (Pieces &&other)
66+
: slice (
67+
clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
68+
to_parse (std::move (other.to_parse))
69+
{
70+
std::cerr << "Arthur: moving pieces. to_parse: " << (void *) to_parse.c_str ()
71+
<< " base_ptr/slice: " << (void *) slice.base_ptr << std::endl;
72+
}
4173

4274
} // namespace Fmt
4375
} // namespace Rust

gcc/rust/ast/rust-fmt.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ struct Piece
222222

223223
struct NextArgument_Body
224224
{
225-
const Argument *_0;
225+
Argument _0;
226226
};
227227

228228
Tag tag;
@@ -243,17 +243,32 @@ struct PieceSlice
243243
extern "C" {
244244

245245
PieceSlice
246-
collect_pieces (const char *input);
246+
collect_pieces (const char *input, bool append_newline);
247+
248+
PieceSlice
249+
clone_pieces (const Piece *base_ptr, size_t len, size_t cap);
247250

248251
void destroy_pieces (PieceSlice);
249252

250253
} // extern "C"
251254

252255
struct Pieces
253256
{
254-
static Pieces collect (std::string &&to_parse);
257+
static Pieces collect (std::string &&to_parse, bool append_newline);
255258
~Pieces ();
256259

260+
Pieces (const Pieces &other);
261+
Pieces &operator= (const Pieces &other);
262+
263+
Pieces (Pieces &&other);
264+
265+
// {
266+
// slice = clone_pieces (&other.slice);
267+
// to_parse = other.to_parse;
268+
269+
// return *this;
270+
// }
271+
257272
private:
258273
Pieces (PieceSlice slice, std::string &&to_parse)
259274
: slice (slice), to_parse (std::move (to_parse))

0 commit comments

Comments
 (0)