public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-7658] gccrs: expand: Add prc macro expander and registration
@ 2024-01-16 17:51 Arthur Cohen
  0 siblings, 0 replies; only message in thread
From: Arthur Cohen @ 2024-01-16 17:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:663c4102a8ad43ec409e04d5ab834d38f161bdb5

commit r14-7658-g663c4102a8ad43ec409e04d5ab834d38f161bdb5
Author: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Date:   Thu May 18 14:05:25 2023 +0200

    gccrs: expand: Add prc macro expander and registration
    
    Add containers and functions to the hir-map in order to register and
    lookup all three kind of procedural macros.
    Add a first draft for attribute procedural macro expansion. This
    expander still lack proper error handling as well as polishing.
    
    gcc/rust/ChangeLog:
    
            * util/rust-hir-map.cc (Mappings::insert_bang_proc_macro):
            Add a function to insert a new bang proc macro.
            (Mappings::lookup_bang_proc_macro): Add a function to lookup a
            bang procedural macro.
            (Mappings::insert_derive_proc_macro): Add a function to insert a
            derive procedural macro.
            (Mappings::lookup_derive_proc_macro): Add a function to lookup a
            derive procedural macro.
            (Mappings::insert_attribute_proc_macro): Add a function to
            insert an attribute procedural macro.
            (Mappings::lookup_attribute_proc_macro): Add a function to
            lookup an attribute procedural macro.
            * util/rust-hir-map.h: Add function prototypes.
            * expand/rust-expand-visitor.cc (ExpandVisitor::expand_outer_attribute):
            Implement expansion of outer attributes.
            (ExpandVisitor::expand_inner_attribute):
            Add call for inner attribute expansion.
            * expand/rust-expand-visitor.h:
            Add new procedural macro expander attribute.
            * expand/rust-proc-macro.cc (load_macros_array): Add a function
            to load the proc macro array from a given shared object.
            (load_macros): Add a function to retrieve procedural macro
            vector from a given shared object.
            (ProcMacroExpander::import_proc_macros): Add a function to load
            procedural macros from a given extern crate name.
            * expand/rust-proc-macro.h (RUST_PROC_MACRO_H): Add new
            proc-macro file.
            (class ProcMacroExpander): Add new ProcMacroExpander class.
            * rust-session-manager.cc (Session::expansion): Create new macro
            expander and feed it to the expand visitor.
            * util/rust-attributes.cc: Add macro_export builtin attribute.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>

Diff:
---
 gcc/rust/expand/rust-expand-visitor.cc |  8 ++--
 gcc/rust/expand/rust-expand-visitor.h  |  6 ++-
 gcc/rust/expand/rust-proc-macro.cc     | 43 ++++++++++++++++++
 gcc/rust/expand/rust-proc-macro.h      | 79 ++++++++++++++++++++++++++++++++++
 gcc/rust/rust-session-manager.cc       |  3 +-
 gcc/rust/util/rust-attributes.cc       |  1 +
 gcc/rust/util/rust-hir-map.cc          | 66 ++++++++++++++++++++++++++++
 gcc/rust/util/rust-hir-map.h           | 29 ++++++++++++-
 8 files changed, 229 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index b95649d5cd6..04a899f1497 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-expand-visitor.h"
+#include "rust-proc-macro.h"
 #include "rust-attributes.h"
 #include "rust-ast.h"
 #include "rust-type.h"
@@ -1551,7 +1552,8 @@ template <typename T>
 void
 ExpandVisitor::expand_outer_attribute (T &item, AST::SimplePath &path)
 {
-  // FIXME: Implement outer attribute expansion
+  // FIXME: Retrieve path from segments + local use statements instead of string
+  proc_expander.expand_attribute_proc_macro (item, path);
 }
 
 template <typename T>
