public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
From: arthur.cohen@embecosm.com
To: gcc-patches@gcc.gnu.org
Cc: gcc-rust@gcc.gnu.org, Arthur Cohen <arthur.cohen@embecosm.com>
Subject: [PATCH Rust front-end v4 25/46] gccrs: Add attributes checker
Date: Tue,  6 Dec 2022 11:13:57 +0100	[thread overview]
Message-ID: <20221206101417.778807-26-arthur.cohen@embecosm.com> (raw)
In-Reply-To: <20221206101417.778807-1-arthur.cohen@embecosm.com>

From: Arthur Cohen <arthur.cohen@embecosm.com>

The attribute checker is responsible for checking the validity of various
attributes including built-in ones. It is currently unfinished and will
receive some modifications, as well as become the host of some existing
code in the compiler which needs to be refactored. One of its
responsibilities is to make sure that arguments given to built-in
attributes are correct, or contain the correct type of information. This
visitor also checks that an attribute is allowed to be used in the current
particular context.
---
 gcc/rust/util/rust-attributes.cc | 839 +++++++++++++++++++++++++++++++
 gcc/rust/util/rust-attributes.h  | 270 ++++++++++
 2 files changed, 1109 insertions(+)
 create mode 100644 gcc/rust/util/rust-attributes.cc
 create mode 100644 gcc/rust/util/rust-attributes.h

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
new file mode 100644
index 00000000000..b73e9534414
--- /dev/null
+++ b/gcc/rust/util/rust-attributes.cc
@@ -0,0 +1,839 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-attributes.h"
+#include "rust-ast.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.h"
+
+namespace Rust {
+namespace Analysis {
+
+// https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
+static const BuiltinAttrDefinition __definitions[] = {
+  {"inline", CODE_GENERATION},
+  {"cold", CODE_GENERATION},
+  {"cfg", EXPANSION},
+  {"cfg_attr", EXPANSION},
+  {"deprecated", STATIC_ANALYSIS},
+  {"allow", STATIC_ANALYSIS},
+  {"doc", HIR_LOWERING},
+  {"must_use", STATIC_ANALYSIS},
+  {"lang", HIR_LOWERING},
+  {"link_section", CODE_GENERATION},
+  {"no_mangle", CODE_GENERATION},
+  {"repr", CODE_GENERATION},
+  {"path", EXPANSION},
+};
+
+BuiltinAttributeMappings *
+BuiltinAttributeMappings::get ()
+{
+  static BuiltinAttributeMappings *instance = nullptr;
+  if (instance == nullptr)
+    instance = new BuiltinAttributeMappings ();
+
+  return instance;
+}
+
+const BuiltinAttrDefinition &
+BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
+{
+  auto it = mappings.find (attr_name);
+  if (it == mappings.end ())
+    return BuiltinAttrDefinition::error_node ();
+
+  return it->second;
+}
+
+BuiltinAttributeMappings::BuiltinAttributeMappings ()
+{
+  size_t ndefinitions = sizeof (__definitions) / sizeof (BuiltinAttrDefinition);
+  for (size_t i = 0; i < ndefinitions; i++)
+    {
+      const BuiltinAttrDefinition &def = __definitions[i];
+      mappings.insert ({def.name, def});
+    }
+}
+
+AttributeChecker::AttributeChecker () {}
+
+void
+AttributeChecker::go (AST::Crate &crate)
+{
+  check_attributes (crate.get_inner_attrs ());
+
+  for (auto &item : crate.items)
+    item->accept_vis (*this);
+}
+
+static bool
+is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
+{
+  auto &segments = attribute.get_path ().get_segments ();
+
+  // Builtin attributes always have a single segment. This avoids us creating
+  // strings all over the place and performing a linear search in the builtins
+  // map
+  if (segments.size () != 1)
+    return false;
+
+  builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
+    segments.at (0).get_segment_name ());
+
+  return !builtin.is_error ();
+}
+
+/**
+ * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
+ * valid.
+ *
+ * This means no whitespace characters other than spaces and no quoting
+ * characters.
+ */
+static void
+check_doc_alias (const std::string &alias_input, const Location &locus)
+{
+  // FIXME: The locus here is for the whole attribute. Can we get the locus
+  // of the alias input instead?
+  for (auto c : alias_input)
+    if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
+      {
+	auto to_print = std::string (1, c);
+	switch (c)
+	  {
+	  case '\n':
+	    to_print = "\\n";
+	    break;
+	  case '\t':
+	    to_print = "\\t";
+	    break;
+	  default:
+	    break;
+	  }
+	rust_error_at (locus,
+		       "invalid character used in %<#[doc(alias)]%> input: %qs",
+		       to_print.c_str ());
+      }
+
+  if (alias_input.empty ())
+    return;
+
+  if (alias_input.front () == ' ' || alias_input.back () == ' ')
+    rust_error_at (locus,
+		   "%<#[doc(alias)]%> input cannot start or end with a space");
+}
+
+static void
+check_doc_attribute (const AST::Attribute &attribute)
+{
+  if (!attribute.has_attr_input ())
+    {
+      rust_error_at (
+	attribute.get_locus (),
+	// FIXME: Improve error message here. Rustc has a very good one
+	"%<#[doc]%> cannot be an empty attribute");
+      return;
+    }
+
+  switch (attribute.get_attr_input ().get_attr_input_type ())
+    {
+    case AST::AttrInput::LITERAL:
+    case AST::AttrInput::META_ITEM:
+      break;
+      // FIXME: Handle them as well
+
+      case AST::AttrInput::TOKEN_TREE: {
+	// FIXME: This doesn't check for #[doc(alias(...))]
+	const auto &option = static_cast<const AST::DelimTokenTree &> (
+	  attribute.get_attr_input ());
+	auto *meta_item = option.parse_to_meta_item ();
+
+	for (auto &item : meta_item->get_items ())
+	  {
+	    if (item->is_key_value_pair ())
+	      {
+		auto name_value
+		  = static_cast<AST::MetaNameValueStr *> (item.get ())
+		      ->get_name_value_pair ();
+
+		// FIXME: Check for other stuff than #[doc(alias = ...)]
+		if (name_value.first == "alias")
+		  check_doc_alias (name_value.second, attribute.get_locus ());
+	      }
+	  }
+	break;
+      }
+    }
+}
+
+void
+AttributeChecker::check_attribute (const AST::Attribute &attribute)
+{
+  BuiltinAttrDefinition result;
+
+  // This checker does not check non-builtin attributes
+  if (!is_builtin (attribute, result))
+    return;
+
+  // TODO: Add checks here for each builtin attribute
+  // TODO: Have an enum of builtins as well, switching on strings is annoying
+  // and costly
+  if (result.name == "doc")
+    check_doc_attribute (attribute);
+}
+
+void
+AttributeChecker::check_attributes (const AST::AttrVec &attributes)
+{
+  for (auto &attr : attributes)
+    check_attribute (attr);
+}
+
+void
+AttributeChecker::visit (AST::Token &tok)
+{}
+
+void
+AttributeChecker::visit (AST::DelimTokenTree &delim_tok_tree)
+{}
+
+void
+AttributeChecker::visit (AST::AttrInputMetaItemContainer &input)
+{}
+
+void
+AttributeChecker::visit (AST::IdentifierExpr &ident_expr)
+{}
+
+void
+AttributeChecker::visit (AST::Lifetime &lifetime)
+{}
+
+void
+AttributeChecker::visit (AST::LifetimeParam &lifetime_param)
+{}
+
+void
+AttributeChecker::visit (AST::ConstGenericParam &const_param)
+{}
+
+// rust-path.h
+void
+AttributeChecker::visit (AST::PathInExpression &path)
+{}
+
+void
+AttributeChecker::visit (AST::TypePathSegment &segment)
+{}
+
+void
+AttributeChecker::visit (AST::TypePathSegmentGeneric &segment)
+{}
+
+void
+AttributeChecker::visit (AST::TypePathSegmentFunction &segment)
+{}
+
+void
+AttributeChecker::visit (AST::TypePath &path)
+{}
+
+void
+AttributeChecker::visit (AST::QualifiedPathInExpression &path)
+{}
+
+void
+AttributeChecker::visit (AST::QualifiedPathInType &path)
+{}
+
+// rust-expr.h
+void
+AttributeChecker::visit (AST::LiteralExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::AttrInputLiteral &attr_input)
+{}
+
+void
+AttributeChecker::visit (AST::MetaItemLitExpr &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaItemPathLit &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::BorrowExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::DereferenceExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ErrorPropagationExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::NegationExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ComparisonExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::LazyBooleanExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::TypeCastExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::AssignmentExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::CompoundAssignmentExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::GroupedExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ArrayElemsValues &elems)
+{}
+
+void
+AttributeChecker::visit (AST::ArrayElemsCopied &elems)
+{}
+
+void
+AttributeChecker::visit (AST::ArrayExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ArrayIndexExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::TupleExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::TupleIndexExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprStruct &expr)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprFieldIdentifier &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprFieldIdentifierValue &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprFieldIndexValue &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprStructFields &expr)
+{}
+
+void
+AttributeChecker::visit (AST::StructExprStructBase &expr)
+{}
+
+void
+AttributeChecker::visit (AST::CallExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::MethodCallExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::FieldAccessExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ClosureExprInner &expr)
+{}
+
+void
+AttributeChecker::visit (AST::BlockExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ClosureExprInnerTyped &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ContinueExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::BreakExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeFromToExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeFromExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeToExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeFullExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeFromToInclExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::RangeToInclExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ReturnExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::UnsafeBlockExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::LoopExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::WhileLoopExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::WhileLetLoopExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::ForLoopExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfExprConseqElse &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfExprConseqIf &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfExprConseqIfLet &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfLetExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfLetExprConseqElse &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfLetExprConseqIf &expr)
+{}
+
+void
+AttributeChecker::visit (AST::IfLetExprConseqIfLet &expr)
+{}
+
+void
+AttributeChecker::visit (AST::MatchExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::AwaitExpr &expr)
+{}
+
+void
+AttributeChecker::visit (AST::AsyncBlockExpr &expr)
+{}
+
+// rust-item.h
+void
+AttributeChecker::visit (AST::TypeParam &param)
+{}
+
+void
+AttributeChecker::visit (AST::LifetimeWhereClauseItem &item)
+{}
+
+void
+AttributeChecker::visit (AST::TypeBoundWhereClauseItem &item)
+{}
+
+void
+AttributeChecker::visit (AST::Method &method)
+{}
+
+void
+AttributeChecker::visit (AST::Module &module)
+{}
+
+void
+AttributeChecker::visit (AST::ExternCrate &crate)
+{}
+
+void
+AttributeChecker::visit (AST::UseTreeGlob &use_tree)
+{}
+
+void
+AttributeChecker::visit (AST::UseTreeList &use_tree)
+{}
+
+void
+AttributeChecker::visit (AST::UseTreeRebind &use_tree)
+{}
+
+void
+AttributeChecker::visit (AST::UseDeclaration &use_decl)
+{}
+
+void
+AttributeChecker::visit (AST::Function &function)
+{}
+
+void
+AttributeChecker::visit (AST::TypeAlias &type_alias)
+{}
+
+void
+AttributeChecker::visit (AST::StructStruct &struct_item)
+{
+  check_attributes (struct_item.get_outer_attrs ());
+}
+
+void
+AttributeChecker::visit (AST::TupleStruct &tuple_struct)
+{}
+
+void
+AttributeChecker::visit (AST::EnumItem &item)
+{}
+
+void
+AttributeChecker::visit (AST::EnumItemTuple &item)
+{}
+
+void
+AttributeChecker::visit (AST::EnumItemStruct &item)
+{}
+
+void
+AttributeChecker::visit (AST::EnumItemDiscriminant &item)
+{}
+
+void
+AttributeChecker::visit (AST::Enum &enum_item)
+{}
+
+void
+AttributeChecker::visit (AST::Union &union_item)
+{}
+
+void
+AttributeChecker::visit (AST::ConstantItem &const_item)
+{}
+
+void
+AttributeChecker::visit (AST::StaticItem &static_item)
+{}
+
+void
+AttributeChecker::visit (AST::TraitItemFunc &item)
+{}
+
+void
+AttributeChecker::visit (AST::TraitItemMethod &item)
+{}
+
+void
+AttributeChecker::visit (AST::TraitItemConst &item)
+{}
+
+void
+AttributeChecker::visit (AST::TraitItemType &item)
+{}
+
+void
+AttributeChecker::visit (AST::Trait &trait)
+{}
+
+void
+AttributeChecker::visit (AST::InherentImpl &impl)
+{}
+
+void
+AttributeChecker::visit (AST::TraitImpl &impl)
+{}
+
+void
+AttributeChecker::visit (AST::ExternalStaticItem &item)
+{}
+
+void
+AttributeChecker::visit (AST::ExternalFunctionItem &item)
+{}
+
+void
+AttributeChecker::visit (AST::ExternBlock &block)
+{}
+
+// rust-macro.h
+void
+AttributeChecker::visit (AST::MacroMatchFragment &match)
+{}
+
+void
+AttributeChecker::visit (AST::MacroMatchRepetition &match)
+{}
+
+void
+AttributeChecker::visit (AST::MacroMatcher &matcher)
+{}
+
+void
+AttributeChecker::visit (AST::MacroRulesDefinition &rules_def)
+{}
+
+void
+AttributeChecker::visit (AST::MacroInvocation &macro_invoc)
+{}
+
+void
+AttributeChecker::visit (AST::MetaItemPath &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaItemSeq &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaWord &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaNameValueStr &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaListPaths &meta_item)
+{}
+
+void
+AttributeChecker::visit (AST::MetaListNameValueStr &meta_item)
+{}
+
+// rust-pattern.h
+void
+AttributeChecker::visit (AST::LiteralPattern &pattern)
+{}
+
+void
+AttributeChecker::visit (AST::IdentifierPattern &pattern)
+{}
+
+void
+AttributeChecker::visit (AST::WildcardPattern &pattern)
+{}
+
+// void AttributeChecker::visit(RangePatternBound& bound){}
+
+void
+AttributeChecker::visit (AST::RangePatternBoundLiteral &bound)
+{}
+
+void
+AttributeChecker::visit (AST::RangePatternBoundPath &bound)
+{}
+
+void
+AttributeChecker::visit (AST::RangePatternBoundQualPath &bound)
+{}
+
+void
+AttributeChecker::visit (AST::RangePattern &pattern)
+{}
+
+void
+AttributeChecker::visit (AST::ReferencePattern &pattern)
+{}
+
+// void AttributeChecker::visit(StructPatternField& field){}
+
+void
+AttributeChecker::visit (AST::StructPatternFieldTuplePat &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructPatternFieldIdentPat &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructPatternFieldIdent &field)
+{}
+
+void
+AttributeChecker::visit (AST::StructPattern &pattern)
+{}
+
+// void AttributeChecker::visit(TupleStructItems& tuple_items){}
+
+void
+AttributeChecker::visit (AST::TupleStructItemsNoRange &tuple_items)
+{}
+
+void
+AttributeChecker::visit (AST::TupleStructItemsRange &tuple_items)
+{}
+
+void
+AttributeChecker::visit (AST::TupleStructPattern &pattern)
+{}
+
+// void AttributeChecker::visit(TuplePatternItems& tuple_items){}
+
+void
+AttributeChecker::visit (AST::TuplePatternItemsMultiple &tuple_items)
+{}
+
+void
+AttributeChecker::visit (AST::TuplePatternItemsRanged &tuple_items)
+{}
+
+void
+AttributeChecker::visit (AST::TuplePattern &pattern)
+{}
+
+void
+AttributeChecker::visit (AST::GroupedPattern &pattern)
+{}
+
+void
+AttributeChecker::visit (AST::SlicePattern &pattern)
+{}
+
+// rust-stmt.h
+void
+AttributeChecker::visit (AST::EmptyStmt &stmt)
+{}
+
+void
+AttributeChecker::visit (AST::LetStmt &stmt)
+{}
+
+void
+AttributeChecker::visit (AST::ExprStmtWithoutBlock &stmt)
+{}
+
+void
+AttributeChecker::visit (AST::ExprStmtWithBlock &stmt)
+{}
+
+// rust-type.h
+void
+AttributeChecker::visit (AST::TraitBound &bound)
+{}
+
+void
+AttributeChecker::visit (AST::ImplTraitType &type)
+{}
+
+void
+AttributeChecker::visit (AST::TraitObjectType &type)
+{}
+
+void
+AttributeChecker::visit (AST::ParenthesisedType &type)
+{}
+
+void
+AttributeChecker::visit (AST::ImplTraitTypeOneBound &type)
+{}
+
+void
+AttributeChecker::visit (AST::TraitObjectTypeOneBound &type)
+{}
+
+void
+AttributeChecker::visit (AST::TupleType &type)
+{}
+
+void
+AttributeChecker::visit (AST::NeverType &type)
+{}
+
+void
+AttributeChecker::visit (AST::RawPointerType &type)
+{}
+
+void
+AttributeChecker::visit (AST::ReferenceType &type)
+{}
+
+void
+AttributeChecker::visit (AST::ArrayType &type)
+{}
+
+void
+AttributeChecker::visit (AST::SliceType &type)
+{}
+
+void
+AttributeChecker::visit (AST::InferredType &type)
+{}
+
+void
+AttributeChecker::visit (AST::BareFunctionType &type)
+{}
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
new file mode 100644
index 00000000000..3ac93ff5908
--- /dev/null
+++ b/gcc/rust/util/rust-attributes.h
@@ -0,0 +1,270 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast.h"
+#include "rust-system.h"
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace Analysis {
+
+enum CompilerPass
+{
+  UNKNOWN,
+
+  EXPANSION,
+  NAME_RESOLUTION,
+  HIR_LOWERING,
+  TYPE_CHECK,
+  STATIC_ANALYSIS,
+  CODE_GENERATION
+};
+
+struct BuiltinAttrDefinition
+{
+  std::string name;
+  CompilerPass handler;
+
+  static BuiltinAttrDefinition get_error ()
+  {
+    return BuiltinAttrDefinition{"", UNKNOWN};
+  }
+
+  static BuiltinAttrDefinition &error_node ()
+  {
+    static BuiltinAttrDefinition error_node = get_error ();
+    return error_node;
+  }
+
+  bool is_error () const { return name.empty (); }
+};
+
+class BuiltinAttributeMappings
+{
+public:
+  static BuiltinAttributeMappings *get ();
+
+  const BuiltinAttrDefinition &
+  lookup_builtin (const std::string &attr_name) const;
+
+private:
+  BuiltinAttributeMappings ();
+
+  std::map<std::string, const BuiltinAttrDefinition> mappings;
+};
+
+/**
+ * Checks the validity of various attributes. The goal of this visitor is to
+ * make sure that attributes are applied in allowed contexts, for example to
+ * make sure that #[inline] is only applied to functions and closures, as well
+ * as checking the "arguments" or input given to these attributes, making sure
+ * it is appropriate and valid.
+ */
+class AttributeChecker : public AST::ASTVisitor
+{
+public:
+  AttributeChecker ();
+
+  /**
+   * Check all the attributes of all the items of a crate
+   */
+  void go (AST::Crate &crate);
+
+private:
+  /* Check the validity of a given attribute */
+  void check_attribute (const AST::Attribute &attribute);
+
+  /* Check the validity of all given attributes */
+  void check_attributes (const AST::AttrVec &attributes);
+
+  // rust-ast.h
+  void visit (AST::Token &tok);
+  void visit (AST::DelimTokenTree &delim_tok_tree);
+  void visit (AST::AttrInputMetaItemContainer &input);
+  void visit (AST::IdentifierExpr &ident_expr);
+  void visit (AST::Lifetime &lifetime);
+  void visit (AST::LifetimeParam &lifetime_param);
+  void visit (AST::ConstGenericParam &const_param);
+
+  // rust-path.h
+  void visit (AST::PathInExpression &path);
+  void visit (AST::TypePathSegment &segment);
+  void visit (AST::TypePathSegmentGeneric &segment);
+  void visit (AST::TypePathSegmentFunction &segment);
+  void visit (AST::TypePath &path);
+  void visit (AST::QualifiedPathInExpression &path);
+  void visit (AST::QualifiedPathInType &path);
+
+  // rust-expr.h
+  void visit (AST::LiteralExpr &expr);
+  void visit (AST::AttrInputLiteral &attr_input);
+  void visit (AST::MetaItemLitExpr &meta_item);
+  void visit (AST::MetaItemPathLit &meta_item);
+  void visit (AST::BorrowExpr &expr);
+  void visit (AST::DereferenceExpr &expr);
+  void visit (AST::ErrorPropagationExpr &expr);
+  void visit (AST::NegationExpr &expr);
+  void visit (AST::ArithmeticOrLogicalExpr &expr);
+  void visit (AST::ComparisonExpr &expr);
+  void visit (AST::LazyBooleanExpr &expr);
+  void visit (AST::TypeCastExpr &expr);
+  void visit (AST::AssignmentExpr &expr);
+  void visit (AST::CompoundAssignmentExpr &expr);
+  void visit (AST::GroupedExpr &expr);
+  void visit (AST::ArrayElemsValues &elems);
+  void visit (AST::ArrayElemsCopied &elems);
+  void visit (AST::ArrayExpr &expr);
+  void visit (AST::ArrayIndexExpr &expr);
+  void visit (AST::TupleExpr &expr);
+  void visit (AST::TupleIndexExpr &expr);
+  void visit (AST::StructExprStruct &expr);
+  void visit (AST::StructExprFieldIdentifier &field);
+  void visit (AST::StructExprFieldIdentifierValue &field);
+  void visit (AST::StructExprFieldIndexValue &field);
+  void visit (AST::StructExprStructFields &expr);
+  void visit (AST::StructExprStructBase &expr);
+  void visit (AST::CallExpr &expr);
+  void visit (AST::MethodCallExpr &expr);
+  void visit (AST::FieldAccessExpr &expr);
+  void visit (AST::ClosureExprInner &expr);
+  void visit (AST::BlockExpr &expr);
+  void visit (AST::ClosureExprInnerTyped &expr);
+  void visit (AST::ContinueExpr &expr);
+  void visit (AST::BreakExpr &expr);
+  void visit (AST::RangeFromToExpr &expr);
+  void visit (AST::RangeFromExpr &expr);
+  void visit (AST::RangeToExpr &expr);
+  void visit (AST::RangeFullExpr &expr);
+  void visit (AST::RangeFromToInclExpr &expr);
+  void visit (AST::RangeToInclExpr &expr);
+  void visit (AST::ReturnExpr &expr);
+  void visit (AST::UnsafeBlockExpr &expr);
+  void visit (AST::LoopExpr &expr);
+  void visit (AST::WhileLoopExpr &expr);
+  void visit (AST::WhileLetLoopExpr &expr);
+  void visit (AST::ForLoopExpr &expr);
+  void visit (AST::IfExpr &expr);
+  void visit (AST::IfExprConseqElse &expr);
+  void visit (AST::IfExprConseqIf &expr);
+  void visit (AST::IfExprConseqIfLet &expr);
+  void visit (AST::IfLetExpr &expr);
+  void visit (AST::IfLetExprConseqElse &expr);
+  void visit (AST::IfLetExprConseqIf &expr);
+  void visit (AST::IfLetExprConseqIfLet &expr);
+  void visit (AST::MatchExpr &expr);
+  void visit (AST::AwaitExpr &expr);
+  void visit (AST::AsyncBlockExpr &expr);
+
+  // rust-item.h
+  void visit (AST::TypeParam &param);
+  void visit (AST::LifetimeWhereClauseItem &item);
+  void visit (AST::TypeBoundWhereClauseItem &item);
+  void visit (AST::Method &method);
+  void visit (AST::Module &module);
+  void visit (AST::ExternCrate &crate);
+  void visit (AST::UseTreeGlob &use_tree);
+  void visit (AST::UseTreeList &use_tree);
+  void visit (AST::UseTreeRebind &use_tree);
+  void visit (AST::UseDeclaration &use_decl);
+  void visit (AST::Function &function);
+  void visit (AST::TypeAlias &type_alias);
+  void visit (AST::StructStruct &struct_item);
+  void visit (AST::TupleStruct &tuple_struct);
+  void visit (AST::EnumItem &item);
+  void visit (AST::EnumItemTuple &item);
+  void visit (AST::EnumItemStruct &item);
+  void visit (AST::EnumItemDiscriminant &item);
+  void visit (AST::Enum &enum_item);
+  void visit (AST::Union &union_item);
+  void visit (AST::ConstantItem &const_item);
+  void visit (AST::StaticItem &static_item);
+  void visit (AST::TraitItemFunc &item);
+  void visit (AST::TraitItemMethod &item);
+  void visit (AST::TraitItemConst &item);
+  void visit (AST::TraitItemType &item);
+  void visit (AST::Trait &trait);
+  void visit (AST::InherentImpl &impl);
+  void visit (AST::TraitImpl &impl);
+  void visit (AST::ExternalStaticItem &item);
+  void visit (AST::ExternalFunctionItem &item);
+  void visit (AST::ExternBlock &block);
+
+  // rust-macro.h
+  void visit (AST::MacroMatchFragment &match);
+  void visit (AST::MacroMatchRepetition &match);
+  void visit (AST::MacroMatcher &matcher);
+  void visit (AST::MacroRulesDefinition &rules_def);
+  void visit (AST::MacroInvocation &macro_invoc);
+  void visit (AST::MetaItemPath &meta_item);
+  void visit (AST::MetaItemSeq &meta_item);
+  void visit (AST::MetaWord &meta_item);
+  void visit (AST::MetaNameValueStr &meta_item);
+  void visit (AST::MetaListPaths &meta_item);
+  void visit (AST::MetaListNameValueStr &meta_item);
+
+  // rust-pattern.h
+  void visit (AST::LiteralPattern &pattern);
+  void visit (AST::IdentifierPattern &pattern);
+  void visit (AST::WildcardPattern &pattern);
+  // void visit(RangePatternBound& bound);
+  void visit (AST::RangePatternBoundLiteral &bound);
+  void visit (AST::RangePatternBoundPath &bound);
+  void visit (AST::RangePatternBoundQualPath &bound);
+  void visit (AST::RangePattern &pattern);
+  void visit (AST::ReferencePattern &pattern);
+  // void visit(StructPatternField& field);
+  void visit (AST::StructPatternFieldTuplePat &field);
+  void visit (AST::StructPatternFieldIdentPat &field);
+  void visit (AST::StructPatternFieldIdent &field);
+  void visit (AST::StructPattern &pattern);
+  // void visit(TupleStructItems& tuple_items);
+  void visit (AST::TupleStructItemsNoRange &tuple_items);
+  void visit (AST::TupleStructItemsRange &tuple_items);
+  void visit (AST::TupleStructPattern &pattern);
+  // void visit(TuplePatternItems& tuple_items);
+  void visit (AST::TuplePatternItemsMultiple &tuple_items);
+  void visit (AST::TuplePatternItemsRanged &tuple_items);
+  void visit (AST::TuplePattern &pattern);
+  void visit (AST::GroupedPattern &pattern);
+  void visit (AST::SlicePattern &pattern);
+
+  // rust-stmt.h
+  void visit (AST::EmptyStmt &stmt);
+  void visit (AST::LetStmt &stmt);
+  void visit (AST::ExprStmtWithoutBlock &stmt);
+  void visit (AST::ExprStmtWithBlock &stmt);
+
+  // rust-type.h
+  void visit (AST::TraitBound &bound);
+  void visit (AST::ImplTraitType &type);
+  void visit (AST::TraitObjectType &type);
+  void visit (AST::ParenthesisedType &type);
+  void visit (AST::ImplTraitTypeOneBound &type);
+  void visit (AST::TraitObjectTypeOneBound &type);
+  void visit (AST::TupleType &type);
+  void visit (AST::NeverType &type);
+  void visit (AST::RawPointerType &type);
+  void visit (AST::ReferenceType &type);
+  void visit (AST::ArrayType &type);
+  void visit (AST::SliceType &type);
+  void visit (AST::InferredType &type);
+  void visit (AST::BareFunctionType &type);
+};
+
+} // namespace Analysis
+} // namespace Rust
-- 
2.38.1


  parent reply	other threads:[~2022-12-06 10:12 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-06 10:13 Rust front-end patches v4 arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 01/46] Use DW_ATE_UTF for the Rust 'char' type arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 02/46] gccrs: Add necessary hooks for a Rust front-end testsuite arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 03/46] gccrs: Add Debug info testsuite arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 04/46] gccrs: Add link cases testsuite arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 05/46] gccrs: Add general compilation test cases arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 06/46] gccrs: Add execution " arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 07/46] gccrs: Add gcc-check-target check-rust arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 08/46] gccrs: Add Rust front-end base AST data structures arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 09/46] gccrs: Add definitions of Rust Items in " arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 10/46] gccrs: Add full definitions of Rust " arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 11/46] gccrs: Add Rust AST visitors arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 12/46] gccrs: Add Lexer for Rust front-end arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 13/46] gccrs: Add Parser for Rust front-end pt.1 arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 14/46] gccrs: Add Parser for Rust front-end pt.2 arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 15/46] gccrs: Add expansion pass for the Rust front-end arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 16/46] gccrs: Add name resolution pass to " arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 17/46] gccrs: Add declarations for Rust HIR arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 18/46] gccrs: Add HIR definitions and visitor framework arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 19/46] gccrs: Add AST to HIR lowering pass arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 20/46] gccrs: Add wrapper for make_unique arthur.cohen
