From: Mason Pike <[email protected]>

gcc/rust/ChangeLog:
        * util/rust-attributes.cc: factor out loops from
        several functions to prevent us from having to loop
        several times over the same attributes

Signed-off-by: Mason Pike <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/028f3e8cc5a09ea7c3bd4823892f36cb902d25ba

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4339

 gcc/rust/util/rust-attributes.cc | 195 ++++++++++++++++++-------------
 1 file changed, 113 insertions(+), 82 deletions(-)

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 6c0fa0ea0..9141bf5b1 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -380,31 +380,27 @@ check_deprecated_attribute (const AST::Attribute 
&attribute)
  * explicitly in rust-derive.cc
  */
 static void
-check_valid_attribute_for_item (const AST::AttrVec &attributes,
+check_valid_attribute_for_item (const AST::Attribute &attr,
                                const AST::Item &item)
 {
-  for (auto &attr : attributes)
+  if (item.get_item_kind () != AST::Item::Kind::Function
+      && (attr.get_path () == Values::Attributes::TARGET_FEATURE
+         || attr.get_path () == Values::Attributes::COLD
+         || attr.get_path () == Values::Attributes::INLINE))
     {
-      if (item.get_item_kind () != AST::Item::Kind::Function
-         && (attr.get_path () == Values::Attributes::TARGET_FEATURE
-             || attr.get_path () == Values::Attributes::COLD
-             || attr.get_path () == Values::Attributes::INLINE))
-       {
-         rust_error_at (
-           attr.get_locus (),
-           "the %<#[%s]%> attribute may only be applied to functions",
-           attr.get_path ().as_string ().c_str ());
-       }
-      else if (attr.get_path () == Values::Attributes::REPR
-              && item.get_item_kind () == AST::Item::Kind::Enum
-              && item.get_item_kind () == AST::Item::Kind::Union
-              && item.get_item_kind () == AST::Item::Kind::Struct)
-       {
-         rust_error_at (attr.get_locus (),
-                        "the %<#[%s]%> attribute may only be applied "
-                        "to structs, enums and unions",
-                        attr.get_path ().as_string ().c_str ());
-       }
+      rust_error_at (attr.get_locus (),
+                    "the %<#[%s]%> attribute may only be applied to functions",
+                    attr.get_path ().as_string ().c_str ());
+    }
+  else if (attr.get_path () == Values::Attributes::REPR
+          && item.get_item_kind () != AST::Item::Kind::Enum
+          && item.get_item_kind () != AST::Item::Kind::Union
+          && item.get_item_kind () != AST::Item::Kind::Struct)
+    {
+      rust_error_at (attr.get_locus (),
+                    "the %<#[%s]%> attribute may only be applied "
+                    "to structs, enums and unions",
+                    attr.get_path ().as_string ().c_str ());
     }
 }
 
@@ -423,33 +419,26 @@ is_proc_macro_type (const AST::Attribute &attribute)
 // Emit an error when one encountered attribute is either #[proc_macro],
 // #[proc_macro_attribute] or #[proc_macro_derive]
 static void
-check_proc_macro_non_function (const AST::AttrVec &attributes)
+check_proc_macro_non_function (const AST::Attribute &attr)
 {
-  for (auto &attr : attributes)
-    {
-      if (is_proc_macro_type (attr))
-       rust_error_at (
-         attr.get_locus (),
-         "the %<#[%s]%> attribute may only be used on bare functions",
-         attr.get_path ().get_segments ()[0].as_string ().c_str ());
-    }
+  if (is_proc_macro_type (attr))
+    rust_error_at (attr.get_locus (),
+                  "the %<#[%s]%> attribute may only be used on bare functions",
+                  attr.get_path ().get_segments ()[0].as_string ().c_str ());
 }
 
 // Emit an error when one attribute is either proc_macro, proc_macro_attribute
 // or proc_macro_derive
 static void
-check_proc_macro_non_root (AST::AttrVec attributes, location_t loc)
+check_proc_macro_non_root (const AST::Attribute &attr, location_t loc)
 {
-  for (auto &attr : attributes)
+  if (is_proc_macro_type (attr))
     {
-      if (is_proc_macro_type (attr))
-       {
-         rust_error_at (
-           loc,
-           "functions tagged with %<#[%s]%> must currently "
-           "reside in the root of the crate",
-           attr.get_path ().get_segments ().at (0).as_string ().c_str ());
-       }
+      rust_error_at (
+       loc,
+       "functions tagged with %<#[%s]%> must currently "
+       "reside in the root of the crate",
+       attr.get_path ().get_segments ().at (0).as_string ().c_str ());
     }
 }
 
@@ -741,8 +730,8 @@ AttributeChecker::visit (AST::BlockExpr &expr)
        {
          // Non owning pointer, let it go out of scope
          auto item = static_cast<AST::Item *> (stmt.get ());
-         check_proc_macro_non_root (item->get_outer_attrs (),
-                                    item->get_locus ());
+         for (auto &attr : item->get_outer_attrs ())
+           check_proc_macro_non_root (attr, item->get_locus ());
        }
     }
   AST::DefaultASTVisitor::visit (expr);
