diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-fragment.cc | 171 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-fragment.h | 118 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 132 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 18 | ||||
-rw-r--r-- | gcc/rust/expand/rust-attribute-visitor.h | 4 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.cc | 72 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.h | 40 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 42 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 23 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 4 |
11 files changed, 390 insertions, 235 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index d7d6e880..5499e8c 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -69,6 +69,7 @@ GRS_OBJS = \ rust/rust-cfg-parser.o \ rust/rust-parse.o \ rust/rust-ast-full-test.o \ + rust/rust-ast-fragment.o \ rust/rust-ast-dump.o \ rust/rust-hir-dump.o \ rust/rust-session-manager.o \ diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc new file mode 100644 index 0000000..c491609 --- /dev/null +++ b/gcc/rust/ast/rust-ast-fragment.cc @@ -0,0 +1,171 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "rust-ast-fragment.h" + +namespace Rust { +namespace AST { + +Fragment::Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes) + : kind (kind), nodes (std::move (nodes)) +{} + +Fragment::Fragment (Fragment const &other) : kind (other.get_kind ()) +{ + *this = other; +} + +Fragment & +Fragment::operator= (Fragment const &other) +{ + nodes.clear (); + nodes.reserve (other.nodes.size ()); + kind = other.get_kind (); + for (auto &n : other.nodes) + { + nodes.push_back (n); + } + + return *this; +} + +Fragment +Fragment::create_error () +{ + return Fragment (FragmentKind::Error, {}); +} + +Fragment +Fragment::complete (std::vector<AST::SingleASTNode> nodes) +{ + return Fragment (FragmentKind::Complete, std::move (nodes)); +} + +Fragment +Fragment::unexpanded () +{ + return Fragment (FragmentKind::Unexpanded, {}); +} + +std::vector<SingleASTNode> & +Fragment::get_nodes () +{ + return nodes; +} + +FragmentKind +Fragment::get_kind () const +{ + return kind; +} + +bool +Fragment::is_error () const +{ + return get_kind () == FragmentKind::Error; +} + +bool +Fragment::should_expand () const +{ + return !is_error (); +} + +bool +Fragment::is_expression_fragment () const +{ + return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION); +} + +bool +Fragment::is_type_fragment () const +{ + return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE); +} + +std::unique_ptr<Expr> +Fragment::take_expression_fragment () +{ + assert_single_fragment (SingleASTNode::NodeType::EXPRESSION); + return nodes[0].take_expr (); +} + +std::unique_ptr<Type> +Fragment::take_type_fragment () +{ + assert_single_fragment (SingleASTNode::NodeType::TYPE); + return nodes[0].take_type (); +} + +void +Fragment::accept_vis (ASTVisitor &vis) +{ + for (auto &node : nodes) + node.accept_vis (vis); +} + +bool +Fragment::is_single_fragment () const +{ + return nodes.size () == 1; +} + +bool +Fragment::is_single_fragment_of_kind (SingleASTNode::NodeType expected) const +{ + return is_single_fragment () && nodes[0].get_kind () == expected; +} + +void +Fragment::assert_single_fragment (SingleASTNode::NodeType expected) const +{ + static const std::map<SingleASTNode::NodeType, const char *> str_map = { + {SingleASTNode::NodeType::IMPL, "impl"}, + {SingleASTNode::NodeType::ITEM, "item"}, + {SingleASTNode::NodeType::TYPE, "type"}, + {SingleASTNode::NodeType::EXPRESSION, "expr"}, + {SingleASTNode::NodeType::STMT, "stmt"}, + {SingleASTNode::NodeType::EXTERN, "extern"}, + {SingleASTNode::NodeType::TRAIT, "trait"}, + {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"}, + }; + + auto actual = nodes[0].get_kind (); + auto fail = false; + + if (!is_single_fragment ()) + { + rust_error_at (Location (), "fragment is not single"); + fail = true; + } + + if (actual != expected) + { + rust_error_at ( + Location (), + "invalid fragment operation: expected %qs node, got %qs node", + str_map.find (expected)->second, + str_map.find (nodes[0].get_kind ())->second); + fail = true; + } + + rust_assert (!fail); +} + +} // namespace AST +} // namespace Rust diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h new file mode 100644 index 0000000..3ef4ba1 --- /dev/null +++ b/gcc/rust/ast/rust-ast-fragment.h @@ -0,0 +1,118 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_FRAGMENT_H +#define RUST_AST_FRAGMENT_H + +#include "rust-ast.h" +#include "rust-system.h" + +namespace Rust { +namespace AST { + +enum class FragmentKind +{ + /** + * If an AST Fragment still contains unexpanded tokens - this should only be + * used in the case of builtin macros which need to be expanded eagerly. + */ + Unexpanded, + /** + * A completely expanded AST Fragment. This signifies that all + * `SingleASTNode`s in the `nodes` vector are valid. + * + * Note that this doesn't imply that the expansion is "done". One of the + * expanded nodes could very well be another macro invocation + */ + Complete, + /** + * An error fragment. + */ + Error, +}; + +/** + * An AST Fragment. Previously named `ASTFragment`. + * + * Basically, a "fragment" that can be incorporated into the AST, created as + * a result of macro expansion. Really annoying to work with due to the fact + * that macros can really expand to anything. As such, horrible representation + * at the moment. + */ +class Fragment +{ +public: + Fragment (Fragment const &other); + Fragment &operator= (Fragment const &other); + + /** + * Create an error fragment + */ + static Fragment create_error (); + + /** + * Create a complete AST fragment + */ + static Fragment complete (std::vector<AST::SingleASTNode> nodes); + + /** + * Create a fragment which contains unexpanded nodes + */ + static Fragment unexpanded (); + + FragmentKind get_kind () const; + std::vector<SingleASTNode> &get_nodes (); + + bool is_error () const; + bool should_expand () const; + + bool is_expression_fragment () const; + bool is_type_fragment () const; + + std::unique_ptr<Expr> take_expression_fragment (); + std::unique_ptr<Type> take_type_fragment (); + + void accept_vis (ASTVisitor &vis); + +private: + Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes); + + FragmentKind kind; + + /** + * Basic idea: essentially, a vector of tagged unions of different AST node + * types. Now, this could actually be stored without a tagged union if the + * different AST node types had a unified parent, but that would create + * issues with the diamond problem or significant performance penalties. So + * a tagged union had to be used instead. A vector is used to represent the + * ability for a macro to expand to two statements, for instance. + */ + std::vector<SingleASTNode> nodes; + + /** + * We need to make a special case for Expression and Type fragments as only + * one Node will be extracted from the `nodes` vector + */ + bool is_single_fragment () const; + bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const; + void assert_single_fragment (SingleASTNode::NodeType expected) const; +}; +} // namespace AST +} // namespace Rust + +#endif // !RUST_AST_FRAGMENT_H diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 492faea..e0e10dc 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1858,138 +1858,6 @@ public: } }; -/* Basically, a "fragment" that can be incorporated into the AST, created as - * a result of macro expansion. Really annoying to work with due to the fact - * that macros can really expand to anything. As such, horrible representation - * at the moment. */ -class ASTFragment -{ -private: - /* basic idea: essentially, a vector of tagged unions of different AST node - * types. Now, this could actually be stored without a tagged union if the - * different AST node types had a unified parent, but that would create - * issues with the diamond problem or significant performance penalties. So - * a tagged union had to be used instead. A vector is used to represent the - * ability for a macro to expand to two statements, for instance. */ - - std::vector<SingleASTNode> nodes; - bool fragment_is_error; - - /** - * We need to make a special case for Expression and Type fragments as only - * one Node will be extracted from the `nodes` vector - */ - - bool is_single_fragment () const { return nodes.size () == 1; } - - bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const - { - return is_single_fragment () && nodes[0].get_kind () == expected; - } - - void assert_single_fragment (SingleASTNode::NodeType expected) const - { - static const std::map<SingleASTNode::NodeType, const char *> str_map = { - {SingleASTNode::NodeType::IMPL, "impl"}, - {SingleASTNode::NodeType::ITEM, "item"}, - {SingleASTNode::NodeType::TYPE, "type"}, - {SingleASTNode::NodeType::EXPRESSION, "expr"}, - {SingleASTNode::NodeType::STMT, "stmt"}, - {SingleASTNode::NodeType::EXTERN, "extern"}, - {SingleASTNode::NodeType::TRAIT, "trait"}, - {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"}, - }; - - auto actual = nodes[0].get_kind (); - auto fail = false; - - if (!is_single_fragment ()) - { - rust_error_at (Location (), "fragment is not single"); - fail = true; - } - - if (actual != expected) - { - rust_error_at ( - Location (), - "invalid fragment operation: expected %qs node, got %qs node", - str_map.find (expected)->second, - str_map.find (nodes[0].get_kind ())->second); - fail = true; - } - - rust_assert (!fail); - } - -public: - ASTFragment (std::vector<SingleASTNode> nodes, bool fragment_is_error = false) - : nodes (std::move (nodes)), fragment_is_error (fragment_is_error) - { - if (fragment_is_error) - rust_assert (nodes.empty ()); - } - - ASTFragment (ASTFragment const &other) - : fragment_is_error (other.fragment_is_error) - { - nodes.clear (); - nodes.reserve (other.nodes.size ()); - for (auto &n : other.nodes) - { - nodes.push_back (n); - } - } - - ASTFragment &operator= (ASTFragment const &other) - { - fragment_is_error = other.fragment_is_error; - nodes.clear (); - nodes.reserve (other.nodes.size ()); - for (auto &n : other.nodes) - { - nodes.push_back (n); - } - - return *this; - } - - static ASTFragment create_error () { return ASTFragment ({}, true); } - - std::vector<SingleASTNode> &get_nodes () { return nodes; } - bool is_error () const { return fragment_is_error; } - - bool should_expand () const { return !is_error (); } - - bool is_expression_fragment () const - { - return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION); - } - - bool is_type_fragment () const - { - return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE); - } - - std::unique_ptr<Expr> take_expression_fragment () - { - assert_single_fragment (SingleASTNode::NodeType::EXPRESSION); - return nodes[0].take_expr (); - } - - std::unique_ptr<Type> take_type_fragment () - { - assert_single_fragment (SingleASTNode::NodeType::TYPE); - return nodes[0].take_type (); - } - - void accept_vis (ASTVisitor &vis) - { - for (auto &node : nodes) - node.accept_vis (vis); - } -}; - // A crate AST object - holds all the data for a single compilation unit struct Crate { diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 276f441..a02c216 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -20,6 +20,7 @@ #define RUST_AST_MACRO_H #include "rust-ast.h" +#include "rust-ast-fragment.h" #include "rust-location.h" #include <string> @@ -456,8 +457,7 @@ class MacroRulesDefinition : public MacroItem std::vector<MacroRule> rules; // inlined form Location locus; - std::function<ASTFragment (Location, MacroInvocData &)> - associated_transcriber; + std::function<Fragment (Location, MacroInvocData &)> associated_transcriber; // Since we can't compare std::functions, we need to use an extra boolean bool is_builtin_rule; @@ -468,10 +468,10 @@ class MacroRulesDefinition : public MacroItem * should make use of the actual rules. If the macro is builtin, then another * associated transcriber should be used */ - static ASTFragment dummy_builtin (Location, MacroInvocData &) + static Fragment dummy_builtin (Location, MacroInvocData &) { gcc_unreachable (); - return ASTFragment::create_error (); + return Fragment::create_error (); } /* NOTE: in rustc, macro definitions are considered (and parsed as) a type @@ -491,9 +491,9 @@ public: associated_transcriber (dummy_builtin), is_builtin_rule (false) {} - MacroRulesDefinition (Identifier builtin_name, DelimType delim_type, - std::function<ASTFragment (Location, MacroInvocData &)> - associated_transcriber) + MacroRulesDefinition ( + Identifier builtin_name, DelimType delim_type, + std::function<Fragment (Location, MacroInvocData &)> associated_transcriber) : outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name), delim_type (delim_type), rules (std::vector<MacroRule> ()), locus (Location ()), associated_transcriber (associated_transcriber), @@ -521,14 +521,14 @@ public: const std::vector<MacroRule> &get_rules () const { return rules; } bool is_builtin () const { return is_builtin_rule; } - const std::function<ASTFragment (Location, MacroInvocData &)> & + const std::function<Fragment (Location, MacroInvocData &)> & get_builtin_transcriber () const { rust_assert (is_builtin ()); return associated_transcriber; } void set_builtin_transcriber ( - std::function<ASTFragment (Location, MacroInvocData &)> transcriber) + std::function<Fragment (Location, MacroInvocData &)> transcriber) { associated_transcriber = transcriber; is_builtin_rule = true; diff --git a/gcc/rust/expand/rust-attribute-visitor.h b/gcc/rust/expand/rust-attribute-visitor.h index 0f9d106..c2e25df 100644 --- a/gcc/rust/expand/rust-attribute-visitor.h +++ b/gcc/rust/expand/rust-attribute-visitor.h @@ -56,11 +56,11 @@ public: * @return Either the expanded fragment or an empty errored-out fragment * indicating an expansion failure. */ - AST::ASTFragment expand_macro_fragment_recursive () + AST::Fragment expand_macro_fragment_recursive () { auto fragment = expander.take_expanded_fragment (*this); unsigned int original_depth = expander.expansion_depth; - auto final_fragment = AST::ASTFragment ({}, true); + auto final_fragment = AST::Fragment::create_error (); while (fragment.should_expand ()) { diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 706b5d4..14322d0 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -66,7 +66,7 @@ macro_end_token (AST::DelimTokenTree &invoc_token_tree, /* Expand and extract an expression from the macro */ -static inline AST::ASTFragment +static inline AST::Fragment try_expand_macro_expression (AST::Expr *expr, MacroExpander *expander) { rust_assert (expander); @@ -264,25 +264,25 @@ load_file_bytes (const char *filename) } } // namespace -AST::ASTFragment +AST::Fragment MacroBuiltin::assert (Location invoc_locus, AST::MacroInvocData &invoc) { rust_debug ("assert!() called"); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } -AST::ASTFragment +AST::Fragment MacroBuiltin::file (Location invoc_locus, AST::MacroInvocData &invoc) { auto current_file = Session::get_instance ().linemap->location_file (invoc_locus); auto file_str = AST::SingleASTNode (make_string (invoc_locus, current_file)); - return AST::ASTFragment ({file_str}); + return AST::Fragment::complete ({file_str}); } -AST::ASTFragment +AST::Fragment MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc) { auto current_column @@ -292,14 +292,14 @@ MacroBuiltin::column (Location invoc_locus, AST::MacroInvocData &invoc) new AST::LiteralExpr (std::to_string (current_column), AST::Literal::INT, PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus))); - return AST::ASTFragment ({column_no}); + return AST::Fragment::complete ({column_no}); } /* Expand builtin macro include_bytes!("filename"), which includes the contents of the given file as reference to a byte array. Yields an expression of type &'static [u8; N]. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc) { /* Get target filename from the macro invocation, which is treated as a path @@ -308,7 +308,7 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc) = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); @@ -335,14 +335,14 @@ MacroBuiltin::include_bytes (Location invoc_locus, AST::MacroInvocData &invoc) new AST::BorrowExpr (std::move (array), false, false, {}, invoc_locus)); auto node = AST::SingleASTNode (std::move (borrow)); - return AST::ASTFragment ({node}); + return AST::Fragment::complete ({node}); } /* Expand builtin macro include_str!("filename"), which includes the contents of the given file as a string. The file must be UTF-8 encoded. Yields an expression of type &'static str. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc) { /* Get target filename from the macro invocation, which is treated as a path @@ -351,7 +351,7 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc) = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); @@ -362,30 +362,30 @@ MacroBuiltin::include_str (Location invoc_locus, AST::MacroInvocData &invoc) std::string str ((const char *) &bytes[0], bytes.size ()); auto node = AST::SingleASTNode (make_string (invoc_locus, str)); - return AST::ASTFragment ({node}); + return AST::Fragment::complete ({node}); } /* Expand builtin macro compile_error!("error"), which forces a compile error during the compile time. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::compile_error (Location invoc_locus, AST::MacroInvocData &invoc) { auto lit_expr = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); std::string error_string = lit_expr->as_string (); rust_error_at (invoc_locus, "%s", error_string.c_str ()); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } /* Expand builtin macro concat!(), which joins all the literal parameters into a string with no delimiter. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc) { auto invoc_token_tree = invoc.get_delim_tok_tree (); @@ -427,16 +427,16 @@ MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc) parser.skip_token (last_token_id); if (has_error) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); auto node = AST::SingleASTNode (make_string (invoc_locus, str)); - return AST::ASTFragment ({node}); + return AST::Fragment::complete ({node}); } /* Expand builtin macro env!(), which inspects an environment variable at compile time. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc) { auto invoc_token_tree = invoc.get_delim_tok_tree (); @@ -451,11 +451,11 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc) auto expanded_expr = try_expand_many_expr (parser, invoc_locus, last_token_id, invoc.get_expander (), has_error); if (has_error) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); if (expanded_expr.size () < 1 || expanded_expr.size () > 2) { rust_error_at (invoc_locus, "env! takes 1 or 2 arguments"); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } if (expanded_expr.size () > 0) { @@ -463,7 +463,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc) = try_extract_string_literal_from_fragment (invoc_locus, expanded_expr[0]))) { - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } } if (expanded_expr.size () > 1) @@ -472,7 +472,7 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc) = try_extract_string_literal_from_fragment (invoc_locus, expanded_expr[1]))) { - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } } @@ -487,14 +487,14 @@ MacroBuiltin::env (Location invoc_locus, AST::MacroInvocData &invoc) lit_expr->as_string ().c_str ()); else rust_error_at (invoc_locus, "%s", error_expr->as_string ().c_str ()); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } auto node = AST::SingleASTNode (make_string (invoc_locus, env_value)); - return AST::ASTFragment ({node}); + return AST::Fragment::complete ({node}); } -AST::ASTFragment +AST::Fragment MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc) { // only parse if not already parsed @@ -519,7 +519,7 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc) /* TODO: assuming that cfg! macros can only have one meta item inner, like cfg * attributes */ if (invoc.get_meta_items ().size () != 1) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); bool result = invoc.get_meta_items ()[0]->check_cfg_predicate ( Session::get_instance ()); @@ -527,13 +527,13 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc) new AST::LiteralExpr (result ? "true" : "false", AST::Literal::BOOL, PrimitiveCoreType::CORETYPE_BOOL, {}, invoc_locus))); - return AST::ASTFragment ({literal_exp}); + return AST::Fragment::complete ({literal_exp}); } /* Expand builtin macro include!(), which includes a source file at the current scope compile time. */ -AST::ASTFragment +AST::Fragment MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) { /* Get target filename from the macro invocation, which is treated as a path @@ -542,7 +542,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); std::string filename = source_relative_path (lit_expr->as_string (), invoc_locus); @@ -556,7 +556,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) { rust_error_at (lit_expr->get_locus (), "cannot open included file %qs: %m", target_filename); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } rust_debug ("Attempting to parse included file %s", target_filename); @@ -574,7 +574,7 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) { // inform the user that the errors above are from a included file rust_inform (invoc_locus, "included from here"); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } std::vector<AST::SingleASTNode> nodes{}; @@ -584,10 +584,10 @@ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) nodes.push_back (node); } - return AST::ASTFragment (nodes); + return AST::Fragment::complete (nodes); } -AST::ASTFragment +AST::Fragment MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc) { auto current_line @@ -597,7 +597,7 @@ MacroBuiltin::line (Location invoc_locus, AST::MacroInvocData &invoc) new AST::LiteralExpr (std::to_string (current_line), AST::Literal::INT, PrimitiveCoreType::CORETYPE_U32, {}, invoc_locus))); - return AST::ASTFragment ({line_no}); + return AST::Fragment::complete ({line_no}); } } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index 91f3727..79305e4 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -20,6 +20,7 @@ #define RUST_MACRO_BUILTINS_H #include "rust-ast.h" +#include "rust-ast-fragment.h" #include "rust-location.h" /** @@ -61,6 +62,7 @@ /* If assert is defined as a macro this file will not parse, so undefine this before continuing. */ +// TODO: Rename all functions here `*_handler` #ifdef assert #undef assert #endif @@ -69,38 +71,34 @@ namespace Rust { class MacroBuiltin { public: - static AST::ASTFragment assert (Location invoc_locus, - AST::MacroInvocData &invoc); - - static AST::ASTFragment file (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment assert (Location invoc_locus, + AST::MacroInvocData &invoc); - static AST::ASTFragment column (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment file (Location invoc_locus, AST::MacroInvocData &invoc); - static AST::ASTFragment include_bytes (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment column (Location invoc_locus, + AST::MacroInvocData &invoc); - static AST::ASTFragment include_str (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment include_bytes (Location invoc_locus, + AST::MacroInvocData &invoc); - static AST::ASTFragment compile_error (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment include_str (Location invoc_locus, + AST::MacroInvocData &invoc); - static AST::ASTFragment concat (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment compile_error (Location invoc_locus, + AST::MacroInvocData &invoc); - static AST::ASTFragment env (Location invoc_locus, + static AST::Fragment concat (Location invoc_locus, AST::MacroInvocData &invoc); - static AST::ASTFragment cfg (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment env (Location invoc_locus, AST::MacroInvocData &invoc); - static AST::ASTFragment include (Location invoc_locus, - AST::MacroInvocData &invoc); + static AST::Fragment cfg (Location invoc_locus, AST::MacroInvocData &invoc); - static AST::ASTFragment line (Location invoc_locus, + static AST::Fragment include (Location invoc_locus, AST::MacroInvocData &invoc); + + static AST::Fragment line (Location invoc_locus, AST::MacroInvocData &invoc); }; } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 96b74da..5894434 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -26,7 +26,7 @@ #include "rust-early-name-resolver.h" namespace Rust { -AST::ASTFragment +AST::Fragment MacroExpander::expand_decl_macro (Location invoc_locus, AST::MacroInvocData &invoc, AST::MacroRulesDefinition &rules_def, @@ -103,7 +103,7 @@ MacroExpander::expand_decl_macro (Location invoc_locus, RichLocation r (invoc_locus); r.add_range (rules_def.get_locus ()); rust_error_at (r, "Failed to match any rule within macro"); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } return transcribe_rule (*matched_rule, invoc_token_tree, matched_fragments, @@ -139,7 +139,7 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon) // - else is unreachable // - derive container macro - unreachable - auto fragment = AST::ASTFragment::create_error (); + auto fragment = AST::Fragment::create_error (); invoc_data.set_expander (this); // lookup the rules @@ -707,7 +707,7 @@ MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser, /** * Helper function to refactor calling a parsing function 0 or more times */ -static AST::ASTFragment +static AST::Fragment parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter, std::function<AST::SingleASTNode ()> parse_fn) { @@ -723,13 +723,13 @@ parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter, for (auto err : parser.get_errors ()) err.emit_error (); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } nodes.emplace_back (std::move (node)); } - return AST::ASTFragment (std::move (nodes)); + return AST::Fragment::complete (std::move (nodes)); } /** @@ -738,7 +738,7 @@ parse_many (Parser<MacroInvocLexer> &parser, TokenId &delimiter, * @param parser Parser to extract items from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { return parse_many (parser, delimiter, [&parser] () { @@ -753,7 +753,7 @@ transcribe_many_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) * @param parser Parser to extract items from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_ext (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { return parse_many (parser, delimiter, [&parser] () { @@ -768,7 +768,7 @@ transcribe_many_ext (Parser<MacroInvocLexer> &parser, TokenId &delimiter) * @param parser Parser to extract items from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_trait_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { @@ -784,7 +784,7 @@ transcribe_many_trait_items (Parser<MacroInvocLexer> &parser, * @param parser Parser to extract items from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_impl_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { return parse_many (parser, delimiter, [&parser] () { @@ -799,7 +799,7 @@ transcribe_many_impl_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) * @param parser Parser to extract items from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_trait_impl_items (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { @@ -815,7 +815,7 @@ transcribe_many_trait_impl_items (Parser<MacroInvocLexer> &parser, * @param parser Parser to extract statements from * @param delimiter Id of the token on which parsing should stop */ -static AST::ASTFragment +static AST::Fragment transcribe_many_stmts (Parser<MacroInvocLexer> &parser, TokenId &delimiter) { auto restrictions = ParseRestrictions (); @@ -835,12 +835,12 @@ transcribe_many_stmts (Parser<MacroInvocLexer> &parser, TokenId &delimiter) * * @param parser Parser to extract statements from */ -static AST::ASTFragment +static AST::Fragment transcribe_expression (Parser<MacroInvocLexer> &parser) { auto expr = parser.parse_expr (); - return AST::ASTFragment ({std::move (expr)}); + return AST::Fragment::complete ({std::move (expr)}); } /** @@ -848,17 +848,17 @@ transcribe_expression (Parser<MacroInvocLexer> &parser) * * @param parser Parser to extract statements from */ -static AST::ASTFragment +static AST::Fragment transcribe_type (Parser<MacroInvocLexer> &parser) { auto type = parser.parse_type (true); for (auto err : parser.get_errors ()) err.emit_error (); - return AST::ASTFragment ({std::move (type)}); + return AST::Fragment::complete ({std::move (type)}); } -static AST::ASTFragment +static AST::Fragment transcribe_on_delimiter (Parser<MacroInvocLexer> &parser, bool semicolon, AST::DelimType delimiter, TokenId last_token_id) { @@ -868,7 +868,7 @@ transcribe_on_delimiter (Parser<MacroInvocLexer> &parser, bool semicolon, return transcribe_expression (parser); } // namespace Rust -static AST::ASTFragment +static AST::Fragment transcribe_context (MacroExpander::ContextType ctx, Parser<MacroInvocLexer> &parser, bool semicolon, AST::DelimType delimiter, TokenId last_token_id) @@ -929,7 +929,7 @@ tokens_to_str (std::vector<std::unique_ptr<AST::Token>> &tokens) return str; } -AST::ASTFragment +AST::Fragment MacroExpander::transcribe_rule ( AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree, std::map<std::string, MatchedFragmentContainer> &matched_fragments, @@ -951,7 +951,7 @@ MacroExpander::transcribe_rule ( rust_debug ("substituted tokens: %s", tokens_to_str (substituted_tokens).c_str ()); - // parse it to an ASTFragment + // parse it to an Fragment MacroInvocLexer lex (std::move (substituted_tokens)); Parser<MacroInvocLexer> parser (lex); @@ -994,7 +994,7 @@ MacroExpander::transcribe_rule ( { for (auto &err : parser.get_errors ()) rust_error_at (err.locus, "%s", err.message.c_str ()); - return AST::ASTFragment::create_error (); + return AST::Fragment::create_error (); } // are all the tokens used? diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index c45a3bc..6253a4e 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -230,7 +230,7 @@ struct MacroExpander MacroExpander (AST::Crate &crate, ExpansionCfg cfg, Session &session) : cfg (cfg), crate (crate), session (session), sub_stack (SubstitutionScope ()), - expanded_fragment (AST::ASTFragment::create_error ()), + expanded_fragment (AST::Fragment::create_error ()), resolver (Resolver::Resolver::get ()), mappings (Analysis::Mappings::get ()) {} @@ -246,10 +246,9 @@ struct MacroExpander void expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon); // Expands a single declarative macro. - AST::ASTFragment expand_decl_macro (Location locus, - AST::MacroInvocData &invoc, - AST::MacroRulesDefinition &rules_def, - bool semicolon); + AST::Fragment expand_decl_macro (Location locus, AST::MacroInvocData &invoc, + AST::MacroRulesDefinition &rules_def, + bool semicolon); void expand_cfg_attrs (AST::AttrVec &attrs); bool fails_cfg (const AST::AttrVec &attr) const; @@ -260,7 +259,7 @@ struct MacroExpander bool try_match_rule (AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree); - AST::ASTFragment transcribe_rule ( + AST::Fragment transcribe_rule ( AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree, std::map<std::string, MatchedFragmentContainer> &matched_fragments, bool semicolon, ContextType ctx); @@ -314,16 +313,16 @@ struct MacroExpander ContextType peek_context () { return context.back (); } - void set_expanded_fragment (AST::ASTFragment &&fragment) + void set_expanded_fragment (AST::Fragment &&fragment) { expanded_fragment = std::move (fragment); } - AST::ASTFragment take_expanded_fragment (AST::ASTVisitor &vis) + AST::Fragment take_expanded_fragment (AST::ASTVisitor &vis) { - AST::ASTFragment old_fragment = std::move (expanded_fragment); + AST::Fragment old_fragment = std::move (expanded_fragment); auto accumulator = std::vector<AST::SingleASTNode> (); - expanded_fragment = AST::ASTFragment::create_error (); + expanded_fragment = AST::Fragment::create_error (); auto early_name_resolver = Resolver::EarlyNameResolver (); for (auto &node : old_fragment.get_nodes ()) @@ -345,7 +344,7 @@ struct MacroExpander auto new_nodes = expanded_fragment.get_nodes (); std::move (new_nodes.begin (), new_nodes.end (), std::back_inserter (accumulator)); - expanded_fragment = AST::ASTFragment (accumulator); + expanded_fragment = AST::Fragment::complete (accumulator); } expansion_depth--; } @@ -358,7 +357,7 @@ private: Session &session; SubstitutionScope sub_stack; std::vector<ContextType> context; - AST::ASTFragment expanded_fragment; + AST::Fragment expanded_fragment; public: Resolver::Resolver *resolver; diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index cb540cd..a3073c0 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -840,8 +840,8 @@ Mappings::iterate_trait_items ( void Mappings::insert_macro_def (AST::MacroRulesDefinition *macro) { - static std::map<std::string, std::function<AST::ASTFragment ( - Location, AST::MacroInvocData &)>> + static std::map< + std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>> builtin_macros = { {"assert", MacroBuiltin::assert}, {"file", MacroBuiltin::file}, |