// Copyright (C) 2026 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-attribute-checker.h"
#include "rust-attributes.h"
#include "rust-attribute-values.h"
#include "rust-diagnostics.h"
#include "rust-session-manager.h"

namespace Rust {
namespace Analysis {

using Attrs = Values::Attributes;

static bool
is_proc_macro_type (const AST::Attribute &attribute)
{
  auto result_opt = lookup_builtin (attribute);
  if (!result_opt.has_value ())
    return false;
  auto result = result_opt.value ();

  auto name = result.name;
  return name == Attrs::PROC_MACRO || name == Attrs::PROC_MACRO_DERIVE
	 || name == Attrs::PROC_MACRO_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::Attribute &attr)
{
  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 (const AST::Attribute &attr, location_t loc)
{
  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 ());
    }
}

AttributeChecker::AttributeChecker () {}

void
AttributeChecker::go (AST::Crate &crate)
{
  visit (crate);
}

void
AttributeChecker::visit (AST::Attribute &attribute)
{
  auto &session = Session::get_instance ();
  if (attribute.get_path () == Values::Attributes::CFG_ATTR)
    {
      if (!attribute.is_parsed_to_meta_item ())
	attribute.parse_attr_to_meta_item ();
      if (!attribute.check_cfg_predicate (session))
	return; // Do not emit errors for attribute that'll get stripped.
    }

  AST::DefaultASTVisitor::visit (attribute);
}

void
AttributeChecker::visit (AST::Token &)
{}

void
AttributeChecker::visit (AST::DelimTokenTree &)
{}

void
AttributeChecker::visit (AST::IdentifierExpr &)
{}

void
AttributeChecker::visit (AST::Lifetime &)
{}

void
AttributeChecker::visit (AST::LifetimeParam &)
{}

void
AttributeChecker::visit (AST::ConstGenericParam &)
{}

// rust-path.h
void
AttributeChecker::visit (AST::PathInExpression &)
{}

void
AttributeChecker::visit (AST::TypePathSegment &)
{}

void
AttributeChecker::visit (AST::TypePathSegmentGeneric &)
{}

void
AttributeChecker::visit (AST::TypePathSegmentFunction &)
{}

void
AttributeChecker::visit (AST::TypePath &)
{}

void
AttributeChecker::visit (AST::QualifiedPathInExpression &)
{}

void
AttributeChecker::visit (AST::QualifiedPathInType &)
{}

// rust-expr.h
void
AttributeChecker::visit (AST::LiteralExpr &)
{}

void
AttributeChecker::visit (AST::AttrInputLiteral &)
{}

void
AttributeChecker::visit (AST::MetaItemLitExpr &)
{}

void
AttributeChecker::visit (AST::MetaItemPathExpr &attribute)
{
  if (!attribute.get_expr ().is_literal ())
    {
      rust_error_at (attribute.get_expr ().get_locus (),
		     "malformed %<path%> attribute input");
      rust_inform (attribute.get_expr ().get_locus (),
		   "must be of the form: %<#[path = \"file\"]%>");
    }
}

void
AttributeChecker::visit (AST::BorrowExpr &)
{}

void
AttributeChecker::visit (AST::DereferenceExpr &)
{}

void
AttributeChecker::visit (AST::ErrorPropagationExpr &)
{}

void
AttributeChecker::visit (AST::NegationExpr &)
{}

void
AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &)
{}

void
AttributeChecker::visit (AST::ComparisonExpr &)
{}

void
AttributeChecker::visit (AST::LazyBooleanExpr &)
{}

void
AttributeChecker::visit (AST::TypeCastExpr &)
{}

void
AttributeChecker::visit (AST::AssignmentExpr &)
{}

void
AttributeChecker::visit (AST::CompoundAssignmentExpr &)
{}

void
AttributeChecker::visit (AST::GroupedExpr &)
{}

void
AttributeChecker::visit (AST::ArrayElemsValues &)
{}

void
AttributeChecker::visit (AST::ArrayElemsCopied &)
{}

void
AttributeChecker::visit (AST::ArrayExpr &)
{}

void
AttributeChecker::visit (AST::ArrayIndexExpr &)
{}

void
AttributeChecker::visit (AST::TupleExpr &)
{}

void
AttributeChecker::visit (AST::TupleIndexExpr &)
{}

void
AttributeChecker::visit (AST::StructExprStruct &)
{}

void
AttributeChecker::visit (AST::StructExprFieldIdentifier &)
{}

void
AttributeChecker::visit (AST::StructExprFieldIdentifierValue &)
{}

void
AttributeChecker::visit (AST::StructExprFieldIndexValue &)
{}

void
AttributeChecker::visit (AST::StructExprStructFields &)
{}

void
AttributeChecker::visit (AST::StructExprStructBase &)
{}

