Skip to content

Commit 511d309

Browse files
committed
FormatArgsEager
1 parent 6c247bf commit 511d309

16 files changed

+209
-93
lines changed

gcc/rust/ast/rust-ast-collector.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3013,6 +3013,13 @@ TokenCollector::visit (AST::FormatArgs &fmt)
30133013
__FILE__, __LINE__);
30143014
}
30153015

3016+
void
3017+
TokenCollector::visit (AST::FormatArgsEager &fmt)
3018+
{
3019+
rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgsEager visitor",
3020+
__FILE__, __LINE__);
3021+
}
3022+
30163023
void
30173024
TokenCollector::visit (AST::OffsetOf &offset_of)
30183025
{

gcc/rust/ast/rust-ast-collector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ class TokenCollector : public ASTVisitor
405405
void visit (BareFunctionType &type);
406406

407407
void visit (FormatArgs &fmt);
408+
void visit (FormatArgsEager &fmt);
408409
void visit (OffsetOf &offset_of);
409410
};
410411
} // namespace AST

gcc/rust/ast/rust-ast-full-decls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ class BareFunctionType;
272272

273273
// rust-builtin-ast-nodes.h
274274
class FormatArgs;
275+
class FormatArgsEager;
275276
} // namespace AST
276277
} // namespace Rust
277278

gcc/rust/ast/rust-ast-visitor.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,15 @@ DefaultASTVisitor::visit (AST::FormatArgs &)
15051505
// FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
15061506
}
15071507

1508+
void
1509+
DefaultASTVisitor::visit (AST::FormatArgsEager &fmt)
1510+
{
1511+
// FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
1512+
1513+
// we need this to resolve/expand macros, at least
1514+
visit (fmt.get_template ());
1515+
}
1516+
15081517
void
15091518
DefaultASTVisitor::visit (AST::OffsetOf &offset_of)
15101519
{

gcc/rust/ast/rust-ast-visitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class ASTVisitor
240240

241241
// special AST nodes for certain builtin macros such as `asm!()`
242242
virtual void visit (FormatArgs &fmt) = 0;
243+
virtual void visit (FormatArgsEager &fmt) = 0;
243244
virtual void visit (OffsetOf &fmt) = 0;
244245

245246
// TODO: rust-cond-compilation.h visiting? not currently used
@@ -413,6 +414,7 @@ class DefaultASTVisitor : public ASTVisitor
413414
virtual void visit (AST::FunctionParam &param) override;
414415
virtual void visit (AST::VariadicParam &param) override;
415416
virtual void visit (AST::FormatArgs &fmt) override;
417+
virtual void visit (AST::FormatArgsEager &fmt) override;
416418
virtual void visit (AST::OffsetOf &fmt) override;
417419

418420
template <typename T> void visit (T &node) { node.accept_vis (*this); }

gcc/rust/ast/rust-ast.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5054,6 +5054,59 @@ FormatArgs::clone_expr_impl () const
50545054
return new FormatArgs (*this);
50555055
}
50565056

5057+
void
5058+
FormatArgsEager::accept_vis (ASTVisitor &vis)
5059+
{
5060+
vis.visit (*this);
5061+
}
5062+
5063+
std::string
5064+
FormatArgsEager::as_string () const
5065+
{
5066+
// FIXME(Arthur): Improve
5067+
return "FormatArgsEager";
5068+
}
5069+
5070+
bool
5071+
FormatArgsEager::is_expr_without_block () const
5072+
{
5073+
return false;
5074+
}
5075+
5076+
void
5077+
FormatArgsEager::mark_for_strip ()
5078+
{
5079+
marked_for_strip = true;
5080+
}
5081+
5082+
bool
5083+
FormatArgsEager::is_marked_for_strip () const
5084+
{
5085+
return marked_for_strip;
5086+
}
5087+
5088+
std::vector<Attribute> &
5089+
FormatArgsEager::get_outer_attrs ()
5090+
{
5091+
rust_unreachable ();
5092+
}
5093+
5094+
void
5095+
FormatArgsEager::set_outer_attrs (std::vector<Attribute>)
5096+
{
5097+
rust_unreachable ();
5098+
}
5099+
5100+
FormatArgsEager *
5101+
FormatArgsEager::clone_expr_impl () const
5102+
{
5103+
// based on FormatArgs::clone_expr_impl
5104+
// TODO: should this be happening?
5105+
rust_debug_loc (get_locus (), "[ARTHUR/OWEN] cloning FormatArgsEager!");
5106+
5107+
return new FormatArgsEager (*this);
5108+
}
5109+
50575110
std::vector<Attribute> &
50585111
OffsetOf::get_outer_attrs ()
50595112
{

gcc/rust/ast/rust-ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,7 @@ class Expr : public Visitable
13101310
LlvmInlineAsm,
13111311
Identifier,
13121312
FormatArgs,
1313+
FormatArgsEager,
13131314
OffsetOf,
13141315
MacroInvocation,
13151316
Borrow,

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,70 @@ class FormatArgs : public Expr
225225
virtual Expr *clone_expr_impl () const override;
226226
};
227227

