diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-09-13 16:12:45 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-13 16:12:45 +0000 |
commit | c644ee4c4351e3590f5396e94ec24ad7b828a954 (patch) | |
tree | b1bcaa2f68d4fc74e4e90ff6d608613e4f11a8a7 /gcc/rust/backend | |
parent | e3b7eb58844c446d097ddee00ecd455d5537c6b2 (diff) | |
parent | 9464066111c715a63e632b1dc60f3230e8c48bb1 (diff) | |
download | gcc-c644ee4c4351e3590f5396e94ec24ad7b828a954.zip gcc-c644ee4c4351e3590f5396e94ec24ad7b828a954.tar.gz gcc-c644ee4c4351e3590f5396e94ec24ad7b828a954.tar.bz2 |
Merge #671
671: Support indirection for struct and tuple field access r=philberty a=philberty
This allows for fat pointers to be used for tuple or struct field access by
supporting the GCC indirect references by binding the type to the reference.
This might get updated when we support the autoderef mechanism and if the
type supports the deref trait.
Addresses #241
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index ac33ccd..d0c0b74 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -46,6 +46,26 @@ public: TupleIndex index = expr.get_tuple_index (); Bexpression *receiver_ref = CompileExpr::Compile (tuple_expr, ctx); + + TyTy::BaseType *tuple_expr_ty = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + tuple_expr->get_mappings ().get_hirid (), &tuple_expr_ty); + rust_assert (ok); + + // do we need to add an indirect reference + if (tuple_expr_ty->get_kind () == TyTy::TypeKind::REF) + { + TyTy::ReferenceType *r + = static_cast<TyTy::ReferenceType *> (tuple_expr_ty); + TyTy::BaseType *tuple_type = r->get_base (); + Btype *tuple_tyty = TyTyResolveCompile::compile (ctx, tuple_type); + + Bexpression *indirect + = ctx->get_backend ()->indirect_expression (tuple_tyty, receiver_ref, + true, expr.get_locus ()); + receiver_ref = indirect; + } + translated = ctx->get_backend ()->struct_field_expression (receiver_ref, index, expr.get_locus ()); @@ -606,6 +626,9 @@ public: void visit (HIR::FieldAccessExpr &expr) override { + Bexpression *receiver_ref + = CompileExpr::Compile (expr.get_receiver_expr ().get (), ctx); + // resolve the receiver back to ADT type TyTy::BaseType *receiver = nullptr; if (!ctx->get_tyctx ()->lookup_type ( @@ -615,17 +638,31 @@ public: "unresolved type for receiver"); return; } - rust_assert (receiver->get_kind () == TyTy::TypeKind::ADT); - TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver); - size_t index = 0; - adt->get_field (expr.get_field_name (), &index); + size_t field_index = 0; + if (receiver->get_kind () == TyTy::TypeKind::ADT) + { + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver); + adt->get_field (expr.get_field_name (), &field_index); + } + else if (receiver->get_kind () == TyTy::TypeKind::REF) + { + TyTy::ReferenceType *r = static_cast<TyTy::ReferenceType *> (receiver); + TyTy::BaseType *b = r->get_base (); + rust_assert (b->get_kind () == TyTy::TypeKind::ADT); - Bexpression *struct_ref - = CompileExpr::Compile (expr.get_receiver_expr ().get (), ctx); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (b); + adt->get_field (expr.get_field_name (), &field_index); + Btype *adt_tyty = TyTyResolveCompile::compile (ctx, adt); + + Bexpression *indirect + = ctx->get_backend ()->indirect_expression (adt_tyty, receiver_ref, + true, expr.get_locus ()); + receiver_ref = indirect; + } translated - = ctx->get_backend ()->struct_field_expression (struct_ref, index, + = ctx->get_backend ()->struct_field_expression (receiver_ref, field_index, expr.get_locus ()); } |