@@ -848,21 +837,28 @@ AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
 void
 AttributeChecker::visit (AST::Module &module)
 {
-  check_valid_attribute_for_item (module.get_outer_attrs (), module);
-  check_attributes (module.get_outer_attrs ());
-  check_proc_macro_non_function (module.get_outer_attrs ());
-  for (auto &item : module.get_items ())
+  for (auto &attr : module.get_outer_attrs ())
     {
-      check_proc_macro_non_root (item->get_outer_attrs (), item->get_locus ());
+      check_valid_attribute_for_item (attr, module);
+      check_attribute (attr);
+      check_proc_macro_non_function (attr);
     }
+
+  for (auto &item : module.get_items ())
+    for (auto &attr : item->get_outer_attrs ())
+      check_proc_macro_non_root (attr, item->get_locus ());
+
   AST::DefaultASTVisitor::visit (module);
 }
 
 void
 AttributeChecker::visit (AST::ExternCrate &crate)
 {
-  check_valid_attribute_for_item (crate.get_outer_attrs (), crate);
-  check_proc_macro_non_function (crate.get_outer_attrs ());
+  for (auto &attr : crate.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, crate);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
@@ -880,8 +876,11 @@ AttributeChecker::visit (AST::UseTreeRebind &)
 void
 AttributeChecker::visit (AST::UseDeclaration &declaration)
 {
-  check_valid_attribute_for_item (declaration.get_outer_attrs (), declaration);
-  check_proc_macro_non_function (declaration.get_outer_attrs ());
+  for (auto &attr : declaration.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, declaration);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 static void
@@ -903,7 +902,9 @@ check_no_mangle_function (const AST::Attribute &attribute,
 void
 AttributeChecker::visit (AST::Function &fun)
 {
-  check_valid_attribute_for_item (fun.get_outer_attrs (), fun);
+  for (auto &attr : fun.get_outer_attrs ())
+    check_valid_attribute_for_item (attr, fun);
+
   auto check_crate_type = [] (const char *name, AST::Attribute &attribute) {
     if (!Session::get_instance ().options.is_proc_macro ())
       rust_error_at (attribute.get_locus (),
@@ -995,23 +996,32 @@ AttributeChecker::visit (AST::Function &fun)
 void
 AttributeChecker::visit (AST::TypeAlias &alias)
 {
-  check_valid_attribute_for_item (alias.get_outer_attrs (), alias);
-  check_proc_macro_non_function (alias.get_outer_attrs ());
+  for (auto &attr : alias.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, alias);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::StructStruct &struct_item)
 {
-  check_valid_attribute_for_item (struct_item.get_outer_attrs (), struct_item);
-  check_attributes (struct_item.get_outer_attrs ());
-  check_proc_macro_non_function (struct_item.get_outer_attrs ());
+  for (auto &attr : struct_item.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, struct_item);
+      check_attribute (attr);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::TupleStruct &tuplestruct)
 {
-  check_valid_attribute_for_item (tuplestruct.get_outer_attrs (), tuplestruct);
-  check_proc_macro_non_function (tuplestruct.get_outer_attrs ());
+  for (auto &attr : tuplestruct.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, tuplestruct);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
@@ -1033,42 +1043,50 @@ AttributeChecker::visit (AST::EnumItemDiscriminant &)
 void
 AttributeChecker::visit (AST::Enum &enumeration)
 {
-  check_valid_attribute_for_item (enumeration.get_outer_attrs (), enumeration);
-  check_proc_macro_non_function (enumeration.get_outer_attrs ());
+  for (auto &attr : enumeration.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, enumeration);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::Union &u)
 {
-  check_valid_attribute_for_item (u.get_outer_attrs (), u);
-  check_proc_macro_non_function (u.get_outer_attrs ());
+  for (auto &attr : u.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, u);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::ConstantItem &item)
 {
-  check_valid_attribute_for_item (item.get_outer_attrs (), item);
-  check_proc_macro_non_function (item.get_outer_attrs ());
+  for (auto &attr : item.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, item);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::StaticItem &item)
 {
-  check_valid_attribute_for_item (item.get_outer_attrs (), item);
-  check_proc_macro_non_function (item.get_outer_attrs ());
-
   BuiltinAttrDefinition result;
-  for (auto &attribute : item.get_outer_attrs ())
+  for (auto &attr : item.get_outer_attrs ())
     {
-      if (is_builtin (attribute, result))
+      check_valid_attribute_for_item (attr, item);
+      check_proc_macro_non_function (attr);
+      if (is_builtin (attr, result))
        {
          if (result.name == Attrs::LINK_SECTION)
            {
-             check_link_section_attribute (attribute);
+             check_link_section_attribute (attr);
            }
          else if (result.name == Attrs::EXPORT_NAME)
            {
-             check_export_name_attribute (attribute);
+             check_export_name_attribute (attr);
            }
        }
     }
@@ -1081,24 +1099,34 @@ AttributeChecker::visit (AST::TraitItemType &)
 void
 AttributeChecker::visit (AST::Trait &trait)
 {
-  check_valid_attribute_for_item (trait.get_outer_attrs (), trait);
-  check_proc_macro_non_function (trait.get_outer_attrs ());
-  check_attributes (trait.get_outer_attrs ());
+  for (auto &attr : trait.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, trait);
+      check_proc_macro_non_function (attr);
+      check_attribute (attr);
+    }
 }
 
 void
 AttributeChecker::visit (AST::InherentImpl &impl)
 {
-  check_valid_attribute_for_item (impl.get_outer_attrs (), impl);
-  check_proc_macro_non_function (impl.get_outer_attrs ());
+  for (auto &attr : impl.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, impl);
+      check_proc_macro_non_function (attr);
+    }
+
   AST::DefaultASTVisitor::visit (impl);
 }
 
 void
 AttributeChecker::visit (AST::TraitImpl &impl)
 {
-  check_valid_attribute_for_item (impl.get_outer_attrs (), impl);
-  check_proc_macro_non_function (impl.get_outer_attrs ());
+  for (auto &attr : impl.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, impl);
+      check_proc_macro_non_function (attr);
+    }
   AST::DefaultASTVisitor::visit (impl);
 }
 
@@ -1113,8 +1141,11 @@ AttributeChecker::visit (AST::ExternalStaticItem &)
 void
 AttributeChecker::visit (AST::ExternBlock &block)
 {
-  check_valid_attribute_for_item (block.get_outer_attrs (), block);
-  check_proc_macro_non_function (block.get_outer_attrs ());
+  for (auto &attr : block.get_outer_attrs ())
+    {
+      check_valid_attribute_for_item (attr, block);
+      check_proc_macro_non_function (attr);
+    }
 }
 
 // rust-macro.h
-- 
2.52.0

Reply via email to