Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #ifndef RUST_COMPILE_VAR_DECL
20 : : #define RUST_COMPILE_VAR_DECL
21 : :
22 : : #include "rust-compile-base.h"
23 : : #include "rust-hir-visitor.h"
24 : :
25 : : namespace Rust {
26 : : namespace Compile {
27 : :
28 : 25388 : class CompileVarDecl : public HIRCompileBase, public HIR::HIRPatternVisitor
29 : : {
30 : : using HIR::HIRPatternVisitor::visit;
31 : :
32 : : public:
33 : 12694 : static std::vector<Bvariable *> compile (tree fndecl, tree translated_type,
34 : : HIR::Pattern *pattern, Context *ctx)
35 : : {
36 : 12694 : CompileVarDecl compiler (ctx, fndecl, translated_type);
37 : 12694 : pattern->accept_vis (compiler);
38 : 12694 : return compiler.vars;
39 : 12694 : }
40 : :
41 : 12118 : void visit (HIR::IdentifierPattern &pattern) override
42 : : {
43 : 12118 : if (!pattern.is_mut ())
44 : 11262 : translated_type = Backend::immutable_type (translated_type);
45 : :
46 : 12118 : tree bind_tree = ctx->peek_enclosing_scope ();
47 : 24236 : std::string identifier = pattern.get_identifier ().as_string ();
48 : 12118 : tree decl
49 : 12118 : = build_decl (pattern.get_locus (), VAR_DECL,
50 : : Backend::get_identifier_node (identifier), translated_type);
51 : 12118 : DECL_CONTEXT (decl) = fndecl;
52 : :
53 : 12118 : gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
54 : 12118 : tree block_tree = BIND_EXPR_BLOCK (bind_tree);
55 : 12118 : gcc_assert (TREE_CODE (block_tree) == BLOCK);
56 : 12118 : DECL_CHAIN (decl) = BLOCK_VARS (block_tree);
57 : 12118 : BLOCK_VARS (block_tree) = decl;
58 : 12118 : BIND_EXPR_VARS (bind_tree) = BLOCK_VARS (block_tree);
59 : :
60 : 12118 : rust_preserve_from_gc (decl);
61 : 12118 : Bvariable *var = new Bvariable (decl);
62 : :
63 : 12118 : HirId stmt_id = pattern.get_mappings ().get_hirid ();
64 : 12118 : ctx->insert_var_decl (stmt_id, var);
65 : :
66 : 12118 : vars.push_back (var);
67 : :
68 : 12118 : if (pattern.has_subpattern ())
69 : : {
70 : 7 : auto subpattern_vars
71 : : = CompileVarDecl::compile (fndecl, translated_type,
72 : 7 : &pattern.get_subpattern (), ctx);
73 : 7 : vars.insert (vars.end (), subpattern_vars.begin (),
74 : : subpattern_vars.end ());
75 : 7 : }
76 : 12118 : }
77 : :
78 : 289 : void visit (HIR::TuplePattern &pattern) override
79 : : {
80 : 289 : rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
81 : 289 : switch (pattern.get_items ().get_item_type ())
82 : : {
83 : 287 : case HIR::TuplePatternItems::ItemType::NO_REST:
84 : 287 : {
85 : 287 : auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> (
86 : 287 : pattern.get_items ());
87 : :
88 : 287 : tree field = TYPE_FIELDS (translated_type);
89 : 873 : for (auto &sub : items_no_rest.get_patterns ())
90 : : {
91 : 586 : gcc_assert (field != NULL_TREE);
92 : 586 : tree sub_ty = TREE_TYPE (field);
93 : 586 : CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
94 : 586 : field = DECL_CHAIN (field);
95 : : }
96 : : }
97 : : break;
98 : :
99 : 2 : case HIR::TuplePatternItems::ItemType::HAS_REST:
100 : 2 : {
101 : 2 : auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> (
102 : 2 : pattern.get_items ());
103 : :
104 : : // count total fields in translated_type
105 : 2 : size_t total_fields = 0;
106 : 6 : for (tree t = TYPE_FIELDS (translated_type); t; t = DECL_CHAIN (t))
107 : : {
108 : 4 : total_fields++;
109 : : }
110 : :
111 : : // process lower patterns
112 : 2 : tree field = TYPE_FIELDS (translated_type);
113 : 4 : for (auto &sub : items_has_rest.get_lower_patterns ())
114 : : {
115 : 2 : gcc_assert (field != NULL_TREE);
116 : 2 : tree sub_ty = TREE_TYPE (field);
117 : 2 : CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
118 : 2 : field = DECL_CHAIN (field);
119 : : }
120 : :
121 : : // process upper patterns
122 : 2 : if (!items_has_rest.get_upper_patterns ().empty ())
123 : : {
124 : 2 : size_t upper_start
125 : 2 : = total_fields - items_has_rest.get_upper_patterns ().size ();
126 : 2 : field = TYPE_FIELDS (translated_type);
127 : 4 : for (size_t i = 0; i < upper_start; i++)
128 : : {
129 : 2 : field = DECL_CHAIN (field);
130 : 2 : gcc_assert (field != NULL_TREE);
131 : : }
132 : :
133 : 4 : for (auto &sub : items_has_rest.get_upper_patterns ())
134 : : {
135 : 2 : gcc_assert (field != NULL_TREE);
136 : 2 : tree sub_ty = TREE_TYPE (field);
137 : 2 : CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
138 : 2 : field = DECL_CHAIN (field);
139 : : }
140 : : }
141 : : }
142 : : break;
143 : :
144 : : default:
145 : : break;
146 : : }
147 : 289 : }
148 : :
149 : : // Empty visit for unused Pattern HIR nodes.
150 : 0 : void visit (HIR::AltPattern &) override {}
151 : 0 : void visit (HIR::LiteralPattern &) override {}
152 : 0 : void visit (HIR::PathInExpression &) override {}
153 : 0 : void visit (HIR::QualifiedPathInExpression &) override {}
154 : 0 : void visit (HIR::RangePattern &) override {}
155 : 1 : void visit (HIR::ReferencePattern &) override {}
156 : 0 : void visit (HIR::SlicePattern &) override {}
157 : 0 : void visit (HIR::StructPattern &) override {}
158 : 0 : void visit (HIR::TupleStructPattern &) override {}
159 : 286 : void visit (HIR::WildcardPattern &) override {}
160 : :
161 : : private:
162 : 12694 : CompileVarDecl (Context *ctx, tree fndecl, tree translated_type)
163 : 12694 : : HIRCompileBase (ctx), fndecl (fndecl), translated_type (translated_type)
164 : : {}
165 : :
166 : : tree fndecl;
167 : : tree translated_type;
168 : :
169 : : std::vector<Bvariable *> vars;
170 : : };
171 : :
172 : : } // namespace Compile
173 : : } // namespace Rust
174 : :
175 : : #endif // RUST_COMPILE_VAR_DECL
|