Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions gcc/rust/expand/rust-macro-expand.cc
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,11 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
auto attrs = parser.parse_outer_attributes ();
auto expr = parser.parse_expr (std::move (attrs));
if (expr == nullptr)
return AST::Fragment::create_error ();
{
for (auto error : parser.get_errors ())
error.emit ();
return AST::Fragment::create_error ();
}

// FIXME: make this an error for some edititons
if (parser.peek_current_token ()->get_id () == SEMICOLON)
Expand Down Expand Up @@ -1104,8 +1108,9 @@ MacroExpander::transcribe_rule (
auto invoc_stream = invoc_token_tree.to_token_stream ();
auto macro_rule_tokens = transcribe_tree.to_token_stream ();

auto substitute_context = SubstituteCtx (invoc_stream, macro_rule_tokens,
matched_fragments, definition);
auto substitute_context
= SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments,
definition, invoc_token_tree.get_locus ());
std::vector<std::unique_ptr<AST::Token>> substituted_tokens
= substitute_context.substitute_tokens ();

Expand Down Expand Up @@ -1152,11 +1157,7 @@ MacroExpander::transcribe_rule (

// emit any errors
if (parser.has_errors ())
{
for (auto &err : parser.get_errors ())
rust_error_at (err.locus, "%s", err.message.c_str ());
return AST::Fragment::create_error ();
}
return AST::Fragment::create_error ();

// are all the tokens used?
bool did_delimit = parser.skip_token (last_token_id);
Expand Down
19 changes: 15 additions & 4 deletions gcc/rust/expand/rust-macro-substitute-ctx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ SubstituteCtx::substitute_dollar_crate (
if (*def_crate == current_crate)
{
expanded.push_back (std::make_unique<AST::Token> (
Rust::Token::make_identifier (UNKNOWN_LOCATION, "crate")));
Rust::Token::make_identifier (origin, "crate")));
}
else
{
Expand All @@ -49,9 +49,9 @@ SubstituteCtx::substitute_dollar_crate (
rust_assert (name);

expanded.push_back (std::make_unique<AST::Token> (
Rust::Token::make (SCOPE_RESOLUTION, UNKNOWN_LOCATION)));
Rust::Token::make (SCOPE_RESOLUTION, origin)));
expanded.push_back (std::make_unique<AST::Token> (
Rust::Token::make_identifier (UNKNOWN_LOCATION, std::string (*name))));
Rust::Token::make_identifier (origin, std::string (*name))));
}

return true;
Expand Down Expand Up @@ -108,6 +108,12 @@ SubstituteCtx::substitute_metavar (
return true;
}

static bool
is_builtin_metavariable (AST::Token &token)
{
return token.get_id () == CRATE;
}

bool
SubstituteCtx::check_repetition_amount (size_t pattern_start,
size_t pattern_end,
Expand All @@ -125,6 +131,10 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
|| frag_token->get_id () == IDENTIFIER)
{
auto it = fragments.find (frag_token->get_str ());

if (is_builtin_metavariable (*frag_token))
continue;

if (it == fragments.end ())
{
// If the repetition is not anything we know (ie no declared
Expand All @@ -136,6 +146,7 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
frag_token->get_str ().c_str ());

is_valid = false;
continue;
}

auto &fragment = *it->second;
Expand Down Expand Up @@ -226,7 +237,7 @@ SubstituteCtx::substitute_repetition (
}

auto substitute_context
= SubstituteCtx (input, new_macro, sub_map, definition);
= SubstituteCtx (input, new_macro, sub_map, definition, origin);
auto new_tokens = substitute_context.substitute_tokens ();

// Skip the first repetition, but add the separator to the expanded
Expand Down
6 changes: 4 additions & 2 deletions gcc/rust/expand/rust-macro-substitute-ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class SubstituteCtx
std::vector<std::unique_ptr<AST::Token>> &macro;
std::map<std::string, MatchedFragmentContainer *> &fragments;
AST::MacroRulesDefinition &definition;
// Macro invocation location
location_t origin;

/**
* Find the repetition amount to use when expanding a repetition, and
Expand All @@ -43,9 +45,9 @@ class SubstituteCtx
SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input,
std::vector<std::unique_ptr<AST::Token>> &macro,
std::map<std::string, MatchedFragmentContainer *> &fragments,
AST::MacroRulesDefinition &definition)
AST::MacroRulesDefinition &definition, location_t origin)
: input (input), macro (macro), fragments (fragments),
definition (definition)
definition (definition), origin (origin)
{}

/**
Expand Down
12 changes: 12 additions & 0 deletions gcc/testsuite/rust/compile/macros/mbe/macro58.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub fn print(a: *const u8) {}
#[macro_export]
macro_rules! pr_warn (
($($arg:tt)*) => (
$($crate::print($arg))*
)
);

fn main() {
pr_warn!("test\0", "test\0");
// { dg-error "expecting .;. but .identifier. found" "" { target *-*-* } .-1 }
}
Loading