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 "expected.h"
20 : : #include "libproc_macro_internal/tokenstream.h"
21 : : #include "optional.h"
22 : : #include "rust-ast-full-decls.h"
23 : : #include "rust-builtin-ast-nodes.h"
24 : : #include "rust-expand-format-args.h"
25 : : #include "rust-token-converter.h"
26 : : #include "rust-system.h"
27 : : #include "rust-macro-builtins.h"
28 : : #include "rust-ast-fragment.h"
29 : : #include "rust-ast.h"
30 : : #include "rust-cfg-strip.h"
31 : : #include "rust-diagnostics.h"
32 : : #include "rust-early-name-resolver.h"
33 : : #include "rust-expr.h"
34 : : #include "rust-lex.h"
35 : : #include "rust-macro-invoc-lexer.h"
36 : : #include "rust-macro.h"
37 : : #include "rust-parse.h"
38 : : #include "rust-session-manager.h"
39 : : #include "rust-attribute-values.h"
40 : : #include "rust-fmt.h"
41 : : #include "rust-token.h"
42 : :
43 : : #include "rust-macro-builtins-helpers.h"
44 : : namespace Rust {
45 : :
46 : : const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
47 : : {"assert", BuiltinMacro::Assert},
48 : : {"file", BuiltinMacro::File},
49 : : {"line", BuiltinMacro::Line},
50 : : {"column", BuiltinMacro::Column},
51 : : {"include_bytes", BuiltinMacro::IncludeBytes},
52 : : {"include_str", BuiltinMacro::IncludeStr},
53 : : {"stringify", BuiltinMacro::Stringify},
54 : : {"compile_error", BuiltinMacro::CompileError},
55 : : {"concat", BuiltinMacro::Concat},
56 : : {"env", BuiltinMacro::Env},
57 : : {"option_env", BuiltinMacro::OptionEnv},
58 : : {"cfg", BuiltinMacro::Cfg},
59 : : {"include", BuiltinMacro::Include},
60 : : {"format_args", BuiltinMacro::FormatArgs},
61 : : {"format_args_nl", BuiltinMacro::FormatArgsNl},
62 : : {"concat_idents", BuiltinMacro::ConcatIdents},
63 : : {"module_path", BuiltinMacro::ModulePath},
64 : : {"asm", BuiltinMacro::Asm},
65 : : // FIXME: Is that okay
66 : : {"llvm_asm", BuiltinMacro::Asm},
67 : : {"global_asm", BuiltinMacro::GlobalAsm},
68 : : {"log_syntax", BuiltinMacro::LogSyntax},
69 : : {"trace_macros", BuiltinMacro::TraceMacros},
70 : : {"test", BuiltinMacro::Test},
71 : : {"bench", BuiltinMacro::Bench},
72 : : {"test_case", BuiltinMacro::TestCase},
73 : : {"global_allocator", BuiltinMacro::GlobalAllocator},
74 : : {"cfg_accessible", BuiltinMacro::CfgAccessible},
75 : : {"RustcEncodable", BuiltinMacro::RustcDecodable},
76 : : {"RustcDecodable", BuiltinMacro::RustcEncodable},
77 : : {"Clone", BuiltinMacro::Clone},
78 : : {"Copy", BuiltinMacro::Copy},
79 : : {"Debug", BuiltinMacro::Debug},
80 : : {"Default", BuiltinMacro::Default},
81 : : {"Eq", BuiltinMacro::Eq},
82 : : {"PartialEq", BuiltinMacro::PartialEq},
83 : : {"Ord", BuiltinMacro::Ord},
84 : : {"PartialOrd", BuiltinMacro::PartialOrd},
85 : : {"Hash", BuiltinMacro::Hash},
86 : : }};
87 : :
88 : : AST::MacroTranscriberFunc
89 : 10244 : format_args_maker (AST::FormatArgs::Newline nl)
90 : : {
91 : 10248 : return [nl] (location_t loc, AST::MacroInvocData &invoc,
92 : : AST::InvocKind semicolon) {
93 : 4 : return MacroBuiltin::format_args_handler (loc, invoc, semicolon, nl);
94 : 10244 : };
95 : : }
96 : :
97 : : AST::MacroTranscriberFunc
98 : 10244 : inline_asm_maker (AST::AsmKind global_asm)
99 : : {
100 : 10302 : return [global_asm] (location_t loc, AST::MacroInvocData &invoc,
101 : : AST::InvocKind semicolon) {
102 : 58 : return MacroBuiltin::asm_handler (loc, invoc, semicolon, global_asm);
103 : 10244 : };
104 : : }
105 : :
106 : : AST::MacroTranscriberFunc
107 : 5122 : inline_llvm_asm_maker (AST::AsmKind global_asm)
108 : : {
109 : 5124 : return [global_asm] (location_t loc, AST::MacroInvocData &invoc,
110 : : AST::InvocKind semicolon) {
111 : 2 : return MacroBuiltin::llvm_asm_handler (loc, invoc, semicolon, global_asm);
112 : 5122 : };
113 : : }
114 : :
115 : : std::unordered_map<std::string, AST::MacroTranscriberFunc>
116 : : MacroBuiltin::builtin_transcribers = {
117 : : {"assert", MacroBuiltin::assert_handler},
118 : : {"file", MacroBuiltin::file_handler},
119 : : {"line", MacroBuiltin::line_handler},
120 : : {"column", MacroBuiltin::column_handler},
121 : : {"include_bytes", MacroBuiltin::include_bytes_handler},
122 : : {"include_str", MacroBuiltin::include_str_handler},
123 : : {"stringify", MacroBuiltin::stringify_handler},
124 : : {"compile_error", MacroBuiltin::compile_error_handler},
125 : : {"concat", MacroBuiltin::concat_handler},
126 : : {"env", MacroBuiltin::env_handler},
127 : : {"cfg", MacroBuiltin::cfg_handler},
128 : : {"include", MacroBuiltin::include_handler},
129 : : {"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
130 : : {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
131 : : {"asm", inline_asm_maker (AST::AsmKind::Inline)},
132 : : // FIXME: Is that okay?
133 : : {"llvm_asm", inline_llvm_asm_maker (AST::AsmKind::Inline)},
134 : : {"global_asm", inline_asm_maker (AST::AsmKind::Global)},
135 : : {"option_env", MacroBuiltin::option_env_handler},
136 : : /* Unimplemented macro builtins */
137 : : {"concat_idents", MacroBuiltin::sorry},
138 : : {"module_path", MacroBuiltin::sorry},
139 : : {"log_syntax", MacroBuiltin::sorry},
140 : : {"trace_macros", MacroBuiltin::sorry},
141 : : {"test", MacroBuiltin::sorry},
142 : : {"bench", MacroBuiltin::sorry},
143 : : {"test_case", MacroBuiltin::sorry},
144 : : {"global_allocator", MacroBuiltin::sorry},
145 : : {"cfg_accessible", MacroBuiltin::sorry},
146 : : {"rustc_const_stable", MacroBuiltin::sorry},
147 : : {"rustc_const_unstable", MacroBuiltin::sorry},
148 : : {"track_caller", MacroBuiltin::sorry},
149 : : /* Derive builtins do not need a real transcriber, but still need one. It
150 : : should however never be called since builtin derive macros get expanded
151 : : differently, and benefit from knowing on what kind of items they are
152 : : applied (struct, enums, unions) rather than receiving a list of tokens
153 : : like regular builtin macros */
154 : : {"RustcEncodable", MacroBuiltin::proc_macro_builtin},
155 : : {"RustcDecodable", MacroBuiltin::proc_macro_builtin},
156 : : {"Clone", MacroBuiltin::proc_macro_builtin},
157 : : {"Copy", MacroBuiltin::proc_macro_builtin},
158 : : {"Debug", MacroBuiltin::proc_macro_builtin},
159 : : {"Default", MacroBuiltin::proc_macro_builtin},
160 : : {"Eq", MacroBuiltin::proc_macro_builtin},
161 : : {"PartialEq", MacroBuiltin::proc_macro_builtin},
162 : : {"Ord", MacroBuiltin::proc_macro_builtin},
163 : : {"PartialOrd", MacroBuiltin::proc_macro_builtin},
164 : : {"Hash", MacroBuiltin::proc_macro_builtin},
165 : : };
166 : :
167 : : tl::optional<BuiltinMacro>
168 : 349 : builtin_macro_from_string (const std::string &identifier)
169 : : {
170 : 349 : auto macro = MacroBuiltin::builtins.lookup (identifier);
171 : 349 : rust_assert (macro.has_value ());
172 : :
173 : 349 : return macro;
174 : : }
175 : :
176 : : tl::optional<AST::Fragment>
177 : 0 : MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc,
178 : : AST::InvocKind semicolon)
179 : : {
180 : 0 : rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs",
181 : : invoc.get_path ().as_string ().c_str ());
182 : :
183 : 0 : return AST::Fragment::create_error ();
184 : : }
185 : :
186 : : tl::optional<AST::Fragment>
187 : 2 : MacroBuiltin::proc_macro_builtin (location_t invoc_locus,
188 : : AST::MacroInvocData &invoc,
189 : : AST::InvocKind semicolon)
190 : : {
191 : 2 : rust_error_at (invoc_locus, "cannot invoke derive macro: %qs",
192 : 2 : invoc.get_path ().as_string ().c_str ());
193 : :
194 : 2 : return AST::Fragment::create_error ();
195 : : }
196 : :
197 : : } // namespace Rust
|