diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-10-21 13:05:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-21 13:05:18 +0000 |
commit | 60b21d2f58f46c93fc33f6192682abfed62d8dd9 (patch) | |
tree | 2f8fd5e728e601f5fa74d71afe1579a5fd3ba440 /gcc/rust/ast/rust-ast.h | |
parent | dfb5921b76589c09e7794f5f8010427b93616e9d (diff) | |
parent | 89490980726d298311107a452bdebeb43a2ff7e6 (diff) | |
download | gcc-60b21d2f58f46c93fc33f6192682abfed62d8dd9.zip gcc-60b21d2f58f46c93fc33f6192682abfed62d8dd9.tar.gz gcc-60b21d2f58f46c93fc33f6192682abfed62d8dd9.tar.bz2 |
Merge #1607
1607: Improve AST Fragment class r=CohenArthur a=CohenArthur
This changes the APIs around creating AST fragments and refactors the class into its own header and source file, hopefully making it easier to use. This will also help creating "unexpanded" AST fragments for proper builtin macro expansion with the new fixed-point algorithm introduced by #1606
`@liushuyu` pinging you since you've worked extensively with the macro system. Would love your review!
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc/rust/ast/rust-ast.h')
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 132 |
1 files changed, 0 insertions, 132 deletions
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 { |