summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/crate.cpp9
-rw-r--r--src/ast/crate.hpp3
-rw-r--r--src/expand/macro_rules.cpp86
3 files changed, 62 insertions, 36 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index a663e300..ea1bbf1c 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -67,7 +67,14 @@ ExternCrate::ExternCrate(const ::std::string& path)
m_hir = HIR_Deserialise(path);
}
-const MacroRules* ExternCrate::find_macro_rules(const ::std::string& name)
+void ExternCrate::with_all_macros(::std::function<void(const ::std::string& , const MacroRules&)> cb) const
+{
+ for(const auto& m : m_hir->m_exported_macros)
+ {
+ cb(m.first, m.second);
+ }
+}
+const MacroRules* ExternCrate::find_macro_rules(const ::std::string& name) const
{
auto i = m_hir->m_exported_macros.find(name);
if(i != m_hir->m_exported_macros.end())
diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp
index 1b4c5645..e598c568 100644
--- a/src/ast/crate.hpp
+++ b/src/ast/crate.hpp
@@ -62,7 +62,8 @@ public:
ExternCrate(const ExternCrate&) = delete;
ExternCrate(ExternCrate&&) = default;
- const MacroRules* find_macro_rules(const ::std::string& name);
+ void with_all_macros(::std::function<void(const ::std::string& , const MacroRules&)> cb) const;
+ const MacroRules* find_macro_rules(const ::std::string& name) const;
};
} // namespace AST
diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp
index 4f5d33cf..359b9865 100644
--- a/src/expand/macro_rules.cpp
+++ b/src/expand/macro_rules.cpp
@@ -3,6 +3,7 @@
#include "../ast/expr.hpp"
#include "../ast/ast.hpp"
#include "../parse/common.hpp"
+#include <ast/crate.hpp>
#include "macro_rules.hpp"
#include <macro_rules/macro_rules.hpp>
@@ -33,49 +34,66 @@ class CMacroUseHandler:
void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override
{
TRACE_FUNCTION_F("path=" << path);
- if( !i.is_Module() )
- ERROR(sp, E0000, "Use of #[macro_use] on non-module");
- const auto& submod = i.as_Module();
-
- if( mi.has_sub_items() )
- {
- for( const auto& si : mi.items() )
+ TU_IFLET( ::AST::Item, i, None, e,
+ // Just ignore
+ )
+ else TU_IFLET( ::AST::Item, i, Crate, ec_name,
+ const auto& ec = crate.m_extern_crates.at(ec_name.name);
+ if( mi.has_sub_items() )
{
- const auto& name = si.name();
- for( const auto& mr : submod.macros() )
+ TODO(sp, "Named import from extern crate");
+ }
+ else
+ {
+ ec.with_all_macros([&](const auto& name, const auto& mac) {
+ mod.add_macro_import( name, mac );
+ });
+ }
+ )
+ else TU_IFLET( ::AST::Item, i, Module, submod,
+ if( mi.has_sub_items() )
+ {
+ for( const auto& si : mi.items() )
{
- if( mr.name == name ) {
- DEBUG("Imported " << mr.name);
- mod.add_macro_import( mr.name, *mr.data );
- goto _good;
+ const auto& name = si.name();
+ for( const auto& mr : submod.macros() )
+ {
+ if( mr.name == name ) {
+ DEBUG("Imported " << mr.name);
+ mod.add_macro_import( mr.name, *mr.data );
+ goto _good;
+ }
}
- }
- for( const auto& mri : submod.macro_imports_res() )
- {
- if( mri.name == name ) {
- DEBUG("Imported " << mri.name << " (propagate)");
- mod.add_macro_import( mri.name, *mri.data );
- goto _good;
+ for( const auto& mri : submod.macro_imports_res() )
+ {
+ if( mri.name == name ) {
+ DEBUG("Imported " << mri.name << " (propagate)");
+ mod.add_macro_import( mri.name, *mri.data );
+ goto _good;
+ }
}
+ ERROR(sp, E0000, "Couldn't find macro " << name);
+ _good:
+ (void)0;
}
- ERROR(sp, E0000, "Couldn't find macro " << name);
- _good:
- (void)0;
}
- }
- else
- {
- for( const auto& mr : submod.macros() )
- {
- DEBUG("Imported " << mr.name);
- mod.add_macro_import( mr.name, *mr.data );
- }
- for( const auto& mri : submod.macro_imports_res() )
+ else
{
- DEBUG("Imported " << mri.name << " (propagate)");
- mod.add_macro_import( mri.name, *mri.data );
+ for( const auto& mr : submod.macros() )
+ {
+ DEBUG("Imported " << mr.name);
+ mod.add_macro_import( mr.name, *mr.data );
+ }
+ for( const auto& mri : submod.macro_imports_res() )
+ {
+ DEBUG("Imported " << mri.name << " (propagate)");
+ mod.add_macro_import( mri.name, *mri.data );
+ }
}
+ )
+ else {
+ ERROR(sp, E0000, "Use of #[macro_use] on non-module/crate - " << i.tag_str());
}
}