public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Refactor TyTy::ResolveCompile pass to be in its own file
@ 2022-06-08 11:56 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:40aae6224b1bab4825b11a1d16ea73ba52a04d6b

commit 40aae6224b1bab4825b11a1d16ea73ba52a04d6b
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Tue Dec 14 11:56:12 2021 +0000

    Refactor TyTy::ResolveCompile pass to be in its own file
    
    This name likely needs refactored, this class is used to take TyTy types
    and compile them down to GCC tree's but take into account that we may have
    already compiled this type before so to preserve the canonical types we
    "resolve" the type if possible and then compile.

Diff:
---
 gcc/rust/Make-lang.in                   |   1 +
 gcc/rust/backend/rust-compile-base.h    |   1 +
 gcc/rust/backend/rust-compile-context.h | 344 -----------------------------
 gcc/rust/backend/rust-compile-type.cc   | 371 ++++++++++++++++++++++++++++++++
 gcc/rust/backend/rust-compile-type.h    |  79 +++++++
 5 files changed, 452 insertions(+), 344 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 6aaa0fc3227..3a5e7cc2724 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -93,6 +93,7 @@ GRS_OBJS = \
     rust/rust-compile-intrinsic.o \
     rust/rust-base62.o \
     rust/rust-compile-expr.o \
+    rust/rust-compile-type.o \
     $(END)
 # removed object files from here
 
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index af0ea408ccd..ed6bba4dc3c 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -18,6 +18,7 @@
 #define RUST_COMPILE_BASE
 
 #include "rust-compile-context.h"
+#include "rust-compile-type.h"
 #include "rust-hir-visitor.h"
 #include "rust-hir-full.h"
 
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 668e8ba8f52..6347e766f97 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -334,350 +334,6 @@ private:
   std::vector<tree> func_decls;
 };
 