@@ -1585,8 +1587,8 @@ template <typename T>
 void
 ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
 {
-  // TODO: Warn about instability ?
-  // FIXME: Implement expansion for that particular path
+  // FIXME: Retrieve path from segments + local use statements instead of string
+  proc_expander.expand_attribute_proc_macro (item, path);
 }
 
 template <typename T>
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index 85893347def..fd72d0b6771 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -21,6 +21,7 @@
 
 #include "rust-ast-visitor.h"
 #include "rust-macro-expand.h"
+#include "rust-proc-macro.h"
 
 namespace Rust {
 
@@ -39,7 +40,9 @@ is_builtin (AST::Attribute &attr);
 class ExpandVisitor : public AST::ASTVisitor
 {
 public:
-  ExpandVisitor (MacroExpander &expander) : expander (expander) {}
+  ExpandVisitor (MacroExpander &expander, ProcMacroExpander &proc_expander)
+    : expander (expander), proc_expander (proc_expander)
+  {}
 
   /* Expand all of the macro invocations currently contained in a crate */
   void go (AST::Crate &crate);
@@ -374,6 +377,7 @@ public:
 
 private:
   MacroExpander &expander;
+  ProcMacroExpander &proc_expander;
 };
 
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-proc-macro.cc b/gcc/rust/expand/rust-proc-macro.cc
index 22744cb547d..a53a5d87ab9 100644
--- a/gcc/rust/expand/rust-proc-macro.cc
+++ b/gcc/rust/expand/rust-proc-macro.cc
@@ -61,4 +61,47 @@ load_macros (std::string path)
 					    array->macros + array->length);
 }
 
+void
+ProcMacroExpander::import_proc_macros (std::string extern_crate)
+{
+  auto path = session.extern_crates.find (extern_crate);
+  if (path == session.extern_crates.end ())
+    {
+      // Extern crate path is not available.
+      // FIXME: Emit error
+      rust_error_at (Location (), "Cannot find requested proc macro crate");
+      gcc_unreachable ();
+    }
+  auto macros = load_macros (path->second);
+
+  std::string prefix = extern_crate + "::";
+  for (auto &macro : macros)
+    {
+      switch (macro.tag)
+	{
+	case ProcMacro::CUSTOM_DERIVE:
+	  rust_debug ("Found one derive proc macro.");
+	  mappings->insert_derive_proc_macro (
+	    std::make_pair (extern_crate,
+			    macro.payload.custom_derive.trait_name),
+	    macro.payload.custom_derive);
+	  break;
+	case ProcMacro::ATTR:
+	  rust_debug ("Found one attribute proc macro.");
+	  mappings->insert_attribute_proc_macro (
+	    std::make_pair (extern_crate, macro.payload.attribute.name),
+	    macro.payload.attribute);
+	  break;
+	case ProcMacro::BANG:
+	  rust_debug ("Found one bang proc macro.");
+	  mappings->insert_bang_proc_macro (
+	    std::make_pair (extern_crate, macro.payload.bang.name),
+	    macro.payload.bang);
+	  break;
+	default:
+	  gcc_unreachable ();
+	}
+    }
+}
+
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-proc-macro.h b/gcc/rust/expand/rust-proc-macro.h
index 779d3c70fbc..244d274773c 100644
--- a/gcc/rust/expand/rust-proc-macro.h
+++ b/gcc/rust/expand/rust-proc-macro.h
@@ -17,6 +17,13 @@
 #ifndef RUST_PROC_MACRO_H
 #define RUST_PROC_MACRO_H
 
