[gcc r14-7870] gccrs: use tl::optional for macro transcribers

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 18:05:41 GMT 2024


https://gcc.gnu.org/g:58b49a65a3f91f0f6643dc973f46911363148c16

commit r14-7870-g58b49a65a3f91f0f6643dc973f46911363148c16
Author: Marc Poulhiès <dkm@kataplop.net>
Date:   Wed Jul 19 10:54:52 2023 +0200

    gccrs: use tl::optional for macro transcribers
    
    refs #2421.
    
    gcc/rust/ChangeLog:
    
            * ast/rust-ast-fragment.cc (Fragment::create_empty): New.
            * ast/rust-ast-fragment.h (MacroTranscriberFunc): New.
            * ast/rust-macro.h (MacroRulesDefinition): Use MacroTranscriberFunc.
            * expand/rust-macro-builtins.cc
            (MacroBuiltin::builtin_transcribers): likewise.
            (MacroBuiltin::assert_handler): Return optional.
            (MacroBuiltin::file_handler): Likewise.
            (MacroBuiltin::column_handler): Likewise.
            (MacroBuiltin::include_bytes_handler): Likewise.
            (MacroBuiltin::include_str_handler): Likewise.
            (MacroBuiltin::compile_error_handler): Likewise.
            (MacroBuiltin::concat_handler): Likewise.
            (MacroBuiltin::env_handler): Likewise.
            (MacroBuiltin::cfg_handler): Likewise.
            (MacroBuiltin::include_handler): Likewise.
            (MacroBuiltin::line_handler): Likewise.
            (MacroBuiltin::stringify_handler): Likewise.
            (MacroBuiltin::sorry): Likewise.
            * expand/rust-macro-builtins.h (builtin_transcribers): Use
            MacroTranscriberFunc.
            (assert_handler): Return optional.
            (file_handler): Likewise.
            (column_handler): Likewise.
            (include_bytes_handler): Likewise.
            (include_str_handler): Likewise.
            (compile_error_handler): Likewise.
            (concat_handler): Likewise.
            (env_handler): Likewise.
            (cfg_handler): Likewise.
            (include_handler): Likewise.
            (line_handler): Likewise.
            (stringify_handler): Likewise.
            (sorry): Likewise.
            * expand/rust-macro-expand.cc (MacroExpander::expand_invoc):
            Adjust to transcribers returning optional.
    
    Signed-off-by: Marc Poulhiès <dkm@kataplop.net>

Diff:
---
 gcc/rust/ast/rust-ast-fragment.cc      |  6 ++++
 gcc/rust/ast/rust-ast-fragment.h       | 13 ++++++++
 gcc/rust/ast/rust-macro.h              | 12 +++----
 gcc/rust/expand/rust-macro-builtins.cc | 31 +++++++++---------
 gcc/rust/expand/rust-macro-builtins.h  | 58 +++++++++++++++++-----------------
 gcc/rust/expand/rust-macro-expand.cc   |  3 +-
 6 files changed, 70 insertions(+), 53 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
index 0814ef49426..e7574519465 100644
--- a/gcc/rust/ast/rust-ast-fragment.cc
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -55,6 +55,12 @@ Fragment::create_error ()
   return Fragment (FragmentKind::Error, {}, {});
 }
 
+Fragment
+Fragment::create_empty ()
+{
+  return Fragment (FragmentKind::Complete, {}, {});
+}
+
 Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
 		    std::vector<std::unique_ptr<AST::Token>> tokens)
   : kind (FragmentKind::Complete), nodes (std::move (nodes)),
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
index e74632ae055..33603ac5a4e 100644
--- a/gcc/rust/ast/rust-ast-fragment.h
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -60,6 +60,11 @@ public:
    */
   static Fragment create_error ();
 
+  /**
+   * Create an empty fragment
+   */
+  static Fragment create_empty ();
+
   /**
    * Create a complete AST fragment
    */
@@ -117,6 +122,14 @@ private:
   bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const;
   void assert_single_fragment (SingleASTNode::NodeType expected) const;
 };
