diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h index 0c4204f71fab..8dde9ed5f6b9 100644 --- a/gcc/rust/ast/rust-ast-fragment.h +++ b/gcc/rust/ast/rust-ast-fragment.h @@ -123,13 +123,25 @@ class Fragment void assert_single_fragment (SingleASTNode::NodeType expected) const; }; +enum class InvocKind +{ + Expr, + Semicoloned, +}; + +enum class AsmKind +{ + Global, + Inline +}; + /** * This is the type for transcriber functions found in * rust-macro-builtins.{h,cc}. */ using MacroTranscriberFunc = std::function (location_t, MacroInvocData &, - bool semicolon)>; + InvocKind semicolon)>; } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 69b59c25d084..71cdcf0471ea 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -482,7 +482,7 @@ class MacroRulesDefinition : public VisItem * should make use of the actual rules. If the macro is builtin, then another * associated transcriber should be used */ - static Fragment dummy_builtin (location_t, MacroInvocData &, bool) + static Fragment dummy_builtin (location_t, MacroInvocData &, AST::InvocKind) { rust_unreachable (); return Fragment::create_error (); diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc index c840c25994ee..b29523b414bf 100644 --- a/gcc/rust/expand/rust-expand-visitor.cc +++ b/gcc/rust/expand/rust-expand-visitor.cc @@ -17,6 +17,7 @@ // . #include "rust-expand-visitor.h" +#include "rust-ast-fragment.h" #include "rust-proc-macro.h" #include "rust-attributes.h" #include "rust-ast.h" @@ -467,7 +468,9 @@ void ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc) { // TODO: Can we do the AST fragment replacing here? Probably not, right? - expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()); + expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon () + ? AST::InvocKind::Semicoloned + : AST::InvocKind::Expr); } void diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc index 473070bd3437..964ca679ebb0 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.cc +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc @@ -16,7 +16,9 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-make-unique.h" #include "rust-macro-builtins-asm.h" +#include "rust-ast-fragment.h" #include "rust-ast.h" #include "rust-stmt.h" @@ -537,9 +539,9 @@ parse_format_string (InlineAsmContext &inline_asm_ctx) tl::optional MacroBuiltin::asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon, bool is_global_asm) + AST::InvocKind semicolon, AST::AsmKind is_global_asm) { - return parse_asm (invoc_locus, invoc, is_global_asm, semicolon); + return parse_asm (invoc_locus, invoc, semicolon, is_global_asm); } tl::expected @@ -609,7 +611,7 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx) tl::optional parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, - bool is_global_asm, bool semicolon) + AST::InvocKind semicolon, AST::AsmKind is_global_asm) { // From the rule of asm. // We first peek and see if it is a format string or not. @@ -631,7 +633,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, Parser parser (lex); auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser); - AST::InlineAsm inline_asm (invoc_locus, is_global_asm); + AST::InlineAsm inline_asm (invoc_locus, + is_global_asm == AST::AsmKind::Global); auto inline_asm_ctx = InlineAsmContext (inline_asm, parser, last_token_id); // operands stream, also handles the optional "," @@ -654,10 +657,11 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, // If the macro invocation has a semicolon (`asm!("...");`), then we need // to make it a statement. This way, it will be expanded properly. - if (semicolon) - single_vec.emplace_back ( - AST::SingleASTNode (std::unique_ptr ( - new AST::ExprStmt (std::move (node), invoc_locus, semicolon)))); + if (semicolon == AST::InvocKind::Semicoloned) + single_vec.emplace_back (AST::SingleASTNode ( + Rust::make_unique (std::move (node), invoc_locus, + semicolon + == AST::InvocKind::Semicoloned))); else single_vec.emplace_back (AST::SingleASTNode (std::move (node))); diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h index b290ebce4586..30a68e620922 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.h +++ b/gcc/rust/expand/rust-macro-builtins-asm.h @@ -1,4 +1,5 @@ +#include "rust-ast-fragment.h" #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" #include "expected.h" @@ -59,7 +60,7 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx); tl::optional parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, - bool is_global_asm, bool semicolon); + AST::InvocKind semicolon, AST::AsmKind is_global_asm); bool check_identifier (Parser &parser, std::string ident); diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc index d0daa77c67aa..dbceecad4757 100644 --- a/gcc/rust/expand/rust-macro-builtins-format-args.cc +++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc @@ -15,6 +15,7 @@ // You should have received a copy of the GNU General Public License // along with GCC; see the file COPYING3. If not see // . +#include "rust-ast-fragment.h" #include "rust-macro-builtins-helpers.h" #include "rust-expand-format-args.h" @@ -115,7 +116,8 @@ format_args_parse_arguments (AST::MacroInvocData &invoc) tl::optional MacroBuiltin::format_args_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon, + AST::MacroInvocData &invoc, + AST::InvocKind semicolon, AST::FormatArgs::Newline nl) { auto input = format_args_parse_arguments (invoc); diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc b/gcc/rust/expand/rust-macro-builtins-include.cc index 291eae80210e..eb9ea02729bd 100644 --- a/gcc/rust/expand/rust-macro-builtins-include.cc +++ b/gcc/rust/expand/rust-macro-builtins-include.cc @@ -16,6 +16,7 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-ast-fragment.h" #include "rust-common.h" #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" @@ -27,7 +28,8 @@ of the given file as reference to a byte array. Yields an expression of type tl::optional MacroBuiltin::include_bytes_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ @@ -93,7 +95,8 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus, tl::optional MacroBuiltin::include_str_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ @@ -182,7 +185,8 @@ scope compile time. */ tl::optional MacroBuiltin::include_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ diff --git a/gcc/rust/expand/rust-macro-builtins-location.cc b/gcc/rust/expand/rust-macro-builtins-location.cc index 0d19be6c720f..56333c94b1cb 100644 --- a/gcc/rust/expand/rust-macro-builtins-location.cc +++ b/gcc/rust/expand/rust-macro-builtins-location.cc @@ -16,12 +16,14 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-ast-fragment.h" #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" namespace Rust { tl::optional -MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &, bool) +MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &, + AST::InvocKind) { auto current_file = LOCATION_FILE (invoc_locus); auto file_str = AST::SingleASTNode (make_string (invoc_locus, current_file)); @@ -33,7 +35,7 @@ MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &, bool) tl::optional MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &, - bool) + AST::InvocKind) { auto current_column = LOCATION_COLUMN (invoc_locus); @@ -47,7 +49,8 @@ MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &, } tl::optional -MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &, bool) +MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &, + AST::InvocKind) { auto current_line = LOCATION_LINE (invoc_locus); diff --git a/gcc/rust/expand/rust-macro-builtins-log-debug.cc b/gcc/rust/expand/rust-macro-builtins-log-debug.cc index 3bebf543c867..9401a398f1db 100644 --- a/gcc/rust/expand/rust-macro-builtins-log-debug.cc +++ b/gcc/rust/expand/rust-macro-builtins-log-debug.cc @@ -16,13 +16,15 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-ast-fragment.h" #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" namespace Rust { tl::optional MacroBuiltin::assert_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { rust_debug ("assert!() called"); diff --git a/gcc/rust/expand/rust-macro-builtins-utility.cc b/gcc/rust/expand/rust-macro-builtins-utility.cc index 75b8fb2fac53..aea2902202bb 100644 --- a/gcc/rust/expand/rust-macro-builtins-utility.cc +++ b/gcc/rust/expand/rust-macro-builtins-utility.cc @@ -26,7 +26,8 @@ namespace Rust { during the compile time. */ tl::optional MacroBuiltin::compile_error_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { auto lit_expr = parse_single_string_literal (BuiltinMacro::CompileError, @@ -87,7 +88,8 @@ MacroBuiltin::compile_error_handler (location_t invoc_locus, // Can we do that easily? tl::optional MacroBuiltin::concat_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { auto invoc_token_tree = invoc.get_delim_tok_tree (); MacroInvocLexer lex (invoc_token_tree.to_token_stream ()); @@ -152,7 +154,7 @@ MacroBuiltin::concat_handler (location_t invoc_locus, compile time. */ tl::optional MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon) + AST::InvocKind semicolon) { auto invoc_token_tree = invoc.get_delim_tok_tree (); MacroInvocLexer lex (invoc_token_tree.to_token_stream ()); @@ -226,7 +228,7 @@ MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc, tl::optional MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon) + AST::InvocKind semicolon) { // only parse if not already parsed if (!invoc.is_parsed ()) @@ -265,7 +267,8 @@ MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc, tl::optional MacroBuiltin::stringify_handler (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { std::string content; auto invoc_token_tree = invoc.get_delim_tok_tree (); diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 567f4db30fc7..07a1f3cc8d1b 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -87,26 +87,19 @@ const BiMap MacroBuiltin::builtins = {{ AST::MacroTranscriberFunc format_args_maker (AST::FormatArgs::Newline nl) { - return [nl] (location_t loc, AST::MacroInvocData &invoc, bool semicolon) { + return [nl] (location_t loc, AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { return MacroBuiltin::format_args_handler (loc, invoc, semicolon, nl); }; } -enum class isGlobalAsm -{ - Global, - Inline, -}; - AST::MacroTranscriberFunc -inline_asm_maker (isGlobalAsm is_global_asm) +inline_asm_maker (AST::AsmKind global_asm) { - bool global_asm = is_global_asm == isGlobalAsm::Global ? true : false; - - return - [global_asm] (location_t loc, AST::MacroInvocData &invoc, bool semicolon) { - return MacroBuiltin::asm_handler (loc, invoc, semicolon, global_asm); - }; + return [global_asm] (location_t loc, AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { + return MacroBuiltin::asm_handler (loc, invoc, semicolon, global_asm); + }; } std::unordered_map @@ -125,8 +118,8 @@ std::unordered_map {"include", MacroBuiltin::include_handler}, {"format_args", format_args_maker (AST::FormatArgs::Newline::No)}, {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)}, - {"asm", inline_asm_maker (isGlobalAsm::Inline)}, - {"global_asm", inline_asm_maker (isGlobalAsm::Global)}, + {"asm", inline_asm_maker (AST::AsmKind::Inline)}, + {"global_asm", inline_asm_maker (AST::AsmKind::Global)}, /* Unimplemented macro builtins */ {"option_env", MacroBuiltin::sorry}, {"concat_idents", MacroBuiltin::sorry}, @@ -169,7 +162,7 @@ builtin_macro_from_string (const std::string &identifier) tl::optional MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon) + AST::InvocKind semicolon) { rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs", invoc.get_path ().as_string ().c_str ()); @@ -179,7 +172,8 @@ MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc, tl::optional MacroBuiltin::proc_macro_builtin (location_t invoc_locus, - AST::MacroInvocData &invoc, bool semicolon) + AST::MacroInvocData &invoc, + AST::InvocKind semicolon) { rust_error_at (invoc_locus, "cannot invoke derive macro: %qs", invoc.get_path ().as_string ().c_str ()); diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index 448fe216cbe3..b0c4a648bd17 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -125,68 +125,69 @@ class MacroBuiltin static tl::optional assert_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional file_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional column_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional include_bytes_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional include_str_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional stringify_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional compile_error_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional concat_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional env_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional include_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional line_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon); + AST::InvocKind semicolon); static tl::optional asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon, - bool is_global_asm); + AST::InvocKind semicolon, + AST::AsmKind is_global_asm); static tl::optional format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc, - bool semicolon, AST::FormatArgs::Newline nl); + AST::InvocKind semicolon, AST::FormatArgs::Newline nl); - static tl::optional - sorry (location_t invoc_locus, AST::MacroInvocData &invoc, bool semicolon); + static tl::optional sorry (location_t invoc_locus, + AST::MacroInvocData &invoc, + AST::InvocKind semicolon); /* Builtin procedural macros do not work directly on tokens, but still need a * builtin transcriber to be considered proper builtin macros */ static tl::optional - proc_macro_builtin (location_t, AST::MacroInvocData &, bool); + proc_macro_builtin (location_t, AST::MacroInvocData &, AST::InvocKind); }; } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 9742bbc236db..7c558f771b47 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -18,6 +18,7 @@ #include "rust-macro-expand.h" #include "optional.h" +#include "rust-ast-fragment.h" #include "rust-macro-substitute-ctx.h" #include "rust-ast-full.h" #include "rust-ast-visitor.h" @@ -34,7 +35,7 @@ AST::Fragment MacroExpander::expand_decl_macro (location_t invoc_locus, AST::MacroInvocData &invoc, AST::MacroRulesDefinition &rules_def, - bool semicolon) + AST::InvocKind semicolon) { // ensure that both invocation and rules are in a valid state rust_assert (!invoc.is_marked_for_strip ()); @@ -201,7 +202,7 @@ MacroExpander::expand_eager_invocations (AST::MacroInvocation &invoc) for (auto kv : substitution_map) { auto &to_expand = kv.second; - expand_invoc (*to_expand, false); + expand_invoc (*to_expand, AST::InvocKind::Expr); auto fragment = take_expanded_fragment (); auto &new_tokens = fragment.get_tokens (); @@ -239,7 +240,8 @@ MacroExpander::expand_eager_invocations (AST::MacroInvocation &invoc) } void -MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon) +MacroExpander::expand_invoc (AST::MacroInvocation &invoc, + AST::InvocKind semicolon) { if (depth_exceeds_recursion_limit ()) { @@ -288,16 +290,14 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon) last_invoc = *invoc.clone_macro_invocation_impl (); last_def = *rdef; - rust_debug ("[ARTHUR] semicolon: %s", has_semicolon ? "yes" : "no"); - if (rdef->is_builtin ()) fragment = rdef ->get_builtin_transcriber () (invoc.get_locus (), invoc_data, - has_semicolon) + semicolon) .value_or (AST::Fragment::create_empty ()); else - fragment = expand_decl_macro (invoc.get_locus (), invoc_data, *rdef, - has_semicolon); + fragment + = expand_decl_macro (invoc.get_locus (), invoc_data, *rdef, semicolon); set_expanded_fragment (std::move (fragment)); } @@ -1021,8 +1021,10 @@ AST::Fragment MacroExpander::transcribe_rule ( AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree, std::map &matched_fragments, - bool semicolon, ContextType ctx) + AST::InvocKind invoc_kind, ContextType ctx) { + bool semicolon = invoc_kind == AST::InvocKind::Semicoloned; + // we can manipulate the token tree to substitute the dollar identifiers so // that when we call parse its already substituted for us AST::MacroTranscriber &transcriber = match_rule.get_transcriber (); diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index c6dd0c9eb105..c186f3d7c3c1 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -20,6 +20,7 @@ #define RUST_MACRO_EXPAND_H #include "optional.h" +#include "rust-ast-fragment.h" #include "rust-buffered-queue.h" #include "rust-parse.h" #include "rust-token.h" @@ -317,12 +318,12 @@ struct MacroExpander /* Expands a macro invocation - possibly make both * have similar duck-typed interface and use templates?*/ // should this be public or private? - void expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon); + void expand_invoc (AST::MacroInvocation &invoc, AST::InvocKind semicolon); // Expands a single declarative macro. AST::Fragment expand_decl_macro (location_t locus, AST::MacroInvocData &invoc, AST::MacroRulesDefinition &rules_def, - bool semicolon); + AST::InvocKind semicolon); bool depth_exceeds_recursion_limit () const; @@ -332,7 +333,7 @@ struct MacroExpander AST::Fragment transcribe_rule ( AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree, std::map &matched_fragments, - bool semicolon, ContextType ctx); + AST::InvocKind invoc_kind, ContextType ctx); bool match_fragment (Parser &parser, AST::MacroMatchFragment &fragment);