Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 : : #ifndef RUST_MACRO_BUILTINS_H
20 : : #define RUST_MACRO_BUILTINS_H
21 : :
22 : : #include "rust-ast.h"
23 : : #include "rust-ast-fragment.h"
24 : : #include "rust-location.h"
25 : : #include "bi-map.h"
26 : :
27 : : namespace Rust {
28 : :
29 : : // FIXME: Add a BuiltinMacro class which contains a name (or should it?), a
30 : : // transcriber and extra info if necessary
31 : : // then make a global map<string, BuiltinMacro>
32 : :
33 : : /**
34 : : * All builtin macros possible
35 : : */
36 : : enum class BuiltinMacro
37 : : {
38 : : Assert,
39 : : File,
40 : : Line,
41 : : Column,
42 : : IncludeBytes,
43 : : IncludeStr,
44 : : Stringify,
45 : : CompileError,
46 : : Concat,
47 : : Env,
48 : : OptionEnv,
49 : : Cfg,
50 : : Include,
51 : : FormatArgs,
52 : : FormatArgsNl,
53 : : ConcatIdents,
54 : : ModulePath,
55 : : Asm,
56 : : LlvmAsm,
57 : : GlobalAsm,
58 : : LogSyntax,
59 : : TraceMacros,
60 : : Test,
61 : : Bench,
62 : : TestCase,
63 : : GlobalAllocator,
64 : : CfgAccessible,
65 : : RustcDecodable,
66 : : RustcEncodable,
67 : : Clone,
68 : : Copy,
69 : : Debug,
70 : : Default,
71 : : Eq,
72 : : PartialEq,
73 : : Ord,
74 : : PartialOrd,
75 : : Hash,
76 : : };
77 : :
78 : : BuiltinMacro
79 : : builtin_macro_from_string (const std::string &identifier);
80 : :
81 : : /**
82 : : * This class provides a list of builtin macros implemented by the compiler.
83 : : * The functions defined are called "builtin transcribers" in that they replace
84 : : * the transcribing part of a macro definition.
85 : : *
86 : : * Like regular macro transcribers, they are responsible for building and
87 : : * returning an AST fragment: basically a vector of AST nodes put together.
88 : : *
89 : : * Unlike regular declarative macros where each match arm has its own associated
90 : : * transcriber, builtin transcribers are responsible for handling all match arms
91 : : * of the macro. This means that you should take extra care when implementing a
92 : : * builtin containing multiple match arms: You will probably need to do some
93 : : * lookahead in order to determine which match arm the user intended to use.
94 : : *
95 : : * An example of this is the `assert!()` macro:
96 : : *
97 : : * ```
98 : : * macro_rules! assert {
99 : : * ($cond:expr $(,)?) => {{ ... }};
100 : : * ($cond : expr, $ ($arg : tt) +) = > {{ ... }};
101 : : * }
102 : : * ```
103 : : *
104 : : * If more tokens exist beyond the optional comma, they need to be handled as
105 : : * a token-tree for a custom panic message.
106 : : *
107 : : * These builtin macros with empty transcribers are defined in the standard
108 : : * library. They are marked with a special attribute, `#[rustc_builtin_macro]`.
109 : : * When this attribute is present on a macro definition, the compiler should
110 : : * look for an associated transcriber in the mappings. Meaning that you must
111 : : * remember to insert your transcriber in the `builtin_macros` map of the
112 : : *`Mappings`.
113 : : *
114 : : * This map is built as a static variable in the `insert_macro_def()` method
115 : : * of the `Mappings` class.
116 : : */
117 : : class MacroBuiltin
118 : : {
119 : : public:
120 : : static const BiMap<std::string, BuiltinMacro> builtins;
121 : : static std::unordered_map<std::string, AST::MacroTranscriberFunc>
122 : : builtin_transcribers;
123 : :
124 : : static tl::optional<AST::Fragment>
125 : : assert_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
126 : :
127 : : static tl::optional<AST::Fragment> file_handler (location_t invoc_locus,
128 : : AST::MacroInvocData &invoc);
129 : :
130 : : static tl::optional<AST::Fragment>
131 : : column_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
132 : :
133 : : static tl::optional<AST::Fragment>
134 : : include_bytes_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
135 : :
136 : : static tl::optional<AST::Fragment>
137 : : include_str_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
138 : :
139 : : static tl::optional<AST::Fragment>
140 : : stringify_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
141 : :
142 : : static tl::optional<AST::Fragment>
143 : : compile_error_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
144 : :
145 : : static tl::optional<AST::Fragment>
146 : : concat_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
147 : :
148 : : static tl::optional<AST::Fragment> env_handler (location_t invoc_locus,
149 : : AST::MacroInvocData &invoc);
150 : :
151 : : static tl::optional<AST::Fragment> cfg_handler (location_t invoc_locus,
152 : : AST::MacroInvocData &invoc);
153 : :
154 : : static tl::optional<AST::Fragment>
155 : : include_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
156 : :
157 : : static tl::optional<AST::Fragment> line_handler (location_t invoc_locus,
158 : : AST::MacroInvocData &invoc);
159 : :
160 : : static tl::optional<AST::Fragment> sorry (location_t invoc_locus,
161 : : AST::MacroInvocData &invoc);
162 : :
163 : : /* Builtin procedural macros do not work directly on tokens, but still need a
164 : : * builtin transcriber to be considered proper builtin macros */
165 : : static tl::optional<AST::Fragment> proc_macro_builtin (location_t,
166 : : AST::MacroInvocData &);
167 : : };
168 : : } // namespace Rust
169 : :
170 : : namespace std {
171 : : template <> struct hash<Rust::BuiltinMacro>
172 : : {
173 : 432556 : size_t operator() (const Rust::BuiltinMacro ¯o) const noexcept
174 : : {
175 : 432556 : return hash<std::underlying_type<Rust::BuiltinMacro>::type> () (
176 : : static_cast<std::underlying_type<Rust::BuiltinMacro>::type> (macro));
177 : : }
178 : : };
179 : : } // namespace std
180 : :
181 : : #endif // RUST_MACRO_BUILTINS_H
|