+
+/**
+ * This is the type for transcriber functions found in
+ * rust-macro-builtins.{h,cc}.
+ */
+using MacroTranscriberFunc
+  = std::function<tl::optional<Fragment> (location_t, MacroInvocData &)>;
+
 } // namespace AST
 } // namespace Rust
 
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index a9d5b95fda6..76d244e604e 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -468,7 +468,8 @@ private:
   std::vector<MacroRule> rules; // inlined form
   location_t locus;
 
-  std::function<Fragment (location_t, MacroInvocData &)> associated_transcriber;
+  MacroTranscriberFunc associated_transcriber;
+
   // Since we can't compare std::functions, we need to use an extra boolean
   bool is_builtin_rule;
   MacroKind kind;
@@ -503,8 +504,7 @@ private:
   {}
 
   MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
-			std::function<Fragment (location_t, MacroInvocData &)>
-			  associated_transcriber,
+			MacroTranscriberFunc associated_transcriber,
 			MacroKind kind, Visibility vis)
     : VisItem (std::move (vis), std::vector<Attribute> ()),
       outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
@@ -560,14 +560,12 @@ public:
   const std::vector<MacroRule> &get_rules () const { return rules; }
 
   bool is_builtin () const { return is_builtin_rule; }
-  const std::function<Fragment (location_t, MacroInvocData &)> &
-  get_builtin_transcriber () const
+  const MacroTranscriberFunc &get_builtin_transcriber () const
   {
     rust_assert (is_builtin ());
     return associated_transcriber;
   }
-  void set_builtin_transcriber (
-    std::function<Fragment (location_t, MacroInvocData &)> transcriber)
+  void set_builtin_transcriber (MacroTranscriberFunc transcriber)
   {
     associated_transcriber = transcriber;
     is_builtin_rule = true;
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 57949ad3392..20c207ea17d 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -74,8 +74,7 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
 
 }};
 
