diff options
author | liushuyu <liushuyu011@gmail.com> | 2022-04-09 02:23:16 -0600 |
---|---|---|
committer | liushuyu <liushuyu011@gmail.com> | 2022-04-17 17:35:57 -0600 |
commit | e753fa4e3633c6e6158ca26d930f0d1aaca15a6a (patch) | |
tree | fcaf248d3951da6f88f0544b41d149382962982e | |
parent | 27ad3813dccc50c9026a99b8e7c1d675c78f72e2 (diff) | |
download | gcc-e753fa4e3633c6e6158ca26d930f0d1aaca15a6a.zip gcc-e753fa4e3633c6e6158ca26d930f0d1aaca15a6a.tar.gz gcc-e753fa4e3633c6e6158ca26d930f0d1aaca15a6a.tar.bz2 |
macros: add include! macro
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.cc | 54 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.h | 3 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 1 |
3 files changed, 58 insertions, 0 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 8c68a7d..e4beb95 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -412,4 +412,58 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc) return AST::ASTFragment ({literal_exp}); } +/* Expand builtin macro include!(), which includes a source file at the current + scope compile time. */ + +AST::ASTFragment +MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc) +{ + /* Get target filename from the macro invocation, which is treated as a path + relative to the include!-ing file (currently being compiled). */ + auto lit_expr + = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus); + if (lit_expr == nullptr) + return AST::ASTFragment::create_error (); + + std::string target_filename + = source_relative_path (lit_expr->as_string (), invoc_locus); + + RAIIFile target_file (target_filename.c_str ()); + Linemap *linemap = Session::get_instance ().linemap; + + if (target_file.get_raw () == nullptr) + { + rust_error_at (lit_expr->get_locus (), "cannot open included file %s: %m", + target_filename.c_str ()); + return AST::ASTFragment::create_error (); + } + + rust_debug ("Attempting to parse included file %s", target_filename.c_str ()); + + Lexer lex (target_filename.c_str (), std::move (target_file), linemap); + Parser<Lexer> parser (std::move (lex)); + + auto parsed_items = parser.parse_items (); + bool has_error = !parser.get_errors ().empty (); + + for (const auto &error : parser.get_errors ()) + error.emit_error (); + + if (has_error) + { + // inform the user that the errors above are from a included file + rust_inform (invoc_locus, "included from here"); + return AST::ASTFragment::create_error (); + } + + std::vector<AST::SingleASTNode> nodes{}; + for (auto &item : parsed_items) + { + AST::SingleASTNode node (std::move (item)); + nodes.push_back (node); + } + + return AST::ASTFragment (nodes); +} + } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index e284c03..f1d10df 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -95,6 +95,9 @@ public: static AST::ASTFragment cfg (Location invoc_locus, AST::MacroInvocData &invoc); + + static AST::ASTFragment include (Location invoc_locus, + AST::MacroInvocData &invoc); }; } // namespace Rust diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index e9ad87c..b08258c 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -757,6 +757,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro) {"concat", MacroBuiltin::concat}, {"env", MacroBuiltin::env}, {"cfg", MacroBuiltin::cfg}, + {"include", MacroBuiltin::include}, }; auto builtin = builtin_macros.find (macro->get_rule_name ()); |