+#include <string>
+#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
+#include "rust-session-manager.h"
+#include "rust-ast.h"
+#include "rust-ast-collector.h"
+#include "rust-token-converter.h"
 #include "libproc_macro/proc_macro.h"
 
 namespace Rust {
@@ -29,6 +36,78 @@ namespace Rust {
 const std::vector<ProcMacro::Procmacro>
 load_macros (std::string path);
 
+class ProcMacroExpander
+{
+public:
+  ProcMacroExpander (Session &session)
+    : session (session), has_changed_flag (false),
+      resolver (Resolver::Resolver::get ()),
+      mappings (Analysis::Mappings::get ())
+
+  {}
+
+  ~ProcMacroExpander () = default;
+
+  void import_proc_macros (std::string extern_crate);
+
+  template <typename T>
+  void expand_derive_proc_macro (T &item, std::string &trait_name)
+  {}
+
+  template <typename T>
+  void expand_bang_proc_macro (T &item, AST::SimplePath &path)
+  {}
+
+  template <typename T>
+  void expand_attribute_proc_macro (T &item, AST::SimplePath &path)
+  {
+    ProcMacro::Attribute macro;
+
+    std::string crate = path.get_segments ()[0].get_segment_name ();
+    std::string name = path.get_segments ()[1].get_segment_name ();
+    if (!mappings->lookup_attribute_proc_macro (std::make_pair (crate, name),
+						macro))
+      {
+	// FIXME: Resolve this path segment instead of taking it directly.
+	import_proc_macros (crate);
+      }
+
+    if (!mappings->lookup_attribute_proc_macro (std::make_pair (crate, name),
+						macro))
+      {
+	rust_error_at (Location (), "procedural macro %s not found",
+		       name.c_str ());
+	rust_assert (false);
+      }
+    // FIXME: Attach result back to the ast
+    std::vector<TokenPtr> tokens;
+    AST::TokenCollector collector (tokens);
+
+    collector.visit (item);
+
+    std::vector<const_TokenPtr> vec;
+    for (auto i : collector.collect_tokens ())
+      {
+	vec.push_back (std::const_pointer_cast<Token> (i));
+      }
+
+    // FIXME: Handle attributes
+    macro.macro (ProcMacro::TokenStream::make_tokenstream (), convert (vec));
+  }
+
+  bool has_changed () const { return has_changed_flag; }
+
+  void reset_changed_state () { has_changed_flag = false; }
+
+private:
+  Session &session;
+  bool has_changed_flag;
+
+public:
+  Resolver::Resolver *resolver;
+  Analysis::Mappings *mappings;
+};
+
 } // namespace Rust
 
 #endif /* ! RUST_PROC_MACRO_H */
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index c7bbe89b281..401d70590c4 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -867,12 +867,13 @@ Session::expansion (AST::Crate &crate)
   /* expand by calling cxtctxt object's monotonic_expander's expand_crate
    * method. */
   MacroExpander expander (crate, cfg, *this);
+  ProcMacroExpander proc_expander (*this);
 
   while (!fixed_point_reached && iterations < cfg.recursion_limit)
     {
       CfgStrip ().go (crate);
       Resolver::EarlyNameResolver ().go (crate);
-      ExpandVisitor (expander).go (crate);
+      ExpandVisitor (expander, proc_expander).go (crate);
 
       fixed_point_reached = !expander.has_changed ();
       expander.reset_changed_state ();
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 3a33d0629f2..4c7cb869861 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -43,6 +43,7 @@ static const BuiltinAttrDefinition __definitions[]
      {"rustc_builtin_macro", EXPANSION},
      {"path", EXPANSION},
      {"macro_use", NAME_RESOLUTION},
+     {"macro_export", NAME_RESOLUTION},
      // FIXME: This is not implemented yet, see
      // https://github.com/Rust-GCC/gccrs/issues/1475
      {"target_feature", CODE_GENERATION},
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 93066f52d95..2f6d02d4187 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -941,6 +941,72 @@ Mappings::get_exported_macros ()
   return exportedMacros;
 }
 
+void
+Mappings::insert_derive_proc_macro (
+  std::pair<std::string, std::string> hierarchy, ProcMacro::CustomDerive macro)
+{
+  auto it = procmacroDeriveMappings.find (hierarchy);
+  rust_assert (it == procmacroDeriveMappings.end ());
+
+  procmacroDeriveMappings[hierarchy] = macro;
+}
+
+void
+Mappings::insert_bang_proc_macro (std::pair<std::string, std::string> hierarchy,
+				  ProcMacro::Bang macro)
+{
+  auto it = procmacroBangMappings.find (hierarchy);
+  rust_assert (it == procmacroBangMappings.end ());
+
+  procmacroBangMappings[hierarchy] = macro;
+}
+
+void
+Mappings::insert_attribute_proc_macro (
+  std::pair<std::string, std::string> hierarchy, ProcMacro::Attribute macro)
+{
+  auto it = procmacroAttributeMappings.find (hierarchy);
+  rust_assert (it == procmacroAttributeMappings.end ());
+
+  procmacroAttributeMappings[hierarchy] = macro;
+}
+
+bool
+Mappings::lookup_derive_proc_macro (
+  std::pair<std::string, std::string> hierarchy, ProcMacro::CustomDerive &macro)
+{
+  auto it = procmacroDeriveMappings.find (hierarchy);
+  if (it == procmacroDeriveMappings.end ())
+    return false;
+
+  macro = it->second;
+  return true;
+}
+
+bool
+Mappings::lookup_bang_proc_macro (std::pair<std::string, std::string> hierarchy,
+				  ProcMacro::Bang &macro)
+{
+  auto it = procmacroBangMappings.find (hierarchy);
+  if (it == procmacroBangMappings.end ())
+    return false;
+
+  macro = it->second;
+  return true;
+}
+
+bool
+Mappings::lookup_attribute_proc_macro (
+  std::pair<std::string, std::string> hierarchy, ProcMacro::Attribute &macro)
+{
+  auto it = procmacroAttributeMappings.find (hierarchy);
+  if (it == procmacroAttributeMappings.end ())
+    return false;
+
+  macro = it->second;
+  return true;
+}
+
 void
 Mappings::insert_visibility (NodeId id, Privacy::ModuleVisibility visibility)
 {
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 21d1bc0622a..60498dec91c 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -28,6 +28,7 @@
 #include "rust-hir-full-decls.h"
 #include "rust-lang-item.h"
 #include "rust-privacy-common.h"
+#include "libproc_macro/proc_macro.h"
 
 namespace Rust {
 namespace Analysis {
@@ -282,6 +283,22 @@ public:
   void insert_exported_macro (AST::MacroRulesDefinition &def);
   std::vector<NodeId> &get_exported_macros ();
 
+  void insert_derive_proc_macro (std::pair<std::string, std::string> hierachy,
+				 ProcMacro::CustomDerive macro);
+  void insert_bang_proc_macro (std::pair<std::string, std::string> hierachy,
+			       ProcMacro::Bang macro);
+  void
+  insert_attribute_proc_macro (std::pair<std::string, std::string> hierachy,
+			       ProcMacro::Attribute macro);
+
+  bool lookup_derive_proc_macro (std::pair<std::string, std::string> hierachy,
+				 ProcMacro::CustomDerive &macro);
+  bool lookup_bang_proc_macro (std::pair<std::string, std::string> hierachy,
+			       ProcMacro::Bang &macro);
+  bool
+  lookup_attribute_proc_macro (std::pair<std::string, std::string> hierachy,
+			       ProcMacro::Attribute &macro);
+
   void insert_visibility (NodeId id, Privacy::ModuleVisibility visibility);
   bool lookup_visibility (NodeId id, Privacy::ModuleVisibility &def);
 
@@ -350,11 +367,21 @@ private:
   // all hirid nodes
   std::map<CrateNum, std::set<HirId>> hirNodesWithinCrate;
 
-  // macros
+  // MBE macros
   std::map<NodeId, AST::MacroRulesDefinition *> macroMappings;
   std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
   std::vector<NodeId> exportedMacros;
 
+  // Procedural macros
+  std::map<std::pair<std::string, std::string>, ProcMacro::CustomDerive>
+    procmacroDeriveMappings;
+
+  std::map<std::pair<std::string, std::string>, ProcMacro::Bang>
+    procmacroBangMappings;
+
+  std::map<std::pair<std::string, std::string>, ProcMacro::Attribute>
+    procmacroAttributeMappings;
+
   // crate names
   std::map<CrateNum, std::string> crate_names;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-01-16 17:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-16 17:51 [gcc r14-7658] gccrs: expand: Add prc macro expander and registration Arthur Cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).