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 : : #include "rust-compile-context.h"
20 : : #include "rust-compile-type.h"
21 : :
22 : : namespace Rust {
23 : : namespace Compile {
24 : :
25 : : Context *
26 : 5182 : Context::get ()
27 : : {
28 : 5182 : static Context *instance;
29 : 5182 : if (instance == nullptr)
30 : 4118 : instance = new Context ();
31 : :
32 : 5182 : return instance;
33 : : }
34 : :
35 : 4118 : Context::Context ()
36 : 4118 : : tyctx (Resolver::TypeCheckContext::get ()),
37 : 4118 : mappings (Analysis::Mappings::get ()), mangler (Mangler ())
38 : : {
39 : 4118 : setup_builtins ();
40 : 4118 : }
41 : :
42 : : void
43 : 4118 : Context::setup_builtins ()
44 : : {
45 : 160602 : for (auto &builtin : tyctx->get_builtins ())
46 : 156484 : TyTyResolveCompile::compile (this, builtin.get ());
47 : 4118 : }
48 : :
49 : : hashval_t
50 : 560921 : Context::type_hasher (tree type)
51 : : {
52 : 560921 : inchash::hash hstate;
53 : :
54 : 560921 : hstate.add_int (TREE_CODE (type));
55 : :
56 : 560921 : if (TYPE_NAME (type))
57 : : {
58 : 450558 : hashval_t record_name_hash
59 : 450558 : = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
60 : 450558 : hstate.add_object (record_name_hash);
61 : : }
62 : :
63 : 560921 : 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 : 560921 : switch (TREE_CODE (type))
68 : : {
69 : 0 : case METHOD_TYPE:
70 : 0 : hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
71 : : /* FALLTHROUGH. */
72 : 21 : case FUNCTION_TYPE:
73 : 63 : for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
74 : 42 : if (TREE_VALUE (t) != error_mark_node)
75 : 42 : 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 : 339458 : case INTEGER_TYPE:
95 : 339458 : {
96 : 339458 : tree t = TYPE_MAX_VALUE (type);
97 : 339458 : if (!t)
98 : 0 : t = TYPE_MIN_VALUE (type);
99 : 688359 : for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
100 : 348901 : hstate.add_object (TREE_INT_CST_ELT (t, i));
101 : : break;
102 : : }
103 : :
104 : 25593 : case REAL_TYPE:
105 : 25593 : case FIXED_POINT_TYPE:
106 : 25593 : {
107 : 25593 : unsigned prec = TYPE_PRECISION (type);
108 : 25593 : hstate.add_object (prec);
109 : 25593 : break;
110 : : }
111 : :
112 : 0 : case VECTOR_TYPE:
113 : 0 : hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
114 : 0 : break;
115 : :
116 : 114447 : case RECORD_TYPE:
117 : 114447 : case UNION_TYPE:
118 : 114447 : case QUAL_UNION_TYPE:
119 : 114447 : {
120 : 257631 : for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
121 : : {
122 : 143184 : hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
123 : 143184 : hashval_t type_hash = type_hasher (TREE_TYPE (t));
124 : 143184 : hstate.add_object (name_hash);
125 : 143184 : hstate.add_object (type_hash);
126 : : }
127 : : }
128 : : break;
129 : :
130 : : case BOOLEAN_TYPE:
131 : : break;
132 : :
133 : 63016 : case REFERENCE_TYPE:
134 : 63016 : case POINTER_TYPE:
135 : 63016 : {
136 : 63016 : hashval_t type_hash = type_hasher (TREE_TYPE (type));
137 : 63016 : hstate.add_object (type_hash);
138 : : }
139 : 63016 : break;
140 : :
141 : : default:
142 : : break;
143 : : }
144 : :
145 : 560921 : return hstate.end ();
146 : : }
147 : :
148 : : void
149 : 60 : Context::push_closure_context (HirId id)
150 : : {
151 : 60 : auto it = closure_bindings.find (id);
152 : 60 : rust_assert (it == closure_bindings.end ());
153 : :
154 : 60 : closure_bindings.insert ({id, {}});
155 : 60 : closure_scope_bindings.push_back (id);
156 : 60 : }
157 : :
158 : : void
159 : 60 : Context::pop_closure_context ()
160 : : {
161 : 60 : rust_assert (!closure_scope_bindings.empty ());
162 : :
163 : 60 : HirId ref = closure_scope_bindings.back ();
164 : 60 : closure_scope_bindings.pop_back ();
165 : 60 : closure_bindings.erase (ref);
166 : 60 : }
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 : 40394 : Context::lookup_closure_binding (HirId id, tree *expr)
179 : : {
180 : 40394 : 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
|