2022-12-07  8:50   ` Arsen Arsenović
2022-12-07  9:14     ` Thomas Schwinge
2022-12-06 10:13 ` [PATCH Rust front-end v4 21/46] gccrs: Add port of FNV hash used during legacy symbol mangling arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 22/46] gccrs: Add Rust ABI enum helpers arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 23/46] gccrs: Add Base62 implementation arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 24/46] gccrs: Add implementation of Optional arthur.cohen
2022-12-06 10:13 ` arthur.cohen [this message]
2022-12-06 10:13 ` [PATCH Rust front-end v4 26/46] gccrs: Add helpers mappings canonical path and lang items arthur.cohen
2022-12-06 10:13 ` [PATCH Rust front-end v4 27/46] gccrs: Add type resolution and trait solving pass arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 28/46] gccrs: Add Rust type information arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 29/46] gccrs: Add remaining type system transformations arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 30/46] gccrs: Add unsafe checks for Rust arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 31/46] gccrs: Add const checker arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 32/46] gccrs: Add privacy checks arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 33/46] gccrs: Add dead code scan on HIR arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 34/46] gccrs: Add unused variable scan arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 35/46] gccrs: Add metadata output pass arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 36/46] gccrs: Add base for HIR to GCC GENERIC lowering arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 37/46] gccrs: Add HIR to GCC GENERIC lowering for all nodes arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 38/46] gccrs: Add HIR to GCC GENERIC lowering entry point arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 39/46] gccrs: These are wrappers ported from reusing gccgo arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 40/46] gccrs: Add GCC Rust front-end Make-lang.in arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 41/46] gccrs: Add config-lang.in arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 42/46] gccrs: Add lang-spec.h arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 43/46] gccrs: Add lang.opt arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 44/46] gccrs: Add compiler driver arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 45/46] gccrs: Compiler proper interface kicks off the pipeline arthur.cohen
2022-12-06 10:14 ` [PATCH Rust front-end v4 46/46] gccrs: Add README, CONTRIBUTING and compiler logo arthur.cohen
2022-12-09 10:18   ` Martin Liška
2022-12-13  1:43     ` Joseph Myers
2022-12-13 12:59       ` Martin Liška
2022-12-13 18:46         ` Joseph Myers
2022-12-06 11:03 ` Rust front-end patches v4 Richard Biener
2022-12-06 11:09   ` John Paul Adrian Glaubitz
2022-12-06 11:40     ` Arthur Cohen
2022-12-06 11:57       ` John Paul Adrian Glaubitz
2022-12-06 12:40         ` Mark Wielaard
2022-12-06 11:41   ` Iain Buclaw
2022-12-10  6:39   ` Prepare 'contrib/gcc-changelog/git_commit.py' for GCC/Rust (was: Rust front-end patches v4) Thomas Schwinge
2022-12-10  7:37     ` Add stub 'gcc/rust/ChangeLog' (was: Prepare 'contrib/gcc-changelog/git_commit.py' for GCC/Rust) Thomas Schwinge
2022-12-13 13:26   ` Rust front-end patches v4 Arthur Cohen
2022-12-13 13:30     ` Martin Liška
2022-12-13 13:53       ` Arthur Cohen
2022-12-13 13:40     ` Arthur Cohen
2022-12-14 22:58       ` Make '-frust-incomplete-and-experimental-compiler-do-not-use' a 'Common' option (was: Rust front-end patches v4) Thomas Schwinge
2022-12-15  7:53         ` Richard Biener
2022-12-15 10:14           ` Thomas Schwinge
2022-12-15 11:16             ` Jakub Jelinek
2022-12-15 11:39               ` Iain Buclaw
2022-12-15 11:50                 ` Jakub Jelinek
2022-12-15 15:01                   ` Thomas Schwinge
2022-12-15 15:17                     ` Jakub Jelinek
2022-12-16 14:10                       ` Add '-Wno-complain-wrong-lang', and use it in 'gcc/testsuite/lib/target-supports.exp:check_compile' and elsewhere (was: Make '-frust-incomplete-and-experimental-compiler-do-not-use' a 'Common' option) Thomas Schwinge
2022-12-16 21:24                         ` Iain Buclaw
2023-01-11 11:41                         ` [PING] Add '-Wno-complain-wrong-lang', and use it in 'gcc/testsuite/lib/target-supports.exp:check_compile' and elsewhere Thomas Schwinge
2023-01-11 12:31                           ` Jakub Jelinek
2023-02-21 10:21                             ` [PING, v2] " Thomas Schwinge
2023-02-21 23:20                               ` Joseph Myers
2022-12-09 13:24 ` Rust front-end patches v4 Martin Liška
2022-12-10 21:44   ` Thomas Schwinge

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221206101417.778807-26-arthur.cohen@embecosm.com \
    --to=arthur.cohen@embecosm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc-rust@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).