aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-expr.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-09-13 16:31:18 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-09-13 16:33:58 +0100
commit9464066111c715a63e632b1dc60f3230e8c48bb1 (patch)
treeb1bcaa2f68d4fc74e4e90ff6d608613e4f11a8a7 /gcc/rust/backend/rust-compile-expr.h
parente3b7eb58844c446d097ddee00ecd455d5537c6b2 (diff)
downloadgcc-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.h51
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 ());
}