expand: correctly handles non-macro nodes ...

... when expanding macros recursively to avoid improperly stripping them

Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
This commit is contained in:
liushuyu 2022-08-02 02:17:48 -06:00
parent 8809ee8c6a
commit 9fc6a27b5c
No known key found for this signature in database
GPG Key ID: 23D1CE4534419437
2 changed files with 47 additions and 0 deletions

View File

@ -321,12 +321,28 @@ struct MacroExpander
AST::ASTFragment take_expanded_fragment (AST::ASTVisitor &vis)
{
AST::ASTFragment old_fragment = std::move (expanded_fragment);
auto accumulator = std::vector<AST::SingleASTNode> ();
expanded_fragment = AST::ASTFragment::create_error ();
for (auto &node : old_fragment.get_nodes ())
{
expansion_depth++;
node.accept_vis (vis);
// we'll decide the next move according to the outcome of the macro
// expansion
if (expanded_fragment.is_error ())
accumulator.push_back (node); // if expansion fails, there might be a
// non-macro expression we need to keep
else
{
// if expansion succeeded, then we need to merge the fragment with
// the contents in the accumulator, so that our final expansion
// result will contain non-macro nodes as it should
auto new_nodes = expanded_fragment.get_nodes ();
std::move (new_nodes.begin (), new_nodes.end (),
std::back_inserter (accumulator));
expanded_fragment = AST::ASTFragment (accumulator);
}
expansion_depth--;
}

View File

@ -0,0 +1,31 @@
// { dg-do compile }
// { dg-options "-O1 -gdwarf-5 -dA -w" }
macro_rules! stmt {
($s:stmt) => {
$s
};
($s:stmt, $($ss:stmt),*) => {
$s;
stmt!($($ss),*);
};
}
pub fn test() -> i32 {
stmt!(
let a = 1
);
stmt!(
let b = 2,
let c = 3,
let d = 4,
let e = 5,
let f = b + c + d + e
);
// { dg-final { scan-assembler "14" } }
f
}
fn main() {
let _ = test();
}