diff options
author | John Hodge <tpg@mutabah.net> | 2016-10-09 12:53:11 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-10-09 12:53:11 +0800 |
commit | bc0bc36123727c258dd3f2a61b7e46507485777b (patch) | |
tree | 069fced4cc9226d3cd49abfb1b401bddf3b48fef | |
parent | baaca746b480d0ede1c15ae24327f57475d04353 (diff) | |
download | mrust-bc0bc36123727c258dd3f2a61b7e46507485777b.tar.gz |
Expand - #[macro_reexport]
-rw-r--r-- | src/ast/ast.cpp | 3 | ||||
-rw-r--r-- | src/ast/ast.hpp | 4 | ||||
-rw-r--r-- | src/expand/macro_rules.cpp | 39 | ||||
-rw-r--r-- | src/expand/mod.cpp | 1 | ||||
-rw-r--r-- | src/hir/deserialise.cpp | 3 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 27 | ||||
-rw-r--r-- | src/macro_rules/macro_rules_ptr.hpp | 2 |
7 files changed, 62 insertions, 17 deletions
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<MacroRulesPtr>( mv$(name), mv$(macro), is_exported ) );
}
+void Module::add_macro_import(::std::string name, const MacroRules& mr) {
+ m_macro_import_res.push_back( NamedNS<const MacroRules*>( 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<const MacroRules*>( 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 <synext.hpp> #include "../ast/expr.hpp" #include "../ast/ast.hpp" @@ -6,6 +16,7 @@ #include <ast/crate.hpp> #include "macro_rules.hpp" #include <macro_rules/macro_rules.hpp> +#include <hir/hir.hpp> // 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<MacroRules*>(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<MacroRules*>(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) |