Skip to content

Commit 58d1721

Browse files
committed
macroinvocation: Only allow *stmt* visitors when semicoloned
1 parent 12d1565 commit 58d1721

11 files changed

+181
-193
lines changed

gcc/rust/ast/rust-ast-full-test.cc

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,19 +1275,6 @@ TypeAlias::as_string () const
12751275
return str;
12761276
}
12771277

1278-
// FIXME: ARTHUR: Check if this is necessary for MacroInvocation
1279-
// std::string
1280-
// MacroInvocationSemi::as_string () const
1281-
// {
1282-
// std::string str = "MacroInvocationSemi: ";
1283-
//
1284-
// str += append_attributes (outer_attrs, OUTER);
1285-
//
1286-
// str += "\n" + invoc_data.as_string ();
1287-
//
1288-
// return str;
1289-
// }
1290-
12911278
std::string
12921279
ExternBlock::as_string () const
12931280
{

gcc/rust/ast/rust-macro.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ class MacroInvocation : public TypeNoBounds,
469469
// Important for when we actually expand the macro
470470
bool is_semi_coloned;
471471

472+
NodeId node_id;
473+
472474
public:
473475
std::string as_string () const override;
474476

@@ -477,7 +479,9 @@ class MacroInvocation : public TypeNoBounds,
477479
bool is_semi_coloned = false)
478480
: outer_attrs (std::move (outer_attrs)),
479481
invoc_data (std::move (invoc_data)), locus (locus),
480-
fragment (ASTFragment::create_empty ()), is_semi_coloned (is_semi_coloned)
482+
fragment (ASTFragment::create_empty ()),
483+
is_semi_coloned (is_semi_coloned),
484+
node_id (Analysis::Mappings::get ()->get_next_node_id ())
481485
{}
482486

483487
Location get_locus () const override final { return locus; }
@@ -504,6 +508,8 @@ class MacroInvocation : public TypeNoBounds,
504508
return ExprWithoutBlock::get_node_id ();
505509
}
506510

511+
NodeId get_macro_node_id () const { return node_id; }
512+
507513
MacroInvocData &get_invoc_data () { return invoc_data; }
508514

509515
ASTFragment &get_fragment () { return fragment; }
@@ -562,12 +568,9 @@ class MacroInvocation : public TypeNoBounds,
562568
}
563569

564570
ExprWithoutBlock *to_stmt () const override
565-
566-
567-
568-
569-
{
570-
auto new_impl = clone_macro_invocation_impl();
571+
572+
{
573+
auto new_impl = clone_macro_invocation_impl ();
571574
new_impl->is_semi_coloned = true;
572575

573576
return new_impl;

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 62 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -310,31 +310,33 @@ class AttrVisitor : public AST::ASTVisitor
310310
// supposedly does not require - cfg does nothing
311311
}
312312

313-
// FIXME: ARTHUR: Check to see if necessary for MacroInvocation
314-
// void visit (AST::MacroInvocationSemi &macro_invoc) override
315-
// {
316-
// // initial strip test based on outer attrs
317-
// expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ());
318-
// if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
319-
// {
320-
// macro_invoc.mark_for_strip ();
321-
// return;
322-
// }
313+
void visit (AST::MacroInvocation &macro_invoc) override
314+
{
315+
// initial strip test based on outer attrs
316+
expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ());
317+
if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
318+
{
319+
macro_invoc.mark_for_strip ();
320+
return;
321+
}
323322

324-
// // can't strip simple path
323+
// can't strip simple path
325324

326-
// // I don't think any macro token trees can be stripped in any way
325+
// I don't think any macro token trees can be stripped in any way
327326

328-
// // TODO: maybe have cfg! macro stripping behaviour here?
327+
// TODO: maybe have cfg! macro stripping behaviour here?
329328

330-
// expander.expand_invoc_semi (macro_invoc);
329+
if (macro_invoc.has_semicolon ())
330+
expander.expand_invoc_semi (macro_invoc);
331+
else
332+
expander.expand_invoc (macro_invoc);
331333

332-
// // we need to visit the expanded fragments since it may need cfg
333-
// expansion
334-
// // and it may be recursive
335-
// for (auto &node : macro_invoc.get_fragment ().get_nodes ())
336-
// node.accept_vis (*this);
337-
// }
334+
// we need to visit the expanded fragments since it may need cfg
335+
// expansion
336+
// and it may be recursive
337+
for (auto &node : macro_invoc.get_fragment ().get_nodes ())
338+
node.accept_vis (*this);
339+
}
338340

339341
void visit (AST::PathInExpression &path) override
340342
{
@@ -2536,28 +2538,6 @@ class AttrVisitor : public AST::ASTVisitor
25362538
expander.mappings->insert_macro_def (&rules_def);
25372539
}
25382540

