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