From bc0bc36123727c258dd3f2a61b7e46507485777b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 9 Oct 2016 12:53:11 +0800 Subject: Expand - #[macro_reexport] --- src/ast/ast.cpp | 3 +++ src/ast/ast.hpp | 4 +--- src/expand/macro_rules.cpp | 39 +++++++++++++++++++++++++++++++------ src/expand/mod.cpp | 1 + src/hir/deserialise.cpp | 3 ++- src/hir/from_ast.cpp | 27 +++++++++++++++++++------ src/macro_rules/macro_rules_ptr.hpp | 2 +- 7 files changed, 62 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 25a1c82f..08aad21b 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -299,6 +299,9 @@ void Module::add_macro_invocation(MacroInvocation item) { void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) { m_macros.push_back( Named( mv$(name), mv$(macro), is_exported ) ); } +void Module::add_macro_import(::std::string name, const MacroRules& mr) { + m_macro_import_res.push_back( NamedNS( mv$(name), &mr, false ) ); +} Item Item::clone() const { diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index e65ba2c2..700a7e40 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -549,9 +549,7 @@ public: m_neg_impls.emplace_back( mv$(impl) ); } void add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro); - void add_macro_import(::std::string name, const MacroRules& mr) { - m_macro_import_res.push_back( NamedNS( mv$(name), &mr, false ) ); - } + void add_macro_import(::std::string name, const MacroRules& mr); diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 99e7680b..c460e35d 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -1,4 +1,14 @@ - +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * expand/macro_rules.cpp + * - Top-level handling of macro_rules! macros + * > macro_rules! dispatch handler + * > #[macro_use] + * > #[macro_export] + * > #[macro_reexport] + */ #include #include "../ast/expr.hpp" #include "../ast/ast.hpp" @@ -6,6 +16,7 @@ #include #include "macro_rules.hpp" #include +#include // for HIR::Crate class CMacroRulesExpander: public ExpandProcMacro @@ -115,6 +126,7 @@ class CMacroExportHandler: auto it = ::std::find_if( mod.macros().begin(), mod.macros().end(), [&](const auto& x){ return x.name == name; } ); ASSERT_BUG(sp, it != mod.macros().end(), "Macro '" << name << "' not defined in this module"); it->data->m_exported = true; + DEBUG("- Export macro " << name << "!"); } else { ERROR(sp, E0000, "Use of #[macro_export] on non-macro - " << i.tag_str()); @@ -128,13 +140,28 @@ class CMacroReexportHandler: AttrStage stage() const override { return AttrStage::Post; } void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override { - if( i.is_Crate() ) { - // TODO: Need to look up this crate in the crate list, then import all of the macros listed with the "export" flag set - // - For now, all externally loaded macros are exported (weakly) so things work... - } - else { + if( !i.is_Crate() ) { ERROR(sp, E0000, "Use of #[macro_reexport] on non-crate - " << i.tag_str()); } + + const auto& crate_name = i.as_Crate().name; + auto& ext_crate = *crate.m_extern_crates.at(crate_name).m_hir; + + if( mi.has_sub_items() ) + { + for( const auto& si : mi.items() ) + { + const auto& name = si.name(); + auto it = ext_crate.m_exported_macros.find(name); + if( it == ext_crate.m_exported_macros.end() ) + ERROR(sp, E0000, "Could not find macro " << name << "! in crate " << crate_name); + it->second->m_exported = true; + } + } + else + { + ERROR(sp, E0000, "#[macro_reexport] requires a list of macros"); + } } }; diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 7c3206dd..485c0032 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -100,6 +100,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& return e; } } + // TODO: Shouldn't this use the _last_ located macro? Allowing later (local) defininitions to override it? for( const auto& mri : mac_mod.macro_imports_res() ) { //DEBUG("- " << mri.name); diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index be8cccc9..f9ad4460 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -286,7 +286,8 @@ namespace { ::MacroRules deserialise_macrorules() { ::MacroRules rv; - rv.m_exported = true; + // NOTE: This is set after loading. + //rv.m_exported = true; rv.m_rules = deserialise_vec_c< ::MacroRulesArm>( [&](){ return deserialise_macrorulesarm(); }); rv.m_source_crate = read_string(); if(rv.m_source_crate == "") diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 02aa7e02..fb0b3186 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1309,14 +1309,29 @@ public: auto& macros = rv.m_exported_macros; // - Extract macros from root module - for( auto& mac : crate.m_root_module.macro_imports_res() ) { - //if( mac.data->export ) { - macros.insert( ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast(mac.data)) )) ) ); - //} - } for( /*const*/ auto& mac : crate.m_root_module.macros() ) { if( mac.data->m_exported ) { - macros.insert( ::std::make_pair( mac.name, mv$(mac.data) ) ); + auto res = macros.insert( ::std::make_pair( mac.name, mv$(mac.data) ) ); + if( res.second ) + DEBUG("- Define " << mac.name << "!"); + } + else { + DEBUG("- Non-exported " << mac.name << "!"); + } + } + for( auto& mac : crate.m_root_module.macro_imports_res() ) { + if( mac.data->m_exported && mac.name != "" ) { + auto v = ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast(mac.data)) )) ); + auto it = macros.find(mac.name); + if( it == macros.end() ) + { + auto res = macros.insert( mv$(v) ); + DEBUG("- Import " << mac.name << "! (from \"" << res.first->second->m_source_crate << "\")"); + } + else { + DEBUG("- Replace " << mac.name << "! (from \"" << it->second->m_source_crate << "\") with one from \"" << v.second->m_source_crate << "\""); + it->second = mv$( v.second ); + } } } diff --git a/src/macro_rules/macro_rules_ptr.hpp b/src/macro_rules/macro_rules_ptr.hpp index b910d2af..c5c01488 100644 --- a/src/macro_rules/macro_rules_ptr.hpp +++ b/src/macro_rules/macro_rules_ptr.hpp @@ -13,7 +13,7 @@ class MacroRulesPtr { MacroRules* m_ptr; public: - MacroRulesPtr() {} + MacroRulesPtr(): m_ptr(nullptr) {} MacroRulesPtr(MacroRules* p): m_ptr(p) {} MacroRulesPtr(MacroRulesPtr&& x): m_ptr(x.m_ptr) -- cgit v1.2.3