]>
Commit | Line | Data |
---|---|---|
83ffe9cd | 1 | // Copyright (C) 2020-2023 Free Software Foundation, Inc. |
06688fe4 PH |
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-hir-type-check.h" | |
20 | ||
21 | namespace Rust { | |
22 | namespace Resolver { | |
23 | ||
24 | TypeCheckContext * | |
25 | TypeCheckContext::get () | |
26 | { | |
27 | static TypeCheckContext *instance; | |
28 | if (instance == nullptr) | |
29 | instance = new TypeCheckContext (); | |
30 | ||
31 | return instance; | |
32 | } | |
33 | ||
34 | TypeCheckContext::TypeCheckContext () {} | |
35 | ||
36 | TypeCheckContext::~TypeCheckContext () {} | |
37 | ||
38 | bool | |
39 | TypeCheckContext::lookup_builtin (NodeId id, TyTy::BaseType **type) | |
40 | { | |
41 | auto ref_it = node_id_refs.find (id); | |
42 | if (ref_it == node_id_refs.end ()) | |
43 | return false; | |
44 | ||
45 | auto it = resolved.find (ref_it->second); | |
46 | if (it == resolved.end ()) | |
47 | return false; | |
48 | ||
49 | *type = it->second; | |
50 | return true; | |
51 | } | |
52 | ||
53 | bool | |
54 | TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type) | |
55 | { | |
56 | for (auto &builtin : builtins) | |
57 | { | |
58 | if (name.compare (builtin->as_string ()) == 0) | |
59 | { | |
60 | *type = builtin.get (); | |
61 | return true; | |
62 | } | |
63 | } | |
64 | return false; | |
65 | } | |
66 | ||
67 | void | |
68 | TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type) | |
69 | { | |
70 | node_id_refs[ref] = id; | |
71 | resolved[id] = type; | |
72 | builtins.push_back (std::unique_ptr<TyTy::BaseType> (type)); | |
73 | } | |
74 | ||
75 | void | |
76 | TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings, | |
77 | TyTy::BaseType *type) | |
78 | { | |
79 | rust_assert (type != nullptr); | |
80 | NodeId ref = mappings.get_nodeid (); | |
81 | HirId id = mappings.get_hirid (); | |
82 | node_id_refs[ref] = id; | |
83 | resolved[id] = type; | |
84 | } | |
85 | ||
86 | void | |
87 | TypeCheckContext::insert_implicit_type (TyTy::BaseType *type) | |
88 | { | |
89 | rust_assert (type != nullptr); | |
90 | resolved[type->get_ref ()] = type; | |
91 | } | |
92 | ||
93 | void | |
94 | TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type) | |
95 | { | |
96 | rust_assert (type != nullptr); | |
97 | resolved[id] = type; | |
98 | } | |
99 | ||
100 | bool | |
101 | TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const | |
102 | { | |
103 | auto it = resolved.find (id); | |
104 | if (it == resolved.end ()) | |
105 | return false; | |
106 | ||
107 | *type = it->second; | |
108 | return true; | |
109 | } | |
110 | ||
111 | void | |
112 | TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id) | |
113 | { | |
114 | rust_assert (node_id_refs.find (ref) == node_id_refs.end ()); | |
115 | node_id_refs[ref] = id; | |
116 | } | |
117 | ||
118 | bool | |
119 | TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id) | |
120 | { | |
121 | auto it = node_id_refs.find (ref); | |
122 | if (it == node_id_refs.end ()) | |
123 | return false; | |
124 | ||
125 | *id = it->second; | |
126 | return true; | |
127 | } | |
128 | ||
129 | TyTy::BaseType * | |
130 | TypeCheckContext::peek_return_type () | |
131 | { | |
7ad24d80 | 132 | rust_assert (!return_type_stack.empty ()); |
06688fe4 PH |
133 | return return_type_stack.back ().second; |
134 | } | |
135 | ||
136 | void | |
137 | TypeCheckContext::push_return_type (TypeCheckContextItem item, | |
138 | TyTy::BaseType *return_type) | |
139 | { | |
140 | return_type_stack.push_back ({std::move (item), return_type}); | |
141 | } | |
142 | ||
143 | void | |
144 | TypeCheckContext::pop_return_type () | |
145 | { | |
245ce6f2 | 146 | rust_assert (!return_type_stack.empty ()); |
06688fe4 PH |
147 | return_type_stack.pop_back (); |
148 | } | |
149 | ||
150 | TypeCheckContextItem & | |
151 | TypeCheckContext::peek_context () | |
152 | { | |
245ce6f2 | 153 | rust_assert (!return_type_stack.empty ()); |
06688fe4 PH |
154 | return return_type_stack.back ().first; |
155 | } | |
156 | ||
740a1997 PH |
157 | // TypeCheckContextItem |
158 | ||
159 | TyTy::FnType * | |
160 | TypeCheckContextItem::get_context_type () | |
161 | { | |
162 | auto &context = *TypeCheckContext::get (); | |
163 | ||
164 | HirId reference = UNKNOWN_HIRID; | |
165 | switch (get_type ()) | |
166 | { | |
167 | case ITEM: | |
168 | reference = get_item ()->get_mappings ().get_hirid (); | |
169 | break; | |
170 | ||
171 | case IMPL_ITEM: | |
172 | reference = get_impl_item ().second->get_mappings ().get_hirid (); | |
173 | break; | |
174 | ||
175 | case TRAIT_ITEM: | |
176 | reference = get_trait_item ()->get_mappings ().get_hirid (); | |
177 | break; | |
178 | } | |
179 | ||
180 | rust_assert (reference != UNKNOWN_HIRID); | |
181 | ||
182 | TyTy::BaseType *lookup = nullptr; | |
183 | bool ok = context.lookup_type (reference, &lookup); | |
184 | rust_assert (ok); | |
185 | rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); | |
186 | return static_cast<TyTy::FnType *> (lookup); | |
187 | } | |
188 | ||
06688fe4 PH |
189 | } // namespace Resolver |
190 | } // namespace Rust |