void
AttributeChecker::visit (AST::CallExpr &)
{}

void
AttributeChecker::visit (AST::MethodCallExpr &)
{}

void
AttributeChecker::visit (AST::FieldAccessExpr &)
{}

void
AttributeChecker::visit (AST::ClosureExprInner &)
{}

void
AttributeChecker::visit (AST::BlockExpr &expr)
{
  for (auto &stmt : expr.get_statements ())
    {
      if (stmt->get_stmt_kind () == AST::Stmt::Kind::Item)
	{
	  // Non owning pointer, let it go out of scope
	  auto item = static_cast<AST::Item *> (stmt.get ());
	  for (auto &attr : item->get_outer_attrs ())
	    check_proc_macro_non_root (attr, item->get_locus ());
	}
    }
  AST::DefaultASTVisitor::visit (expr);
}

void
AttributeChecker::visit (AST::ClosureExprInnerTyped &)
{}

void
AttributeChecker::visit (AST::ContinueExpr &)
{}

void
AttributeChecker::visit (AST::BreakExpr &)
{}

void
AttributeChecker::visit (AST::RangeFromToExpr &)
{}

void
AttributeChecker::visit (AST::RangeFromExpr &)
{}

void
AttributeChecker::visit (AST::RangeToExpr &)
{}

void
AttributeChecker::visit (AST::RangeFullExpr &)
{}

void
AttributeChecker::visit (AST::RangeFromToInclExpr &)
{}

void
AttributeChecker::visit (AST::RangeToInclExpr &)
{}

void
AttributeChecker::visit (AST::ReturnExpr &)
{}

void
AttributeChecker::visit (AST::LoopExpr &)
{}

void
AttributeChecker::visit (AST::WhileLoopExpr &)
{}

void
AttributeChecker::visit (AST::WhileLetLoopExpr &)
{}

void
AttributeChecker::visit (AST::ForLoopExpr &)
{}

void
AttributeChecker::visit (AST::IfExpr &)
{}

void
AttributeChecker::visit (AST::IfExprConseqElse &)
{}

void
AttributeChecker::visit (AST::IfLetExpr &)
{}

void
AttributeChecker::visit (AST::IfLetExprConseqElse &)
{}

void
AttributeChecker::visit (AST::MatchExpr &)
{}

void
AttributeChecker::visit (AST::AwaitExpr &)
{}

void
AttributeChecker::visit (AST::AsyncBlockExpr &)
{}

// rust-item.h
void
AttributeChecker::visit (AST::TypeParam &)
{}

void
AttributeChecker::visit (AST::LifetimeWhereClauseItem &)
{}

void
AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
{}

