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 5488 : Context::get ()
27 : {
28 5488 : static Context *instance;
29 5488 : if (instance == nullptr)
30 4301 : instance = new Context ();
31 :
32 5488 : return instance;
33 : }
34 :
35 4301 : Context::Context ()
36 4301 : : tyctx (Resolver::TypeCheckContext::get ()),
37 4301 : mappings (Analysis::Mappings::get ()), mangler (Mangler ())
38 : {
39 4301 : setup_builtins ();
40 4301 : }
41 :
42 : void
43 4301 : Context::setup_builtins ()
44 : {
45 86020 : for (auto &builtin : tyctx->get_builtins ())
46 81719 : TyTyResolveCompile::compile (this, builtin.get ());
47 4301 : }
48 :
49 : hashval_t
50 451393 : Context::type_hasher (tree type)
51 : {
52 451393 : inchash::hash hstate;
53 :
54 451393 : hstate.add_int (TREE_CODE (type));
55 :
56 451393 : if (TYPE_NAME (type))
57 : {
58 367041 : hashval_t record_name_hash
59 367041 : = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
60 367041 : hstate.add_object (record_name_hash);
61 : }
62 :
63 451393 : 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 451393 : 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 1454 : case ARRAY_TYPE:
83 1454 : {
84 1454 : if (TYPE_DOMAIN (type))
85 1454 : hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
86 1454 : if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
87 : {
88 1409 : unsigned typeless = TYPE_TYPELESS_STORAGE (type);
89 1409 : hstate.add_object (typeless);
90 : }
91 : }
92 : break;
93 :
94 271959 : case INTEGER_TYPE:
95 271959 : {
96 271959 : tree t = TYPE_MAX_VALUE (type);
97 271959 : if (!t)
98 0 : t = TYPE_MIN_VALUE (type);
99 549426 : for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
100 277467 : hstate.add_object (TREE_INT_CST_ELT (t, i));
101 : break;
102 : }
103 :
104 17731 : case REAL_TYPE:
105 17731 : case FIXED_POINT_TYPE:
106 17731 : {
107 17731 : unsigned prec = TYPE_PRECISION (type);
108 17731 : hstate.add_object (prec);
109 17731 : break;
110 : }
111 :
112 0 : case VECTOR_TYPE:
113 0 : hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
114 0 : break;
115 :
116 99586 : case RECORD_TYPE:
117 99586 : case UNION_TYPE:
118 99586 : case QUAL_UNION_TYPE:
119 99586 : {
120 227706 : for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
121 : {
122 128120 : hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
123 128120 : hashval_t type_hash = type_hasher (TREE_TYPE (t));
124 128120 : hstate.add_object (name_hash);
125 128120 : hstate.add_object (type_hash);
126 : }
127 : }
128 : break;
129 :
130 : case BOOLEAN_TYPE:
131 : break;
132 :
133 48159 : case REFERENCE_TYPE:
134 48159 : case POINTER_TYPE:
135 48159 : {
136 48159 : hashval_t type_hash = type_hasher (TREE_TYPE (type));
137 48159 : hstate.add_object (type_hash);
138 : }
139 48159 : break;
140 :
141 : default:
142 : break;
143 : }
144 :
145 451393 : 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 40966 : Context::lookup_closure_binding (HirId id, tree *expr)
179 : {
180 40966 : 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
|