diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index a4d0d062accc..4ca2f2e7cd21 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -33,6 +33,7 @@ #include "rust-compile-implitem.h" #include "rust-attribute-values.h" #include "rust-immutable-name-resolution-context.h" +#include "rust-attributes.h" #include "fold-const.h" #include "stringpool.h" @@ -158,64 +159,6 @@ HIRCompileBase::handle_attribute_proc_macro_attribute_on_fndecl ( ctx->collect_attribute_proc_macro (fndecl); } -static std::vector -get_attributes (const AST::Attribute &attr) -{ - std::vector result; - - rust_assert (attr.get_attr_input ().get_attr_input_type () - == Rust::AST::AttrInput::TOKEN_TREE); - const auto &tt - = static_cast (attr.get_attr_input ()); - - // TODO: Should we rely on fixed index ? Should we search for the - // attribute tokentree instead ? - - // Derive proc macros have the following format: - // #[proc_macro_derive(TraitName, attributes(attr1, attr2, attr3))] - // -~~~~~~~~ - ~~~~~~~~~~--------------------- - // ^0 ^1 ^2 ^3 ^4 - // - "attributes" is stored at position 3 in the token tree - // - attribute are stored in the delimited token tree in position 4 - constexpr size_t attr_kw_pos = 3; - constexpr size_t attribute_list_pos = 4; - - if (tt.get_token_trees ().size () > attr_kw_pos) - { - rust_assert (tt.get_token_trees ()[attr_kw_pos]->as_string () - == "attributes"); - - auto attributes = static_cast ( - tt.get_token_trees ()[attribute_list_pos].get ()); - - auto &token_trees = attributes->get_token_trees (); - - for (auto i = token_trees.cbegin () + 1; // Skip opening parenthesis - i < token_trees.cend (); - i += 2) // Skip comma and closing parenthesis - { - result.push_back ((*i)->as_string ()); - } - } - return result; -} - -static std::string -get_trait_name (const AST::Attribute &attr) -{ - // Derive proc macros have the following format: - // #[proc_macro_derive(TraitName, attributes(attr1, attr2, attr3))] - // -~~~~~~~~ - ~~~~~~~~~~--------------------- - // ^0 ^1 ^2 ^3 ^4 - // - The trait name is stored at position 1 - constexpr size_t trait_name_pos = 1; - - rust_assert (attr.get_attr_input ().get_attr_input_type () - == Rust::AST::AttrInput::TOKEN_TREE); - const auto &tt - = static_cast (attr.get_attr_input ()); - return tt.get_token_trees ()[trait_name_pos]->as_string (); -} void HIRCompileBase::handle_derive_proc_macro_attribute_on_fndecl ( @@ -225,7 +168,7 @@ HIRCompileBase::handle_derive_proc_macro_attribute_on_fndecl ( attr.get_attr_input ().parse_to_meta_item (); CustomDeriveInfo macro - = {fndecl, get_trait_name (attr), get_attributes (attr)}; + = {fndecl, Attributes::get_trait_name (attr), Attributes::get_attributes (attr)}; ctx->collect_derive_proc_macro (macro); } diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index 45ebf8c65461..21e9cc45c199 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -37,6 +37,64 @@ Attributes::is_known (const std::string &attribute_path) return !lookup.is_error (); } +static std::vector +Attributes::get_attributes (const AST::Attribute &attr) +{ + std::vector result; + + rust_assert (attr.get_attr_input ().get_attr_input_type () + == Rust::AST::AttrInput::TOKEN_TREE); + const auto &tt + = static_cast (attr.get_attr_input ()); + + // TODO: Should we rely on fixed index ? Should we search for the + // attribute tokentree instead ? + + // Derive proc macros have the following format: + // #[proc_macro_derive(TraitName, attributes(attr1, attr2, attr3))] + // -~~~~~~~~ - ~~~~~~~~~~--------------------- + // ^0 ^1 ^2 ^3 ^4 + // - "attributes" is stored at position 3 in the token tree + // - attribute are stored in the delimited token tree in position 4 + constexpr size_t attr_kw_pos = 3; + constexpr size_t attribute_list_pos = 4; + + if (tt.get_token_trees ().size () > attr_kw_pos) + { + rust_assert (tt.get_token_trees ()[attr_kw_pos]->as_string () + == "attributes"); + + auto attributes = static_cast ( + tt.get_token_trees ()[attribute_list_pos].get ()); + + auto &token_trees = attributes->get_token_trees (); + + for (auto i = token_trees.cbegin () + 1; // Skip opening parenthesis + i < token_trees.cend (); + i += 2) // Skip comma and closing parenthesis + { + result.push_back ((*i)->as_string ()); + } + } + return result; +} + +static std::string +Attributes::get_trait_name (const AST::Attribute &attr) +{ + // Derive proc macros have the following format: + // #[proc_macro_derive(TraitName, attributes(attr1, attr2, attr3))] + // -~~~~~~~~ - ~~~~~~~~~~--------------------- + // ^0 ^1 ^2 ^3 ^4 + // - The trait name is stored at position 1 + constexpr size_t trait_name_pos = 1; + + rust_assert (attr.get_attr_input ().get_attr_input_type () + == Rust::AST::AttrInput::TOKEN_TREE); + const auto &tt + = static_cast (attr.get_attr_input ()); + return tt.get_token_trees ()[trait_name_pos]->as_string (); +} using Attrs = Values::Attributes; diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h index c341b3e0a5db..3aecfcbb41bb 100644 --- a/gcc/rust/util/rust-attributes.h +++ b/gcc/rust/util/rust-attributes.h @@ -29,6 +29,8 @@ class Attributes { public: static bool is_known (const std::string &attribute_path); + static std::vector get_attributes (const AST::Attribute &attr); + static std::string get_trait_name (const AST::Attribute &attr); }; enum CompilerPass