diff options
Diffstat (limited to 'gcc/rust/backend/rust-compile-var-decl.h')
| -rw-r--r-- | gcc/rust/backend/rust-compile-var-decl.h | 70 |
1 files changed, 59 insertions, 11 deletions
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index 5c6d145..1f306ad 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -64,31 +64,79 @@ public: ctx->insert_var_decl (stmt_id, var); vars.push_back (var); + + if (pattern.has_subpattern ()) + { + auto subpattern_vars + = CompileVarDecl::compile (fndecl, translated_type, + &pattern.get_subpattern (), ctx); + vars.insert (vars.end (), subpattern_vars.begin (), + subpattern_vars.end ()); + } } void visit (HIR::TuplePattern &pattern) override { + rust_assert (TREE_CODE (translated_type) == RECORD_TYPE); switch (pattern.get_items ().get_item_type ()) { - case HIR::TuplePatternItems::ItemType::MULTIPLE: + case HIR::TuplePatternItems::ItemType::NO_REST: { - rust_assert (TREE_CODE (translated_type) == RECORD_TYPE); - auto &items = static_cast<HIR::TuplePatternItemsMultiple &> ( + auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> ( pattern.get_items ()); - size_t offs = 0; - for (auto &sub : items.get_patterns ()) + tree field = TYPE_FIELDS (translated_type); + for (auto &sub : items_no_rest.get_patterns ()) { - tree sub_ty = error_mark_node; - tree field = TYPE_FIELDS (translated_type); - for (size_t i = 0; i < offs; i++) + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } + } + break; + + case HIR::TuplePatternItems::ItemType::HAS_REST: + { + auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> ( + pattern.get_items ()); + + // count total fields in translated_type + size_t total_fields = 0; + for (tree t = TYPE_FIELDS (translated_type); t; t = DECL_CHAIN (t)) + { + total_fields++; + } + + // process lower patterns + tree field = TYPE_FIELDS (translated_type); + for (auto &sub : items_has_rest.get_lower_patterns ()) + { + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } + + // process upper patterns + if (!items_has_rest.get_upper_patterns ().empty ()) + { + size_t upper_start + = total_fields - items_has_rest.get_upper_patterns ().size (); + field = TYPE_FIELDS (translated_type); + for (size_t i = 0; i < upper_start; i++) { field = DECL_CHAIN (field); gcc_assert (field != NULL_TREE); } - sub_ty = TREE_TYPE (field); - CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); - offs++; + + for (auto &sub : items_has_rest.get_upper_patterns ()) + { + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } } } break; |
