]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: builtin: Cleanup handling of builtin macros
authorArthur Cohen <arthur.cohen@embecosm.com>
Wed, 3 May 2023 09:19:30 +0000 (11:19 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:34:17 +0000 (18:34 +0100)
This commit regroups information related to builtin macros in one place instead
of spreading it over multiple files. It also adds a simple bi-directional
hashmap in order to perform lookups from a key as well as a value.

gcc/rust/ChangeLog:

* ast/rust-macro.cc (builtin_macro_from_string): Move function.
* ast/rust-macro.h (enum class): Move enum.
(builtin_macro_from_string): Move function.
* expand/rust-macro-builtins.cc (builtin_macro_from_string): New function.
(make_macro_path_str): Use new bi-map.
(parse_single_string_literal): Use new `BuiltinMacro` enum.
(MacroBuiltin::include_bytes_handler): Likewise.
(MacroBuiltin::include_str_handler): Likewise.
(MacroBuiltin::compile_error_handler): Likewise.
(MacroBuiltin::concat_handler): Likewise.
(MacroBuiltin::env_handler): Likewise.
(MacroBuiltin::include_handler): Likewise.
(MacroBuiltin::sorry): New function.
* expand/rust-macro-builtins.h (enum class): Move enum here.
(builtin_macro_from_string): New function declaration.
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit): Use
new function.
* util/rust-hir-map.cc (Mappings::insert_macro_def): Remove old
builtin macro map.

gcc/rust/ast/rust-macro.cc
gcc/rust/ast/rust-macro.h
gcc/rust/expand/rust-macro-builtins.cc
gcc/rust/expand/rust-macro-builtins.h
gcc/rust/resolve/rust-early-name-resolver.cc
gcc/rust/util/rust-hir-map.cc

index b558969eba4c672066aa22dad7affa8920401483..f36feda9970f0accc4b25c53c7a87c4d222be84a 100644 (file)
 namespace Rust {
 namespace AST {
 
-BuiltinMacro
-builtin_macro_from_string (const std::string &identifier)
-{
-  if (identifier == "assert")
-    return BuiltinMacro::Assert;
-
-  if (identifier == "file")
-    return BuiltinMacro::File;
-
-  if (identifier == "line")
-    return BuiltinMacro::Line;
-
-  if (identifier == "column")
-    return BuiltinMacro::Column;
-
-  if (identifier == "include_bytes")
-    return BuiltinMacro::IncludeBytes;
-
-  if (identifier == "include_str")
-    return BuiltinMacro::IncludeStr;
-
-  if (identifier == "stringify")
-    return BuiltinMacro::Stringify;
-
-  if (identifier == "compile_error")
-    return BuiltinMacro::CompileError;
-
-  if (identifier == "concat")
-    return BuiltinMacro::Concat;
-
-  if (identifier == "env")
-    return BuiltinMacro::Env;
-
-  if (identifier == "cfg")
-    return BuiltinMacro::Cfg;
-
-  if (identifier == "include")
-    return BuiltinMacro::Include;
-
-  gcc_unreachable ();
-}
-
 } // namespace AST
 } // namespace Rust
index 7216db8be53be475fe79417493153e5e2787a08f..b6349a71ed3e1a74f3b1f1540dd4e2855a6eb7db 100644 (file)
@@ -25,6 +25,7 @@
 #include "rust-location.h"
 #include "rust-item.h"
 #include "rust-make-unique.h"
+#include "rust-macro-builtins.h"
 
 namespace Rust {
 namespace AST {
@@ -578,28 +579,6 @@ protected:
   }
 };
 
