diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-03-06 09:58:02 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-03-07 10:07:31 +0000 |
commit | f6e926a68941cda00086c3ed29523de0c0980b9f (patch) | |
tree | d2261cf70b1d8e5ec43ccc2f1e3b29d6575ca517 /gcc | |
parent | 914b938884f9903681305184534a2e9869760f84 (diff) | |
download | gcc-f6e926a68941cda00086c3ed29523de0c0980b9f.zip gcc-f6e926a68941cda00086c3ed29523de0c0980b9f.tar.gz gcc-f6e926a68941cda00086c3ed29523de0c0980b9f.tar.bz2 |
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 <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-macro.cc | 3 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 1 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.cc | 33 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.h | 3 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/stringify.rs | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/builtin_macro_stringify.rs | 34 |
7 files changed, 85 insertions, 0 deletions
diff --git a/gcc/rust/ast/rust-macro.cc b/gcc/rust/ast/rust-macro.cc index b6f8f6c..cb4bae7 100644 --- a/gcc/rust/ast/rust-macro.cc +++ b/gcc/rust/ast/rust-macro.cc @@ -42,6 +42,9 @@ builtin_macro_from_string (const std::string &identifier) if (identifier == "include_str") return BuiltinMacro::IncludeStr; + if (identifier == "stringify") + return BuiltinMacro::Stringify; + if (identifier == "compile_error") return BuiltinMacro::CompileError; diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index be8ed56..f667a0a 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -589,6 +589,7 @@ enum class BuiltinMacro Column, IncludeBytes, IncludeStr, + Stringify, CompileError, Concat, Env, diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 5f317a0..f30c963 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -58,6 +58,9 @@ make_macro_path_str (AST::BuiltinMacro kind) case AST::BuiltinMacro::IncludeStr: path_str = "include_str"; break; + case AST::BuiltinMacro::Stringify: + path_str = "stringify"; + break; case AST::BuiltinMacro::CompileError: path_str = "compile_error"; break; @@ -845,4 +848,34 @@ MacroBuiltin::line_handler (Location invoc_locus, AST::MacroInvocData &) return AST::Fragment ({line_no}, std::move (tok)); } +AST::Fragment +MacroBuiltin::stringify_handler (Location invoc_locus, + AST::MacroInvocData &invoc) +{ + std::string content; + auto invoc_token_tree = invoc.get_delim_tok_tree (); + auto tokens = invoc_token_tree.to_token_stream (); + + // Tokens stream includes the first and last delimiter + // which we need to skip. + for (auto token = tokens.cbegin () + 1; token < tokens.cend () - 1; token++) + { + // Rust stringify format has no garantees but the reference compiler + // removes spaces before some tokens depending on the lexer's behavior, + // let's mimick some of those behaviors. + auto token_id = (*token)->get_id (); + if (token_id != RIGHT_PAREN && token_id != EXCLAM + && token != tokens.cbegin () + 1) + { + content.push_back (' '); + } + content += (*token)->as_string (); + } + + auto node = AST::SingleASTNode (make_string (invoc_locus, content)); + auto token + = make_token (Token::make_string (invoc_locus, std::move (content))); + return AST::Fragment ({node}, std::move (token)); +} // namespace Rust + } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index 6d7a012..ea0f64a 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -79,6 +79,9 @@ public: static AST::Fragment include_str_handler (Location invoc_locus, AST::MacroInvocData &invoc); + static AST::Fragment stringify_handler (Location invoc_locus, + AST::MacroInvocData &invoc); + static AST::Fragment compile_error_handler (Location invoc_locus, AST::MacroInvocData &invoc); diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index a968704..57c0a3c 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -856,6 +856,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro) {"column", MacroBuiltin::column_handler}, {"include_bytes", MacroBuiltin::include_bytes_handler}, {"include_str", MacroBuiltin::include_str_handler}, + {"stringify", MacroBuiltin::stringify_handler}, {"compile_error", MacroBuiltin::compile_error_handler}, {"concat", MacroBuiltin::concat_handler}, {"env", MacroBuiltin::env_handler}, diff --git a/gcc/testsuite/rust/compile/stringify.rs b/gcc/testsuite/rust/compile/stringify.rs new file mode 100644 index 0000000..0350a3c --- /dev/null +++ b/gcc/testsuite/rust/compile/stringify.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! stringify { + () => {}; +} + +fn main() { + let _a = stringify!(sample text with parenthesis () and things! This will become a "string".); +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_stringify.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_stringify.rs new file mode 100644 index 0000000..e6f4a33 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_stringify.rs @@ -0,0 +1,34 @@ +// { dg-output "a! ()" } +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! stringify { + () => {}; +} + +macro_rules! a { + () => { + " foo" + }; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + let a = stringify!(a!()); + + print(a); + + 0 +} |