// 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 // . #include "rust-ast-builder.h" #include "rust-ast-builder-type.h" #include "rust-common.h" #include "rust-expr.h" #include "rust-token.h" #include "rust-make-unique.h" namespace Rust { namespace AST { std::unique_ptr Builder::literal_string (std::string &&content) const { return std::unique_ptr ( new AST::LiteralExpr (std::move (content), Literal::LitType::STRING, PrimitiveCoreType::CORETYPE_STR, {}, loc)); } std::unique_ptr Builder::call (std::unique_ptr &&path, std::vector> &&args) const { return std::unique_ptr ( new CallExpr (std::move (path), std::move (args), {}, loc)); } std::unique_ptr Builder::array (std::vector> &&members) const { auto elts = Rust::make_unique (std::move (members), loc); return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc)); } std::unique_ptr Builder::identifier (std::string name) const { return std::unique_ptr (new IdentifierExpr (name, {}, loc)); } std::unique_ptr Builder::tuple_idx (std::string receiver, int idx) const { return std::unique_ptr ( new TupleIndexExpr (identifier (receiver), idx, {}, loc)); } FunctionQualifiers Builder::fn_qualifiers () const { return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal); } PathExprSegment Builder::path_segment (std::string seg) const { return PathExprSegment (PathIdentSegment (seg, loc), loc); } std::unique_ptr Builder::type_path_segment (std::string seg) const { return std::unique_ptr ( new TypePathSegment (seg, false, loc)); } std::unique_ptr Builder::generic_type_path_segment (std::string seg, GenericArgs args) const { return std::unique_ptr ( new TypePathSegmentGeneric (PathIdentSegment (seg, loc), false, args, loc)); } std::unique_ptr Builder::single_type_path (std::string type) const { auto segments = std::vector> (); segments.emplace_back (type_path_segment (type)); return std::unique_ptr (new TypePath (std::move (segments), loc)); } std::unique_ptr Builder::single_generic_type_path (std::string type, GenericArgs args) const { auto segments = std::vector> (); segments.emplace_back (generic_type_path_segment (type, args)); return std::unique_ptr (new TypePath (std::move (segments), loc)); } PathInExpression Builder::path_in_expression (std::vector &&segments) const { auto path_segments = std::vector (); for (auto &seg : segments) path_segments.emplace_back (path_segment (seg)); return PathInExpression (std::move (path_segments), {}, loc); } std::unique_ptr Builder::block (std::vector> &&stmts, std::unique_ptr &&tail_expr) const { return std::unique_ptr (new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, LoopLabel::error (), loc, loc)); } std::unique_ptr Builder::let (std::unique_ptr pattern, std::unique_ptr type, std::unique_ptr init) const { return std::unique_ptr (new LetStmt (std::move (pattern), std::move (init), std::move (type), {}, loc)); } std::unique_ptr Builder::ref (std::unique_ptr &&of, bool mut) const { auto mutability = mut ? Mutability::Mut : Mutability::Imm; return std::unique_ptr ( new BorrowExpr (std::move (of), mutability, /* raw */ false, /* is double */ false, {}, loc)); } std::unique_ptr Builder::deref (std::unique_ptr &&of) const { return std::unique_ptr (new DereferenceExpr (std::move (of), {}, loc)); } std::unique_ptr Builder::struct_expr_struct (std::string struct_name) const { return std::unique_ptr ( new StructExprStruct (path_in_expression ({struct_name}), {}, {}, loc)); } std::unique_ptr Builder::struct_expr ( std::string struct_name, std::vector> &&fields) const { return std::unique_ptr ( new StructExprStructFields (path_in_expression ({struct_name}), std::move (fields), loc)); } std::unique_ptr Builder::struct_expr_field (std::string field_name, std::unique_ptr &&value) const { return std::unique_ptr ( new StructExprFieldIdentifierValue (field_name, std::move (value), loc)); } std::unique_ptr Builder::field_access (std::unique_ptr &&instance, std::string field) const { return std::unique_ptr ( new FieldAccessExpr (std::move (instance), field, {}, loc)); } std::unique_ptr Builder::wildcard () const { return std::unique_ptr (new WildcardPattern (loc)); } std::unique_ptr Builder::new_type (Type &type) { Type *t = ASTTypeBuilder::build (type); return std::unique_ptr (t); } std::unique_ptr Builder::new_lifetime_param (LifetimeParam ¶m) { Lifetime l = new_lifetime (param.get_lifetime ()); std::vector lifetime_bounds; for (auto b : param.get_lifetime_bounds ()) { Lifetime bl = new_lifetime (b); lifetime_bounds.push_back (bl); } auto p = new LifetimeParam (l, std::move (lifetime_bounds), param.get_outer_attrs (), param.get_locus ()); return std::unique_ptr (p); } std::unique_ptr Builder::new_type_param (TypeParam ¶m) { location_t locus = param.get_locus (); AST::AttrVec outer_attrs = param.get_outer_attrs (); Identifier type_representation = param.get_type_representation (); std::vector> type_param_bounds; std::unique_ptr type = nullptr; if (param.has_type ()) type = new_type (param.get_type ()); for (const auto &b : param.get_type_param_bounds ()) { switch (b->get_bound_type ()) { case TypeParamBound::TypeParamBoundType::TRAIT: { const TraitBound &tb = (const TraitBound &) *b.get (); const TypePath &path = tb.get_type_path (); std::vector for_lifetimes; for (const auto &lifetime : tb.get_for_lifetimes ()) { std::vector lifetime_bounds; for (const auto &b : lifetime.get_lifetime_bounds ()) { Lifetime bl = new_lifetime (b); lifetime_bounds.push_back (std::move (bl)); } Lifetime nl = new_lifetime (lifetime.get_lifetime ()); LifetimeParam p (std::move (nl), std::move (lifetime_bounds), {}, lifetime.get_locus ()); for_lifetimes.push_back (std::move (p)); } std::vector> segments; for (auto &seg : path.get_segments ()) { switch (seg->get_type ()) { case TypePathSegment::REG: { const TypePathSegment &segment = (const TypePathSegment &) (*seg.get ()); TypePathSegment *s = new TypePathSegment ( segment.get_ident_segment (), segment.get_separating_scope_resolution (), segment.get_locus ()); std::unique_ptr sg (s); segments.push_back (std::move (sg)); } break; case TypePathSegment::GENERIC: { TypePathSegmentGeneric &generic = (TypePathSegmentGeneric &) (*seg.get ()); GenericArgs args = new_generic_args (generic.get_generic_args ()); TypePathSegmentGeneric *s = new TypePathSegmentGeneric ( generic.get_ident_segment (), false, std::move (args), generic.get_locus ()); std::unique_ptr sg (s); segments.push_back (std::move (sg)); } break; case TypePathSegment::FUNCTION: { rust_unreachable (); // TODO // const TypePathSegmentFunction &fn // = (const TypePathSegmentFunction &) (*seg.get ()); } break; } } TypePath p (std::move (segments), path.get_locus (), path.has_opening_scope_resolution_op ()); TraitBound *b = new TraitBound (std::move (p), tb.get_locus (), tb.is_in_parens (), tb.has_opening_question_mark (), std::move (for_lifetimes)); std::unique_ptr bound (b); type_param_bounds.push_back (std::move (bound)); } break; case TypeParamBound::TypeParamBoundType::LIFETIME: { const Lifetime &l = (const Lifetime &) *b.get (); auto bl = new Lifetime (l.get_lifetime_type (), l.get_lifetime_name (), l.get_locus ()); std::unique_ptr bound (bl); type_param_bounds.push_back (std::move (bound)); } break; } } auto type_param = new TypeParam (type_representation, locus, std::move (type_param_bounds), std::move (type), std::move (outer_attrs)); return std::unique_ptr (type_param); } Lifetime Builder::new_lifetime (const Lifetime &lifetime) { return Lifetime (lifetime.get_lifetime_type (), lifetime.get_lifetime_name (), lifetime.get_locus ()); } GenericArgs Builder::new_generic_args (GenericArgs &args) { std::vector lifetime_args; std::vector generic_args; std::vector binding_args; location_t locus = args.get_locus (); for (const auto &lifetime : args.get_lifetime_args ()) { Lifetime l = new_lifetime (lifetime); lifetime_args.push_back (std::move (l)); } for (auto &binding : args.get_binding_args ()) { Type &t = *binding.get_type_ptr ().get (); std::unique_ptr ty = new_type (t); GenericArgsBinding b (binding.get_identifier (), std::move (ty), binding.get_locus ()); binding_args.push_back (std::move (b)); } for (auto &arg : args.get_generic_args ()) { switch (arg.get_kind ()) { case GenericArg::Kind::Type: { std::unique_ptr ty = new_type (arg.get_type ()); GenericArg arg = GenericArg::create_type (std::move (ty)); } break; default: // FIXME rust_unreachable (); break; } } return GenericArgs (std::move (lifetime_args), std::move (generic_args), std::move (binding_args), locus); } } // namespace AST } // namespace Rust