void
AttributeChecker::visit (AST::Module &module)
{
  for (auto &attr : module.get_outer_attrs ())
    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)
{
  for (auto &attr : crate.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::UseTreeGlob &)
{}

void
AttributeChecker::visit (AST::UseTreeList &)
{}

void
AttributeChecker::visit (AST::UseTreeRebind &)
{}

void
AttributeChecker::visit (AST::UseDeclaration &declaration)
{
  for (auto &attr : declaration.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::Function &fun)
{
  if (fun.has_body ())
    fun.get_definition ().value ()->accept_vis (*this);
}

void
AttributeChecker::visit (AST::TypeAlias &alias)
{
  for (auto &attr : alias.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::StructStruct &struct_item)
{
  for (auto &attr : struct_item.get_outer_attrs ())
    {
      check_proc_macro_non_function (attr);
    }

  AST::DefaultASTVisitor::visit (struct_item);
}

void
AttributeChecker::visit (AST::TupleStruct &tuplestruct)
{
  for (auto &attr : tuplestruct.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::EnumItem &)
{}

void
AttributeChecker::visit (AST::EnumItemTuple &)
{}

void
AttributeChecker::visit (AST::EnumItemStruct &)
{}

void
AttributeChecker::visit (AST::EnumItemDiscriminant &)
{}

void
AttributeChecker::visit (AST::Enum &enumeration)
{
  for (auto &attr : enumeration.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::Union &u)
{
  for (auto &attr : u.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::ConstantItem &item)
{
  for (auto &attr : item.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::StaticItem &item)
{
  for (auto &attr : item.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

void
AttributeChecker::visit (AST::TraitItemType &)
{}

void
AttributeChecker::visit (AST::Trait &trait)
{
  for (auto &attr : trait.get_outer_attrs ())
    check_proc_macro_non_function (attr);

  AST::DefaultASTVisitor::visit (trait);
}

void
AttributeChecker::visit (AST::InherentImpl &impl)
{
  for (auto &attr : impl.get_outer_attrs ())
    check_proc_macro_non_function (attr);

  AST::DefaultASTVisitor::visit (impl);
}

void
AttributeChecker::visit (AST::TraitImpl &impl)
{
  for (auto &attr : impl.get_outer_attrs ())
    check_proc_macro_non_function (attr);

  AST::DefaultASTVisitor::visit (impl);
}

void
AttributeChecker::visit (AST::ExternalTypeItem &)
{}

void
AttributeChecker::visit (AST::ExternalStaticItem &)
{}

void
AttributeChecker::visit (AST::ExternBlock &block)
{
  for (auto &attr : block.get_outer_attrs ())
    check_proc_macro_non_function (attr);
}

// rust-macro.h
void
AttributeChecker::visit (AST::MacroMatchFragment &)
{}

void
AttributeChecker::visit (AST::MacroMatchRepetition &)
{}

void
AttributeChecker::visit (AST::MacroMatcher &)
{}

void
AttributeChecker::visit (AST::MacroRulesDefinition &)
{}

void
AttributeChecker::visit (AST::MacroInvocation &)
{}

void
AttributeChecker::visit (AST::MetaItemPath &)
{}

void
AttributeChecker::visit (AST::MetaWord &)
{}

void
AttributeChecker::visit (AST::MetaNameValueStr &)
{}

void
AttributeChecker::visit (AST::MetaListPaths &)
{}

void
AttributeChecker::visit (AST::MetaListNameValueStr &)
{}

// rust-pattern.h
void
AttributeChecker::visit (AST::LiteralPattern &)
{}

void
AttributeChecker::visit (AST::IdentifierPattern &)
{}

void
AttributeChecker::visit (AST::WildcardPattern &)
{}

void
AttributeChecker::visit (AST::RestPattern &)
{}

// void AttributeChecker::visit(RangePatternBound& ){}

void
AttributeChecker::visit (AST::RangePatternBoundLiteral &)
{}

void
AttributeChecker::visit (AST::RangePatternBoundPath &)
{}

void
AttributeChecker::visit (AST::RangePatternBoundQualPath &)
{}

void
AttributeChecker::visit (AST::RangePattern &)
{}

void
AttributeChecker::visit (AST::ReferencePattern &)
{}

// void AttributeChecker::visit(StructPatternField& ){}

void
AttributeChecker::visit (AST::StructPatternFieldTuplePat &)
{}

void
AttributeChecker::visit (AST::StructPatternFieldIdentPat &)
{}

void
AttributeChecker::visit (AST::StructPatternFieldIdent &)
{}

void
AttributeChecker::visit (AST::StructPattern &)
{}

// void AttributeChecker::visit(TupleStructItems& ){}

void
AttributeChecker::visit (AST::TupleStructItemsNoRest &)
{}

void
AttributeChecker::visit (AST::TupleStructItemsHasRest &)
{}

void
AttributeChecker::visit (AST::TupleStructPattern &)
{}

// void AttributeChecker::visit(TuplePatternItems& ){}

void
AttributeChecker::visit (AST::TuplePatternItemsNoRest &)
{}

void
AttributeChecker::visit (AST::TuplePatternItemsHasRest &)
{}

void
AttributeChecker::visit (AST::TuplePattern &)
{}

void
AttributeChecker::visit (AST::GroupedPattern &)
{}

void
AttributeChecker::visit (AST::SlicePattern &)
{}

void
AttributeChecker::visit (AST::AltPattern &)
{}

// rust-stmt.h
void
AttributeChecker::visit (AST::EmptyStmt &)
{}

void
AttributeChecker::visit (AST::LetStmt &)
{}

void
AttributeChecker::visit (AST::ExprStmt &)
{}

// rust-type.h
void
AttributeChecker::visit (AST::TraitBound &)
{}

void
AttributeChecker::visit (AST::ImplTraitType &)
{}

void
AttributeChecker::visit (AST::TraitObjectType &)
{}

void
AttributeChecker::visit (AST::ParenthesisedType &)
{}

void
AttributeChecker::visit (AST::ImplTraitTypeOneBound &)
{}

void
AttributeChecker::visit (AST::TraitObjectTypeOneBound &)
{}

void
AttributeChecker::visit (AST::TupleType &)
{}

void
AttributeChecker::visit (AST::NeverType &)
{}

void
AttributeChecker::visit (AST::RawPointerType &)
{}

void
AttributeChecker::visit (AST::ReferenceType &)
{}

void
AttributeChecker::visit (AST::ArrayType &)
{}

void
AttributeChecker::visit (AST::SliceType &)
{}

void
AttributeChecker::visit (AST::InferredType &)
{}

void
AttributeChecker::visit (AST::BareFunctionType &)
{}

void
AttributeChecker::visit (AST::SelfParam &)
{}

void
AttributeChecker::visit (AST::VariadicParam &)
{}

void
AttributeChecker::visit (AST::FunctionParam &)
{}

} // namespace Analysis
} // namespace Rust
