LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-type.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.4 % 433 400
Test Date: 2025-07-12 13:27:34 Functions: 81.2 % 32 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-compile-expr.h"
      21                 :             : #include "rust-constexpr.h"
      22                 :             : #include "rust-gcc.h"
      23                 :             : 
      24                 :             : #include "tree.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                 :      283799 : TyTyResolveCompile::TyTyResolveCompile (Context *ctx, bool trait_object_mode)
      33                 :      283799 :   : ctx (ctx), trait_object_mode (trait_object_mode),
      34                 :      283799 :     translated (error_mark_node)
      35                 :      283799 : {}
      36                 :             : 
      37                 :             : tree
      38                 :      283799 : TyTyResolveCompile::compile (Context *ctx, const TyTy::BaseType *ty,
      39                 :             :                              bool trait_object_mode)
      40                 :             : {
      41                 :      283799 :   TyTyResolveCompile compiler (ctx, trait_object_mode);
      42                 :      283799 :   const TyTy::BaseType *destructured = ty->destructure ();
      43                 :      283799 :   destructured->accept_vis (compiler);
      44                 :             : 
      45                 :      283799 :   if (compiler.translated != error_mark_node
      46                 :      283799 :       && TYPE_NAME (compiler.translated) != NULL)
      47                 :             :     {
      48                 :             :       // canonicalize the type
      49                 :      249347 :       compiler.translated = ctx->insert_compiled_type (compiler.translated);
      50                 :             :     }
      51                 :             : 
      52                 :      283799 :   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                 :        2454 : 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                 :        2454 :   return compile (ctx, repr);
      81                 :             : }
      82                 :             : 
      83                 :             : tree
      84                 :       27414 : TyTyResolveCompile::get_unit_type (Context *ctx)
      85                 :             : {
      86                 :       27414 :   static tree unit_type;
      87                 :       27414 :   if (unit_type == nullptr)
      88                 :             :     {
      89                 :        4254 :       auto cn = ctx->get_mappings ().get_current_crate ();
      90                 :        4254 :       auto &c = ctx->get_mappings ().get_ast_crate (cn);
      91                 :        4254 :       location_t locus = BUILTINS_LOCATION;
      92                 :        4254 :       if (c.items.size () > 0)
      93                 :             :         {
      94                 :        4252 :           auto &item = c.items[0];
      95                 :        4252 :           locus = item->get_locus ();
      96                 :             :         }
      97                 :             : 
      98                 :        4254 :       auto unit_type_node = Backend::struct_type ({});
      99                 :        4254 :       unit_type = Backend::named_type ("()", unit_type_node, locus);
     100                 :             :     }
     101                 :       27414 :   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                 :          18 : TyTyResolveCompile::visit (const TyTy::InferType &type)
     112                 :             : {
     113                 :          18 :   const TyTy::BaseType *orig = &type;
     114                 :          18 :   TyTy::BaseType *lookup = nullptr;
     115                 :          18 :   bool ok = ctx->get_tyctx ()->lookup_type (type.get_ref (), &lookup);
     116                 :          18 :   if (!ok)
     117                 :             :     {
     118                 :           0 :       translated = error_mark_node;
     119                 :           0 :       return;
     120                 :             :     }
     121                 :             : 
     122                 :          18 :   if (orig == lookup)
     123                 :             :     {
     124                 :           0 :       translated = error_mark_node;
     125                 :           0 :       return;
     126                 :             :     }
     127                 :             : 
     128                 :          18 :   translated = TyTyResolveCompile::compile (ctx, lookup);
     129                 :             : }
     130                 :             : 
     131                 :             : void
     132                 :           0 : TyTyResolveCompile::visit (const TyTy::ParamType &)
     133                 :             : {
     134                 :           0 :   translated = error_mark_node;
     135                 :           0 : }
     136                 :             : 
     137                 :             : void
     138                 :           0 : TyTyResolveCompile::visit (const TyTy::ProjectionType &type)
     139                 :             : {
     140                 :           0 :   translated = error_mark_node;
     141                 :           0 : }
     142                 :             : 
     143                 :             : void
     144                 :           0 : TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
     145                 :             : {
     146                 :           0 :   translated = error_mark_node;
     147                 :           0 : }
     148                 :             : 
     149                 :             : void
     150                 :         194 : TyTyResolveCompile::visit (const TyTy::ClosureType &type)
     151                 :             : {
     152                 :         194 :   auto &mappings = ctx->get_mappings ();
     153                 :             : 
     154                 :         194 :   std::vector<Backend::typed_identifier> fields;
     155                 :             : 
     156                 :         194 :   size_t i = 0;
     157                 :         229 :   for (const auto &capture : type.get_captures ())
     158                 :             :     {
     159                 :             :       // lookup the HirId
     160                 :          35 :       tl::optional<HirId> hid = mappings.lookup_node_to_hir (capture);
     161                 :          35 :       rust_assert (hid.has_value ());
     162                 :          35 :       auto ref = hid.value ();
     163                 :             : 
     164                 :             :       // lookup the var decl type
     165                 :          35 :       TyTy::BaseType *lookup = nullptr;
     166                 :          35 :       bool found = ctx->get_tyctx ()->lookup_type (ref, &lookup);
     167                 :          35 :       rust_assert (found);
     168                 :             : 
     169                 :             :       // FIXME get the var pattern name
     170                 :          35 :       std::string mappings_name = "capture_" + std::to_string (i);
     171                 :             : 
     172                 :             :       // FIXME
     173                 :             :       // this should be based on the closure move-ability
     174                 :          35 :       tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
     175                 :          35 :       tree capture_type = build_reference_type (decl_type);
     176                 :          35 :       fields.push_back (Backend::typed_identifier (mappings_name, capture_type,
     177                 :          70 :                                                    type.get_ident ().locus));
     178                 :          35 :     }
     179                 :             : 
     180                 :         194 :   tree type_record = Backend::struct_type (fields);
     181                 :         194 :   RS_CLOSURE_FLAG (type_record) = 1;
     182                 :             : 
     183                 :         194 :   std::string named_struct_str
     184                 :         388 :     = type.get_ident ().path.get () + "::{{closure}}";
     185                 :         194 :   translated = Backend::named_type (named_struct_str, type_record,
     186                 :         194 :                                     type.get_ident ().locus);
     187                 :         194 : }
     188                 :             : 
     189                 :             : void
     190                 :       16472 : TyTyResolveCompile::visit (const TyTy::FnType &type)
     191                 :             : {
     192                 :       16472 :   Backend::typed_identifier receiver;
     193                 :       16472 :   std::vector<Backend::typed_identifier> parameters;
     194                 :       16472 :   std::vector<Backend::typed_identifier> results;
     195                 :             : 
     196                 :             :   // we can only return unit-type if its not the C ABI because it will expect
     197                 :             :   // void
     198                 :       16472 :   auto hir_type = type.get_return_type ()->destructure ();
     199                 :       16472 :   bool return_is_unit = hir_type->is_unit ();
     200                 :       16472 :   bool is_c_abi = type.get_abi () == ABI::C;
     201                 :       16472 :   bool should_be_void = is_c_abi && return_is_unit;
     202                 :       16472 :   if (!should_be_void)
     203                 :             :     {
     204                 :       15589 :       auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
     205                 :       15589 :       location_t return_type_locus
     206                 :       15589 :         = ctx->get_mappings ().lookup_location (hir_type->get_ref ());
     207                 :       31178 :       results.push_back (
     208                 :       46767 :         Backend::typed_identifier ("_", ret, return_type_locus));
     209                 :             :     }
     210                 :             : 
     211                 :       29986 :   for (auto &param_pair : type.get_params ())
     212                 :             :     {
     213                 :       13514 :       auto param_tyty = param_pair.get_type ();
     214                 :       13514 :       auto compiled_param_type
     215                 :       13514 :         = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
     216                 :             : 
     217                 :       13514 :       auto compiled_param = Backend::typed_identifier (
     218                 :       13514 :         param_pair.get_pattern ().as_string (), compiled_param_type,
     219                 :       27028 :         ctx->get_mappings ().lookup_location (param_tyty->get_ref ()));
     220                 :             : 
     221                 :       13514 :       parameters.push_back (compiled_param);
     222                 :       13514 :     }
     223                 :             : 
     224                 :       16472 :   if (!type.is_variadic ())
     225                 :       15656 :     translated = Backend::function_type (receiver, parameters, results, NULL,
     226                 :       15656 :                                          type.get_ident ().locus);
     227                 :             :   else
     228                 :         816 :     translated
     229                 :         816 :       = Backend::function_type_variadic (receiver, parameters, results, NULL,
     230                 :         816 :                                          type.get_ident ().locus);
     231                 :       16472 : }
     232                 :             : 
     233                 :             : void
     234                 :          88 : TyTyResolveCompile::visit (const TyTy::FnPtr &type)
     235                 :             : {
     236                 :          88 :   tree result_type = TyTyResolveCompile::compile (ctx, type.get_return_type ());
     237                 :             : 
     238                 :          88 :   std::vector<tree> parameters;
     239                 :             : 
     240                 :          88 :   auto &params = type.get_params ();
     241                 :         184 :   for (auto &p : params)
     242                 :             :     {
     243                 :          96 :       tree pty = TyTyResolveCompile::compile (ctx, p.get_tyty ());
     244                 :          96 :       parameters.push_back (pty);
     245                 :             :     }
     246                 :             : 
     247                 :          88 :   translated = Backend::function_ptr_type (result_type, parameters,
     248                 :          88 :                                            type.get_ident ().locus);
     249                 :          88 : }
     250                 :             : 
     251                 :             : void
     252                 :       12185 : TyTyResolveCompile::visit (const TyTy::ADTType &type)
     253                 :             : {
     254                 :       12185 :   tree type_record = error_mark_node;
     255                 :       12185 :   if (!type.is_enum ())
     256                 :             :     {
     257                 :        9731 :       rust_assert (type.number_of_variants () == 1);
     258                 :             : 
     259                 :        9731 :       TyTy::VariantDef &variant = *type.get_variants ().at (0);
     260                 :        9731 :       std::vector<Backend::typed_identifier> fields;
     261                 :       28082 :       for (size_t i = 0; i < variant.num_fields (); i++)
     262                 :             :         {
     263                 :       18351 :           const TyTy::StructFieldType *field = variant.get_field_at_index (i);
     264                 :       18351 :           tree compiled_field_ty
     265                 :       18351 :             = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     266                 :             : 
     267                 :       18351 :           Backend::typed_identifier f (field->get_name (), compiled_field_ty,
     268                 :       18351 :                                        ctx->get_mappings ().lookup_location (
     269                 :       36702 :                                          type.get_ty_ref ()));
     270                 :       18351 :           fields.push_back (std::move (f));
     271                 :       18351 :         }
     272                 :             : 
     273                 :        9731 :       type_record = type.is_union () ? Backend::union_type (fields, false)
     274                 :        9558 :                                      : Backend::struct_type (fields, false);
     275                 :        9731 :     }
     276                 :             :   else
     277                 :             :     {
     278                 :             :       // see:
     279                 :             :       // https://github.com/bminor/binutils-gdb/blob/527b8861cd472385fa9160a91dd6d65a25c41987/gdb/dwarf2/read.c#L9010-L9241
     280                 :             :       //
     281                 :             :       // enums are actually a big union so for example the rust enum:
     282                 :             :       //
     283                 :             :       // enum AnEnum {
     284                 :             :       //   A,
     285                 :             :       //   B,
     286                 :             :       //   C (char),
     287                 :             :       //   D { x: i64, y: i64 },
     288                 :             :       // }
     289                 :             :       //
     290                 :             :       // we actually turn this into
     291                 :             :       //
     292                 :             :       // union {
     293                 :             :       //   struct A { int RUST$ENUM$DISR; }; <- this is a data-less variant
     294                 :             :       //   struct B { int RUST$ENUM$DISR; }; <- this is a data-less variant
     295                 :             :       //   struct C { int RUST$ENUM$DISR; char __0; };
     296                 :             :       //   struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
     297                 :             :       // }
     298                 :             :       //
     299                 :             :       // Ada, qual_union_types might still work for this but I am not 100% sure.
     300                 :             :       // I ran into some issues lets reuse our normal union and ask Ada people
     301                 :             :       // about it.
     302                 :             :       //
     303                 :             :       // I think the above is actually wrong and it should actually be this
     304                 :             :       //
     305                 :             :       // struct {
     306                 :             :       //     int RUST$ENUM$DISR; // take into account the repr for this TODO
     307                 :             :       //     union {
     308                 :             :       //         // Variant A
     309                 :             :       //         struct {
     310                 :             :       //             // No additional fields
     311                 :             :       //         } A;
     312                 :             : 
     313                 :             :       //         // Variant B
     314                 :             :       //         struct {
     315                 :             :       //             // No additional fields
     316                 :             :       //         } B;
     317                 :             : 
     318                 :             :       //         // Variant C
     319                 :             :       //         struct {
     320                 :             :       //             char c;
     321                 :             :       //         } C;
     322                 :             : 
     323                 :             :       //         // Variant D
     324                 :             :       //         struct {
     325                 :             :       //             int64_t x;
     326                 :             :       //             int64_t y;
     327                 :             :       //         } D;
     328                 :             :       //     } payload; // The union of all variant data
     329                 :             :       // };
     330                 :             : 
     331                 :        2454 :       std::vector<tree> variant_records;
     332                 :        8033 :       for (auto &variant : type.get_variants ())
     333                 :             :         {
     334                 :        5579 :           std::vector<Backend::typed_identifier> fields;
     335                 :        8624 :           for (size_t i = 0; i < variant->num_fields (); i++)
     336                 :             :             {
     337                 :        3045 :               const TyTy::StructFieldType *field
     338                 :        3045 :                 = variant->get_field_at_index (i);
     339                 :        3045 :               tree compiled_field_ty
     340                 :        3045 :                 = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     341                 :             : 
     342                 :        3045 :               std::string field_name = field->get_name ();
     343                 :        3045 :               if (variant->get_variant_type ()
     344                 :             :                   == TyTy::VariantDef::VariantType::TUPLE)
     345                 :        2342 :                 field_name = "__" + field->get_name ();
     346                 :             : 
     347                 :        3045 :               Backend::typed_identifier f (
     348                 :             :                 field_name, compiled_field_ty,
     349                 :        3045 :                 ctx->get_mappings ().lookup_location (type.get_ty_ref ()));
     350                 :        3045 :               fields.push_back (std::move (f));
     351                 :        3045 :             }
     352                 :             : 
     353                 :        5579 :           tree variant_record = Backend::struct_type (fields);
     354                 :        5579 :           tree named_variant_record
     355                 :        5579 :             = Backend::named_type (variant->get_ident ().path.get (),
     356                 :       11158 :                                    variant_record, variant->get_ident ().locus);
     357                 :             : 
     358                 :             :           // add them to the list
     359                 :        5579 :           variant_records.push_back (named_variant_record);
     360                 :        5579 :         }
     361                 :             : 
     362                 :             :       // now we need to make the actual union, but first we need to make
     363                 :             :       // named_type TYPE_DECL's out of the variants
     364                 :             : 
     365                 :        2454 :       size_t i = 0;
     366                 :        2454 :       std::vector<Backend::typed_identifier> enum_fields;
     367                 :        8033 :       for (auto &variant_record : variant_records)
     368                 :             :         {
     369                 :        5579 :           TyTy::VariantDef *variant = type.get_variants ().at (i++);
     370                 :        5579 :           std::string implicit_variant_name = variant->get_identifier ();
     371                 :             : 
     372                 :        5579 :           Backend::typed_identifier f (implicit_variant_name, variant_record,
     373                 :        5579 :                                        ctx->get_mappings ().lookup_location (
     374                 :        5579 :                                          type.get_ty_ref ()));
     375                 :        5579 :           enum_fields.push_back (std::move (f));
     376                 :        5579 :         }
     377                 :             : 
     378                 :             :       //
     379                 :        2454 :       location_t locus = ctx->get_mappings ().lookup_location (type.get_ref ());
     380                 :             : 
     381                 :             :       // finally make the union or the enum
     382                 :        2454 :       tree variants_union = Backend::union_type (enum_fields, false);
     383                 :        2454 :       layout_type (variants_union);
     384                 :        2454 :       tree named_union_record
     385                 :        2454 :         = Backend::named_type ("payload", variants_union, locus);
     386                 :             : 
     387                 :             :       // create the overall struct
     388                 :        2454 :       tree enumeral_type = TyTyResolveCompile::get_implicit_enumeral_node_type (
     389                 :        2454 :         type.get_repr_options ().repr);
     390                 :        2454 :       Backend::typed_identifier discrim (RUST_ENUM_DISR_FIELD_NAME,
     391                 :        2454 :                                          enumeral_type, locus);
     392                 :        2454 :       Backend::typed_identifier variants_union_field ("payload",
     393                 :             :                                                       named_union_record,
     394                 :        2454 :                                                       locus);
     395                 :             : 
     396                 :        2454 :       std::vector<Backend::typed_identifier> fields
     397                 :        7362 :         = {discrim, variants_union_field};
     398                 :        2454 :       type_record = Backend::struct_type (fields, false);
     399                 :        2454 :     }
     400                 :             : 
     401                 :             :   // Handle repr options
     402                 :             :   // TODO: "packed" should only narrow type alignment and "align" should only
     403                 :             :   // widen it. Do we need to check and enforce this here, or is it taken care of
     404                 :             :   // later on in the gcc middle-end?
     405                 :       12185 :   TyTy::ADTType::ReprOptions repr = type.get_repr_options ();
     406                 :       12185 :   if (repr.pack)
     407                 :             :     {
     408                 :          16 :       TYPE_PACKED (type_record) = 1;
     409                 :          16 :       if (repr.pack > 1)
     410                 :             :         {
     411                 :           8 :           SET_TYPE_ALIGN (type_record, repr.pack * 8);
     412                 :           8 :           TYPE_USER_ALIGN (type_record) = 1;
     413                 :             :         }
     414                 :             :     }
     415                 :       12169 :   else if (repr.align)
     416                 :             :     {
     417                 :          16 :       SET_TYPE_ALIGN (type_record, repr.align * 8);
     418                 :          16 :       TYPE_USER_ALIGN (type_record) = 1;
     419                 :             :     }
     420                 :       12185 :   layout_type (type_record);
     421                 :             : 
     422                 :       12185 :   std::string named_struct_str
     423                 :       12185 :     = type.get_ident ().path.get () + type.subst_as_string ();
     424                 :       12185 :   translated = Backend::named_type (named_struct_str, type_record,
     425                 :       12185 :                                     type.get_ident ().locus);
     426                 :       12185 : }
     427                 :             : 
     428                 :             : void
     429                 :       17964 : TyTyResolveCompile::visit (const TyTy::TupleType &type)
     430                 :             : {
     431                 :       17964 :   if (type.num_fields () == 0)
     432                 :             :     {
     433                 :       15711 :       translated = get_unit_type (ctx);
     434                 :       15711 :       return;
     435                 :             :     }
     436                 :             : 
     437                 :             :   // create implicit struct
     438                 :        2253 :   std::vector<Backend::typed_identifier> fields;
     439                 :        6934 :   for (size_t i = 0; i < type.num_fields (); i++)
     440                 :             :     {
     441                 :        4681 :       TyTy::BaseType *field = type.get_field (i);
     442                 :        4681 :       tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
     443                 :             : 
     444                 :             :       // rustc uses the convention __N, where N is an integer, to
     445                 :             :       // name the fields of a tuple.  We follow this as well,
     446                 :             :       // because this is used by GDB.  One further reason to prefer
     447                 :             :       // this, rather than simply emitting the integer, is that this
     448                 :             :       // approach makes it simpler to use a C-only debugger, or
     449                 :             :       // GDB's C mode, when debugging Rust.
     450                 :        9362 :       Backend::typed_identifier f ("__" + std::to_string (i), compiled_field_ty,
     451                 :        4681 :                                    ctx->get_mappings ().lookup_location (
     452                 :        9362 :                                      type.get_ty_ref ()));
     453                 :        4681 :       fields.push_back (std::move (f));
     454                 :        4681 :     }
     455                 :             : 
     456                 :        2253 :   tree struct_type_record = Backend::struct_type (fields);
     457                 :        2253 :   translated = Backend::named_type (type.as_string (), struct_type_record,
     458                 :        2253 :                                     type.get_ident ().locus);
     459                 :        2253 : }
     460                 :             : 
     461                 :             : void
     462                 :        3955 : TyTyResolveCompile::visit (const TyTy::ArrayType &type)
     463                 :             : {
     464                 :        3955 :   tree element_type
     465                 :        3955 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     466                 :             : 
     467                 :        3955 :   ctx->push_const_context ();
     468                 :             : 
     469                 :        3955 :   HIR::Expr &hir_capacity_expr = type.get_capacity_expr ();
     470                 :        3955 :   TyTy::BaseType *capacity_expr_ty = nullptr;
     471                 :        3955 :   bool ok = ctx->get_tyctx ()->lookup_type (
     472                 :        3955 :     hir_capacity_expr.get_mappings ().get_hirid (), &capacity_expr_ty);
     473                 :        3955 :   rust_assert (ok);
     474                 :        7910 :   tree capacity_expr = HIRCompileBase::compile_constant_expr (
     475                 :        3955 :     ctx, hir_capacity_expr.get_mappings ().get_hirid (), capacity_expr_ty,
     476                 :        3955 :     capacity_expr_ty, Resolver::CanonicalPath::create_empty (),
     477                 :        3955 :     hir_capacity_expr, type.get_locus (), hir_capacity_expr.get_locus ());
     478                 :             : 
     479                 :        3955 :   ctx->pop_const_context ();
     480                 :             : 
     481                 :        3955 :   tree folded_capacity_expr = fold_expr (capacity_expr);
     482                 :             : 
     483                 :        3955 :   translated = Backend::array_type (element_type, folded_capacity_expr);
     484                 :        3955 :   if (translated != error_mark_node)
     485                 :        3889 :     translated = ctx->insert_compiled_type (translated);
     486                 :        3955 : }
     487                 :             : 
     488                 :             : void
     489                 :          86 : TyTyResolveCompile::visit (const TyTy::SliceType &type)
     490                 :             : {
     491                 :          86 :   tree type_record = create_slice_type_record (type);
     492                 :             : 
     493                 :          86 :   std::string named_struct_str
     494                 :         172 :     = std::string ("[") + type.get_element_type ()->get_name () + "]";
     495                 :          86 :   translated = Backend::named_type (named_struct_str, type_record,
     496                 :          86 :                                     type.get_ident ().locus);
     497                 :          86 : }
     498                 :             : 
     499                 :             : void
     500                 :        9362 : TyTyResolveCompile::visit (const TyTy::BoolType &)
     501                 :             : {
     502                 :        9362 :   translated
     503                 :        9362 :     = Backend::named_type ("bool", boolean_type_node, BUILTINS_LOCATION);
     504                 :        9362 : }
     505                 :             : 
     506                 :             : void
     507                 :       64384 : TyTyResolveCompile::visit (const TyTy::IntType &type)
     508                 :             : {
     509                 :       64384 :   switch (type.get_int_kind ())
     510                 :             :     {
     511                 :        9221 :     case TyTy::IntType::I8:
     512                 :        9221 :       translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
     513                 :             :                                         BUILTINS_LOCATION);
     514                 :        9221 :       return;
     515                 :             : 
     516                 :        5631 :     case TyTy::IntType::I16:
     517                 :        5631 :       translated
     518                 :        5631 :         = Backend::named_type ("i16", Backend::integer_type (false, 16),
     519                 :             :                                BUILTINS_LOCATION);
     520                 :        5631 :       return;
     521                 :             : 
     522                 :       38129 :     case TyTy::IntType::I32:
     523                 :       38129 :       translated
     524                 :       38129 :         = Backend::named_type ("i32", Backend::integer_type (false, 32),
     525                 :             :                                BUILTINS_LOCATION);
     526                 :       38129 :       return;
     527                 :             : 
     528                 :        5783 :     case TyTy::IntType::I64:
     529                 :        5783 :       translated
     530                 :        5783 :         = Backend::named_type ("i64", Backend::integer_type (false, 64),
     531                 :             :                                BUILTINS_LOCATION);
     532                 :        5783 :       return;
     533                 :             : 
     534                 :        5620 :     case TyTy::IntType::I128:
     535                 :        5620 :       translated
     536                 :        5620 :         = Backend::named_type ("i128", Backend::integer_type (false, 128),
     537                 :             :                                BUILTINS_LOCATION);
     538                 :        5620 :       return;
     539                 :             :     }
     540                 :             : }
     541                 :             : 
     542                 :             : void
     543                 :       53665 : TyTyResolveCompile::visit (const TyTy::UintType &type)
     544                 :             : {
     545                 :       53665 :   switch (type.get_uint_kind ())
     546                 :             :     {
     547                 :       14960 :     case TyTy::UintType::U8:
     548                 :       14960 :       translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
     549                 :             :                                         BUILTINS_LOCATION);
     550                 :       14960 :       return;
     551                 :             : 
     552                 :        9247 :     case TyTy::UintType::U16:
     553                 :        9247 :       translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
     554                 :             :                                         BUILTINS_LOCATION);
     555                 :        9247 :       return;
     556                 :             : 
     557                 :       13134 :     case TyTy::UintType::U32:
     558                 :       13134 :       translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
     559                 :             :                                         BUILTINS_LOCATION);
     560                 :       13134 :       return;
     561                 :             : 
     562                 :       11184 :     case TyTy::UintType::U64:
     563                 :       11184 :       translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
     564                 :             :                                         BUILTINS_LOCATION);
     565                 :       11184 :       return;
     566                 :             : 
     567                 :        5140 :     case TyTy::UintType::U128:
     568                 :        5140 :       translated
     569                 :        5140 :         = Backend::named_type ("u128", Backend::integer_type (true, 128),
     570                 :             :                                BUILTINS_LOCATION);
     571                 :        5140 :       return;
     572                 :             :     }
     573                 :             : }
     574                 :             : 
     575                 :             : void
     576                 :       16134 : TyTyResolveCompile::visit (const TyTy::FloatType &type)
     577                 :             : {
     578                 :       16134 :   switch (type.get_float_kind ())
     579                 :             :     {
     580                 :        7895 :     case TyTy::FloatType::F32:
     581                 :        7895 :       translated = Backend::named_type ("f32", Backend::float_type (32),
     582                 :             :                                         BUILTINS_LOCATION);
     583                 :        7895 :       return;
     584                 :             : 
     585                 :        8239 :     case TyTy::FloatType::F64:
     586                 :        8239 :       translated = Backend::named_type ("f64", Backend::float_type (64),
     587                 :             :                                         BUILTINS_LOCATION);
     588                 :        8239 :       return;
     589                 :             :     }
     590                 :             : }
     591                 :             : 
     592                 :             : void
     593                 :       41781 : TyTyResolveCompile::visit (const TyTy::USizeType &)
     594                 :             : {
     595                 :       41781 :   translated
     596                 :       41781 :     = Backend::named_type ("usize",
     597                 :             :                            Backend::integer_type (true,
     598                 :             :                                                   Backend::get_pointer_size ()),
     599                 :             :                            BUILTINS_LOCATION);
     600                 :       41781 : }
     601                 :             : 
     602                 :             : void
     603                 :       10568 : TyTyResolveCompile::visit (const TyTy::ISizeType &)
     604                 :             : {
     605                 :       10568 :   translated
     606                 :       10568 :     = Backend::named_type ("isize",
     607                 :             :                            Backend::integer_type (false,
     608                 :             :                                                   Backend::get_pointer_size ()),
     609                 :             :                            BUILTINS_LOCATION);
     610                 :       10568 : }
     611                 :             : 
     612                 :             : void
     613                 :        5899 : TyTyResolveCompile::visit (const TyTy::CharType &)
     614                 :             : {
     615                 :        5899 :   translated
     616                 :        5899 :     = Backend::named_type ("char", Backend::wchar_type (), BUILTINS_LOCATION);
     617                 :        5899 : }
     618                 :             : 
     619                 :             : void
     620                 :       11256 : TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
     621                 :             : {
     622                 :       11256 :   const TyTy::SliceType *slice = nullptr;
     623                 :       11256 :   const TyTy::StrType *str = nullptr;
     624                 :       11256 :   const TyTy::DynamicObjectType *dyn = nullptr;
     625                 :       11256 :   if (type.is_dyn_slice_type (&slice))
     626                 :             :     {
     627                 :         502 :       tree type_record = create_slice_type_record (*slice);
     628                 :         502 :       std::string dyn_slice_type_str
     629                 :        1506 :         = std::string (type.is_mutable () ? "&mut " : "&") + "["
     630                 :        1506 :           + slice->get_element_type ()->get_name () + "]";
     631                 :             : 
     632                 :         502 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     633                 :             :                                         slice->get_locus ());
     634                 :             : 
     635                 :         502 :       return;
     636                 :         502 :     }
     637                 :       10754 :   else if (type.is_dyn_str_type (&str))
     638                 :             :     {
     639                 :        3119 :       tree type_record = create_str_type_record (*str);
     640                 :        3119 :       std::string dyn_str_type_str
     641                 :        9357 :         = std::string (type.is_mutable () ? "&mut " : "&") + "str";
     642                 :             : 
     643                 :        3119 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     644                 :             :                                         str->get_locus ());
     645                 :             : 
     646                 :        3119 :       return;
     647                 :        3119 :     }
     648                 :        7635 :   else if (type.is_dyn_obj_type (&dyn))
     649                 :             :     {
     650                 :         573 :       tree type_record = create_dyn_obj_record (*dyn);
     651                 :         573 :       std::string dyn_str_type_str
     652                 :        1146 :         = std::string (type.is_mutable () ? "&mut " : "& ") + dyn->get_name ();
     653                 :             : 
     654                 :         573 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     655                 :             :                                         dyn->get_locus ());
     656                 :             : 
     657                 :         573 :       return;
     658                 :         573 :     }
     659                 :             : 
     660                 :        7062 :   tree base_compiled_type
     661                 :        7062 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     662                 :        7062 :   if (type.is_mutable ())
     663                 :             :     {
     664                 :        1035 :       translated = Backend::reference_type (base_compiled_type);
     665                 :             :     }
     666                 :             :   else
     667                 :             :     {
     668                 :        6027 :       auto base = Backend::immutable_type (base_compiled_type);
     669                 :        6027 :       translated = Backend::reference_type (base);
     670                 :             :     }
     671                 :             : }
     672                 :             : 
     673                 :             : void
     674                 :        9665 : TyTyResolveCompile::visit (const TyTy::PointerType &type)
     675                 :             : {
     676                 :        9665 :   const TyTy::SliceType *slice = nullptr;
     677                 :        9665 :   const TyTy::StrType *str = nullptr;
     678                 :        9665 :   const TyTy::DynamicObjectType *dyn = nullptr;
     679                 :        9665 :   if (type.is_dyn_slice_type (&slice))
     680                 :             :     {
     681                 :         506 :       tree type_record = create_slice_type_record (*slice);
     682                 :         506 :       std::string dyn_slice_type_str
     683                 :        1469 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "["
     684                 :        1518 :           + slice->get_element_type ()->get_name () + "]";
     685                 :             : 
     686                 :         506 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     687                 :             :                                         slice->get_locus ());
     688                 :             : 
     689                 :         506 :       return;
     690                 :         506 :     }
     691                 :        9159 :   else if (type.is_dyn_str_type (&str))
     692                 :             :     {
     693                 :        2328 :       tree type_record = create_str_type_record (*str);
     694                 :        2328 :       std::string dyn_str_type_str
     695                 :        6984 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "str";
     696                 :             : 
     697                 :        2328 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     698                 :             :                                         str->get_locus ());
     699                 :             : 
     700                 :        2328 :       return;
     701                 :        2328 :     }
     702                 :        6831 :   else if (type.is_dyn_obj_type (&dyn))
     703                 :             :     {
     704                 :           0 :       tree type_record = create_dyn_obj_record (*dyn);
     705                 :           0 :       std::string dyn_str_type_str
     706                 :           0 :         = std::string (type.is_mutable () ? "*mut " : "*const ")
     707                 :           0 :           + dyn->get_name ();
     708                 :             : 
     709                 :           0 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     710                 :             :                                         dyn->get_locus ());
     711                 :             : 
     712                 :           0 :       return;
     713                 :           0 :     }
     714                 :             : 
     715                 :        6831 :   tree base_compiled_type
     716                 :        6831 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     717                 :        6831 :   if (type.is_mutable ())
     718                 :             :     {
     719                 :        1893 :       translated = Backend::pointer_type (base_compiled_type);
     720                 :             :     }
     721                 :             :   else
     722                 :             :     {
     723                 :        4938 :       auto base = Backend::immutable_type (base_compiled_type);
     724                 :        4938 :       translated = Backend::pointer_type (base);
     725                 :             :     }
     726                 :             : }
     727                 :             : 
     728                 :             : void
     729                 :        4916 : TyTyResolveCompile::visit (const TyTy::StrType &type)
     730                 :             : {
     731                 :        4916 :   tree raw_str = create_str_type_record (type);
     732                 :        4916 :   translated = Backend::named_type ("str", raw_str, BUILTINS_LOCATION);
     733                 :        4916 : }
     734                 :             : 
     735                 :             : void
     736                 :        5207 : TyTyResolveCompile::visit (const TyTy::NeverType &)
     737                 :             : {
     738                 :        5207 :   translated = get_unit_type (ctx);
     739                 :        5207 : }
     740                 :             : 
     741                 :             : void
     742                 :           0 : TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
     743                 :             : {
     744                 :           0 :   if (trait_object_mode)
     745                 :             :     {
     746                 :           0 :       translated = Backend::integer_type (true, Backend::get_pointer_size ());
     747                 :           0 :       return;
     748                 :             :     }
     749                 :             : 
     750                 :           0 :   tree type_record = create_dyn_obj_record (type);
     751                 :           0 :   translated = Backend::named_type (type.get_name (), type_record,
     752                 :           0 :                                     type.get_ident ().locus);
     753                 :             : }
     754                 :             : 
     755                 :             : void
     756                 :           0 : TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
     757                 :             : {
     758                 :           0 :   translated = error_mark_node;
     759                 :           0 : }
     760                 :             : 
     761                 :             : tree
     762                 :         573 : TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
     763                 :             : {
     764                 :             :   // create implicit struct
     765                 :         573 :   auto items = type.get_object_items ();
     766                 :         573 :   std::vector<Backend::typed_identifier> fields;
     767                 :             : 
     768                 :         573 :   tree uint = Backend::integer_type (true, Backend::get_pointer_size ());
     769                 :         573 :   tree uintptr_ty = build_pointer_type (uint);
     770                 :             : 
     771                 :         573 :   Backend::typed_identifier f ("pointer", uintptr_ty,
     772                 :         573 :                                ctx->get_mappings ().lookup_location (
     773                 :        1146 :                                  type.get_ty_ref ()));
     774                 :         573 :   fields.push_back (std::move (f));
     775                 :             : 
     776                 :         573 :   tree vtable_size = build_int_cst (size_type_node, items.size ());
     777                 :         573 :   tree vtable_type = Backend::array_type (uintptr_ty, vtable_size);
     778                 :         573 :   Backend::typed_identifier vtf ("vtable", vtable_type,
     779                 :         573 :                                  ctx->get_mappings ().lookup_location (
     780                 :        1146 :                                    type.get_ty_ref ()));
     781                 :         573 :   fields.push_back (std::move (vtf));
     782                 :             : 
     783                 :         573 :   tree record = Backend::struct_type (fields);
     784                 :         573 :   RS_DST_FLAG (record) = 1;
     785                 :         573 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     786                 :             : 
     787                 :         573 :   return record;
     788                 :         573 : }
     789                 :             : 
     790                 :             : tree
     791                 :        1094 : TyTyResolveCompile::create_slice_type_record (const TyTy::SliceType &type)
     792                 :             : {
     793                 :             :   // lookup usize
     794                 :        1094 :   TyTy::BaseType *usize = nullptr;
     795                 :        1094 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     796                 :        1094 :   rust_assert (ok);
     797                 :             : 
     798                 :        1094 :   tree element_type
     799                 :        1094 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     800                 :        1094 :   tree data_field_ty = build_pointer_type (element_type);
     801                 :        1094 :   Backend::typed_identifier data_field ("data", data_field_ty,
     802                 :        2188 :                                         type.get_locus ());
     803                 :             : 
     804                 :        1094 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     805                 :        2188 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     806                 :             : 
     807                 :        3282 :   tree record = Backend::struct_type ({data_field, len_field});
     808                 :        1094 :   RS_DST_FLAG (record) = 1;
     809                 :        1094 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     810                 :             : 
     811                 :        1094 :   return record;
     812                 :        1094 : }
     813                 :             : 
     814                 :             : tree
     815                 :       10363 : TyTyResolveCompile::create_str_type_record (const TyTy::StrType &type)
     816                 :             : {
     817                 :             :   // lookup usize
     818                 :       10363 :   TyTy::BaseType *usize = nullptr;
     819                 :       10363 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     820                 :       10363 :   rust_assert (ok);
     821                 :             : 
     822                 :       10363 :   tree char_ptr = build_pointer_type (char_type_node);
     823                 :       10363 :   tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
     824                 :             : 
     825                 :       10363 :   tree element_type = const_char_type;
     826                 :       10363 :   tree data_field_ty = build_pointer_type (element_type);
     827                 :       10363 :   Backend::typed_identifier data_field ("data", data_field_ty,
     828                 :       20726 :                                         type.get_locus ());
     829                 :             : 
     830                 :       10363 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     831                 :       20726 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     832                 :             : 
     833                 :       31089 :   tree record = Backend::struct_type ({data_field, len_field});
     834                 :       10363 :   RS_DST_FLAG (record) = 1;
     835                 :       10363 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     836                 :             : 
     837                 :       10363 :   return record;
     838                 :       10363 : }
     839                 :             : 
     840                 :             : } // namespace Compile
     841                 :             : } // 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.