summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.hpp4
-rw-r--r--src/ast/crate.hpp4
-rw-r--r--src/expand/derive.cpp30
-rw-r--r--src/hir/hir.hpp5
-rw-r--r--src/include/main_bindings.hpp1
-rw-r--r--src/main.cpp21
-rw-r--r--src/trans/trans_list.hpp6
7 files changed, 64 insertions, 7 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 2ef17718..6b729f8c 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -534,6 +534,10 @@ public:
::std::unordered_map< ::std::string, IndexEnt > m_type_items;
::std::unordered_map< ::std::string, IndexEnt > m_value_items;
+ // List of macros imported from other modules (via #[macro_use], includes proc macros)
+ // - First value is an absolute path to the macro (including crate name)
+ ::std::vector<::std::pair< ::std::vector<::std::string>, const MacroRules* >> m_macro_imports;
+
public:
Module() {}
Module(::AST::Path path):
diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp
index 1723868c..67b4915e 100644
--- a/src/ast/crate.hpp
+++ b/src/ast/crate.hpp
@@ -43,12 +43,16 @@ public:
bool m_test_harness = false;
::std::vector<TestDesc> m_tests;
+ // Procedural macros!
+ ::std::vector<::std::pair< ::std::string, ::AST::Path>> m_proc_macros;
+
enum class Type {
Unknown,
RustLib,
RustDylib,
CDylib,
Executable,
+ ProcMacro, // Procedural macro
} m_crate_type = Type::Unknown;
enum LoadStd {
LOAD_STD,
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp
index ac9842a7..9d8169ad 100644
--- a/src/expand/derive.cpp
+++ b/src/expand/derive.cpp
@@ -11,6 +11,8 @@
#include "../ast/expr.hpp"
#include "../ast/crate.hpp"
#include <hir/hir.hpp> // ABI_RUST
+#include <parse/common.hpp> // Parse_ModRoot_Items
+#include "proc_macro.hpp"
template<typename T>
static inline ::std::vector<T> vec$(T v1) {
@@ -2205,17 +2207,33 @@ static void derive_item(const Span& sp, const AST::Crate& crate, AST::Module& mo
{
DEBUG("- " << trait.name());
auto dp = find_impl(trait.name());
- if( !dp ) {
- DEBUG("> No handler for " << trait.name());
- missing_handlers.push_back( trait.name() );
- fail = true;
+ if( dp ) {
+ mod.add_item(false, "", dp->handle_item(sp, (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"), params, type, item), {} );
continue ;
}
- // TODO: Support macros 1.1 custom derive
+ // Support custom derive
+ auto mac_name = FMT("deriving#" << trait.name());
// - Requires support all through the chain.
+ for(const auto& mac_path : mod.m_macro_imports)
+ {
+ if( mac_path.first.back() == mac_name )
+ {
+ if( mac_path.second ) {
+ // macro_rules! based derive?
+ TODO(sp, "Custom derive using macro_rules?");
+ }
+ else {
+ // proc_macro - Invoke the handler.
+ auto lex = ProcMacro_Invoke(sp, crate, mac_path.first, path.nodes().back().name(), item);
+ Parse_ModRoot_Items(*lex, mod);
+ }
+ }
+ }
- mod.add_item(false, "", dp->handle_item(sp, (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"), params, type, item), {} );
+ DEBUG("> No handler for " << trait.name());
+ missing_handlers.push_back( trait.name() );
+ fail = true;
}
if( fail ) {
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index 72b8d7dc..a04fd1da 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -470,12 +470,17 @@ public:
/// Macros exported by this crate
::std::unordered_map< ::std::string, ::MacroRulesPtr > m_exported_macros;
+ /// Procedural macros presented
+ ::std::vector<::HIR::SimplePath> m_proc_macros;
/// Language items avaliable through this crate (includes ones from loaded externs)
::std::unordered_map< ::std::string, ::HIR::SimplePath> m_lang_items;
+ /// Referenced crates
::std::unordered_map< ::std::string, ExternCrate> m_ext_crates;
+ /// Referenced system libraries
::std::vector<ExternLibrary> m_ext_libs;
+ /// Extra paths for the linker
::std::vector<::std::string> m_link_paths;
/// Method called to populate runtime state after deserialisation
diff --git a/src/include/main_bindings.hpp b/src/include/main_bindings.hpp
index 184f266f..ee8f4c54 100644
--- a/src/include/main_bindings.hpp
+++ b/src/include/main_bindings.hpp
@@ -17,6 +17,7 @@ extern AST::Crate Parse_Crate(::std::string mainfile);
extern void Expand(::AST::Crate& crate);
extern void Expand_TestHarness(::AST::Crate& crate);
+extern void Expand_ProcMacro(::AST::Crate& crate);
/// Process #[] decorators
extern void Process_Decorators(AST::Crate& crate);
diff --git a/src/main.cpp b/src/main.cpp
index 20c525d5..7769b4bc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -258,6 +258,11 @@ int main(int argc, char *argv[])
}
crate.m_crate_type = crate_type;
+ if( crate.m_crate_type == ::AST::Crate::Type::ProcMacro )
+ {
+ Expand_ProcMacro(crate);
+ }
+
auto crate_name = params.crate_name;
if( crate_name == "" )
{
@@ -557,6 +562,18 @@ int main(int argc, char *argv[])
case ::AST::Crate::Type::CDylib:
// Generate a .so/.dll
break;
+ case ::AST::Crate::Type::ProcMacro: {
+ // Needs: An executable (the actual macro handler), metadata (for `extern crate foo;`)
+ // Can just emit the metadata and do miri?
+ // - Requires MIR for EVERYTHING, not feasable.
+ TransList items = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Public(*hir_crate); });
+ CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, false); });
+
+ TransList items2 = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Main(*hir_crate); });
+ CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + "-plugin", trans_opt, *hir_crate, items2, true); });
+
+ CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); });
+ break; }
case ::AST::Crate::Type::Executable:
// Generate a binary
// - Enumerate items for translation
@@ -759,6 +776,9 @@ ProgramParams::ProgramParams(int argc, char *argv[])
else if( strcmp(type_str, "bin") == 0 ) {
this->crate_type = ::AST::Crate::Type::Executable;
}
+ else if( strcmp(type_str, "proc-macro") == 0 ) {
+ this->crate_type = ::AST::Crate::Type::ProcMacro;
+ }
else {
::std::cerr << "Unknown value for --crate-type" << ::std::endl;
exit(1);
@@ -897,4 +917,3 @@ ProgramParams::ProgramParams(int argc, char *argv[])
os << ::std::dec;
return os;
}
-
diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp
index 86284172..2ef876d6 100644
--- a/src/trans/trans_list.hpp
+++ b/src/trans/trans_list.hpp
@@ -55,6 +55,12 @@ struct TransList_Static
class TransList
{
public:
+ TransList() = default;
+ TransList(TransList&&) = default;
+ TransList(const TransList&) = delete;
+ TransList& operator=(TransList&&) = default;
+ TransList& operator=(const TransList&) = delete;
+
::std::map< ::HIR::Path, ::std::unique_ptr<TransList_Function> > m_functions;
::std::map< ::HIR::Path, ::std::unique_ptr<TransList_Static> > m_statics;
::std::map< ::HIR::Path, Trans_Params> m_vtables;