| // Copyright (C) 2020-2025 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-derive.h" |
| #include "rust-derive-clone.h" |
| #include "rust-derive-copy.h" |
| #include "rust-derive-debug.h" |
| #include "rust-derive-default.h" |
| #include "rust-derive-eq.h" |
| #include "rust-derive-ord.h" |
| #include "rust-derive-partial-eq.h" |
| #include "rust-derive-hash.h" |
| |
| namespace Rust { |
| namespace AST { |
| |
| DeriveVisitor::DeriveVisitor (location_t loc) |
| : loc (loc), builder (Builder (loc)) |
| {} |
| |
| std::vector<std::unique_ptr<Item>> |
| DeriveVisitor::derive (Item &item, const Attribute &attr, |
| BuiltinMacro to_derive) |
| { |
| auto loc = attr.get_locus (); |
| |
| switch (to_derive) |
| { |
| case BuiltinMacro::Clone: |
| return vec (DeriveClone (loc).go (item)); |
| case BuiltinMacro::Copy: |
| return vec (DeriveCopy (loc).go (item)); |
| case BuiltinMacro::Debug: |
| rust_warning_at ( |
| loc, 0, |
| "derive(Debug) is not fully implemented yet and has no effect - only a " |
| "stub implementation will be generated"); |
| return vec (DeriveDebug (loc).go (item)); |
| case BuiltinMacro::Default: |
| return vec (DeriveDefault (loc).go (item)); |
| case BuiltinMacro::Eq: |
| return DeriveEq (loc).go (item); |
| case BuiltinMacro::PartialEq: |
| return DerivePartialEq (loc).go (item); |
| case BuiltinMacro::Hash: |
| return vec (DeriveHash (loc).go (item)); |
| case BuiltinMacro::Ord: |
| return vec (DeriveOrd (DeriveOrd::Ordering::Total, loc).go (item)); |
| case BuiltinMacro::PartialOrd: |
| return vec (DeriveOrd (DeriveOrd::Ordering::Partial, loc).go (item)); |
| default: |
| rust_unreachable (); |
| }; |
| } |
| |
| DeriveVisitor::ImplGenerics |
| DeriveVisitor::setup_impl_generics ( |
| const std::string &type_name, |
| const std::vector<std::unique_ptr<GenericParam>> &type_generics, |
| tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const |
| { |
| std::vector<Lifetime> lifetime_args; |
| std::vector<GenericArg> generic_args; |
| std::vector<std::unique_ptr<GenericParam>> impl_generics; |
| for (const auto &generic : type_generics) |
| { |
| switch (generic->get_kind ()) |
| { |
| case GenericParam::Kind::Lifetime: |
| { |
| LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get (); |
| |
| Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ()); |
| lifetime_args.push_back (std::move (l)); |
| |
| auto impl_lifetime_param |
| = builder.new_lifetime_param (lifetime_param); |
| impl_generics.push_back (std::move (impl_lifetime_param)); |
| } |
| break; |
| |
| case GenericParam::Kind::Type: |
| { |
| TypeParam &type_param = (TypeParam &) *generic.get (); |
| |
| std::unique_ptr<Type> associated_type = builder.single_type_path ( |
| type_param.get_type_representation ().as_string ()); |
| |
| GenericArg type_arg |
| = GenericArg::create_type (std::move (associated_type)); |
| generic_args.push_back (std::move (type_arg)); |
| |
| std::vector<std::unique_ptr<TypeParamBound>> extra_bounds; |
| |
| if (extra_bound) |
| extra_bounds.emplace_back ( |
| extra_bound.value ()->clone_type_param_bound ()); |
| |
| auto impl_type_param |
| = builder.new_type_param (type_param, std::move (extra_bounds)); |
| |
| impl_generics.push_back (std::move (impl_type_param)); |
| } |
| break; |
| |
| case GenericParam::Kind::Const: |
| { |
| ConstGenericParam &const_param |
| = (ConstGenericParam &) *generic.get (); |
| |
| std::unique_ptr<Type> associated_type |
| = builder.single_type_path (const_param.get_name ().as_string ()); |
| |
| GenericArg type_arg |
| = GenericArg::create_type (std::move (associated_type)); |
| generic_args.push_back (std::move (type_arg)); |
| |
| auto impl_const_param = builder.new_const_param (const_param); |
| impl_generics.push_back (std::move (impl_const_param)); |
| } |
| break; |
| } |
| } |
| |
| auto generic_args_for_self |
| = GenericArgs (lifetime_args, generic_args, {} /*binding args*/, loc); |
| |
| std::unique_ptr<Type> self_type_path |
| = impl_generics.empty () |
| ? builder.single_type_path (type_name) |
| : builder.single_generic_type_path (type_name, generic_args_for_self); |
| |
| return ImplGenerics{std::move (self_type_path), std::move (impl_generics)}; |
| } |
| |
| } // namespace AST |
| } // namespace Rust |