diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-09-13 16:31:18 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-09-13 16:33:58 +0100 |
commit | 9464066111c715a63e632b1dc60f3230e8c48bb1 (patch) | |
tree | b1bcaa2f68d4fc74e4e90ff6d608613e4f11a8a7 /gcc/rust/backend/rust-compile-expr.h | |
parent | e3b7eb58844c446d097ddee00ecd455d5537c6b2 (diff) | |
download | gcc-9464066111c715a63e632b1dc60f3230e8c48bb1.zip gcc-9464066111c715a63e632b1dc60f3230e8c48bb1.tar.gz gcc-9464066111c715a63e632b1dc60f3230e8c48bb1.tar.bz2 |
Support indirection for struct and tuple field access
When we have a fat pointer to a structure the GCC needs to know the RECORD
or UNION type of the type before it can access fields, this can be
supported by C'stye indirection such as '->'.
This might get updated when we support the autoderef mechanism and if the
type supports the deref trait.
Addresses #241
Diffstat (limited to 'gcc/rust/backend/rust-compile-expr.h')
-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 ()); } |