aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc8
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h6
-rw-r--r--gcc/rust/expand/rust-proc-macro.cc43
-rw-r--r--gcc/rust/expand/rust-proc-macro.h79
-rw-r--r--gcc/rust/rust-session-manager.cc3
-rw-r--r--gcc/rust/util/rust-attributes.cc1
-rw-r--r--gcc/rust/util/rust-hir-map.cc66
-rw-r--r--gcc/rust/util/rust-hir-map.h29
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 b95649d..04a899f 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 8589334..fd72d0b 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 22744cb..a53a5d8 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 779d3c7..244d274 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 17f8465..bbcc569 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 0656b27..3403f48 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 3edbc20..706a29c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -942,6 +942,72 @@ Mappings::get_exported_macros ()
}
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)
{
visibility_map.insert ({id, visibility});
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 9f333f4..6e6a1c8 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;