libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / resolve / rust-rib.h
blob3db17b4840a3996f58826d49438fe9b3bcf7464b
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #ifndef RUST_RIB_H
20 #define RUST_RIB_H
22 #include "rust-system.h"
23 #include "rust-ast.h"
24 #include "optional.h"
25 #include "expected.h"
27 namespace Rust {
28 namespace Resolver2_0 {
30 /**
32 pub enum Namespace {
33 /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and
34 `mod`s
35 /// (and, by extension, crates).
36 ///
37 /// Note that the type namespace includes other items; this is not an
38 /// exhaustive list.
39 TypeNS,
40 /// The value namespace includes `fn`s, `const`s, `static`s, and local
41 variables (including function arguments). ValueNS,
42 /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
43 /// procedural macros, attribute macros, `derive` macros, and non-macro
44 attributes
45 /// like `#[inline]` and `#[rustfmt::skip]`.
46 MacroNS,
51 // FIXME: There's no `labels` namespace, not sure if we need one or how to keep
52 // one
53 // FIXME: And where are things like loop labels kept?
55 /**
56 * All namespaces that Rust's name resolution needs to handle
58 // TODO: Move to `rust-forever-stack.h`?
59 enum class Namespace
61 Values,
62 Types,
63 Labels,
64 Macros,
65 // TODO: Which namespaces are we missing?
68 /**
69 * Error returned by `Rib::insert` when the key was already present in the Rib's
70 * map. The class contains the previously-inserted NodeId as well as the name of
71 * the node.
73 struct DuplicateNameError
75 // TODO: We might need multiple kinds of errors later down the line
76 DuplicateNameError (std::string name, NodeId existing);
78 std::string name;
79 NodeId existing;
82 /**
83 * A rib is a container of nodes, either declaration or usages, as well as the
84 * identifier each node uses. They are used to delimit lexical scopes, and have
85 * an impact on name resolution - they restrict certain name accesses and serve
86 * as boundaries between scopes.
88 * For example, if we are resolving the following *variable* use:
90 * ```rust
91 * fn outer() {
92 * let a = 15; // decl
93 * fn inner() -> i32 {
94 * a // use
95 * }
96 * }
97 * ```
99 * The `Function` rib we will have pushed will restrict the access to `outer`'s
100 * `a` declaration: Variable uses cannot cross function boundaries. On the other
101 * hand, if we were resolving a type usage, this would be perfectly allowed.
103 class Rib
105 public:
106 // TODO: Rename the class? to what? Binding? Declaration?
107 // This is useful for items which are in namespaces where shadowing is not
108 // allowed, but which are still shadowable! for example, when you do a glob
109 // import, if a later import has the same name as an item imported in the glob
110 // import, that glob imported item will need to get shadowed
111 class Definition
113 public:
114 static Definition NonShadowable (NodeId id);
115 static Definition Shadowable (NodeId id);
117 std::vector<NodeId> ids;
118 bool shadowable;
120 Definition () = default;
122 Definition &operator= (const Definition &) = default;
123 Definition (Definition const &) = default;
125 bool is_ambiguous () const;
127 NodeId get_node_id ()
129 rust_assert (!is_ambiguous ());
130 return ids[0];
133 std::string to_string () const;
135 private:
136 Definition (NodeId id, bool shadowable);
139 enum class Kind
141 Normal,
142 Module,
143 Function,
144 ConstantItem, // -> this variant has a boolean
145 TraitOrImpl,
146 /* Any item other than a Module, Function, Constant, Trait or Impl block */
147 Item,
148 Closure,
149 MacroDefinition,
150 /* Ban the use of forward-declared generic parameters in defaults */
151 ForwardTypeParamBan,
152 /* Const generic, as in the following example: fn foo<T, const X: T>() {} */
153 ConstParamType,
154 } kind;
156 Rib (Kind kind);
157 Rib (Kind kind, std::string identifier, NodeId id);
158 Rib (Kind kind, std::unordered_map<std::string, NodeId> values);
160 // TODO: What's the correctbehavior if the key already exists? What if a decl
161 // and use are in the same rib? Is that possible? Okay based on RibKind?
164 * Insert a new node in the rib
166 * @param name The name associated with the AST node
167 * @param def The `Definition` to insert
169 * @return `DuplicateNameError` if the node is already present in the rib. The
170 * `DuplicateNameError` class contains the NodeId of the existing
171 * node. Returns the new NodeId on success.
173 tl::expected<NodeId, DuplicateNameError> insert (std::string name,
174 Definition def);
177 * Access an inserted NodeId.
179 * @return tl::nullopt if the key does not exist, the NodeId otherwise
181 tl::optional<Rib::Definition> get (const std::string &name);
183 /* View all the values stored in the rib */
184 const std::unordered_map<std::string, Definition> &get_values () const;
186 private:
187 // TODO: Switch this to (NodeId, shadowable = false);
188 std::unordered_map<std::string, Definition> values;
191 } // namespace Resolver2_0
192 } // namespace Rust
194 #endif // !RUST_RIB_H