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 5819 : Context::get ()
27 : {
28 5819 : static Context *instance;
29 5819 : if (instance == nullptr)
30 4606 : instance = new Context ();
31 :
32 5819 : return instance;
33 : }
34 :
35 4606 : Context::Context ()
36 4606 : : tyctx (Resolver::TypeCheckContext::get ()),
37 4606 : mappings (Analysis::Mappings::get ()), mangler (Mangler ())
38 : {
39 4606 : setup_builtins ();
40 4606 : }
41 :
42 : void
43 4606 : Context::setup_builtins ()
44 : {
45 92576 : for (auto &builtin : tyctx->get_builtins ())
46 87970 : TyTyResolveCompile::compile (this, builtin.get ());
47 4606 : }
48 :
49 : hashval_t
50 484530 : Context::type_hasher (tree type)
51 : {
52 484530 : inchash::hash hstate;
53 :
54 484530 : hstate.add_int (TREE_CODE (type));
55 :
56 484530 : if (TYPE_NAME (type))
57 : {
58 386286 : hashval_t record_name_hash
59 386286 : = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
60 386286 : hstate.add_object (record_name_hash);
61 : }
62 :
63 484530 : for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
64 : /* Just the identifier is adequate to distinguish. */
65 0 : hstate.add_object (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (t)));
66 :
67 484530 : switch (TREE_CODE (type))
68 : {
69 0 : case METHOD_TYPE:
70 0 : hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
71 : /* FALLTHROUGH. */
72 35 : case FUNCTION_TYPE:
73 91 : for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
74 56 : if (TREE_VALUE (t) != error_mark_node)
75 56 : hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
76 : break;
77 :
78 0 : case OFFSET_TYPE:
79 0 : hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
80 0 : break;
81 :
82 376 : case ARRAY_TYPE:
83 376 : {
84 376 : if (TYPE_DOMAIN (type))
85 376 : hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
86 376 : if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
87 : {
88 331 : unsigned typeless = TYPE_TYPELESS_STORAGE (type);
89 331 : hstate.add_object (typeless);
90 : }
91 : }
92 : break;
93 :
94 288372 : case INTEGER_TYPE:
95 288372 : {
96 288372 : tree t = TYPE_MAX_VALUE (type);
97 288372 : if (!t)
98 0 : t = TYPE_MIN_VALUE (type);
99 582595 : for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
100 294223 : hstate.add_object (TREE_INT_CST_ELT (t, i));
101 : break;
102 : }
103 :
104 18487 : case REAL_TYPE:
105 18487 : case FIXED_POINT_TYPE:
106 18487 : {
107 18487 : unsigned prec = TYPE_PRECISION (type);
108 18487 : hstate.add_object (prec);
109 18487 : break;
110 : }
111 :
112 0 : case VECTOR_TYPE:
113 0 : hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
114 0 : break;
115 :
116 104319 : case RECORD_TYPE:
117 104319 : case UNION_TYPE:
118 104319 : case QUAL_UNION_TYPE:
119 104319 : {
120 242430 : for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
121 : {
122 138111 : hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
123 138111 : hashval_t type_hash = type_hasher (TREE_TYPE (t));
124 138111 : hstate.add_object (name_hash);
125 138111 : hstate.add_object (type_hash);
126 : }
127 : }
128 : break;
129 :
130 : case BOOLEAN_TYPE:
131 : break;
132 :
133 55329 : case REFERENCE_TYPE:
134 55329 : case POINTER_TYPE:
135 55329 : {
136 55329 : hashval_t type_hash = type_hasher (TREE_TYPE (type));
137 55329 : hstate.add_object (type_hash);
138 : }
139 55329 : break;
140 :
141 : default:
142 : break;
143 : }
144 :
145 484530 : return hstate.end ();
146 : }
147 :
148 : void
149 61 : Context::push_closure_context (HirId id)
150 : {
151 61 : auto it = closure_bindings.find (id);
152 61 : rust_assert (it == closure_bindings.end ());
153 :
154 61 : closure_bindings.insert ({id, {}});
155 61 : closure_scope_bindings.push_back (id);
156 61 : }
157 :
158 : void
159 61 : Context::pop_closure_context ()
160 : {
161 61 : rust_assert (!closure_scope_bindings.empty ());
162 :
163 61 : HirId ref = closure_scope_bindings.back ();
164 61 : closure_scope_bindings.pop_back ();
165 61 : closure_bindings.erase (ref);
166 61 : }
167 :
168 : void
169 21 : Context::insert_closure_binding (HirId id, tree expr)
170 : {
171 21 : rust_assert (!closure_scope_bindings.empty ());
172 :
173 21 : HirId ref = closure_scope_bindings.back ();
174 21 : closure_bindings[ref].insert ({id, expr});
175 21 : }
176 :
177 : bool
178 43193 : Context::lookup_closure_binding (HirId id, tree *expr)
179 : {
180 43193 : if (closure_scope_bindings.empty ())
181 : return false;
182 :
183 101 : HirId ref = closure_scope_bindings.back ();
184 101 : auto it = closure_bindings.find (ref);
185 101 : rust_assert (it != closure_bindings.end ());
186 :
187 101 : auto iy = it->second.find (id);
188 101 : if (iy == it->second.end ())
189 : return false;
190 :
191 14 : *expr = iy->second;
192 14 : return true;
193 : }
194 :
195 : } // namespace Compile
196 : } // namespace Rust
|