228+
// a FormatArgs which hasn't had its first argument parsed yet
229+
// used to handle eager expansion
230+
class FormatArgsEager final : public Expr
231+
{
232+
public:
233+
using Newline = FormatArgs::Newline;
234+
235+
FormatArgsEager (location_t loc, std::unique_ptr<Expr> &&template_expr,
236+
FormatArguments &&arguments, Newline newline)
237+
: loc (loc), template_expr (std::move (template_expr)),
238+
arguments (std::move (arguments)), newline (newline)
239+
{}
240+
241+
FormatArgsEager (const FormatArgsEager &other): Expr (other), loc (other.loc), template_expr (other.template_expr->clone_expr ()), arguments (other.arguments), newline (other.newline) {}
242+
243+
FormatArgsEager &operator= (const FormatArgsEager &other)
244+
{
245+
Expr::operator= (other);
246+
loc = other.loc;
247+
template_expr = other.template_expr->clone_expr ();
248+
arguments = other.arguments;
249+
newline = other.newline;
250+
return *this;
251+
}
252+
253+
FormatArgsEager (FormatArgsEager &&other) = default;
254+
FormatArgsEager &operator= (FormatArgsEager &&other) = default;
255+
256+
void accept_vis (AST::ASTVisitor &vis) override;
257+
258+
const Expr &get_template () const { return *template_expr; }
259+
260+
Expr &get_template () { return *template_expr; }
261+
262+
std::unique_ptr<Expr> &get_template_ptr () { return template_expr; }
263+
264+
const FormatArguments &get_arguments () const { return arguments; }
265+
266+
FormatArguments &get_arguments () { return arguments; }
267+
268+
virtual location_t get_locus () const override { return loc; }
269+
270+
Newline get_newline () const { return newline; }
271+
272+
Expr::Kind get_expr_kind () const override { return Expr::Kind::FormatArgsEager; }
273+
274+
private:
275+
location_t loc;
276+
std::unique_ptr<Expr> template_expr;
277+
FormatArguments arguments;
278+
Newline newline;
279+
280+
bool marked_for_strip = false;
281+
282+
protected:
283+
virtual std::string as_string () const override;
284+
virtual bool is_expr_without_block () const override;
285+
virtual void mark_for_strip () override;
286+
virtual bool is_marked_for_strip () const override;
287+
virtual std::vector<Attribute> &get_outer_attrs () override;
288+
virtual void set_outer_attrs (std::vector<Attribute>) override;
289+
virtual FormatArgsEager *clone_expr_impl () const override;
290+
};
291+
228292
/**
229293
* The node associated with the builtin offset_of!() macro
230294
*/

gcc/rust/expand/rust-derive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ class DeriveVisitor : public AST::ASTVisitor
256256
virtual void visit (FunctionParam &param) override final{};
257257
virtual void visit (VariadicParam &param) override final{};
258258
virtual void visit (FormatArgs &param) override final{};
259+
virtual void visit (FormatArgsEager &param) override final{};
259260
virtual void visit (OffsetOf &param) override final{};
260261
};
261262

gcc/rust/expand/rust-expand-format-args.cc

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,38 @@ get_trait_name (ffi::FormatSpec format_specifier)
6565
return it->second;
6666
}
6767

68-
tl::optional<AST::Fragment>
69-
expand_format_args (AST::FormatArgs &fmt,
70-
std::vector<std::unique_ptr<AST::Token>> &&tokens)
68+
tl::optional<std::unique_ptr<AST::Expr>>
69+
expand_format_args_eager (AST::FormatArgsEager &fmt_eager)
70+
{
71+
if (!fmt_eager.get_template ().is_literal ())
72+
{
73+
if (fmt_eager.get_template ().get_expr_kind () != AST::Expr::Kind::MacroInvocation)
74+
rust_error_at (fmt_eager.get_locus (), "format argument must be a string literal");
75+
return tl::nullopt;
76+
}
77+
78+
auto &literal = static_cast<AST::LiteralExpr &> (fmt_eager.get_template ());
79+
80+
// TODO: is special handling for RAW_STRING needed?
81+
rust_assert (literal.get_lit_type () == AST::Literal::STRING || literal.get_lit_type () == AST::Literal::RAW_STRING);
82+
83+
// TODO: does this handle escapes in STRING properly?
84+
auto fmt_str = literal.get_literal ().as_string ();
85+
86+
bool append_newline = fmt_eager.get_newline () == AST::FormatArgs::Newline::Yes;
87+
88+
if (append_newline)
89+
fmt_str += '\n';
90+
91+
auto pieces = Fmt::Pieces::collect (fmt_str, append_newline, Fmt::ffi::ParseMode::Format);
92+
93+
auto fmt_args_node = AST::FormatArgs (fmt_eager.get_locus (), std::move (pieces), std::move (fmt_eager.get_arguments ()));
94+
95+
return Fmt::expand_format_args (fmt_args_node);
96+
}
97+
98+
std::unique_ptr<AST::Expr>
99+
expand_format_args (AST::FormatArgs &fmt)
71100
{
72101
auto loc = fmt.get_locus ();
73102
auto builder = AST::Builder (loc);
@@ -131,9 +160,7 @@ expand_format_args (AST::FormatArgs &fmt,
131160
auto final_call
132161
= builder.call (std::move (final_path), std::move (final_args));
133162

134-
auto node = AST::SingleASTNode (std::move (final_call));
135-
136-
return AST::Fragment ({node}, std::move (tokens));
163+
return final_call;
137164
}
138165

139166
} // namespace Fmt

0 commit comments

Comments
 (0)