2539-
void visit (AST::MacroInvocation &macro_invoc) override
2540-
{
2541-
// FIXME
2542-
// we probably need another recurision check here
2543-
2544-
// initial strip test based on outer attrs
2545-
expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ());
2546-
if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ()))
2547-
{
2548-
macro_invoc.mark_for_strip ();
2549-
return;
2550-
}
2551-
2552-
// I don't think any macro token trees can be stripped in any way
2553-
expander.expand_invoc (macro_invoc);
2554-
2555-
// we need to visit the expanded fragments since it may need cfg expansion
2556-
// and it may be recursive
2557-
for (auto &node : macro_invoc.get_fragment ().get_nodes ())
2558-
node.accept_vis (*this);
2559-
}
2560-
25612541
void visit (AST::MetaItemPath &) override {}
25622542
void visit (AST::MetaItemSeq &) override {}
25632543
void visit (AST::MetaWord &) override {}
@@ -3210,48 +3190,46 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc)
32103190
invoc.set_fragment (std::move (fragment));
32113191
}
32123192

3213-
// FIXME: ARTHUR: Check to see if necessary for MacroInvocation
3214-
// void
3215-
// MacroExpander::expand_invoc_semi (AST::MacroInvocationSemi &invoc)
3216-
// {
3217-
// if (depth_exceeds_recursion_limit ())
3218-
// {
3219-
// rust_error_at (invoc.get_locus (), "reached recursion limit");
3220-
// return;
3221-
// }
3222-
//
3223-
// AST::MacroInvocData &invoc_data = invoc.get_invoc_data ();
3224-
//
3225-
// // lookup the rules for this macro
3226-
// NodeId resolved_node = UNKNOWN_NODEID;
3227-
// bool found = resolver->get_macro_scope ().lookup (
3228-
// Resolver::CanonicalPath::new_seg (invoc.get_macro_node_id (),
3229-
// invoc_data.get_path ().as_string ()),
3230-
// &resolved_node);
3231-
// if (!found)
3232-
// {
3233-
// rust_error_at (invoc.get_locus (), "unknown macro");
3234-
// return;
3235-
// }
3236-
//
3237-
// // lookup the rules
3238-
// AST::MacroRulesDefinition *rules_def = nullptr;
3239-
// bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
3240-
// rust_assert (ok);
3241-
//
3242-
// auto fragment = AST::ASTFragment::create_empty ();
3243-
//
3244-
// if (rules_def->is_builtin ())
3245-
// fragment
3246-
// = rules_def->get_builtin_transcriber () (invoc.get_locus (),
3247-
// invoc_data);
3248-
// else
3249-
// fragment
3250-
// = expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true);
3251-
//
3252-
// // lets attach this fragment to the invocation
3253-
// invoc.set_fragment (std::move (fragment));
3254-
// }
3193+
void
3194+
MacroExpander::expand_invoc_semi (AST::MacroInvocation &invoc)
3195+
{
3196+
if (depth_exceeds_recursion_limit ())
3197+
{
3198+
rust_error_at (invoc.get_locus (), "reached recursion limit");
3199+
return;
3200+
}
3201+
3202+
AST::MacroInvocData &invoc_data = invoc.get_invoc_data ();
3203+
3204+
// lookup the rules for this macro
3205+
NodeId resolved_node = UNKNOWN_NODEID;
3206+
bool found = resolver->get_macro_scope ().lookup (
3207+
Resolver::CanonicalPath::new_seg (invoc.get_macro_node_id (),
3208+
invoc_data.get_path ().as_string ()),
3209+
&resolved_node);
3210+
if (!found)
3211+
{
3212+
rust_error_at (invoc.get_locus (), "unknown macro");
3213+
return;
3214+
}
3215+
3216+
// lookup the rules
3217+
AST::MacroRulesDefinition *rules_def = nullptr;
3218+
bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
3219+
rust_assert (ok);
3220+
3221+
auto fragment = AST::ASTFragment::create_empty ();
3222+
3223+
if (rules_def->is_builtin ())
3224+
fragment
3225+
= rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data);
3226+
else
3227+
fragment
3228+
= expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true);
3229+
3230+
// lets attach this fragment to the invocation
3231+
invoc.set_fragment (std::move (fragment));
3232+
}
32553233

32563234
/* Determines whether any cfg predicate is false and hence item with attributes
32573235
* should be stripped. Note that attributes must be expanded before calling. */

gcc/rust/expand/rust-macro-expand.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,11 @@ struct MacroExpander
146146
// Expands all macros in the crate passed in.
147147
void expand_crate ();
148148

149-
/* Expands a macro invocation (not macro invocation semi) - possibly make both
149+
/* Expands a macro invocation - possibly make both
150150
* have similar duck-typed interface and use templates?*/
151151
// should this be public or private?
152152
void expand_invoc (AST::MacroInvocation &invoc);
153+
void expand_invoc_semi (AST::MacroInvocation &invoc);
153154

