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