-/**
- * All builtin macros possible
- */
-enum class BuiltinMacro
-{
-  Assert,
-  File,
-  Line,
-  Column,
-  IncludeBytes,
-  IncludeStr,
-  Stringify,
-  CompileError,
-  Concat,
-  Env,
-  Cfg,
-  Include
-};
-
-BuiltinMacro
-builtin_macro_from_string (const std::string &identifier);
-
 /* AST node of a macro invocation, which is replaced by the macro result at
  * compile time. This is technically a sum-type/tagged-union, which represents
  * both classic macro invocations and builtin macro invocations. Regular macro
index 29a8b8b867b6f63f4a8ec8b7cf4dec43673e7d40..f0f1f8c9230f0dce67553a591da3697ccd9999ad 100644 (file)
 #include "bi-map.h"
 
 namespace Rust {
+static const BiMap<std::string, BuiltinMacro> builtins = {{
+  {"assert", BuiltinMacro::Assert},
+  {"file", BuiltinMacro::File},
+  {"line", BuiltinMacro::Line},
+  {"column", BuiltinMacro::Column},
+  {"include_bytes", BuiltinMacro::IncludeBytes},
+  {"include_str", BuiltinMacro::IncludeStr},
+  {"stringify", BuiltinMacro::Stringify},
+  {"compile_error", BuiltinMacro::CompileError},
+  {"concat", BuiltinMacro::Concat},
+  {"env", BuiltinMacro::Env},
+  {"option_env", BuiltinMacro::OptionEnv},
+  {"cfg", BuiltinMacro::Cfg},
+  {"include", BuiltinMacro::Include},
+  {"format_args", BuiltinMacro::FormatArgs},
+  {"format_args_nl", BuiltinMacro::FormatArgsNl},
+  {"concat_idents", BuiltinMacro::ConcatIdents},
+  {"module_path", BuiltinMacro::ModulePath},
+  {"asm", BuiltinMacro::Asm},
+  {"llvm_asm", BuiltinMacro::LlvmAsm},
+  {"global_asm", BuiltinMacro::GlobalAsm},
+  {"log_syntax", BuiltinMacro::LogSyntax},
+  {"trace_macros", BuiltinMacro::TraceMacros},
+  {"test", BuiltinMacro::Test},
+  {"bench", BuiltinMacro::Bench},
+  {"test_case", BuiltinMacro::TestCase},
+  {"global_allocator", BuiltinMacro::GlobalAllocator},
+  {"cfg_accessible", BuiltinMacro::CfgAccessible},
+  {"RustcEncodable", BuiltinMacro::RustcDecodable},
+  {"RustcDecodable", BuiltinMacro::RustcEncodable},
+}};
+
+std::unordered_map<
+  std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>>
+  MacroBuiltin::builtin_transcribers = {
+    {"assert", MacroBuiltin::assert_handler},
+    {"file", MacroBuiltin::file_handler},
+    {"line", MacroBuiltin::line_handler},
+    {"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},
+    {"cfg", MacroBuiltin::cfg_handler},
+    {"include", MacroBuiltin::include_handler},
+    /* Unimplemented macro builtins */
+    {"format_args", MacroBuiltin::sorry},
+    {"option_env", MacroBuiltin::sorry},
+    {"format_args_nl", MacroBuiltin::sorry},
+    {"concat_idents", MacroBuiltin::sorry},
+    {"module_path", MacroBuiltin::sorry},
+    {"asm", MacroBuiltin::sorry},
+    {"llvm_asm", MacroBuiltin::sorry},
+    {"global_asm", MacroBuiltin::sorry},
+    {"log_syntax", MacroBuiltin::sorry},
+    {"trace_macros", MacroBuiltin::sorry},
+    {"test", MacroBuiltin::sorry},
+    {"bench", MacroBuiltin::sorry},
+    {"test_case", MacroBuiltin::sorry},
+    {"global_allocator", MacroBuiltin::sorry},
+    {"cfg_accessible", MacroBuiltin::sorry},
+    {"RustcEncodable", MacroBuiltin::sorry},
+    {"RustcDecodable", MacroBuiltin::sorry},
+};
+
+// FIXME: This should return an Optional
+BuiltinMacro
+builtin_macro_from_string (const std::string &identifier)
+{
+  auto macro = builtins.lookup (identifier);
+  rust_assert (builtins.is_iter_ok (macro));
+
+  return macro->second;
+}
+
 namespace {
 std::string
-make_macro_path_str (AST::BuiltinMacro kind)
+make_macro_path_str (BuiltinMacro kind)
 {
-  std::string path_str;
+  auto str = builtins.lookup (kind);
+  rust_assert (builtins.is_iter_ok (str));
 
-  switch (kind)
-    {
-    // TODO: Should this be a table lookup?
-    case AST::BuiltinMacro::Assert:
-      path_str = "assert";
-      break;
-    case AST::BuiltinMacro::File:
-      path_str = "file";
-      break;
-    case AST::BuiltinMacro::Line:
-      path_str = "line";
-      break;
-    case AST::BuiltinMacro::Column:
-      path_str = "column";
-      break;
-    case AST::BuiltinMacro::IncludeBytes:
-      path_str = "include_bytes";
-      break;
-    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;
-    case AST::BuiltinMacro::Concat:
-      path_str = "concat";
-      break;
-    case AST::BuiltinMacro::Env:
-      path_str = "env";
-      break;
-    case AST::BuiltinMacro::Cfg:
-      path_str = "cfg";
-      break;
-    case AST::BuiltinMacro::Include:
-      path_str = "include";
-      break;
-    }
-
-  return path_str;
+  return str->second;
 }
 
 static std::vector<std::unique_ptr<AST::MacroInvocation>>
@@ -116,7 +153,7 @@ make_string (Location locus, std::string value)
 // TODO: Is this correct?
 static AST::Fragment
 make_eager_builtin_invocation (
-  AST::BuiltinMacro kind, Location locus, AST::DelimTokenTree arguments,
+  BuiltinMacro kind, Location locus, AST::DelimTokenTree arguments,
   std::vector<std::unique_ptr<AST::MacroInvocation>> &&pending_invocations)
 {
   auto path_str = make_macro_path_str (kind);
@@ -224,7 +261,7 @@ try_expand_many_expr (Parser<MacroInvocLexer> &parser,
    but otherwise enforce that these are the only tokens.  */
 
 std::unique_ptr<AST::Expr>
-parse_single_string_literal (AST::BuiltinMacro kind,
+parse_single_string_literal (BuiltinMacro kind,
                             AST::DelimTokenTree &invoc_token_tree,
                             Location invoc_locus, MacroExpander *expander)
 {
@@ -384,7 +421,7 @@ MacroBuiltin::include_bytes_handler (Location invoc_locus,
   /* 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 (AST::BuiltinMacro::IncludeBytes,
+    = parse_single_string_literal (BuiltinMacro::IncludeBytes,
                                   invoc.get_delim_tok_tree (), invoc_locus,
                                   invoc.get_expander ());
   if (lit_expr == nullptr)
@@ -444,7 +481,7 @@ MacroBuiltin::include_str_handler (Location invoc_locus,
   /* 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 (AST::BuiltinMacro::IncludeStr,
+    = parse_single_string_literal (BuiltinMacro::IncludeStr,
                                   invoc.get_delim_tok_tree (), invoc_locus,
                                   invoc.get_expander ());
   if (lit_expr == nullptr)
@@ -527,7 +564,7 @@ MacroBuiltin::compile_error_handler (Location invoc_locus,
                                     AST::MacroInvocData &invoc)
 {
   auto lit_expr
-    = parse_single_string_literal (AST::BuiltinMacro::CompileError,
+    = parse_single_string_literal (BuiltinMacro::CompileError,
                                   invoc.get_delim_tok_tree (), invoc_locus,
                                   invoc.get_expander ());
   if (lit_expr == nullptr)
@@ -605,8 +642,7 @@ MacroBuiltin::concat_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 
   auto pending_invocations = check_for_eager_invocations (expanded_expr);
   if (!pending_invocations.empty ())
-    return make_eager_builtin_invocation (AST::BuiltinMacro::Concat,
-                                         invoc_locus,
+    return make_eager_builtin_invocation (BuiltinMacro::Concat, invoc_locus,
                                          invoc.get_delim_tok_tree (),
                                          std::move (pending_invocations));
 
@@ -672,7 +708,7 @@ MacroBuiltin::env_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 
   auto pending = check_for_eager_invocations (expanded_expr);
   if (!pending.empty ())
-    return make_eager_builtin_invocation (AST::BuiltinMacro::Env, invoc_locus,
+    return make_eager_builtin_invocation (BuiltinMacro::Env, invoc_locus,
                                          invoc_token_tree,
                                          std::move (pending));
 
@@ -770,7 +806,7 @@ MacroBuiltin::include_handler (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 (AST::BuiltinMacro::Include,
+    = parse_single_string_literal (BuiltinMacro::Include,
                                   invoc.get_delim_tok_tree (), invoc_locus,
                                   invoc.get_expander ());
   if (lit_expr == nullptr)
@@ -877,6 +913,15 @@ MacroBuiltin::stringify_handler (Location invoc_locus,
   auto token
     = make_token (Token::make_string (invoc_locus, std::move (content)));
   return AST::Fragment ({node}, std::move (token));
-} // namespace Rust
+}
+
+AST::Fragment
+MacroBuiltin::sorry (Location invoc_locus, AST::MacroInvocData &invoc)
+{
+  rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs",
+                invoc.get_path ().as_string ().c_str ());
+
+  return AST::Fragment::create_error ();
+}
 
 } // namespace Rust
index bd4f1f95b741f54e8d71c9683f688a8298a047d5..10a38d7b93f03ce5bd1e68aa706ddbc6c4ad279f 100644 (file)
 #include "rust-ast-fragment.h"
 #include "rust-location.h"
 
+namespace Rust {
+
+// FIXME: Add a BuiltinMacro class which contains a name (or should it?), a
+// transcriber and extra info if necessary
+// then make a global map<string, BuiltinMacro>
+
+/**
+ * All builtin macros possible
+ */
+enum class BuiltinMacro
+{
+  Assert,
+  File,
+  Line,
+  Column,
+  IncludeBytes,
+  IncludeStr,
+  Stringify,
+  CompileError,
+  Concat,
+  Env,
+  OptionEnv,
+  Cfg,
+  Include,
+  FormatArgs,
+  FormatArgsNl,
+  ConcatIdents,
+  ModulePath,
+  Asm,
+  LlvmAsm,
+  GlobalAsm,
+  LogSyntax,
+  TraceMacros,
+  Test,
+  Bench,
+  TestCase,
+  GlobalAllocator,
+  CfgAccessible,
+  RustcDecodable,
+  RustcEncodable,
+};
+
+BuiltinMacro
+builtin_macro_from_string (const std::string &identifier);
+
 /**
  * This class provides a list of builtin macros implemented by the compiler.
  * The functions defined are called "builtin transcribers" in that they replace
  * This map is built as a static variable in the `insert_macro_def()` method
  * of the `Mappings` class.
  */
-
-namespace Rust {
 class MacroBuiltin
 {
 public:
+  static std::unordered_map<
+    std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>>
+    builtin_transcribers;
+
   static AST::Fragment assert_handler (Location invoc_locus,
                                       AST::MacroInvocData &invoc);
 
@@ -99,7 +146,20 @@ public:
 
   static AST::Fragment line_handler (Location invoc_locus,
                                     AST::MacroInvocData &invoc);
+
+  static AST::Fragment sorry (Location invoc_locus, AST::MacroInvocData &invoc);
 };
 } // namespace Rust
 
+namespace std {
+template <> struct hash<Rust::BuiltinMacro>
+{
+  size_t operator() (const Rust::BuiltinMacro &macro) const noexcept
+  {
+    return hash<std::underlying_type<Rust::BuiltinMacro>::type> () (
+      static_cast<std::underlying_type<Rust::BuiltinMacro>::type> (macro));
+  }
+};
+} // namespace std
+
 #endif // RUST_MACRO_BUILTINS_H
index 6e869d6a7c9207290153f456c373f8a0e84cd3f7..145b39311882cc13949f3a740e166d4407cfed6b 100644 (file)
@@ -19,6 +19,7 @@
 #include "rust-early-name-resolver.h"
 #include "rust-ast-full.h"
 #include "rust-name-resolver.h"
+#include "rust-macro-builtins.h"
 
 namespace Rust {
 namespace Resolver {
@@ -873,7 +874,7 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
   if (is_builtin)
     {
       auto builtin_kind
-       = AST::builtin_macro_from_string (rules_def->get_rule_name ());
+       = builtin_macro_from_string (rules_def->get_rule_name ());
       invoc.map_to_builtin (builtin_kind);
     }
 
index 8d001fd8241f755d9988f4e41ee6119180a0de56..5c711ca6ee393a69092fbfa904d1a33a854eb9de 100644 (file)
@@ -868,23 +868,6 @@ Mappings::iterate_trait_items (
 void
 Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
 {
-  static std::map<
-    std::string, std::function<AST::Fragment (Location, AST::MacroInvocData &)>>
-    builtin_macros = {
-      {"assert", MacroBuiltin::assert_handler},
-      {"file", MacroBuiltin::file_handler},
-      {"line", MacroBuiltin::line_handler},
-      {"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},
-      {"cfg", MacroBuiltin::cfg_handler},
-      {"include", MacroBuiltin::include_handler},
-    };
-
   auto outer_attrs = macro->get_outer_attrs ();
   bool should_be_builtin
     = std::any_of (outer_attrs.begin (), outer_attrs.end (),
@@ -893,8 +876,9 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
                   });
   if (should_be_builtin)
     {
-      auto builtin = builtin_macros.find (macro->get_rule_name ());
-      if (builtin != builtin_macros.end ())
+      auto builtin
+       = MacroBuiltin::builtin_transcribers.find (macro->get_rule_name ());
+      if (builtin != MacroBuiltin::builtin_transcribers.end ())
        macro->set_builtin_transcriber (builtin->second);
       else
        rust_error_at (macro->get_locus (),