154155
// Expands a single declarative macro.
155156
AST::ASTFragment expand_decl_macro (Location locus,

gcc/rust/hir/rust-ast-lower-implitem.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,18 @@ class ASTLowerImplItem : public ASTLoweringBase
5252
return resolver.translated;
5353
}
5454

55-
// FIXME: ARTHUR: See if this is necessary for MacroInvocation
56-
// void visit (AST::MacroInvocationSemi &invoc) override
57-
// {
58-
// AST::ASTFragment &fragment = invoc.get_fragment ();
55+
void visit (AST::MacroInvocation &invoc) override
56+
{
57+
if (!invoc.has_semicolon ())
58+
return;
59+
60+
AST::ASTFragment &fragment = invoc.get_fragment ();
5961

60-
// // FIXME
61-
// // this assertion might go away, maybe on failure's to expand a macro?
62-
// rust_assert (!fragment.get_nodes ().empty ());
63-
// fragment.get_nodes ().at (0).accept_vis (*this);
64-
// }
62+
// FIXME
63+
// this assertion might go away, maybe on failure's to expand a macro?
64+
rust_assert (!fragment.get_nodes ().empty ());
65+
fragment.get_nodes ().at (0).accept_vis (*this);
66+
}
6567

6668
void visit (AST::TypeAlias &alias) override
6769
{
@@ -319,16 +321,18 @@ class ASTLowerTraitItem : public ASTLoweringBase
319321
return resolver.translated;
320322
}
321323

322-
// FIXME: ARTHUR: See if this is necessary for MacroInvocation
323-
// void visit (AST::MacroInvocationSemi &invoc) override
324-
// {
325-
// AST::ASTFragment &fragment = invoc.get_fragment ();
324+
void visit (AST::MacroInvocation &invoc) override
325+
{
326+
if (!invoc.has_semicolon ())
327+
return;
328+
329+
AST::ASTFragment &fragment = invoc.get_fragment ();
326330

327-
// // FIXME
328-
// // this assertion might go away, maybe on failure's to expand a macro?
329-
// rust_assert (!fragment.get_nodes ().empty ());
330-
// fragment.get_nodes ().at (0).accept_vis (*this);
331-
// }
331+
// FIXME
332+
// this assertion might go away, maybe on failure's to expand a macro?
333+
rust_assert (!fragment.get_nodes ().empty ());
334+
fragment.get_nodes ().at (0).accept_vis (*this);
335+
}
332336

333337
void visit (AST::TraitItemFunc &func) override
334338
{

gcc/rust/hir/rust-ast-lower-item.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,18 @@ class ASTLoweringItem : public ASTLoweringBase
5151
return resolver.translated;
5252
}
5353

54-
// FIXME: ARTHUR: See if this is necessary for MacroInvocation
55-
// void visit (AST::MacroInvocationSemi &invoc) override
56-
// {
57-
// AST::ASTFragment &fragment = invoc.get_fragment ();
58-
59-
// // FIXME
60-
// // this assertion might go away, maybe on failure's to expand a macro?
61-
// rust_assert (!fragment.get_nodes ().empty ());
62-
// fragment.get_nodes ().at (0).accept_vis (*this);
63-
// }
54+
void visit (AST::MacroInvocation &invoc) override
55+
{
56+
if (!invoc.has_semicolon ())
57+
return;
58+
59+
AST::ASTFragment &fragment = invoc.get_fragment ();
60+
61+
// FIXME
62+
// this assertion might go away, maybe on failure's to expand a macro?
63+
rust_assert (!fragment.get_nodes ().empty ());
64+
fragment.get_nodes ().at (0).accept_vis (*this);
65+
}
6466

6567
void visit (AST::Module &module) override
6668
{

gcc/rust/hir/rust-ast-lower-stmt.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,18 @@ class ASTLoweringStmt : public ASTLoweringBase
4545
return resolver.translated;
4646
}
4747

48-
// FIXME: ARTHUR: See if this implementation is necessary for MacroInvocation
49-
// void visit (AST::MacroInvocationSemi &invoc) override
50-
// {
51-
// AST::ASTFragment &fragment = invoc.get_fragment ();
52-
53-
// // FIXME
54-
// // this assertion might go away, maybe on failure's to expand a macro?
55-
// rust_assert (!fragment.get_nodes ().empty ());
56-
// fragment.get_nodes ().at (0).accept_vis (*this);
57-
// }
48+
void visit (AST::MacroInvocation &invoc) override
49+
{
50+
if (!invoc.has_semicolon ())
51+
return;
52+
53+
AST::ASTFragment &fragment = invoc.get_fragment ();
54+
55+
// FIXME
56+
// this assertion might go away, maybe on failure's to expand a macro?
57+
rust_assert (!fragment.get_nodes ().empty ());
58+
fragment.get_nodes ().at (0).accept_vis (*this);
59+
}
5860

5961
void visit (AST::ExprStmtWithBlock &stmt) override
6062
{

0 commit comments

Comments
 (0)