Skip to content

Commit

Permalink
gcc/rust/ChangeLog:
Browse files Browse the repository at this point in the history
	* backend/rust-compile-base.cc (get_attributes):
	(get_trait_name):
	* util/rust-attributes.cc (Attributes::get_attributes):
	(Attributes::get_trait_name):
	* util/rust-attributes.h:

Signed-off-by: Om Swaroop Nayak <96killerat96@gmail.com>
  • Loading branch information
saeitoshi-10 committed Dec 31, 2024
1 parent d28cae5 commit 2c1e525
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 59 deletions.
61 changes: 2 additions & 59 deletions gcc/rust/backend/rust-compile-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -158,64 +159,6 @@ HIRCompileBase::handle_attribute_proc_macro_attribute_on_fndecl (
ctx->collect_attribute_proc_macro (fndecl);
}

static std::vector<std::string>
get_attributes (const AST::Attribute &attr)
{
std::vector<std::string> result;

rust_assert (attr.get_attr_input ().get_attr_input_type ()
== Rust::AST::AttrInput::TOKEN_TREE);
const auto &tt
= static_cast<const AST::DelimTokenTree &> (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<const AST::DelimTokenTree *> (
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<const AST::DelimTokenTree &> (attr.get_attr_input ());
return tt.get_token_trees ()[trait_name_pos]->as_string ();
}

void
HIRCompileBase::handle_derive_proc_macro_attribute_on_fndecl (
Expand All @@ -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);
}

Expand Down
58 changes: 58 additions & 0 deletions gcc/rust/util/rust-attributes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,64 @@ Attributes::is_known (const std::string &attribute_path)

return !lookup.is_error ();
}
static std::vector<std::string>
Attributes::get_attributes (const AST::Attribute &attr)
{
std::vector<std::string> result;

rust_assert (attr.get_attr_input ().get_attr_input_type ()
== Rust::AST::AttrInput::TOKEN_TREE);
const auto &tt
= static_cast<const AST::DelimTokenTree &> (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<const AST::DelimTokenTree *> (
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<const AST::DelimTokenTree &> (attr.get_attr_input ());
return tt.get_token_trees ()[trait_name_pos]->as_string ();
}

using Attrs = Values::Attributes;

Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/util/rust-attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Attributes
{
public:
static bool is_known (const std::string &attribute_path);
static std::vector<std::string> get_attributes (const AST::Attribute &attr);
static std::string get_trait_name (const AST::Attribute &attr);
};

enum CompilerPass
Expand Down

0 comments on commit 2c1e525

Please sign in to comment.