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.7 % 410 380
Test Date: 2024-03-23 14:05:01 Functions: 83.9 % 31 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-2024 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                 :             : 
      26                 :             : namespace Rust {
      27                 :             : namespace Compile {
      28                 :             : 
      29                 :             : static const std::string RUST_ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR";
      30                 :             : 
      31                 :      181395 : TyTyResolveCompile::TyTyResolveCompile (Context *ctx, bool trait_object_mode)
      32                 :      181395 :   : ctx (ctx), trait_object_mode (trait_object_mode),
      33                 :      181395 :     translated (error_mark_node)
      34                 :      181395 : {}
      35                 :             : 
      36                 :             : tree
      37                 :      181395 : TyTyResolveCompile::compile (Context *ctx, const TyTy::BaseType *ty,
      38                 :             :                              bool trait_object_mode)
      39                 :             : {
      40                 :      181395 :   TyTyResolveCompile compiler (ctx, trait_object_mode);
      41                 :      181395 :   const TyTy::BaseType *destructured = ty->destructure ();
      42                 :      181395 :   destructured->accept_vis (compiler);
      43                 :             : 
      44                 :      181395 :   if (compiler.translated != error_mark_node
      45                 :      181395 :       && TYPE_NAME (compiler.translated) != NULL)
      46                 :             :     {
      47                 :             :       // canonicalize the type
      48                 :      160074 :       compiler.translated = ctx->insert_compiled_type (compiler.translated);
      49                 :             :     }
      50                 :             : 
      51                 :      181395 :   return compiler.translated;
      52                 :             : }
      53                 :             : 
      54                 :             : // see: gcc/c/c-decl.cc:8230-8241
      55                 :             : // https://github.com/Rust-GCC/gccrs/blob/0024bc2f028369b871a65ceb11b2fddfb0f9c3aa/gcc/c/c-decl.c#L8229-L8241
      56                 :             : tree
      57                 :        2128 : TyTyResolveCompile::get_implicit_enumeral_node_type (Context *ctx)
      58                 :             : {
      59                 :             :   // static tree enum_node = NULL_TREE;
      60                 :             :   // if (enum_node == NULL_TREE)
      61                 :             :   //   {
      62                 :             :   //     enum_node = make_node (ENUMERAL_TYPE);
      63                 :             :   //     SET_TYPE_MODE (enum_node, TYPE_MODE (unsigned_type_node));
      64                 :             :   //     SET_TYPE_ALIGN (enum_node, TYPE_ALIGN (unsigned_type_node));
      65                 :             :   //     TYPE_USER_ALIGN (enum_node) = 0;
      66                 :             :   //     TYPE_UNSIGNED (enum_node) = 1;
      67                 :             :   //     TYPE_PRECISION (enum_node) = TYPE_PRECISION (unsigned_type_node);
      68                 :             :   //     TYPE_MIN_VALUE (enum_node) = TYPE_MIN_VALUE (unsigned_type_node);
      69                 :             :   //     TYPE_MAX_VALUE (enum_node) = TYPE_MAX_VALUE (unsigned_type_node);
      70                 :             : 
      71                 :             :   //     // tree identifier = ctx->get_backend ()->get_identifier_node
      72                 :             :   //     // ("enumeral"); tree enum_decl
      73                 :             :   //     //   = build_decl (BUILTINS_LOCATION, TYPE_DECL, identifier,
      74                 :             :   //     enum_node);
      75                 :             :   //     // TYPE_NAME (enum_node) = enum_decl;
      76                 :             :   //   }
      77                 :             :   // return enum_node;
      78                 :             : 
      79                 :        2128 :   static tree enum_node = NULL_TREE;
      80                 :        2128 :   if (enum_node == NULL_TREE)
      81                 :             :     {
      82                 :             :       // equivalent to isize
      83                 :         106 :       enum_node = Backend::named_type (
      84                 :             :         "enumeral", Backend::integer_type (false, Backend::get_pointer_size ()),
      85                 :             :         BUILTINS_LOCATION);
      86                 :             :     }
      87                 :        2128 :   return enum_node;
      88                 :             : }
      89                 :             : 
      90                 :             : tree
      91                 :       19460 : TyTyResolveCompile::get_unit_type (Context *ctx)
      92                 :             : {
      93                 :       19460 :   static tree unit_type;
      94                 :       19460 :   if (unit_type == nullptr)
      95                 :             :     {
      96                 :        3313 :       auto unit_type_node = Backend::struct_type ({});
      97                 :        3313 :       unit_type = Backend::named_type ("()", unit_type_node, BUILTINS_LOCATION);
      98                 :             :     }
      99                 :       19460 :   return unit_type;
     100                 :             : }
     101                 :             : 
     102                 :             : void
     103                 :           0 : TyTyResolveCompile::visit (const TyTy::ErrorType &)
     104                 :             : {
     105                 :           0 :   translated = error_mark_node;
     106                 :           0 : }
     107                 :             : 
     108                 :             : void
     109                 :          16 : TyTyResolveCompile::visit (const TyTy::InferType &type)
     110                 :             : {
     111                 :          16 :   const TyTy::BaseType *orig = &type;
     112                 :          16 :   TyTy::BaseType *lookup = nullptr;
     113                 :          16 :   bool ok = ctx->get_tyctx ()->lookup_type (type.get_ref (), &lookup);
     114                 :          16 :   if (!ok)
     115                 :             :     {
     116                 :           0 :       translated = error_mark_node;
     117                 :           0 :       return;
     118                 :             :     }
     119                 :             : 
     120                 :          16 :   if (orig == lookup)
     121                 :             :     {
     122                 :           0 :       translated = error_mark_node;
     123                 :           0 :       return;
     124                 :             :     }
     125                 :             : 
     126                 :          16 :   translated = TyTyResolveCompile::compile (ctx, lookup);
     127                 :             : }
     128                 :             : 
     129                 :             : void
     130                 :           0 : TyTyResolveCompile::visit (const TyTy::ParamType &)
     131                 :             : {
     132                 :           0 :   translated = error_mark_node;
     133                 :           0 : }
     134                 :             : 
     135                 :             : void
     136                 :           0 : TyTyResolveCompile::visit (const TyTy::ProjectionType &type)
     137                 :             : {
     138                 :           0 :   translated = error_mark_node;
     139                 :           0 : }
     140                 :             : 
     141                 :             : void
     142                 :           0 : TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
     143                 :             : {
     144                 :           0 :   translated = error_mark_node;
     145                 :           0 : }
     146                 :             : 
     147                 :             : void
     148                 :         181 : TyTyResolveCompile::visit (const TyTy::ClosureType &type)
     149                 :             : {
     150                 :         181 :   auto mappings = ctx->get_mappings ();
     151                 :             : 
     152                 :         181 :   std::vector<Backend::typed_identifier> fields;
     153                 :             : 
     154                 :         181 :   size_t i = 0;
     155                 :         216 :   for (const auto &capture : type.get_captures ())
     156                 :             :     {
     157                 :             :       // lookup the HirId
     158                 :          35 :       HirId ref = UNKNOWN_HIRID;
     159                 :          35 :       bool ok = mappings->lookup_node_to_hir (capture, &ref);
     160                 :          35 :       rust_assert (ok);
     161                 :             : 
     162                 :             :       // lookup the var decl type
     163                 :          35 :       TyTy::BaseType *lookup = nullptr;
     164                 :          35 :       bool found = ctx->get_tyctx ()->lookup_type (ref, &lookup);
     165                 :          35 :       rust_assert (found);
     166                 :             : 
     167                 :             :       // FIXME get the var pattern name
     168                 :          35 :       std::string mappings_name = "capture_" + std::to_string (i);
     169                 :             : 
     170                 :             :       // FIXME
     171                 :             :       // this should be based on the closure move-ability
     172                 :          35 :       tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
     173                 :          35 :       tree capture_type = build_reference_type (decl_type);
     174                 :          35 :       fields.push_back (Backend::typed_identifier (mappings_name, capture_type,
     175                 :          35 :                                                    type.get_ident ().locus));
     176                 :          35 :     }
     177                 :             : 
     178                 :         181 :   tree type_record = Backend::struct_type (fields);
     179                 :         181 :   RS_CLOSURE_FLAG (type_record) = 1;
     180                 :             : 
     181                 :         181 :   std::string named_struct_str
     182                 :         362 :     = type.get_ident ().path.get () + "::{{closure}}";
     183                 :         181 :   translated = Backend::named_type (named_struct_str, type_record,
     184                 :         181 :                                     type.get_ident ().locus);
     185                 :         181 : }
     186                 :             : 
     187                 :             : void
     188                 :       10547 : TyTyResolveCompile::visit (const TyTy::FnType &type)
     189                 :             : {
     190                 :       10547 :   Backend::typed_identifier receiver;
     191                 :       10547 :   std::vector<Backend::typed_identifier> parameters;
     192                 :       10547 :   std::vector<Backend::typed_identifier> results;
     193                 :             : 
     194                 :             :   // we can only return unit-type if its not the C ABI because it will expect
     195                 :             :   // void
     196                 :       10547 :   auto hir_type = type.get_return_type ()->destructure ();
     197                 :       10547 :   bool return_is_unit = hir_type->is_unit ();
     198                 :       10547 :   bool is_c_abi = type.get_abi () == ABI::C;
     199                 :       10547 :   bool should_be_void = is_c_abi && return_is_unit;
     200                 :       10547 :   if (!should_be_void)
     201                 :             :     {
     202                 :        9821 :       auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
     203                 :        9821 :       location_t return_type_locus
     204                 :        9821 :         = ctx->get_mappings ()->lookup_location (hir_type->get_ref ());
     205                 :       19642 :       results.push_back (
     206                 :       19642 :         Backend::typed_identifier ("_", ret, return_type_locus));
     207                 :             :     }
     208                 :             : 
     209                 :       18135 :   for (auto &param_pair : type.get_params ())
     210                 :             :     {
     211                 :        7588 :       auto param_tyty = param_pair.second;
     212                 :        7588 :       auto compiled_param_type
     213                 :        7588 :         = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
     214                 :             : 
     215                 :        7588 :       auto compiled_param = Backend::typed_identifier (
     216                 :        7588 :         param_pair.first->as_string (), compiled_param_type,
     217                 :       15176 :         ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()));
     218                 :             : 
     219                 :        7588 :       parameters.push_back (compiled_param);
     220                 :        7588 :     }
     221                 :             : 
     222                 :       10547 :   if (!type.is_variadic ())
     223                 :        9850 :     translated = Backend::function_type (receiver, parameters, results, NULL,
     224                 :        9850 :                                          type.get_ident ().locus);
     225                 :             :   else
     226                 :         697 :     translated
     227                 :         697 :       = Backend::function_type_variadic (receiver, parameters, results, NULL,
     228                 :         697 :                                          type.get_ident ().locus);
     229                 :       10547 : }
     230                 :             : 
     231                 :             : void
     232                 :          45 : TyTyResolveCompile::visit (const TyTy::FnPtr &type)
     233                 :             : {
     234                 :          45 :   tree result_type = TyTyResolveCompile::compile (ctx, type.get_return_type ());
     235                 :             : 
     236                 :          45 :   std::vector<tree> parameters;
     237                 :             : 
     238                 :          45 :   auto &params = type.get_params ();
     239                 :          84 :   for (auto &p : params)
     240                 :             :     {
     241                 :          39 :       tree pty = TyTyResolveCompile::compile (ctx, p.get_tyty ());
     242                 :          39 :       parameters.push_back (pty);
     243                 :             :     }
     244                 :             : 
     245                 :         135 :   translated = Backend::function_ptr_type (result_type, parameters,
     246                 :          45 :                                            type.get_ident ().locus);
     247                 :          45 : }
     248                 :             : 
     249                 :             : void
     250                 :        7503 : TyTyResolveCompile::visit (const TyTy::ADTType &type)
     251                 :             : {
     252                 :        7503 :   tree type_record = error_mark_node;
     253                 :        7503 :   if (!type.is_enum ())
     254                 :             :     {
     255                 :        6662 :       rust_assert (type.number_of_variants () == 1);
     256                 :             : 
     257                 :        6662 :       TyTy::VariantDef &variant = *type.get_variants ().at (0);
     258                 :        6662 :       std::vector<Backend::typed_identifier> fields;
     259                 :       20090 :       for (size_t i = 0; i < variant.num_fields (); i++)
     260                 :             :         {
     261                 :       13428 :           const TyTy::StructFieldType *field = variant.get_field_at_index (i);
     262                 :       13428 :           tree compiled_field_ty
     263                 :       13428 :             = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     264                 :             : 
     265                 :       13428 :           Backend::typed_identifier f (field->get_name (), compiled_field_ty,
     266                 :       13428 :                                        ctx->get_mappings ()->lookup_location (
     267                 :       26856 :                                          type.get_ty_ref ()));
     268                 :       13428 :           fields.push_back (std::move (f));
     269                 :       13428 :         }
     270                 :             : 
     271                 :        6662 :       type_record = type.is_union () ? Backend::union_type (fields)
     272                 :        6509 :                                      : Backend::struct_type (fields);
     273                 :        6662 :     }
     274                 :             :   else
     275                 :             :     {
     276                 :             :       // see:
     277                 :             :       // https://github.com/bminor/binutils-gdb/blob/527b8861cd472385fa9160a91dd6d65a25c41987/gdb/dwarf2/read.c#L9010-L9241
     278                 :             :       //
     279                 :             :       // enums are actually a big union so for example the rust enum:
     280                 :             :       //
     281                 :             :       // enum AnEnum {
     282                 :             :       //   A,
     283                 :             :       //   B,
     284                 :             :       //   C (char),
     285                 :             :       //   D { x: i64, y: i64 },
     286                 :             :       // }
     287                 :             :       //
     288                 :             :       // we actually turn this into
     289                 :             :       //
     290                 :             :       // union {
     291                 :             :       //   struct A { int RUST$ENUM$DISR; }; <- this is a data-less variant
     292                 :             :       //   struct B { int RUST$ENUM$DISR; }; <- this is a data-less variant
     293                 :             :       //   struct C { int RUST$ENUM$DISR; char __0; };
     294                 :             :       //   struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
     295                 :             :       // }
     296                 :             :       //
     297                 :             :       // Ada, qual_union_types might still work for this but I am not 100% sure.
     298                 :             :       // I ran into some issues lets reuse our normal union and ask Ada people
     299                 :             :       // about it.
     300                 :             : 
     301                 :         841 :       std::vector<tree> variant_records;
     302                 :        2969 :       for (auto &variant : type.get_variants ())
     303                 :             :         {
     304                 :        2128 :           std::vector<Backend::typed_identifier> fields;
     305                 :             : 
     306                 :             :           // add in the qualifier field for the variant
     307                 :        2128 :           tree enumeral_type
     308                 :        2128 :             = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx);
     309                 :        2128 :           Backend::typed_identifier f (RUST_ENUM_DISR_FIELD_NAME, enumeral_type,
     310                 :        2128 :                                        ctx->get_mappings ()->lookup_location (
     311                 :        2128 :                                          variant->get_id ()));
     312                 :        2128 :           fields.push_back (std::move (f));
     313                 :             : 
     314                 :             :           // compile the rest of the fields
     315                 :        3453 :           for (size_t i = 0; i < variant->num_fields (); i++)
     316                 :             :             {
     317                 :        1325 :               const TyTy::StructFieldType *field
     318                 :        1325 :                 = variant->get_field_at_index (i);
     319                 :        1325 :               tree compiled_field_ty
     320                 :        1325 :                 = TyTyResolveCompile::compile (ctx, field->get_field_type ());
     321                 :             : 
     322                 :        1325 :               std::string field_name = field->get_name ();
     323                 :        1325 :               if (variant->get_variant_type ()
     324                 :             :                   == TyTy::VariantDef::VariantType::TUPLE)
     325                 :         821 :                 field_name = "__" + field->get_name ();
     326                 :             : 
     327                 :        1325 :               Backend::typed_identifier f (
     328                 :             :                 field_name, compiled_field_ty,
     329                 :        1325 :                 ctx->get_mappings ()->lookup_location (type.get_ty_ref ()));
     330                 :        1325 :               fields.push_back (std::move (f));
     331                 :        1325 :             }
     332                 :             : 
     333                 :        2128 :           tree variant_record = Backend::struct_type (fields);
     334                 :        2128 :           tree named_variant_record
     335                 :        2128 :             = Backend::named_type (variant->get_ident ().path.get (),
     336                 :        4256 :                                    variant_record, variant->get_ident ().locus);
     337                 :             : 
     338                 :             :           // set the qualifier to be a builtin
     339                 :        2128 :           DECL_ARTIFICIAL (TYPE_FIELDS (variant_record)) = 1;
     340                 :             : 
     341                 :             :           // add them to the list
     342                 :        2128 :           variant_records.push_back (named_variant_record);
     343                 :        2128 :         }
     344                 :             : 
     345                 :             :       // now we need to make the actual union, but first we need to make
     346                 :             :       // named_type TYPE_DECL's out of the variants
     347                 :             : 
     348                 :         841 :       size_t i = 0;
     349                 :         841 :       std::vector<Backend::typed_identifier> enum_fields;
     350                 :        2969 :       for (auto &variant_record : variant_records)
     351                 :             :         {
     352                 :        2128 :           TyTy::VariantDef *variant = type.get_variants ().at (i++);
     353                 :        2128 :           std::string implicit_variant_name = variant->get_identifier ();
     354                 :             : 
     355                 :        2128 :           Backend::typed_identifier f (implicit_variant_name, variant_record,
     356                 :        2128 :                                        ctx->get_mappings ()->lookup_location (
     357                 :        2128 :                                          type.get_ty_ref ()));
     358                 :        2128 :           enum_fields.push_back (std::move (f));
     359                 :        2128 :         }
     360                 :             : 
     361                 :             :       // finally make the union or the enum
     362                 :         841 :       type_record = Backend::union_type (enum_fields);
     363                 :         841 :     }
     364                 :             : 
     365                 :             :   // Handle repr options
     366                 :             :   // TODO: "packed" should only narrow type alignment and "align" should only
     367                 :             :   // widen it. Do we need to check and enforce this here, or is it taken care of
     368                 :             :   // later on in the gcc middle-end?
     369                 :        7503 :   TyTy::ADTType::ReprOptions repr = type.get_repr_options ();
     370                 :        7503 :   if (repr.pack)
     371                 :             :     {
     372                 :           8 :       TYPE_PACKED (type_record) = 1;
     373                 :           8 :       if (repr.pack > 1)
     374                 :             :         {
     375                 :           4 :           SET_TYPE_ALIGN (type_record, repr.pack * 8);
     376                 :           4 :           TYPE_USER_ALIGN (type_record) = 1;
     377                 :             :         }
     378                 :             :     }
     379                 :        7495 :   else if (repr.align)
     380                 :             :     {
     381                 :           8 :       SET_TYPE_ALIGN (type_record, repr.align * 8);
     382                 :           8 :       TYPE_USER_ALIGN (type_record) = 1;
     383                 :             :     }
     384                 :             : 
     385                 :        7503 :   std::string named_struct_str
     386                 :        7503 :     = type.get_ident ().path.get () + type.subst_as_string ();
     387                 :        7503 :   translated = Backend::named_type (named_struct_str, type_record,
     388                 :        7503 :                                     type.get_ident ().locus);
     389                 :        7503 : }
     390                 :             : 
     391                 :             : void
     392                 :       12478 : TyTyResolveCompile::visit (const TyTy::TupleType &type)
     393                 :             : {
     394                 :       12478 :   if (type.num_fields () == 0)
     395                 :             :     {
     396                 :       11222 :       translated = get_unit_type (ctx);
     397                 :       11222 :       return;
     398                 :             :     }
     399                 :             : 
     400                 :             :   // create implicit struct
     401                 :        1256 :   std::vector<Backend::typed_identifier> fields;
     402                 :        3921 :   for (size_t i = 0; i < type.num_fields (); i++)
     403                 :             :     {
     404                 :        2665 :       TyTy::BaseType *field = type.get_field (i);
     405                 :        2665 :       tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
     406                 :             : 
     407                 :             :       // rustc uses the convention __N, where N is an integer, to
     408                 :             :       // name the fields of a tuple.  We follow this as well,
     409                 :             :       // because this is used by GDB.  One further reason to prefer
     410                 :             :       // this, rather than simply emitting the integer, is that this
     411                 :             :       // approach makes it simpler to use a C-only debugger, or
     412                 :             :       // GDB's C mode, when debugging Rust.
     413                 :        5330 :       Backend::typed_identifier f ("__" + std::to_string (i), compiled_field_ty,
     414                 :        2665 :                                    ctx->get_mappings ()->lookup_location (
     415                 :        5330 :                                      type.get_ty_ref ()));
     416                 :        2665 :       fields.push_back (std::move (f));
     417                 :        2665 :     }
     418                 :             : 
     419                 :        1256 :   tree struct_type_record = Backend::struct_type (fields);
     420                 :        1256 :   translated = Backend::named_type (type.as_string (), struct_type_record,
     421                 :        1256 :                                     type.get_ident ().locus);
     422                 :        1256 : }
     423                 :             : 
     424                 :             : void
     425                 :        2337 : TyTyResolveCompile::visit (const TyTy::ArrayType &type)
     426                 :             : {
     427                 :        2337 :   tree element_type
     428                 :        2337 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     429                 :             : 
     430                 :        2337 :   ctx->push_const_context ();
     431                 :        2337 :   tree capacity_expr = CompileExpr::Compile (&type.get_capacity_expr (), ctx);
     432                 :        2337 :   ctx->pop_const_context ();
     433                 :             : 
     434                 :        2337 :   tree folded_capacity_expr = fold_expr (capacity_expr);
     435                 :             : 
     436                 :        2337 :   translated = Backend::array_type (element_type, folded_capacity_expr);
     437                 :        2337 : }
     438                 :             : 
     439                 :             : void
     440                 :          73 : TyTyResolveCompile::visit (const TyTy::SliceType &type)
     441                 :             : {
     442                 :          73 :   tree type_record = create_slice_type_record (type);
     443                 :             : 
     444                 :          73 :   std::string named_struct_str
     445                 :         146 :     = std::string ("[") + type.get_element_type ()->get_name () + "]";
     446                 :          73 :   translated = Backend::named_type (named_struct_str, type_record,
     447                 :          73 :                                     type.get_ident ().locus);
     448                 :          73 : }
     449                 :             : 
     450                 :             : void
     451                 :        6160 : TyTyResolveCompile::visit (const TyTy::BoolType &)
     452                 :             : {
     453                 :        6160 :   translated
     454                 :        6160 :     = Backend::named_type ("bool", boolean_type_node, BUILTINS_LOCATION);
     455                 :        6160 : }
     456                 :             : 
     457                 :             : void
     458                 :       48687 : TyTyResolveCompile::visit (const TyTy::IntType &type)
     459                 :             : {
     460                 :       48687 :   switch (type.get_int_kind ())
     461                 :             :     {
     462                 :        6954 :     case TyTy::IntType::I8:
     463                 :        6954 :       translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
     464                 :             :                                         BUILTINS_LOCATION);
     465                 :        6954 :       return;
     466                 :             : 
     467                 :        3811 :     case TyTy::IntType::I16:
     468                 :        3811 :       translated
     469                 :        3811 :         = Backend::named_type ("i16", Backend::integer_type (false, 16),
     470                 :             :                                BUILTINS_LOCATION);
     471                 :        3811 :       return;
     472                 :             : 
     473                 :       30115 :     case TyTy::IntType::I32:
     474                 :       30115 :       translated
     475                 :       30115 :         = Backend::named_type ("i32", Backend::integer_type (false, 32),
     476                 :             :                                BUILTINS_LOCATION);
     477                 :       30115 :       return;
     478                 :             : 
     479                 :        3927 :     case TyTy::IntType::I64:
     480                 :        3927 :       translated
     481                 :        3927 :         = Backend::named_type ("i64", Backend::integer_type (false, 64),
     482                 :             :                                BUILTINS_LOCATION);
     483                 :        3927 :       return;
     484                 :             : 
     485                 :        3880 :     case TyTy::IntType::I128:
     486                 :        3880 :       translated
     487                 :        3880 :         = Backend::named_type ("i128", Backend::integer_type (false, 128),
     488                 :             :                                BUILTINS_LOCATION);
     489                 :        3880 :       return;
     490                 :             :     }
     491                 :             : }
     492                 :             : 
     493                 :             : void
     494                 :       29963 : TyTyResolveCompile::visit (const TyTy::UintType &type)
     495                 :             : {
     496                 :       29963 :   switch (type.get_uint_kind ())
     497                 :             :     {
     498                 :        8114 :     case TyTy::UintType::U8:
     499                 :        8114 :       translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
     500                 :             :                                         BUILTINS_LOCATION);
     501                 :        8114 :       return;
     502                 :             : 
     503                 :        5202 :     case TyTy::UintType::U16:
     504                 :        5202 :       translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
     505                 :             :                                         BUILTINS_LOCATION);
     506                 :        5202 :       return;
     507                 :             : 
     508                 :        7349 :     case TyTy::UintType::U32:
     509                 :        7349 :       translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
     510                 :             :                                         BUILTINS_LOCATION);
     511                 :        7349 :       return;
     512                 :             : 
     513                 :        5810 :     case TyTy::UintType::U64:
     514                 :        5810 :       translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
     515                 :             :                                         BUILTINS_LOCATION);
     516                 :        5810 :       return;
     517                 :             : 
     518                 :        3488 :     case TyTy::UintType::U128:
     519                 :        3488 :       translated
     520                 :        3488 :         = Backend::named_type ("u128", Backend::integer_type (true, 128),
     521                 :             :                                BUILTINS_LOCATION);
     522                 :        3488 :       return;
     523                 :             :     }
     524                 :             : }
     525                 :             : 
     526                 :             : void
     527                 :       11418 : TyTyResolveCompile::visit (const TyTy::FloatType &type)
     528                 :             : {
     529                 :       11418 :   switch (type.get_float_kind ())
     530                 :             :     {
     531                 :        5549 :     case TyTy::FloatType::F32:
     532                 :        5549 :       translated = Backend::named_type ("f32", Backend::float_type (32),
     533                 :             :                                         BUILTINS_LOCATION);
     534                 :        5549 :       return;
     535                 :             : 
     536                 :        5869 :     case TyTy::FloatType::F64:
     537                 :        5869 :       translated = Backend::named_type ("f64", Backend::float_type (64),
     538                 :             :                                         BUILTINS_LOCATION);
     539                 :        5869 :       return;
     540                 :             :     }
     541                 :             : }
     542                 :             : 
     543                 :             : void
     544                 :       21863 : TyTyResolveCompile::visit (const TyTy::USizeType &)
     545                 :             : {
     546                 :       21863 :   translated
     547                 :       21863 :     = Backend::named_type ("usize",
     548                 :             :                            Backend::integer_type (true,
     549                 :             :                                                   Backend::get_pointer_size ()),
     550                 :             :                            BUILTINS_LOCATION);
     551                 :       21863 : }
     552                 :             : 
     553                 :             : void
     554                 :        5059 : TyTyResolveCompile::visit (const TyTy::ISizeType &)
     555                 :             : {
     556                 :        5059 :   translated
     557                 :        5059 :     = Backend::named_type ("isize",
     558                 :             :                            Backend::integer_type (false,
     559                 :             :                                                   Backend::get_pointer_size ()),
     560                 :             :                            BUILTINS_LOCATION);
     561                 :        5059 : }
     562                 :             : 
     563                 :             : void
     564                 :        4101 : TyTyResolveCompile::visit (const TyTy::CharType &)
     565                 :             : {
     566                 :        4101 :   translated
     567                 :        4101 :     = Backend::named_type ("char", Backend::wchar_type (), BUILTINS_LOCATION);
     568                 :        4101 : }
     569                 :             : 
     570                 :             : void
     571                 :        6950 : TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
     572                 :             : {
     573                 :        6950 :   const TyTy::SliceType *slice = nullptr;
     574                 :        6950 :   const TyTy::StrType *str = nullptr;
     575                 :        6950 :   const TyTy::DynamicObjectType *dyn = nullptr;
     576                 :        6950 :   if (type.is_dyn_slice_type (&slice))
     577                 :             :     {
     578                 :         463 :       tree type_record = create_slice_type_record (*slice);
     579                 :         463 :       std::string dyn_slice_type_str
     580                 :        1389 :         = std::string (type.is_mutable () ? "&mut " : "&") + "["
     581                 :        1389 :           + slice->get_element_type ()->get_name () + "]";
     582                 :             : 
     583                 :         463 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     584                 :             :                                         slice->get_locus ());
     585                 :             : 
     586                 :         463 :       return;
     587                 :         463 :     }
     588                 :        6487 :   else if (type.is_dyn_str_type (&str))
     589                 :             :     {
     590                 :        2526 :       tree type_record = create_str_type_record (*str);
     591                 :        2526 :       std::string dyn_str_type_str
     592                 :        7578 :         = std::string (type.is_mutable () ? "&mut " : "&") + "str";
     593                 :             : 
     594                 :        2526 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     595                 :             :                                         str->get_locus ());
     596                 :             : 
     597                 :        2526 :       return;
     598                 :        2526 :     }
     599                 :        3961 :   else if (type.is_dyn_obj_type (&dyn))
     600                 :             :     {
     601                 :         342 :       tree type_record = create_dyn_obj_record (*dyn);
     602                 :         342 :       std::string dyn_str_type_str
     603                 :         684 :         = std::string (type.is_mutable () ? "&mut " : "& ") + dyn->get_name ();
     604                 :             : 
     605                 :         342 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     606                 :             :                                         dyn->get_locus ());
     607                 :             : 
     608                 :         342 :       return;
     609                 :         342 :     }
     610                 :             : 
     611                 :        3619 :   tree base_compiled_type
     612                 :        3619 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     613                 :        3619 :   if (type.is_mutable ())
     614                 :             :     {
     615                 :         325 :       translated = Backend::reference_type (base_compiled_type);
     616                 :             :     }
     617                 :             :   else
     618                 :             :     {
     619                 :        3294 :       auto base = Backend::immutable_type (base_compiled_type);
     620                 :        3294 :       translated = Backend::reference_type (base);
     621                 :             :     }
     622                 :             : }
     623                 :             : 
     624                 :             : void
     625                 :        7275 : TyTyResolveCompile::visit (const TyTy::PointerType &type)
     626                 :             : {
     627                 :        7275 :   const TyTy::SliceType *slice = nullptr;
     628                 :        7275 :   const TyTy::StrType *str = nullptr;
     629                 :        7275 :   const TyTy::DynamicObjectType *dyn = nullptr;
     630                 :        7275 :   if (type.is_dyn_slice_type (&slice))
     631                 :             :     {
     632                 :         505 :       tree type_record = create_slice_type_record (*slice);
     633                 :         505 :       std::string dyn_slice_type_str
     634                 :        1466 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "["
     635                 :        1515 :           + slice->get_element_type ()->get_name () + "]";
     636                 :             : 
     637                 :         505 :       translated = Backend::named_type (dyn_slice_type_str, type_record,
     638                 :             :                                         slice->get_locus ());
     639                 :             : 
     640                 :         505 :       return;
     641                 :         505 :     }
     642                 :        6770 :   else if (type.is_dyn_str_type (&str))
     643                 :             :     {
     644                 :        1997 :       tree type_record = create_str_type_record (*str);
     645                 :        1997 :       std::string dyn_str_type_str
     646                 :        5991 :         = std::string (type.is_mutable () ? "*mut " : "*const ") + "str";
     647                 :             : 
     648                 :        1997 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     649                 :             :                                         str->get_locus ());
     650                 :             : 
     651                 :        1997 :       return;
     652                 :        1997 :     }
     653                 :        4773 :   else if (type.is_dyn_obj_type (&dyn))
     654                 :             :     {
     655                 :           0 :       tree type_record = create_dyn_obj_record (*dyn);
     656                 :           0 :       std::string dyn_str_type_str
     657                 :           0 :         = std::string (type.is_mutable () ? "*mut " : "*const ")
     658                 :           0 :           + dyn->get_name ();
     659                 :             : 
     660                 :           0 :       translated = Backend::named_type (dyn_str_type_str, type_record,
     661                 :             :                                         dyn->get_locus ());
     662                 :             : 
     663                 :           0 :       return;
     664                 :           0 :     }
     665                 :             : 
     666                 :        4773 :   tree base_compiled_type
     667                 :        4773 :     = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
     668                 :        4773 :   if (type.is_mutable ())
     669                 :             :     {
     670                 :         722 :       translated = Backend::pointer_type (base_compiled_type);
     671                 :             :     }
     672                 :             :   else
     673                 :             :     {
     674                 :        4051 :       auto base = Backend::immutable_type (base_compiled_type);
     675                 :        4051 :       translated = Backend::pointer_type (base);
     676                 :             :     }
     677                 :             : }
     678                 :             : 
     679                 :             : void
     680                 :        3313 : TyTyResolveCompile::visit (const TyTy::StrType &type)
     681                 :             : {
     682                 :        3313 :   tree raw_str = create_str_type_record (type);
     683                 :        3313 :   translated = Backend::named_type ("str", raw_str, BUILTINS_LOCATION);
     684                 :        3313 : }
     685                 :             : 
     686                 :             : void
     687                 :        3426 : TyTyResolveCompile::visit (const TyTy::NeverType &)
     688                 :             : {
     689                 :        3426 :   translated = get_unit_type (ctx);
     690                 :        3426 : }
     691                 :             : 
     692                 :             : void
     693                 :           0 : TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
     694                 :             : {
     695                 :           0 :   if (trait_object_mode)
     696                 :             :     {
     697                 :           0 :       translated = Backend::integer_type (true, Backend::get_pointer_size ());
     698                 :           0 :       return;
     699                 :             :     }
     700                 :             : 
     701                 :           0 :   tree type_record = create_dyn_obj_record (type);
     702                 :           0 :   translated = Backend::named_type (type.get_name (), type_record,
     703                 :           0 :                                     type.get_ident ().locus);
     704                 :             : }
     705                 :             : 
     706                 :             : tree
     707                 :         342 : TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
     708                 :             : {
     709                 :             :   // create implicit struct
     710                 :         342 :   auto items = type.get_object_items ();
     711                 :         342 :   std::vector<Backend::typed_identifier> fields;
     712                 :             : 
     713                 :         342 :   tree uint = Backend::integer_type (true, Backend::get_pointer_size ());
     714                 :         342 :   tree uintptr_ty = build_pointer_type (uint);
     715                 :             : 
     716                 :         342 :   Backend::typed_identifier f ("pointer", uintptr_ty,
     717                 :         342 :                                ctx->get_mappings ()->lookup_location (
     718                 :         342 :                                  type.get_ty_ref ()));
     719                 :         342 :   fields.push_back (std::move (f));
     720                 :             : 
     721                 :         342 :   tree vtable_size = build_int_cst (size_type_node, items.size ());
     722                 :         342 :   tree vtable_type = Backend::array_type (uintptr_ty, vtable_size);
     723                 :         342 :   Backend::typed_identifier vtf ("vtable", vtable_type,
     724                 :         342 :                                  ctx->get_mappings ()->lookup_location (
     725                 :         342 :                                    type.get_ty_ref ()));
     726                 :         342 :   fields.push_back (std::move (vtf));
     727                 :             : 
     728                 :         342 :   tree record = Backend::struct_type (fields);
     729                 :         342 :   RS_DST_FLAG (record) = 1;
     730                 :         342 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     731                 :             : 
     732                 :         342 :   return record;
     733                 :         342 : }
     734                 :             : 
     735                 :             : tree
     736                 :        1041 : TyTyResolveCompile::create_slice_type_record (const TyTy::SliceType &type)
     737                 :             : {
     738                 :             :   // lookup usize
     739                 :        1041 :   TyTy::BaseType *usize = nullptr;
     740                 :        1041 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     741                 :        1041 :   rust_assert (ok);
     742                 :             : 
     743                 :        1041 :   tree element_type
     744                 :        1041 :     = TyTyResolveCompile::compile (ctx, type.get_element_type ());
     745                 :        1041 :   tree data_field_ty = build_pointer_type (element_type);
     746                 :        1041 :   Backend::typed_identifier data_field ("data", data_field_ty,
     747                 :        1041 :                                         type.get_locus ());
     748                 :             : 
     749                 :        1041 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     750                 :        1041 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     751                 :             : 
     752                 :        3123 :   tree record = Backend::struct_type ({data_field, len_field});
     753                 :        1041 :   RS_DST_FLAG (record) = 1;
     754                 :        1041 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     755                 :             : 
     756                 :        1041 :   return record;
     757                 :        1041 : }
     758                 :             : 
     759                 :             : tree
     760                 :        7836 : TyTyResolveCompile::create_str_type_record (const TyTy::StrType &type)
     761                 :             : {
     762                 :             :   // lookup usize
     763                 :        7836 :   TyTy::BaseType *usize = nullptr;
     764                 :        7836 :   bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
     765                 :        7836 :   rust_assert (ok);
     766                 :             : 
     767                 :        7836 :   tree char_ptr = build_pointer_type (char_type_node);
     768                 :        7836 :   tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
     769                 :             : 
     770                 :        7836 :   tree element_type = const_char_type;
     771                 :        7836 :   tree data_field_ty = build_pointer_type (element_type);
     772                 :        7836 :   Backend::typed_identifier data_field ("data", data_field_ty,
     773                 :        7836 :                                         type.get_locus ());
     774                 :             : 
     775                 :        7836 :   tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
     776                 :        7836 :   Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
     777                 :             : 
     778                 :       23508 :   tree record = Backend::struct_type ({data_field, len_field});
     779                 :        7836 :   RS_DST_FLAG (record) = 1;
     780                 :        7836 :   TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
     781                 :             : 
     782                 :        7836 :   return record;
     783                 :        7836 : }
     784                 :             : 
     785                 :             : } // namespace Compile
     786                 :             : } // namespace Rust
        

Generated by: LCOV version 2.0-1

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.