LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-type.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.3 % 427 390
Test Date: 2025-09-20 13:40:47 Functions: 78.8 % 33 26
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-compile-type.h"
      20                 :             : #include "rust-constexpr.h"
      21                 :             : #include "rust-compile-base.h"
      22                 :             : 
      23                 :             : #include "tree.h"
      24                 :             : #include "fold-const.h"
      25                 :             : #include "stor-layout.h"
      26                 :             : 
      27                 :             : namespace Rust {
      28                 :             : namespace Compile {
      29                 :             : 
      30                 :             : static const std::string RUST_ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR";
      31                 :             : 
      32                 :      377769 : TyTyResolveCompile::TyTyResolveCompile (Context *ctx, bool trait_object_mode)
      33                 :      377769 :   : ctx (ctx), trait_object_mode (trait_object_mode),
      34                 :      377769 :     translated (error_mark_node)
      35                 :      377769 : {}
      36                 :             : 
      37                 :             : tree
      38                 :      377769 : TyTyResolveCompile::compile (Context *ctx, const TyTy::BaseType *ty,
      39                 :             :                              bool trait_object_mode)
      40                 :             : {
      41                 :      377769 :   TyTyResolveCompile compiler (ctx, trait_object_mode);
      42                 :      377769 :   const TyTy::BaseType *destructured = ty->destructure ();
      43                 :      377769 :   destructured->accept_vis (compiler);
      44                 :             : 
      45                 :      377769 :   if (compiler.translated != error_mark_node
      46                 :      377769 :       && TYPE_NAME (compiler.translated) != NULL)
      47                 :             :     {
      48                 :             :       // canonicalize the type
      49                 :      338286 :       compiler.translated = ctx->insert_compiled_type (compiler.translated);
      50                 :             :     }
      51                 :             : 
      52                 :      377769 :   return compiler.translated;
      53                 :             : }
      54                 :             : 
      55                 :             : // see: gcc/c/c-decl.cc:8230-8241
      56                 :             : // https://github.com/Rust-GCC/gccrs/blob/0024bc2f028369b871a65ceb11b2fddfb0f9c3aa/gcc/c/c-decl.c#L8229-L8241
      57                 :             : tree
      58                 :        6351 : TyTyResolveCompile::get_implicit_enumeral_node_type (TyTy::BaseType *repr)
      59                 :             : {
      60                 :             :   // static tree enum_node = NULL_TREE;
      61                 :             :   // if (enum_node == NULL_TREE)
      62                 :             :   //   {
      63                 :             :   //     enum_node = make_node (ENUMERAL_TYPE);
      64                 :             :   //     SET_TYPE_MODE (enum_node, TYPE_MODE (unsigned_type_node));
      65                 :             :   //     SET_TYPE_ALIGN (enum_node, TYPE_ALIGN (unsigned_type_node));
      66                 :             :   //     TYPE_USER_ALIGN (enum_node) = 0;
      67                 :             :   //     TYPE_UNSIGNED (enum_node) = 1;
      68                 :             :   //     TYPE_PRECISION (enum_node) = TYPE_PRECISION (unsigned_type_node);
      69                 :             :   //     TYPE_MIN_VALUE (enum_node) = TYPE_MIN_VALUE (unsigned_type_node);
      70                 :             :   //     TYPE_MAX_VALUE (enum_node) = TYPE_MAX_VALUE (unsigned_type_node);
      71                 :             : 
      72                 :             :   //     // tree identifier = ctx->get_backend ()->get_identifier_node
      73                 :             :   //     // ("enumeral"); tree enum_decl
      74                 :             :   //     //   = build_decl (BUILTINS_LOCATION, TYPE_DECL, identifier,
      75                 :             :   //     enum_node);
      76                 :             :   //     // TYPE_NAME (enum_node) = enum_decl;
      77                 :             :   //   }
      78                 :             :   // return enum_node;
      79                 :             : 
      80                 :        6351 :   return compile (ctx, repr);
      81                 :             : }
      82                 :             : 
      83                 :             : tree
      84                 :       33665 : TyTyResolveCompile::get_unit_type (Context *ctx)
      85                 :             : {
      86                 :       33665 :   static tree unit_type;
      87                 :       33665 :   if (unit_type == nullptr)
      88                 :             :     {
      89                 :        4118 :       auto cn = ctx->get_mappings ().get_current_crate ();
      90                 :        4118 :       auto &c = ctx->get_mappings ().get_ast_crate (cn);
      91                 :        4118 :       location_t locus = BUILTINS_LOCATION;
      92                 :        4118 :       if (c.items.size () > 0)
      93                 :             :         {
      94                 :        4117 :           auto &item = c.items[0];
      95                 :        4117 :           locus = item->get_locus ();
      96                 :             :         }
      97                 :             : 
      98                 :        4118 :       auto unit_type_node = Backend::struct_type ({});
      99                 :        4118 :       unit_type = Backend::named_type ("()", unit_type_node, locus);
     100                 :             :     }
     101                 :       33665 :   return unit_type;
     102                 :             : }
     103                 :             : 
     104                 :             : void
     105                 :           0 : TyTyResolveCompile::visit (const TyTy::ErrorType &)
     106                 :             : {
     107                 :           0 :   translated = error_mark_node;
     108                 :           0 : }
     109                 :             : 
     110                 :             : void
     111                 :         477 : TyTyResolveCompile::visit (const TyTy::InferType &type)
     112                 :             : {
     113                 :         477 :   const TyTy::BaseType *orig = &type;
     114                 :         477 :   TyTy::BaseType *lookup = nullptr;
     115                 :         477 :   bool ok = ctx->get_tyctx ()->lookup_type (type.get_ref (), &lookup);
     116                 :         477 :   if (!ok)
     117                 :             :     {
     118                 :           0 :       translated = error_mark_node;
     119                 :           4 :       return;
     120                 :             :     }
     121                 :             : 
     122                 :         477 :   if (orig == lookup)
     123                 :             :     {
     124                 :           4 :       TyTy::BaseType *def = nullptr;
     125                 :           4 :       if (type.default_type (&def))
     126                 :             :         {
     127                 :           4 :           translated = TyTyResolveCompile::compile (ctx, def);
     128                 :           4 :           return;
     129                 :             :         }
     130                 :             : 
     131                 :           0 :       translated = error_mark_node;
     132                 :           0 :       return;
     133                 :             :     }
     134                 :             : 
     135                 :         473 :   translated = TyTyResolveCompile::compile (ctx, lookup);
     136                 :             : }
     137                 :             : 
     138                 :             : void
     139                 :           0 : TyTyResolveCompile::visit (const TyTy::ParamType &)
     140                 :             : {
     141                 :           0 :   translated = error_mark_node;
     142                 :           0 : }
     143                 :             : 
     144                 :             : void
     145                 :           0 : TyTyResolveCompile::visit (const TyTy::ConstType &)
     146                 :             : {
     147                 :           0 :   translated = error_mark_node;
     148                 :           0 : }
     149                 :             : 
     150                 :             : void
     151                 :           0 : TyTyResolveCompile::visit (const TyTy::ProjectionType &type)
     152                 :             : {
     153                 :           0 :   translated = error_mark_node;
     154                 :           0 : }
     155                 :             : 
     156                 :             : void
     157                 :           0 : TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
     158                 :             : {
     159                 :           0 :   translated = error_mark_node;
     160                 :           0 : }
     161                 :             : 
     162                 :             : void
     163                 :         239 : TyTyResolveCompile::visit (const TyTy::ClosureType &type)
     164                 :             : {
     165                 :         239 :   auto &mappings = ctx->get_mappings ();
     166                 :             : 
     167                 :         239 :   std::vector<Backend::typed_identifier> fields;
     168                 :             : 
     169                 :         239 :   size_t i = 0;
     170                 :         330 :   for (const auto &capture : type.get_captures ())
     171                 :             :     {
     172                 :             :       // lookup the HirId
     173                 :          91 :       tl::optional<HirId> hid = mappings.lookup_node_to_hir (capture);
     174                 :          91 :       rust_assert (hid.has_value ());
     175                 :          91 :       auto ref = hid.value ();
     176                 :             : 
     177                 :             :       // lookup the var decl type
     178                 :          91 :       TyTy::BaseType *lookup = nullptr;
     179                 :          91 :       bool found = ctx->get_tyctx ()->lookup_type (ref, &lookup);
     180                 :          91 :       rust_assert (found);
     181                 :             : 
     182                 :             :       // FIXME get the var pattern name
     183                 :          91 :       std::string mappings_name = "capture_" + std::to_string (i);
     184                 :             : 
     185                 :             :       // FIXME
     186                 :             :       // this should be based on the closure move-ability
     187                 :          91 :       tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
     188                 :          91 :       tree capture_type = build_reference_type (decl_type);
     189                 :          91 :       fields.push_back (Backend::typed_identifier (mappings_name, capture_type,
     190                 :          91 :                                                    type.get_ident ().locus));
     191                 :          91 :     }
     192                 :             : 
     193                 :         239 :   tree type_record = Backend::struct_type (fields);
     194                 :         239 :   RS_CLOSURE_FLAG (type_record) = 1;
     195                 :             : 
     196                 :         239 :   std::string named_struct_str
     197                 :         478 :     = type.get_ident ().path.get () + "::{{closure}}";
     198                 :         239 :   translated = Backend::named_type (named_struct_str, type_record,
     199                 :         239 :                                     type.get_ident ().locus);
     200                 :         239 : }
     201                 :             : 
     202                 :             : void
     203                 :       15987 : TyTyResolveCompile::visit (const TyTy::FnType &type)
     204                 :             : {
     205                 :       15987 :   Backend::typed_identifier receiver ("", NULL_TREE, UNKNOWN_LOCATION);
     206                 :       15987 :   std::vector<Backend::typed_identifier> parameters;
     207                 :       15987 :   std::vector<Backend::typed_identifier> results;
     208                 :             : 
     209                 :             :   // we can only return unit-type if its not the C ABI because it will expect
     210                 :             :   // void
     211                 :       15987 :   auto hir_type = type.get_return_type ()->destructure ();
     212                 :       15987 :   bool return_is_unit = hir_type->is_unit ();
     213                 :       15987 :   bool is_c_abi = type.get_abi () == ABI::C;
     214                 :       15987 :   bool should_be_void = is_c_abi && return_is_unit;
     215                 :       15987 :   if (!should_be_void)
     216                 :             :     {
     217                 :       14992 :       auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
     218                 :       14992 :       location_t return_type_locus
     219                 :       14992 :         = ctx->get_mappings ().lookup_location (hir_type->get_ref ());
     220                 :       29984 :       results.push_back (
     221                 :       14992 :         Backend::typed_identifier ("_", ret, return_type_locus));
     222                 :             :     }
     223                 :             : 
     224                 :       32081 :   for (auto &param_pair : type.get_params ())
     225                 :             :     {
     226                 :       16094 :       auto param_tyty = param_pair.get_type ();
     227                 :       16094 :       auto compiled_param_type
     228                 :       16094 :         = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
     229                 :             : 
     230                 :       16094 :       auto compiled_param = Backend::typed_identifier (
     231                 :       16094 :         param_pair.get_pattern ().as_string (), compiled_param_type,
     232                 :       32188 :         ctx->get_mappings ().lookup_location (param_tyty->get_ref ()));
     233                 :             : 
     234                 :       16094 :       parameters.push_back (compiled_param);
     235                 :             :     }
     236                 :             : 
     237                 :       15987 :   if (!type.is_variadic ())
     238                 :       15171 :     translated = Backend::function_type (receiver, parameters, results, NULL,
     239                 :       15171 :                                          type.get_ident ().locus);
     240                 :             :   else
     241                 :         816 :     translated
     242                 :         816 :       = Backend::function_type_variadic (receiver, parameters, results, NULL,
     243                 :         816 :                                          type.get_ident ().locus);
     244                 :       15987 : }
     245                 :             : 
     246                 :             : void
     247                 :          66 : TyTyResolveCompile::visit (const TyTy::FnPtr &type)
     248                 :             : {
     249                 :          66 :   tree result_type = TyTyResolveCompile::compile (ctx, type.get_return_type ());
     250                 :             : 
     251                 :          66 :   std::vector<tree> parameters;
     252                 :             : 
     253                 :          66 :   auto &params = type.get_params ();
     254                 :         136 :   for (auto &p : params)
     255                 :             :     {
     256                 :          70 :       tree pty = TyTyResolveCompile::compile (ctx, p.get_tyty ());
     257                 :          70 :       parameters.push_back (pty);
     258                 :             :     }
     259                 :             : 
     260                 :          66 :   translated = Backend::function_ptr_type (result_type, parameters,
     261                 :          66 :                                            type.get_ident ().locus);
     262                 :          66 : }
     263                 :             : 
     264                 :             : void
     265                 :       20464 : TyTyResolveCompile::visit (const TyTy::ADTType &type)
     266                 :             : {
     267                 :       20464 :   tree type_record = error_mark_node;
     268                 :       20464 :   if (!type.is_enum ())
     269                 :             :     {
     270                 :       14113 :       rust_assert (type.number_of_variants () == 1);
     271                 :             : 
     272                 :       14113 :       TyTy::VariantDef &variant = *type.get_variants ().at (0);
     273                 :       14113 :       std::vector<Backend::typed_identifier> fields;
     274                 :       39888 :       for (size_t i = 0; i < variant.num_fields (); i++)
     275                 :             :         {
     276                 :       25775 :           const TyTy::StructFieldType *field = variant.get_field_at_index (i);
     277                 :       25775 :           tree compiled_field_ty
     278                 :       25775 :             = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     279                 :             : 
     280                 :       25775 :           Backend::typed_identifier f (field->get_name (), compiled_field_ty,
     281                 :       25775 :                                        ctx->get_mappings ().lookup_location (
     282                 :       51550 :                                          type.get_ty_ref ()));
     283                 :       25775 :           fields.push_back (std::move (f));
     284                 :             :         }
     285                 :             : 
     286                 :       14113 :       type_record = type.is_union () ? Backend::union_type (fields, false)
     287                 :       13913 :                                      : Backend::struct_type (fields, false);
     288                 :       14113 :     }
     289                 :             :   else
     290                 :             :     {
     291                 :             :       // see:
     292                 :             :       // https://github.com/bminor/binutils-gdb/blob/527b8861cd472385fa9160a91dd6d65a25c41987/gdb/dwarf2/read.c#L9010-L9241
     293                 :             :       //
     294                 :             :       // enums are actually a big union so for example the rust enum:
     295                 :             :       //
     296                 :             :       // enum AnEnum {
     297                 :             :       //   A,
     298                 :             :       //   B,
     299                 :             :       //   C (char),
     300                 :             :       //   D { x: i64, y: i64 },
     301                 :             :       // }
     302                 :             :       //
     303                 :             :       // we actually turn this into
     304                 :             :       //
     305                 :             :       // union {
     306                 :             :       //   struct A { int RUST$ENUM$DISR; }; <- this is a data-less variant
     307                 :             :       //   struct B { int RUST$ENUM$DISR; }; <- this is a data-less variant
     308                 :             :       //   struct C { int RUST$ENUM$DISR; char __0; };
     309                 :             :       //   struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
     310                 :             :       // }
     311                 :             :       //
     312                 :             :       // Ada, qual_union_types might still work for this but I am not 100% sure.
     313                 :             :       // I ran into some issues lets reuse our normal union and ask Ada people
     314                 :             :       // about it.
     315                 :             :       //
     316                 :             :       // I think the above is actually wrong and it should actually be this
     317                 :             :       //
     318                 :             :       // struct {
     319                 :             :       //     int RUST$ENUM$DISR; // take into account the repr for this TODO
     320                 :             :       //     union {
     321                 :             :       //         // Variant A
     322                 :             :       //         struct {
     323                 :             :       //             // No additional fields
     324                 :             :       //         } A;
     325                 :             : 
     326                 :             :       //         // Variant B
     327                 :             :       //         struct {
     328                 :             :       //             // No additional fields
     329                 :             :       //         } B;
     330                 :             : 
     331                 :             :       //         // Variant C
     332                 :             :       //         struct {
     333                 :             :       //             char c;
     334                 :             :       //         } C;
     335                 :             : 
     336                 :             :       //         // Variant D
     337                 :             :       //         struct {
     338                 :             :       //             int64_t x;
     339                 :             :       //             int64_t y;
     340                 :             :       //         } D;
     341                 :             :       //     } payload; // The union of all variant data
     342                 :             :       // };
     343                 :             : 
     344                 :        6351 :       std::vector<tree> variant_records;
     345                 :       22396 :       for (auto &variant : type.get_variants ())
     346                 :             :         {
     347                 :       16045 :           std::vector<Backend::typed_identifier> fields;
     348                 :       22057 :           for (size_t i = 0; i < variant->num_fields (); i++)
     349                 :             :             {
     350                 :        6012 :               const TyTy::StructFieldType *field
     351                 :        6012 :                 = variant->get_field_at_index (i);
     352                 :        6012 :               tree compiled_field_ty
     353                 :        6012 :                 = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     354                 :             : 
     355                 :        6012 :               std::string field_name = field->get_name ();
     356                 :        6012 :               if (variant->get_variant_type ()
     357                 :             :                   == TyTy::VariantDef::VariantType::TUPLE)
     358                 :        4509 :                 field_name = "__" + field->get_name ();
     359                 :             : 
     360                 :        6012 :               Backend::typed_identifier f (
     361                 :        6012 :                 field_name, compiled_field_ty,
     362                 :        6012 :                 ctx->get_mappings ().lookup_location (type.get_ty_ref ()));
     363                 :        6012 :               fields.push_back (std::move (f));
     364                 :        6012 :             }
     365                 :             : 
     366                 :       16045 :           tree variant_record = Backend::struct_type (fields);
     367                 :       16045 :           tree named_variant_record
     368                 :       16045 :             = Backend::named_type (variant->get_ident ().path.get (),
     369                 :       32090 :                                    variant_record, variant->get_ident ().locus);
     370                 :             : 
     371                 :             :           // add them to the list
     372                 :       16045 :           variant_records.push_back (named_variant_record);
     373                 :       16045 :         }
     374                 :             : 
     375                 :             :       // now we need to make the actual union, but first we need to make
     376                 :             :       // named_type TYPE_DECL's out of the variants
     377                 :             : 
     378                 :        6351 :       size_t i = 0;
     379                 :        6351 :       std::vector<Backend::typed_identifier> enum_fields;
     380                 :       22396 :       for (auto &variant_record : variant_records)
     381                 :             :         {
     382                 :       16045 :           TyTy::VariantDef *variant = type.get_variants ().at (i++);
     383                 :       16045 :           std::string implicit_variant_name = variant->get_identifier ();
     384                 :             : 
     385                 :       16045 :           Backend::typed_identifier f (implicit_variant_name, variant_record,
     386                 :       16045 :                                        ctx->get_mappings ().lookup_location (
     387                 :       16045 :                                          type.get_ty_ref ()));
     388                 :       16045 :           enum_fields.push_back (std::move (f));
     389                 :       16045 :         }
     390                 :             : 
     391                 :             :       //
     392                 :        6351 :       location_t locus = ctx->get_mappings ().lookup_location (type.get_ref ());
     393                 :             : 
     394                 :             :       // finally make the union or the enum
     395                 :        6351 :       tree variants_union = Backend::union_type (enum_fields, false);
     396                 :        6351 :       layout_type (variants_union);
     397                 :        6351 :       tree named_union_record
     398                 :        6351 :         = Backend::named_type ("payload", variants_union, locus);
     399                 :             : 
     400                 :             :       // create the overall struct
     401                 :        6351 :       tree enumeral_type = TyTyResolveCompile::get_implicit_enumeral_node_type (
     402                 :        6351 :         type.get_repr_options ().repr);
     403                 :        6351 :       Backend::typed_identifier discrim (RUST_ENUM_DISR_FIELD_NAME,
     404                 :        6351 :                                          enumeral_type, locus);
     405                 :        6351 :       Backend::typed_identifier variants_union_field ("payload",
     406                 :             :                                                       named_union_record,
     407                 :        6351 :                                                       locus);
     408                 :             : 
     409                 :        6351 :       std::vector<Backend::typed_identifier> fields
     410                 :        6351 :         = {discrim, variants_union_field};
     411                 :        6351 :       type_record = Backend::struct_type (fields, false);
     412                 :        6351 :     }
     413                 :             : 
     414                 :             :   // Handle repr options
     415                 :             :   // TODO: "packed" should only narrow type alignment and "align" should only
     416                 :             :   // widen it. Do we need to check and enforce this here, or is it taken care of
     417                 :             :   // later on in the gcc middle-end?
     418                 :       20464 :   TyTy::ADTType::ReprOptions repr = type.get_repr_options ();
     419                 :       20464 :   if (repr.pack)
     420                 :             :     {
     421                 :          10 :       TYPE_PACKED (type_record) = 1;
     422                 :          10 :       if (repr.pack > 1)
     423                 :             :         {
     424                 :           5 :           SET_TYPE_ALIGN (type_record, repr.pack * 8);
     425                 :           5 :           TYPE_USER_ALIGN (type_record) = 1;
     426                 :             :         }
     427                 :             :     }
     428                 :       20454 :   else if (repr.align)
     429                 :             :     {
     430                 :          10 :       SET_TYPE_ALIGN (type_record, repr.align * 8);
     431                 :          10 :       TYPE_USER_ALIGN (type_record) = 1;
     432                 :             :     }
     433                 :       20464 :   layout_type (type_record);
     434                 :             : 
     435                 :       20464 :   std::string named_struct_str
     436                 :       20464 :     = type.get_ident ().path.get () + type.subst_as_string ();
     437                 :       20464 :   translated = Backend::named_type (named_struct_str, type_record,
     438                 :       20464 :                                     type.get_ident ().locus);
     439                 :       20464 : }
     440                 :             : 
     441                 :             : void
     442                 :       20786 : TyTyResolveCompile::visit (const TyTy::TupleType &type)
     443                 :             : {
     444                 :       20786 :   if (type.num_fields () == 0)
     445                 :             :     {
     446                 :       18710 :       translated = get_unit_type (ctx);
     447                 :       18710 :       return;
     448                 :             :     }
     449                 :             : 
     450                 :             :   // create implicit struct
     451                 :        2076 :   std::vector<Backend::typed_identifier> fields;
     452                 :        6399 :   for (size_t i = 0; i < type.num_fields (); i++)
     453                 :             :     {
     454                 :        4323 :       TyTy::BaseType *field = type.get_field (i);
     455                 :        4323 :       tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
     456                 :             : 
     457                 :             :       // rustc uses the convention __N, where N is an integer, to
     458                 :             :       // name the fields of a tuple.  We follow this as well,
     459                 :             :       // because this is used by GDB.  One further reason to prefer
     460                 :             :       // this, rather than simply emitting the integer, is that this
     461                 :             :       // approach makes it simpler to use a C-only debugger, or
     462                 :             :       // GDB's C mode, when debugging Rust.
     463                 :        4323 :       Backend::typed_identifier f ("__" + std::to_string (i), compiled_field_ty,
     464                 :        4323 :                                    ctx->get_mappings ().lookup_location (
     465                 :        8646 :                                      type.get_ty_ref ()));
     466                 :        4323 :       fields.push_back (std::move (f));
     467                 :             :     }
     468                 :             : 
     469                 :        2076 :   tree struct_type_record = Backend::struct_type (fields);
     470                 :        2076 :   translated = Backend::named_type (type.get_name (), struct_type_record,
     471                 :        2076 :                                     type.get_ident ().locus);
     472                 :        2076 : }
     473                 :             : 
     474                 :             : void
     475                 :        3640 : TyTyResolveCompile::visit (const TyTy::ArrayType &type)
     476                 :             : {
     477                 :        3640 :   tree element_type
     478                 :        3640 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     479                 :        3640 :   TyTy::ConstType *const_capacity = type.get_capacity ();
     480                 :        3640 :   tree folded_capacity_expr = const_capacity->get_value ();
     481                 :             : 
     482                 :             :   // build_index_type takes the maximum index, which is one less than
     483                 :             :   // the length.
     484                 :        3640 :   tree index_type_tree = build_index_type (
     485                 :             :     fold_build2 (MINUS_EXPR, sizetype, folded_capacity_expr, size_one_node));
     486                 :             : 
     487                 :        3640 :   translated = build_array_type (element_type, index_type_tree, false);
     488                 :        3640 : }
     489                 :             : 
     490                 :             : void
     491                 :          93 : TyTyResolveCompile::visit (const TyTy::SliceType &type)
     492                 :             : {
     493                 :          93 :   tree type_record = create_slice_type_record (type);
     494                 :             : 
     495                 :          93 :   std::string named_struct_str
     496                 :         186 :     = std::string ("[") + type.get_element_type ()->get_name () + "]";
     497                 :          93 :   translated = Backend::named_type (named_struct_str, type_record,
     498                 :          93 :                                     type.get_ident ().locus);
     499                 :          93 : }
     500                 :             : 
     501                 :             : void
     502                 :       14243 : TyTyResolveCompile::visit (const TyTy::BoolType &)
     503                 :             : {
     504                 :       14243 :   translated
     505                 :       14243 :     = Backend::named_type ("bool", boolean_type_node, BUILTINS_LOCATION);
     506                 :       14243 : }
     507                 :             : 
     508                 :             : void
     509                 :       90761 : TyTyResolveCompile::visit (const TyTy::IntType &type)
     510                 :             : {
     511                 :       90761 :   switch (type.get_int_kind ())
     512                 :             :     {
     513                 :       12717 :     case TyTy::IntType::I8:
     514                 :       12717 :       translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
     515                 :             :                                         BUILTINS_LOCATION);
     516                 :       12717 :       return;
     517                 :             : 
     518                 :        8898 :     case TyTy::IntType::I16:
     519                 :        8898 :       translated
     520                 :        8898 :         = Backend::named_type ("i16", Backend::integer_type (false, 16),
     521                 :             :                                BUILTINS_LOCATION);
     522                 :        8898 :       return;
     523                 :             : 
     524                 :       51149 :     case TyTy::IntType::I32:
     525                 :       51149 :       translated
     526                 :       51149 :         = Backend::named_type ("i32", Backend::integer_type (false, 32),
     527                 :             :                                BUILTINS_LOCATION);
     528                 :       51149 :       return;
     529                 :             : 
     530                 :        9065 :     case TyTy::IntType::I64:
     531                 :        9065 :       translated
     532                 :        9065 :         = Backend::named_type ("i64", Backend::integer_type (false, 64),
     533                 :             :                                BUILTINS_LOCATION);
     534                 :        9065 :       return;
     535                 :             : 
     536                 :        8932 :     case TyTy::IntType::I128:
     537                 :        8932 :       translated
     538                 :        8932 :         = Backend::named_type ("i128", Backend::integer_type (false, 128),
     539                 :             :                                BUILTINS_LOCATION);
     540                 :        8932 :       return;
     541                 :             :     }
     542                 :             : }
     543                 :             : 
     544                 :             : void
     545                 :       71599 : TyTyResolveCompile::visit (const TyTy::UintType &type)
     546                 :             : {
     547                 :       71599 :   switch (type.get_uint_kind ())
     548                 :             :     {
     549                 :       17686 :     case TyTy::UintType::U8:
     550                 :       17686 :       translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
     551                 :             :                                         BUILTINS_LOCATION);
     552                 :       17686 :       return;
     553                 :             : 
     554                 :       12098 :     case TyTy::UintType::U16:
     555                 :       12098 :       translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
     556                 :             :                                         BUILTINS_LOCATION);
     557                 :       12098 :       return;
     558                 :             : 
     559                 :       16254 :     case TyTy::UintType::U32:
     560                 :       16254 :       translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
     561                 :             :                                         BUILTINS_LOCATION);
     562                 :       16254 :       return;
     563                 :             : 
     564                 :       16893 :     case TyTy::UintType::U64:
     565                 :       16893 :       translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
     566                 :             :                                         BUILTINS_LOCATION);
     567                 :       16893 :       return;
     568                 :             : 
     569                 :        8668 :     case TyTy::UintType::U128:
     570                 :        8668 :       translated
     571                 :        8668 :         = Backend::named_type ("u128", Backend::integer_type (true, 128),
     572                 :             :                                BUILTINS_LOCATION);
     573                 :        8668 :       return;
     574                 :             :     }
     575                 :             : }
     576                 :             : 
     577                 :             : void
     578                 :       22293 : TyTyResolveCompile::visit (const TyTy::FloatType &type)
     579                 :             : {
     580                 :       22293 :   switch (type.get_float_kind ())
     581                 :             :     {
     582                 :       10935 :     case TyTy::FloatType::F32:
     583                 :       10935 :       translated = Backend::named_type ("f32", Backend::float_type (32),
     584                 :             :                                         BUILTINS_LOCATION);
     585                 :       10935 :       return;
     586                 :             : 
     587                 :       11358 :     case TyTy::FloatType::F64:
     588                 :       11358 :       translated = Backend::named_type ("f64", Backend::float_type (64),
     589                 :             :                                         BUILTINS_LOCATION);
     590                 :       11358 :       return;
     591                 :             :     }
     592                 :             : }
     593                 :             : 
     594                 :             : void
     595                 :       41157 : TyTyResolveCompile::visit (const TyTy::USizeType &)
     596                 :             : {
     597                 :       41157 :   translated
     598                 :       41157 :     = Backend::named_type ("usize",
     599                 :             :                            Backend::integer_type (true,
     600                 :             :                                                   Backend::get_pointer_size ()),
     601                 :             :                            BUILTINS_LOCATION);
     602                 :       41157 : }
     603                 :             : 
     604                 :             : void
     605                 :       22178 : TyTyResolveCompile::visit (const TyTy::ISizeType &)
     606                 :             : {
     607                 :       22178 :   translated
     608                 :       22178 :     = Backend::named_type ("isize",
     609                 :             :                            Backend::integer_type (false,
     610                 :             :                                                   Backend::get_pointer_size ()),
     611                 :             :                            BUILTINS_LOCATION);
     612                 :       22178 : }
     613                 :             : 
     614                 :             : void
     615                 :        9163 : TyTyResolveCompile::visit (const TyTy::CharType &)
     616                 :             : {
     617                 :        9163 :   translated
     618                 :        9163 :     = Backend::named_type ("char", Backend::wchar_type (), BUILTINS_LOCATION);
     619                 :        9163 : }
     620                 :             : 
     621                 :             : void
     622                 :       17943 : TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
     623                 :             : {
     624                 :       17943 :   const TyTy::SliceType *slice = nullptr;
     625                 :       17943 :   const TyTy::StrType *str = nullptr;
     626                 :       17943 :   const TyTy::DynamicObjectType *dyn = nullptr;
     627                 :       17943 :   if (type.is_dyn_slice_type (&slice))
     628                 :             :     {
     629                 :         596 :       tree type_record = create_slice_type_record (*slice);
     630                 :         596 :       std::string dyn_slice_type_str
     631                 :        1788 :         = std::string (type.is_mutable () ? "&mut " : "&") + "["
     632                 :        1788 :           + slice->get_element_type ()->get_name () + "]";
     633                 :             : 
     634                 :         596 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     635                 :             :                                         slice->get_locus ());
     636                 :             : 
     637                 :         596 :       return;
     638                 :         596 :     }
     639                 :       17347 :   else if (type.is_dyn_str_type (&str))
     640                 :             :     {
     641                 :        3941 :       tree type_record = create_str_type_record (*str);
     642                 :        3941 :       std::string dyn_str_type_str
     643                 :       11823 :         = std::string (type.is_mutable () ? "&mut " : "&") + "str";
     644                 :             : 
     645                 :        3941 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     646                 :             :                                         str->get_locus ());
     647                 :             : 
     648                 :        3941 :       return;
     649                 :        3941 :     }
     650                 :       13406 :   else if (type.is_dyn_obj_type (&dyn))
     651                 :             :     {
     652                 :         549 :       tree type_record = create_dyn_obj_record (*dyn);
     653                 :         549 :       std::string dyn_str_type_str
     654                 :        1098 :         = std::string (type.is_mutable () ? "&mut " : "& ") + dyn->get_name ();
     655                 :             : 
     656                 :         549 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     657                 :             :                                         dyn->get_locus ());
     658                 :             : 
     659                 :         549 :       return;
     660                 :         549 :     }
     661                 :             : 
     662                 :       12857 :   tree base_compiled_type
     663                 :       12857 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     664                 :       12857 :   if (type.is_mutable ())
     665                 :             :     {
     666                 :        1104 :       translated = Backend::reference_type (base_compiled_type);
     667                 :             :     }
     668                 :             :   else
     669                 :             :     {
     670                 :       11753 :       auto base = Backend::immutable_type (base_compiled_type);
     671                 :       11753 :       translated = Backend::reference_type (base);
     672                 :             :     }
     673                 :             : }
     674                 :             : 
     675                 :             : void
     676                 :        9953 : TyTyResolveCompile::visit (const TyTy::PointerType &type)
     677                 :             : {
     678                 :        9953 :   const TyTy::SliceType *slice = nullptr;
     679                 :        9953 :   const TyTy::StrType *str = nullptr;
     680                 :        9953 :   const TyTy::DynamicObjectType *dyn = nullptr;
     681                 :        9953 :   if (type.is_dyn_slice_type (&slice))
     682                 :             :     {
     683                 :         533 :       tree type_record = create_slice_type_record (*slice);
     684                 :         533 :       std::string dyn_slice_type_str
     685                 :        1543 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "["
     686                 :        1599 :           + slice->get_element_type ()->get_name () + "]";
     687                 :             : 
     688                 :         533 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     689                 :             :                                         slice->get_locus ());
     690                 :             : 
     691                 :         533 :       return;
     692                 :         533 :     }
     693                 :        9420 :   else if (type.is_dyn_str_type (&str))
     694                 :             :     {
     695                 :        2487 :       tree type_record = create_str_type_record (*str);
     696                 :        2487 :       std::string dyn_str_type_str
     697                 :        7461 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "str";
     698                 :             : 
     699                 :        2487 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     700                 :             :                                         str->get_locus ());
     701                 :             : 
     702                 :        2487 :       return;
     703                 :        2487 :     }
     704                 :        6933 :   else if (type.is_dyn_obj_type (&dyn))
     705                 :             :     {
     706                 :           0 :       tree type_record = create_dyn_obj_record (*dyn);
     707                 :           0 :       std::string dyn_str_type_str
     708                 :           0 :         = std::string (type.is_mutable () ? "*mut " : "*const ")
     709                 :           0 :           + dyn->get_name ();
     710                 :             : 
     711                 :           0 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     712                 :             :                                         dyn->get_locus ());
     713                 :             : 
     714                 :           0 :       return;
     715                 :           0 :     }
     716                 :             : 
     717                 :        6933 :   tree base_compiled_type
     718                 :        6933 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     719                 :        6933 :   if (type.is_mutable ())
     720                 :             :     {
     721                 :        1681 :       translated = Backend::pointer_type (base_compiled_type);
     722                 :             :     }
     723                 :             :   else
     724                 :             :     {
     725                 :        5252 :       auto base = Backend::immutable_type (base_compiled_type);
     726                 :        5252 :       translated = Backend::pointer_type (base);
     727                 :             :     }
     728                 :             : }
     729                 :             : 
     730                 :             : void
     731                 :        8236 : TyTyResolveCompile::visit (const TyTy::StrType &type)
     732                 :             : {
     733                 :        8236 :   tree raw_str = create_str_type_record (type);
     734                 :        8236 :   translated = Backend::named_type ("str", raw_str, BUILTINS_LOCATION);
     735                 :        8236 : }
     736                 :             : 
     737                 :             : void
     738                 :        8491 : TyTyResolveCompile::visit (const TyTy::NeverType &)
     739                 :             : {
     740                 :        8491 :   translated = get_unit_type (ctx);
     741                 :        8491 : }
     742                 :             : 
     743                 :             : void
     744                 :           0 : TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
     745                 :             : {
     746                 :           0 :   if (trait_object_mode)
     747                 :             :     {
     748                 :           0 :       translated = Backend::integer_type (true, Backend::get_pointer_size ());
     749                 :           0 :       return;
     750                 :             :     }
     751                 :             : 
     752                 :           0 :   tree type_record = create_dyn_obj_record (type);
     753                 :           0 :   translated = Backend::named_type (type.get_name (), type_record,
     754                 :           0 :                                     type.get_ident ().locus);
     755                 :             : }
     756                 :             : 
     757                 :             : void
     758                 :           0 : TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
     759                 :             : {
     760                 :           0 :   rust_assert (type.can_resolve ());
     761                 :           0 :   auto underlying = type.resolve ();
     762                 :           0 :   translated = TyTyResolveCompile::compile (ctx, underlying, trait_object_mode);
     763                 :           0 : }
     764                 :             : 
     765                 :             : tree
     766                 :         549 : TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
     767                 :             : {
     768                 :             :   // create implicit struct
     769                 :         549 :   auto items = type.get_object_items ();
     770                 :         549 :   std::vector<Backend::typed_identifier> fields;
     771                 :             : 
     772                 :         549 :   tree uint = Backend::integer_type (true, Backend::get_pointer_size ());
     773                 :         549 :   tree uintptr_ty = build_pointer_type (uint);
     774                 :             : 
     775                 :         549 :   Backend::typed_identifier f ("pointer", uintptr_ty,
     776                 :         549 :                                ctx->get_mappings ().lookup_location (
     777                 :         549 :                                  type.get_ty_ref ()));
     778                 :         549 :   fields.push_back (std::move (f));
     779                 :             : 
     780                 :         549 :   tree vtable_size = build_int_cst (size_type_node, items.size ());
     781                 :         549 :   tree vtable_type = Backend::array_type (uintptr_ty, vtable_size);
     782                 :         549 :   Backend::typed_identifier vtf ("vtable", vtable_type,
     783                 :         549 :                                  ctx->get_mappings ().lookup_location (
     784                 :         549 :                                    type.get_ty_ref ()));
     785                 :         549 :   fields.push_back (std::move (vtf));
     786                 :             : 
     787                 :         549 :   tree record = Backend::struct_type (fields);
     788                 :         549 :   RS_DST_FLAG (record) = 1;
     789                 :         549 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     790                 :             : 
     791                 :         549 :   return record;
     792                 :         549 : }
     793                 :             : 
     794                 :             : tree
     795                 :        1222 : TyTyResolveCompile::create_slice_type_record (const TyTy::SliceType &type)
     796                 :             : {
     797                 :             :   // lookup usize
     798                 :        1222 :   TyTy::BaseType *usize = nullptr;
     799                 :        1222 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     800                 :        1222 :   rust_assert (ok);
     801                 :             : 
     802                 :        1222 :   tree element_type
     803                 :        1222 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     804                 :        1222 :   tree data_field_ty = build_pointer_type (element_type);
     805                 :        1222 :   Backend::typed_identifier data_field ("data", data_field_ty,
     806                 :        1222 :                                         type.get_locus ());
     807                 :             : 
     808                 :        1222 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     809                 :        1222 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     810                 :             : 
     811                 :        1222 :   tree record = Backend::struct_type ({data_field, len_field});
     812                 :        1222 :   RS_DST_FLAG (record) = 1;
     813                 :        1222 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     814                 :             : 
     815                 :        1222 :   return record;
     816                 :             : }
     817                 :             : 
     818                 :             : tree
     819                 :       14664 : TyTyResolveCompile::create_str_type_record (const TyTy::StrType &type)
     820                 :             : {
     821                 :             :   // lookup usize
     822                 :       14664 :   TyTy::BaseType *usize = nullptr;
     823                 :       14664 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     824                 :       14664 :   rust_assert (ok);
     825                 :             : 
     826                 :       14664 :   tree char_ptr = build_pointer_type (char_type_node);
     827                 :       14664 :   tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
     828                 :             : 
     829                 :       14664 :   tree element_type = const_char_type;
     830                 :       14664 :   tree data_field_ty = build_pointer_type (element_type);
     831                 :       14664 :   Backend::typed_identifier data_field ("data", data_field_ty,
     832                 :       14664 :                                         type.get_locus ());
     833                 :             : 
     834                 :       14664 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     835                 :       14664 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     836                 :             : 
     837                 :       14664 :   tree record = Backend::struct_type ({data_field, len_field});
     838                 :       14664 :   RS_DST_FLAG (record) = 1;
     839                 :       14664 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     840                 :             : 
     841                 :       14664 :   return record;
     842                 :             : }
     843                 :             : 
     844                 :             : } // namespace Compile
     845                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.