Skip to content

Commit f6e926a

Browse files
P-E-Pphilberty
authored andcommitted
expand: Add stringify macro
Add the stringify macro expansion as well as some tests. gcc/rust/ChangeLog: * ast/rust-macro.cc (builtin_macro_from_string): Add identifier identification. * ast/rust-macro.h (enum class): Add Stringify builtin macro type. * expand/rust-macro-builtins.cc (make_macro_path_str): Add path for builtin stringify macro. (MacroBuiltin::stringify_handler): Add handler for builtin stringify macro. * expand/rust-macro-builtins.h: Add stringify handler's prototype. * util/rust-hir-map.cc (Mappings::insert_macro_def): Add stringify handler to builtin hir map. gcc/testsuite/ChangeLog: * rust/compile/stringify.rs: Add a basic test with some text. * rust/execute/torture/builtin_macro_stringify.rs: Verify the text is left as is without any other macro expansion. Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
1 parent 914b938 commit f6e926a

File tree

7 files changed

+85
-0
lines changed

7 files changed

+85
-0
lines changed

gcc/rust/ast/rust-macro.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ builtin_macro_from_string (const std::string &identifier)
4242
if (identifier == "include_str")
4343
return BuiltinMacro::IncludeStr;
4444

45+
if (identifier == "stringify")
46+
return BuiltinMacro::Stringify;
47+
4548
if (identifier == "compile_error")
4649
return BuiltinMacro::CompileError;
4750

gcc/rust/ast/rust-macro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ enum class BuiltinMacro
589589
Column,
590590
IncludeBytes,
591591
IncludeStr,
592+
Stringify,
592593
CompileError,
593594
Concat,
594595
Env,

gcc/rust/expand/rust-macro-builtins.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ make_macro_path_str (AST::BuiltinMacro kind)
5858
case AST::BuiltinMacro::IncludeStr:
5959
path_str = "include_str";
6060
break;
61+
case AST::BuiltinMacro::Stringify:
62+
path_str = "stringify";
63+
break;
6164
case AST::BuiltinMacro::CompileError:
6265
path_str = "compile_error";
6366
break;
@@ -845,4 +848,34 @@ MacroBuiltin::line_handler (Location invoc_locus, AST::MacroInvocData &)
845848
return AST::Fragment ({line_no}, std::move (tok));
846849
}
847850

851+
AST::Fragment
852+
MacroBuiltin::stringify_handler (Location invoc_locus,
853+
AST::MacroInvocData &invoc)
854+
{
855+
std::string content;
856+
auto invoc_token_tree = invoc.get_delim_tok_tree ();
857+
auto tokens = invoc_token_tree.to_token_stream ();
858+
859+
// Tokens stream includes the first and last delimiter
860+
// which we need to skip.
861+
for (auto token = tokens.cbegin () + 1; token < tokens.cend () - 1; token++)
862+
{
863+
// Rust stringify format has no garantees but the reference compiler
864+
// removes spaces before some tokens depending on the lexer's behavior,
865+
// let's mimick some of those behaviors.
866+
auto token_id = (*token)->get_id ();
867+
if (token_id != RIGHT_PAREN && token_id != EXCLAM
868+
&& token != tokens.cbegin () + 1)
869+
{
870+
content.push_back (' ');
871+
}
872+
content += (*token)->as_string ();
873+
}
874+
875+
auto node = AST::SingleASTNode (make_string (invoc_locus, content));
876+
auto token
877+
= make_token (Token::make_string (invoc_locus, std::move (content)));
878+
return AST::Fragment ({node}, std::move (token));
879+
} // namespace Rust
880+
848881
} // namespace Rust

gcc/rust/expand/rust-macro-builtins.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class MacroBuiltin
7979
static AST::Fragment include_str_handler (Location invoc_locus,
8080
AST::MacroInvocData &invoc);
8181

82+
static AST::Fragment stringify_handler (Location invoc_locus,
83+
AST::MacroInvocData &invoc);
84+
8285
static AST::Fragment compile_error_handler (Location invoc_locus,
8386
AST::MacroInvocData &invoc);
8487

gcc/rust/util/rust-hir-map.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
856856
{"column", MacroBuiltin::column_handler},
857857
{"include_bytes", MacroBuiltin::include_bytes_handler},
858858
{"include_str", MacroBuiltin::include_str_handler},
859+
{"stringify", MacroBuiltin::stringify_handler},
859860
{"compile_error", MacroBuiltin::compile_error_handler},
860861
{"concat", MacroBuiltin::concat_handler},
861862
{"env", MacroBuiltin::env_handler},
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(rustc_attrs)]
2+
3+
#[rustc_builtin_macro]
4+
macro_rules! stringify {
5+
() => {};
6+
}
7+
8+
fn main() {
9+
let _a = stringify!(sample text with parenthesis () and things! This will become a "string".);
10+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// { dg-output "a! ()" }
2+
#![feature(rustc_attrs)]
3+
4+
#[rustc_builtin_macro]
5+
macro_rules! stringify {
6+
() => {};
7+
}
8+
9+
macro_rules! a {
10+
() => {
11+
" foo"
12+
};
13+
}
14+
15+
extern "C" {
16+
fn printf(fmt: *const i8, ...);
17+
}
18+
19+
fn print(s: &str) {
20+
unsafe {
21+
printf(
22+
"%s" as *const str as *const i8,
23+
s as *const str as *const i8,
24+
);
25+
}
26+
}
27+
28+
fn main() -> i32 {
29+
let a = stringify!(a!());
30+
31+
print(a);
32+
33+
0
34+
}

0 commit comments

Comments
 (0)