-std::unordered_map<
-  std::string, std::function<AST::Fragment (location_t, AST::MacroInvocData &)>>
+std::unordered_map<std::string, AST::MacroTranscriberFunc>
   MacroBuiltin::builtin_transcribers = {
     {"assert", MacroBuiltin::assert_handler},
     {"file", MacroBuiltin::file_handler},
@@ -398,7 +397,7 @@ load_file_bytes (location_t invoc_locus, const char *filename)
 }
 } // namespace
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::assert_handler (location_t invoc_locus,
 			      AST::MacroInvocData &invoc)
 {
@@ -407,7 +406,7 @@ MacroBuiltin::assert_handler (location_t invoc_locus,
   return AST::Fragment::create_error ();
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &)
 {
   auto current_file = LOCATION_FILE (invoc_locus);
@@ -418,7 +417,7 @@ MacroBuiltin::file_handler (location_t invoc_locus, AST::MacroInvocData &)
   return AST::Fragment ({file_str}, std::move (str_token));
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &)
 {
   auto current_column = LOCATION_COLUMN (invoc_locus);
@@ -436,7 +435,7 @@ MacroBuiltin::column_handler (location_t invoc_locus, AST::MacroInvocData &)
    of the given file as reference to a byte array. Yields an expression of type
    &'static [u8; N].  */
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::include_bytes_handler (location_t invoc_locus,
 				     AST::MacroInvocData &invoc)
 {
@@ -496,7 +495,7 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus,
    of the given file as a string. The file must be UTF-8 encoded. Yields an
    expression of type &'static str.  */
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::include_str_handler (location_t invoc_locus,
 				   AST::MacroInvocData &invoc)
 {
@@ -581,7 +580,7 @@ MacroBuiltin::include_str_handler (location_t invoc_locus,
 
 /* Expand builtin macro compile_error!("error"), which forces a compile error
    during the compile time. */
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::compile_error_handler (location_t invoc_locus,
 				     AST::MacroInvocData &invoc)
 {
@@ -642,7 +641,7 @@ MacroBuiltin::compile_error_handler (location_t invoc_locus,
 // invocation?
 // Do we split the two passes of parsing the token tree and then expanding it?
 // Can we do that easily?
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::concat_handler (location_t invoc_locus,
 			      AST::MacroInvocData &invoc)
 {
@@ -707,7 +706,7 @@ MacroBuiltin::concat_handler (location_t invoc_locus,
 
 /* Expand builtin macro env!(), which inspects an environment variable at
    compile time. */
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
 {
   auto invoc_token_tree = invoc.get_delim_tok_tree ();
@@ -781,7 +780,7 @@ MacroBuiltin::env_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
   return AST::Fragment ({node}, std::move (tok));
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
 {
   // only parse if not already parsed
@@ -823,7 +822,7 @@ MacroBuiltin::cfg_handler (location_t invoc_locus, AST::MacroInvocData &invoc)
 /* Expand builtin macro include!(), which includes a source file at the current
  scope compile time. */
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::include_handler (location_t invoc_locus,
 			       AST::MacroInvocData &invoc)
 {
@@ -893,7 +892,7 @@ MacroBuiltin::include_handler (location_t invoc_locus,
   return AST::Fragment (nodes, std::vector<std::unique_ptr<AST::Token>> ());
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &)
 {
   auto current_line = LOCATION_LINE (invoc_locus);
@@ -908,7 +907,7 @@ MacroBuiltin::line_handler (location_t invoc_locus, AST::MacroInvocData &)
   return AST::Fragment ({line_no}, std::move (tok));
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::stringify_handler (location_t invoc_locus,
 				 AST::MacroInvocData &invoc)
 {
@@ -938,7 +937,7 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
   return AST::Fragment ({node}, std::move (token));
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc)
 {
   rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs",
@@ -947,7 +946,7 @@ MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc)
   return AST::Fragment::create_error ();
 }
 
-AST::Fragment
+tl::optional<AST::Fragment>
 MacroBuiltin::proc_macro_builtin (location_t invoc_locus,
 				  AST::MacroInvocData &invoc)
 {
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index 3bde262018f..6a84a8b86f6 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -118,52 +118,52 @@ class MacroBuiltin
 {
 public:
   static const BiMap<std::string, BuiltinMacro> builtins;
-  static std::unordered_map<std::string, std::function<AST::Fragment (
-					   location_t, AST::MacroInvocData &)>>
+  static std::unordered_map<std::string, AST::MacroTranscriberFunc>
     builtin_transcribers;
 
-  static AST::Fragment assert_handler (location_t invoc_locus,
-				       AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  assert_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment file_handler (location_t invoc_locus,
-				     AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment> file_handler (location_t invoc_locus,
+						   AST::MacroInvocData &invoc);
 
-  static AST::Fragment column_handler (location_t invoc_locus,
-				       AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  column_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment include_bytes_handler (location_t invoc_locus,
-					      AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  include_bytes_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment include_str_handler (location_t invoc_locus,
-					    AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  include_str_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment stringify_handler (location_t invoc_locus,
-					  AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  stringify_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment compile_error_handler (location_t invoc_locus,
-					      AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  compile_error_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment concat_handler (location_t invoc_locus,
-				       AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  concat_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment env_handler (location_t invoc_locus,
-				    AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment> env_handler (location_t invoc_locus,
+						  AST::MacroInvocData &invoc);
 
-  static AST::Fragment cfg_handler (location_t invoc_locus,
-				    AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment> cfg_handler (location_t invoc_locus,
+						  AST::MacroInvocData &invoc);
 
-  static AST::Fragment include_handler (location_t invoc_locus,
-					AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment>
+  include_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
 
-  static AST::Fragment line_handler (location_t invoc_locus,
-				     AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment> line_handler (location_t invoc_locus,
+						   AST::MacroInvocData &invoc);
 
-  static AST::Fragment sorry (location_t invoc_locus,
-			      AST::MacroInvocData &invoc);
+  static tl::optional<AST::Fragment> sorry (location_t invoc_locus,
+					    AST::MacroInvocData &invoc);
 
   /* Builtin procedural macros do not work directly on tokens, but still need a
    * builtin transcriber to be considered proper builtin macros */
-  static AST::Fragment proc_macro_builtin (location_t, AST::MacroInvocData &);
+  static tl::optional<AST::Fragment> proc_macro_builtin (location_t,
+							 AST::MacroInvocData &);
 };
 } // namespace Rust
 
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 09c8fc5b0ea..2010357277d 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -286,7 +286,8 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon)
 
   if (rules_def->is_builtin ())
     fragment
-      = rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data);
+      = rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data)
+	  .value_or (AST::Fragment::create_empty ());
   else
     fragment = expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def,
 				  has_semicolon);


More information about the Gcc-cvs mailing list