Line data Source code
1 : // Copyright (C) 2020-2026 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 : #include "rust-compile-context.h"
20 : #include "rust-compile-type.h"
21 :
22 : namespace Rust {
23 : namespace Compile {
24 :
25 : Context *
26 6087 : Context::get ()
27 : {
28 6087 : static Context *instance;
29 6087 : if (instance == nullptr)
30 4742 : instance = new Context ();
31 :
32 6087 : return instance;
33 : }
34 :
35 4742 : Context::Context ()
36 4742 : : tyctx (Resolver::TypeCheckContext::get ()),
37 4742 : mappings (Analysis::Mappings::get ()), mangler (Mangler ())
38 : {
39 4742 : setup_builtins ();
40 4742 : }
41 :
42 : void
43 4742 : Context::setup_builtins ()
44 : {
45 95296 : for (auto &builtin : tyctx->get_builtins ())
46 90554 : TyTyResolveCompile::compile (this, builtin.get ());
47 4742 : }
48 :
49 : hashval_t
50 307913 : Context::type_hasher (tree type)
51 : {
52 307913 : hash_set<tree> active_types;
53 307913 : return type_hasher (type, active_types);
54 307913 : }
55 :
56 : hashval_t
57 509862 : Context::type_hasher (tree type, hash_set<tree> &active_types)
58 : {
59 509862 : inchash::hash hstate;
60 :
61 509862 : hstate.add_int (TREE_CODE (type));
62 :
63 509862 : if (TYPE_NAME (type))
64 : {
65 408154 : hashval_t record_name_hash
66 408154 : = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
67 408154 : hstate.add_object (record_name_hash);
68 : }
69 :
70 509862 : for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
71 : /* Just the identifier is adequate to distinguish. */
72 0 : hstate.add_object (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (t)));
73 :
74 : /* recursive guard */
75 509862 : bool found = active_types.contains (type);
76 509862 : if (found)
77 : {
78 13 : hstate.add_int (TYPE_UID (TYPE_MAIN_VARIANT (type)));
79 13 : return hstate.end ();
80 : }
81 509849 : active_types.add (type);
82 :
83 509849 : switch (TREE_CODE (type))
84 : {
85 0 : case METHOD_TYPE:
86 0 : hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
87 : /* FALLTHROUGH. */
88 53 : case FUNCTION_TYPE:
89 145 : for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
90 92 : if (TREE_VALUE (t) != error_mark_node)
91 92 : hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
92 : break;
93 :
94 0 : case OFFSET_TYPE:
95 0 : hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
96 0 : break;
97 :
98 588 : case ARRAY_TYPE:
99 588 : {
100 588 : if (TYPE_DOMAIN (type))
101 444 : hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
102 588 : if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
103 : {
104 543 : unsigned typeless = TYPE_TYPELESS_STORAGE (type);
105 543 : hstate.add_object (typeless);
106 : }
107 : }
108 : break;
109 :
110 304826 : case INTEGER_TYPE:
111 304826 : {
112 304826 : tree t = TYPE_MAX_VALUE (type);
113 304826 : if (!t)
114 0 : t = TYPE_MIN_VALUE (type);
115 615639 : for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
116 310813 : hstate.add_object (TREE_INT_CST_ELT (t, i));
117 : break;
118 : }
119 :
120 19007 : case REAL_TYPE:
121 19007 : case FIXED_POINT_TYPE:
122 19007 : {
123 19007 : unsigned prec = TYPE_PRECISION (type);
124 19007 : hstate.add_object (prec);
125 19007 : break;
126 : }
127 :
128 16 : case VECTOR_TYPE:
129 16 : hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
130 16 : break;
131 :
132 109304 : case RECORD_TYPE:
133 109304 : case UNION_TYPE:
134 109304 : case QUAL_UNION_TYPE:
135 109304 : {
136 253987 : for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
137 : {
138 144683 : hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
139 144683 : hashval_t type_hash = type_hasher (TREE_TYPE (t), active_types);
140 144683 : hstate.add_object (name_hash);
141 144683 : hstate.add_object (type_hash);
142 : }
143 : }
144 : break;
145 :
146 : case BOOLEAN_TYPE:
147 : break;
148 :
149 57266 : case REFERENCE_TYPE:
150 57266 : case POINTER_TYPE:
151 57266 : {
152 57266 : hashval_t type_hash = type_hasher (TREE_TYPE (type), active_types);
153 57266 : hstate.add_object (type_hash);
154 : }
155 57266 : break;
156 :
157 : default:
158 : break;
159 : }
160 :
161 509849 : active_types.remove (type);
162 509849 : return hstate.end ();
163 : }
164 :
165 : void
166 61 : Context::push_closure_context (HirId id)
167 : {
168 61 : auto it = closure_bindings.find (id);
169 61 : rust_assert (it == closure_bindings.end ());
170 :
171 61 : closure_bindings.insert ({id, {}});
172 61 : closure_scope_bindings.push_back (id);
173 61 : }
174 :
175 : void
176 61 : Context::pop_closure_context ()
177 : {
178 61 : rust_assert (!closure_scope_bindings.empty ());
179 :
180 61 : HirId ref = closure_scope_bindings.back ();
181 61 : closure_scope_bindings.pop_back ();
182 61 : closure_bindings.erase (ref);
183 61 : }
184 :
185 : void
186 21 : Context::insert_closure_binding (HirId id, tree expr)
187 : {
188 21 : rust_assert (!closure_scope_bindings.empty ());
189 :
190 21 : HirId ref = closure_scope_bindings.back ();
191 21 : closure_bindings[ref].insert ({id, expr});
192 21 : }
193 :
194 : bool
195 46353 : Context::lookup_closure_binding (HirId id, tree *expr)
196 : {
197 46353 : if (closure_scope_bindings.empty ())
198 : return false;
199 :
200 101 : HirId ref = closure_scope_bindings.back ();
201 101 : auto it = closure_bindings.find (ref);
202 101 : rust_assert (it != closure_bindings.end ());
203 :
204 101 : auto iy = it->second.find (id);
205 101 : if (iy == it->second.end ())
206 : return false;
207 :
208 14 : *expr = iy->second;
209 14 : return true;
210 : }
211 :
212 : } // namespace Compile
213 : } // namespace Rust
|