From 4a2bd8382529db95b37c216f5abe96aa752b34a1 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 6 Sep 2023 14:44:20 +0200 Subject: [PATCH] gccrs: Collect procedural macros in the crate Collect informations on procedural macros in the compiled crate. For attribute and bang procedural macros we only require the final address as well as the name of the function. Derive procedural macros are a bit different, we collect the fonction's address through it's fndecl tree as well as the trait's name and the multiple attributes. gcc/rust/ChangeLog: * backend/rust-compile-base.cc (HIRCompileBase::setup_fndecl): Make the function non static in order to be able to access the compile context. Also add the whole proc macro infomrmation collection. (get_attributes): Add a function to retrieve the different attributes from a derive procedural macro definition attribute. (get_trait_name): Add a function to retrieve the trait name from a derive procedural macro definition attribute. * backend/rust-compile-base.h: Add function prototypes. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/backend/rust-compile-base.cc | 59 ++++++++++++++++++++++++--- gcc/rust/backend/rust-compile-base.h | 23 +++++------ 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index d552a675262..fe6d5e3380f 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -117,15 +117,15 @@ HIRCompileBase::setup_fndecl (tree fndecl, bool is_main_entry_point, } else if (is_proc_macro) { - handle_proc_macro_attribute_on_fndecl (fndecl, attr); + handle_bang_proc_macro_attribute_on_fndecl (fndecl, attr); } else if (is_proc_macro_attribute) { - handle_proc_macro_attribute_attribute_on_fndecl (fndecl, attr); + handle_attribute_proc_macro_attribute_on_fndecl (fndecl, attr); } else if (is_proc_macro_derive) { - handle_proc_macro_derive_attribute_on_fndecl (fndecl, attr); + handle_derive_proc_macro_attribute_on_fndecl (fndecl, attr); } } } @@ -138,24 +138,71 @@ handle_proc_macro_common (tree fndecl, const AST::Attribute &attr) } void -HIRCompileBase::handle_proc_macro_attribute_on_fndecl ( +HIRCompileBase::handle_bang_proc_macro_attribute_on_fndecl ( tree fndecl, const AST::Attribute &attr) { handle_proc_macro_common (fndecl, attr); + ctx->collect_bang_proc_macro (fndecl); } void -HIRCompileBase::handle_proc_macro_attribute_attribute_on_fndecl ( +HIRCompileBase::handle_attribute_proc_macro_attribute_on_fndecl ( tree fndecl, const AST::Attribute &attr) { handle_proc_macro_common (fndecl, attr); + 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 ? + if (tt.get_token_trees ().size () > 3) + { + rust_assert (tt.get_token_trees ()[3]->as_string () == "attributes"); + + auto attributes = static_cast ( + tt.get_token_trees ()[4].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) +{ + 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 ()[1]->as_string (); } void -HIRCompileBase::handle_proc_macro_derive_attribute_on_fndecl ( +HIRCompileBase::handle_derive_proc_macro_attribute_on_fndecl ( tree fndecl, const AST::Attribute &attr) { handle_proc_macro_common (fndecl, attr); + + attr.get_attr_input ().parse_to_meta_item (); + CustomDeriveInfo macro + = {fndecl, get_trait_name (attr), get_attributes (attr)}; + ctx->collect_derive_proc_macro (macro); } void diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 56b29a7d368..41907ec02ab 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -102,24 +102,23 @@ protected: static tree unit_expression (Context *ctx, location_t locus); - static void setup_fndecl (tree fndecl, bool is_main_entry_point, - bool is_generic_fn, HIR::Visibility &visibility, - const HIR::FunctionQualifiers &qualifiers, - const AST::AttrVec &attrs); + void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn, + HIR::Visibility &visibility, + const HIR::FunctionQualifiers &qualifiers, + const AST::AttrVec &attrs); static void handle_inline_attribute_on_fndecl (tree fndecl, const AST::Attribute &attr); - static void - handle_proc_macro_attribute_on_fndecl (tree fndecl, - const AST::Attribute &attr); - - static void - handle_proc_macro_attribute_attribute_on_fndecl (tree fndecl, + void handle_bang_proc_macro_attribute_on_fndecl (tree fndecl, const AST::Attribute &attr); - static void - handle_proc_macro_derive_attribute_on_fndecl (tree fndecl, + void + handle_attribute_proc_macro_attribute_on_fndecl (tree fndecl, + const AST::Attribute &attr); + + void + handle_derive_proc_macro_attribute_on_fndecl (tree fndecl, const AST::Attribute &attr); static void handle_cold_attribute_on_fndecl (tree fndecl,