-class TyTyResolveCompile : public TyTy::TyConstVisitor
-{
-public:
-  static tree compile (Context *ctx, const TyTy::BaseType *ty,
-		       bool trait_object_mode = false)
-  {
-    TyTyResolveCompile compiler (ctx, trait_object_mode);
-    ty->accept_vis (compiler);
-    return compiler.translated;
-  }
-
-  void visit (const TyTy::ErrorType &) override { gcc_unreachable (); }
-  void visit (const TyTy::InferType &) override { gcc_unreachable (); }
-
-  void visit (const TyTy::ProjectionType &type) override
-  {
-    type.get ()->accept_vis (*this);
-  }
-
-  void visit (const TyTy::PlaceholderType &type) override
-  {
-    type.resolve ()->accept_vis (*this);
-  }
-
-  void visit (const TyTy::ParamType &param) override
-  {
-    recursion_count++;
-    rust_assert (recursion_count < kDefaultRecusionLimit);
-
-    param.resolve ()->accept_vis (*this);
-  }
-
-  void visit (const TyTy::FnType &type) override
-  {
-    Backend::typed_identifier receiver;
-    std::vector<Backend::typed_identifier> parameters;
-    std::vector<Backend::typed_identifier> results;
-
-    if (!type.get_return_type ()->is_unit ())
-      {
-	auto hir_type = type.get_return_type ();
-	auto ret
-	  = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
-	results.push_back (Backend::typed_identifier (
-	  "_", ret,
-	  ctx->get_mappings ()->lookup_location (hir_type->get_ref ())));
-      }
-
-    for (auto &param_pair : type.get_params ())
-      {
-	auto param_tyty = param_pair.second;
-	auto compiled_param_type
-	  = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
-
-	auto compiled_param = Backend::typed_identifier (
-	  param_pair.first->as_string (), compiled_param_type,
-	  ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()));
-
-	parameters.push_back (compiled_param);
-      }
-
-    if (!type.is_varadic ())
-      translated = ctx->get_backend ()->function_type (
-	receiver, parameters, results, NULL,
-	ctx->get_mappings ()->lookup_location (type.get_ref ()));
-    else
-      translated = ctx->get_backend ()->function_type_varadic (
-	receiver, parameters, results, NULL,
-	ctx->get_mappings ()->lookup_location (type.get_ref ()));
-  }
-
-  void visit (const TyTy::FnPtr &type) override
-  {
-    tree result_type
-      = TyTyResolveCompile::compile (ctx, type.get_return_type ());
-
-    std::vector<tree> parameters;
-    type.iterate_params ([&] (TyTy::BaseType *p) mutable -> bool {
-      tree pty = TyTyResolveCompile::compile (ctx, p);
-      parameters.push_back (pty);
-      return true;
-    });
-
-    translated = ctx->get_backend ()->function_ptr_type (
-      result_type, parameters,
-      ctx->get_mappings ()->lookup_location (type.get_ref ()));
-  }
-
-  void visit (const TyTy::ADTType &type) override
-  {
-    if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
-      return;
-
-    // we dont support enums yet
-    rust_assert (!type.is_enum ());
-    rust_assert (type.number_of_variants () == 1);
-
-    TyTy::VariantDef &variant = *type.get_variants ().at (0);
-    std::vector<Backend::typed_identifier> fields;
-    for (size_t i = 0; i < variant.num_fields (); i++)
-      {
-	const TyTy::StructFieldType *field = variant.get_field_at_index (i);
-	tree compiled_field_ty
-	  = TyTyResolveCompile::compile (ctx, field->get_field_type ());
-
-	Backend::typed_identifier f (field->get_name (), compiled_field_ty,
-				     ctx->get_mappings ()->lookup_location (
-				       type.get_ty_ref ()));
-	fields.push_back (std::move (f));
-      }
-
-    tree type_record;
-    if (type.is_union ())
-      type_record = ctx->get_backend ()->union_type (fields);
-    else
-      type_record = ctx->get_backend ()->struct_type (fields);
-    tree named_struct
-      = ctx->get_backend ()->named_type (type.get_name (), type_record,
-					 ctx->get_mappings ()->lookup_location (
-					   type.get_ty_ref ()));
-
-    ctx->push_type (named_struct);
-    translated = named_struct;
-
-    ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
-  }
-
-  void visit (const TyTy::TupleType &type) override
-  {
-    if (type.num_fields () == 0)
-      {
-	translated = ctx->get_backend ()->unit_type ();
-	return;
-      }
-
-    bool ok
-      = ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type);
-    if (ok)
-      return;
-
-    // create implicit struct
-    std::vector<Backend::typed_identifier> fields;
-    for (size_t i = 0; i < type.num_fields (); i++)
-      {
-	TyTy::BaseType *field = type.get_field (i);
-	tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
-
-	// rustc uses the convention __N, where N is an integer, to
-	// name the fields of a tuple.  We follow this as well,
-	// because this is used by GDB.  One further reason to prefer
-	// this, rather than simply emitting the integer, is that this
-	// approach makes it simpler to use a C-only debugger, or
-	// GDB's C mode, when debugging Rust.
-	Backend::typed_identifier f ("__" + std::to_string (i),
-				     compiled_field_ty,
-				     ctx->get_mappings ()->lookup_location (
-				       type.get_ty_ref ()));
-	fields.push_back (std::move (f));
-      }
-
-    tree struct_type_record = ctx->get_backend ()->struct_type (fields);
-    tree named_struct
-      = ctx->get_backend ()->named_type (type.as_string (), struct_type_record,
-					 ctx->get_mappings ()->lookup_location (
-					   type.get_ty_ref ()));
-
-    ctx->push_type (named_struct);
-    ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
-    translated = named_struct;
-  }
-
-  void visit (const TyTy::ArrayType &type) override
-  {
-    tree element_type
-      = TyTyResolveCompile::compile (ctx, type.get_element_type ());
-    translated
-      = ctx->get_backend ()->array_type (element_type, type.get_capacity ());
-  }
-
-  void visit (const TyTy::BoolType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::IntType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::UintType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::FloatType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::USizeType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::ISizeType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::CharType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::ReferenceType &type) override
-  {
-    tree base_compiled_type
-      = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
-    if (type.is_mutable ())
-      {
-	translated = ctx->get_backend ()->reference_type (base_compiled_type);
-      }
-    else
-      {
-	auto base = ctx->get_backend ()->immutable_type (base_compiled_type);
-	translated = ctx->get_backend ()->reference_type (base);
-      }
-  }
-
-  void visit (const TyTy::PointerType &type) override
-  {
-    tree base_compiled_type
-      = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
-    if (type.is_mutable ())
-      {
-	translated = ctx->get_backend ()->pointer_type (base_compiled_type);
-      }
-    else
-      {
-	auto base = ctx->get_backend ()->immutable_type (base_compiled_type);
-	translated = ctx->get_backend ()->pointer_type (base);
-      }
-  }
-
-  void visit (const TyTy::StrType &type) override
-  {
-    tree compiled_type = nullptr;
-    bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
-    rust_assert (ok);
-    translated = compiled_type;
-  }
-
-  void visit (const TyTy::NeverType &) override
-  {
-    translated = ctx->get_backend ()->unit_type ();
-  }
-
-  void visit (const TyTy::DynamicObjectType &type) override
-  {
-    if (trait_object_mode)
-      {
-	translated = ctx->get_backend ()->integer_type (
-	  true, ctx->get_backend ()->get_pointer_size ());
-	return;
-      }
-
-    if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
-      return;
-
-    // create implicit struct
-    auto items = type.get_object_items ();
-    std::vector<Backend::typed_identifier> fields;
-
-    tree uint = ctx->get_backend ()->integer_type (
-      true, ctx->get_backend ()->get_pointer_size ());
-    tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
-
-    Backend::typed_identifier f ("__receiver_trait_obj_ptr", uintptr_ty,
-				 ctx->get_mappings ()->lookup_location (
-				   type.get_ty_ref ()));
-    fields.push_back (std::move (f));
-
-    for (size_t i = 0; i < items.size (); i++)
-      {
-	// mrustc seems to make a vtable consisting of uintptr's
-	tree uint = ctx->get_backend ()->integer_type (
-	  true, ctx->get_backend ()->get_pointer_size ());
-	tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
-
-	Backend::typed_identifier f ("__" + std::to_string (i), uintptr_ty,
-				     ctx->get_mappings ()->lookup_location (
-				       type.get_ty_ref ()));
-	fields.push_back (std::move (f));
-      }
-
-    tree type_record = ctx->get_backend ()->struct_type (fields);
-    tree named_struct
-      = ctx->get_backend ()->named_type (type.get_name (), type_record,
-					 ctx->get_mappings ()->lookup_location (
-					   type.get_ty_ref ()));
-
-    ctx->push_type (named_struct);
-    translated = named_struct;
-
-    ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
-  }
-
-  void visit (const TyTy::ClosureType &) override { gcc_unreachable (); }
-
-private:
-  TyTyResolveCompile (Context *ctx, bool trait_object_mode)
-    : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr),
-      recursion_count (0)
-  {}
-
-  Context *ctx;
-  bool trait_object_mode;
-  tree translated;
-  size_t recursion_count;
-
-  static const size_t kDefaultRecusionLimit = 5;
-};
-
 } // namespace Compile
 } // namespace Rust
 
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
new file mode 100644
index 00000000000..76ab4db2891
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -0,0 +1,371 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile-type.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+TyTyResolveCompile::visit (const TyTy::ErrorType &)
+{
+  gcc_unreachable ();
+}
+void
+TyTyResolveCompile::visit (const TyTy::InferType &)
+{
+  gcc_unreachable ();
+}
+void
+TyTyResolveCompile::visit (const TyTy::ClosureType &)
+{
+  gcc_unreachable ();
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ProjectionType &type)
+{
+  type.get ()->accept_vis (*this);
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
+{
+  type.resolve ()->accept_vis (*this);
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ParamType &param)
+{
+  recursion_count++;
+  rust_assert (recursion_count < kDefaultRecusionLimit);
+
+  param.resolve ()->accept_vis (*this);
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::FnType &type)
+{
+  Backend::typed_identifier receiver;
+  std::vector<Backend::typed_identifier> parameters;
+  std::vector<Backend::typed_identifier> results;
+
+  if (!type.get_return_type ()->is_unit ())
+    {
+      auto hir_type = type.get_return_type ();
+      auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
+      results.push_back (Backend::typed_identifier (
+	"_", ret,
+	ctx->get_mappings ()->lookup_location (hir_type->get_ref ())));
+    }
+
+  for (auto &param_pair : type.get_params ())
+    {
+      auto param_tyty = param_pair.second;
+      auto compiled_param_type
+	= TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
+
+      auto compiled_param = Backend::typed_identifier (
+	param_pair.first->as_string (), compiled_param_type,
+	ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()));
+
+      parameters.push_back (compiled_param);
+    }
+
+  if (!type.is_varadic ())
+    translated = ctx->get_backend ()->function_type (
+      receiver, parameters, results, NULL,
+      ctx->get_mappings ()->lookup_location (type.get_ref ()));
+  else
+    translated = ctx->get_backend ()->function_type_varadic (
+      receiver, parameters, results, NULL,
+      ctx->get_mappings ()->lookup_location (type.get_ref ()));
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::FnPtr &type)
+{
+  tree result_type = TyTyResolveCompile::compile (ctx, type.get_return_type ());
+
+  std::vector<tree> parameters;
+  type.iterate_params ([&] (TyTy::BaseType *p) mutable -> bool {
+    tree pty = TyTyResolveCompile::compile (ctx, p);
+    parameters.push_back (pty);
+    return true;
+  });
+
+  translated = ctx->get_backend ()->function_ptr_type (
+    result_type, parameters,
+    ctx->get_mappings ()->lookup_location (type.get_ref ()));
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ADTType &type)
+{
+  if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
+    return;
+
+  // we dont support enums yet
+  rust_assert (!type.is_enum ());
+  rust_assert (type.number_of_variants () == 1);
+
+  TyTy::VariantDef &variant = *type.get_variants ().at (0);
+  std::vector<Backend::typed_identifier> fields;
+  for (size_t i = 0; i < variant.num_fields (); i++)
+    {
+      const TyTy::StructFieldType *field = variant.get_field_at_index (i);
+      tree compiled_field_ty
+	= TyTyResolveCompile::compile (ctx, field->get_field_type ());
+
+      Backend::typed_identifier f (field->get_name (), compiled_field_ty,
+				   ctx->get_mappings ()->lookup_location (
+				     type.get_ty_ref ()));
+      fields.push_back (std::move (f));
+    }
+
+  tree type_record;
+  if (type.is_union ())
+    type_record = ctx->get_backend ()->union_type (fields);
+  else
+    type_record = ctx->get_backend ()->struct_type (fields);
+  tree named_struct
+    = ctx->get_backend ()->named_type (type.get_name (), type_record,
+				       ctx->get_mappings ()->lookup_location (
+					 type.get_ty_ref ()));
+
+  ctx->push_type (named_struct);
+  translated = named_struct;
+
+  ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::TupleType &type)
+{
+  if (type.num_fields () == 0)
+    {
+      translated = ctx->get_backend ()->unit_type ();
+      return;
+    }
+
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type);
+  if (ok)
+    return;
+
+  // create implicit struct
+  std::vector<Backend::typed_identifier> fields;
+  for (size_t i = 0; i < type.num_fields (); i++)
+    {
+      TyTy::BaseType *field = type.get_field (i);
+      tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
+
+      // rustc uses the convention __N, where N is an integer, to
+      // name the fields of a tuple.  We follow this as well,
+      // because this is used by GDB.  One further reason to prefer
+      // this, rather than simply emitting the integer, is that this
+      // approach makes it simpler to use a C-only debugger, or
+      // GDB's C mode, when debugging Rust.
+      Backend::typed_identifier f ("__" + std::to_string (i), compiled_field_ty,
+				   ctx->get_mappings ()->lookup_location (
+				     type.get_ty_ref ()));
+      fields.push_back (std::move (f));
+    }
+
+  tree struct_type_record = ctx->get_backend ()->struct_type (fields);
+  tree named_struct
+    = ctx->get_backend ()->named_type (type.as_string (), struct_type_record,
+				       ctx->get_mappings ()->lookup_location (
+					 type.get_ty_ref ()));
+
+  ctx->push_type (named_struct);
+  ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
+  translated = named_struct;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ArrayType &type)
+{
+  tree element_type
+    = TyTyResolveCompile::compile (ctx, type.get_element_type ());
+  translated
+    = ctx->get_backend ()->array_type (element_type, type.get_capacity ());
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::BoolType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::IntType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::UintType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::FloatType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::USizeType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ISizeType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::CharType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
+{
+  tree base_compiled_type
+    = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
+  if (type.is_mutable ())
+    {
+      translated = ctx->get_backend ()->reference_type (base_compiled_type);
+    }
+  else
+    {
+      auto base = ctx->get_backend ()->immutable_type (base_compiled_type);
+      translated = ctx->get_backend ()->reference_type (base);
+    }
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::PointerType &type)
+{
+  tree base_compiled_type
+    = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
+  if (type.is_mutable ())
+    {
+      translated = ctx->get_backend ()->pointer_type (base_compiled_type);
+    }
+  else
+    {
+      auto base = ctx->get_backend ()->immutable_type (base_compiled_type);
+      translated = ctx->get_backend ()->pointer_type (base);
+    }
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::StrType &type)
+{
+  tree compiled_type = nullptr;
+  bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+  rust_assert (ok);
+  translated = compiled_type;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::NeverType &)
+{
+  translated = ctx->get_backend ()->unit_type ();
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
+{
+  if (trait_object_mode)
+    {
+      translated = ctx->get_backend ()->integer_type (
+	true, ctx->get_backend ()->get_pointer_size ());
+      return;
+    }
+
+  if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
+    return;
+
+  // create implicit struct
+  auto items = type.get_object_items ();
+  std::vector<Backend::typed_identifier> fields;
+
+  tree uint = ctx->get_backend ()->integer_type (
+    true, ctx->get_backend ()->get_pointer_size ());
+  tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
+
+  Backend::typed_identifier f ("__receiver_trait_obj_ptr", uintptr_ty,
+			       ctx->get_mappings ()->lookup_location (
+				 type.get_ty_ref ()));
+  fields.push_back (std::move (f));
+
+  for (size_t i = 0; i < items.size (); i++)
+    {
+      // mrustc seems to make a vtable consisting of uintptr's
+      tree uint = ctx->get_backend ()->integer_type (
+	true, ctx->get_backend ()->get_pointer_size ());
+      tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
+
+      Backend::typed_identifier f ("__" + std::to_string (i), uintptr_ty,
+				   ctx->get_mappings ()->lookup_location (
+				     type.get_ty_ref ()));
+      fields.push_back (std::move (f));
+    }
+
+  tree type_record = ctx->get_backend ()->struct_type (fields);
+  tree named_struct
+    = ctx->get_backend ()->named_type (type.get_name (), type_record,
+				       ctx->get_mappings ()->lookup_location (
+					 type.get_ty_ref ()));
+
+  ctx->push_type (named_struct);
+  translated = named_struct;
+
+  ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
new file mode 100644
index 00000000000..f62581fbfad
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -0,0 +1,79 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_COMPILE_TYPE
+#define RUST_COMPILE_TYPE
+
+#include "rust-compile-context.h"
+
+namespace Rust {
+namespace Compile {
+
+class TyTyResolveCompile : public TyTy::TyConstVisitor
+{
+public:
+  static tree compile (Context *ctx, const TyTy::BaseType *ty,
+		       bool trait_object_mode = false)
+  {
+    TyTyResolveCompile compiler (ctx, trait_object_mode);
+    ty->accept_vis (compiler);
+    return compiler.translated;
+  }
+
+  void visit (const TyTy::InferType &) override;
+  void visit (const TyTy::ADTType &) override;
+  void visit (const TyTy::TupleType &) override;
+  void visit (const TyTy::FnType &) override;
+  void visit (const TyTy::FnPtr &) override;
+  void visit (const TyTy::ArrayType &) override;
+  void visit (const TyTy::BoolType &) override;
+  void visit (const TyTy::IntType &) override;
+  void visit (const TyTy::UintType &) override;
+  void visit (const TyTy::FloatType &) override;
+  void visit (const TyTy::USizeType &) override;
+  void visit (const TyTy::ISizeType &) override;
+  void visit (const TyTy::ErrorType &) override;
+  void visit (const TyTy::CharType &) override;
+  void visit (const TyTy::ReferenceType &) override;
+  void visit (const TyTy::PointerType &) override;
+  void visit (const TyTy::ParamType &) override;
+  void visit (const TyTy::StrType &) override;
+  void visit (const TyTy::NeverType &) override;
+  void visit (const TyTy::PlaceholderType &) override;
+  void visit (const TyTy::ProjectionType &) override;
+  void visit (const TyTy::DynamicObjectType &) override;
+  void visit (const TyTy::ClosureType &) override;
+
+private:
+  TyTyResolveCompile (Context *ctx, bool trait_object_mode)
+    : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr),
+      recursion_count (0)
+  {}
+
+  Context *ctx;
+  bool trait_object_mode;
+  tree translated;
+  size_t recursion_count;
+
+  static const size_t kDefaultRecusionLimit = 5;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_TYPE


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 11:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:56 [gcc/devel/rust/master] Refactor TyTy::ResolveCompile pass to be in its own file Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).