summaryrefslogtreecommitdiff
path: root/src/expand/proc_macro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/expand/proc_macro.cpp')
-rw-r--r--src/expand/proc_macro.cpp91
1 files changed, 61 insertions, 30 deletions
diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp
index b61851b3..bc882d77 100644
--- a/src/expand/proc_macro.cpp
+++ b/src/expand/proc_macro.cpp
@@ -35,7 +35,7 @@ class Decorator_ProcMacroDerive:
{
public:
AttrStage stage() const override { return AttrStage::Post; }
- void handle(const Span& sp, const AST::Attribute& attr, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override
+ void handle(const Span& sp, const AST::Attribute& attr, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, slice<const AST::Attribute> attrs, AST::Item& i) const override
{
if( i.is_None() )
return;
@@ -49,13 +49,13 @@ public:
{
if( attr.items()[i].name() == "attributes") {
for(const auto& si : attr.items()[i].items()) {
- attributes.push_back( si.name() );
+ attributes.push_back( si.name().c_str() );
}
}
}
// TODO: Store attributes for later use.
- crate.m_proc_macros.push_back(AST::ProcMacroDef { FMT("derive#" << trait_name), path, mv$(attributes) });
+ crate.m_proc_macros.push_back(AST::ProcMacroDef { RcString::new_interned(FMT("derive#" << trait_name)), path, mv$(attributes) });
}
};
@@ -100,7 +100,7 @@ void Expand_ProcMacro(::AST::Crate& crate)
{
::AST::ExprNode_StructLiteral::t_values desc_vals;
// `name: "foo",`
- desc_vals.push_back({ {}, "name", NEWNODE(_String, desc.name) });
+ desc_vals.push_back({ {}, "name", NEWNODE(_String, desc.name.c_str()) });
// `handler`: ::foo
desc_vals.push_back({ {}, "handler", NEWNODE(_NamedValue, AST::Path(desc.path)) });
@@ -121,12 +121,12 @@ void Expand_ProcMacro(::AST::Crate& crate)
auto newmod = ::AST::Module { ::AST::Path("", { ::AST::PathNode("proc_macro#") }) };
// - TODO: These need to be loaded too.
// > They don't actually need to exist here, just be loaded (and use absolute paths)
- newmod.add_ext_crate(false, "proc_macro", "proc_macro", {});
+ newmod.add_ext_crate(Span(), false, "proc_macro", "proc_macro", {});
- newmod.add_item(false, "main", mv$(main_fn), {});
- newmod.add_item(false, "MACROS", mv$(tests_list), {});
+ newmod.add_item(Span(), false, "main", mv$(main_fn), {});
+ newmod.add_item(Span(), false, "MACROS", mv$(tests_list), {});
- crate.m_root_module.add_item(false, "proc_macro#", mv$(newmod), {});
+ crate.m_root_module.add_item(Span(), false, "proc_macro#", mv$(newmod), {});
crate.m_lang_items["mrustc-main"] = ::AST::Path("", { AST::PathNode("proc_macro#"), AST::PathNode("main") });
}
@@ -211,7 +211,7 @@ public:
void send_float(eCoreType ct, double v);
//void send_fragment();
- bool attr_is_used(const ::std::string& n) const {
+ bool attr_is_used(const RcString& n) const {
return ::std::find(m_proc_macro_desc.attributes.begin(), m_proc_macro_desc.attributes.end(), n) != m_proc_macro_desc.attributes.end();
}
@@ -229,8 +229,9 @@ private:
uint64_t recv_v128u();
};
-ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path)
+ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path)
{
+ TRACE_FUNCTION_F(mac_path);
// 1. Locate macro in HIR list
const auto& crate_name = mac_path.front();
const auto& ext_crate = crate.m_extern_crates.at(crate_name);
@@ -259,7 +260,8 @@ ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, con
}
// 2. Get executable and macro name
- ::std::string proc_macro_exe_name = (ext_crate.m_filename + "-plugin");
+ // TODO: Windows will have .exe?
+ ::std::string proc_macro_exe_name = ext_crate.m_filename;
// 3. Create ProcMacroInv
return ProcMacroInv(sp, proc_macro_exe_name.c_str(), *pmp);
@@ -516,6 +518,9 @@ namespace {
TODO(sp, "");
m_pmi.send_symbol("}");
}
+ void visit(::AST::ExprNode_Try& node) {
+ TODO(sp, "ExprNode_Try");
+ }
void visit(::AST::ExprNode_Macro& node) {
TODO(sp, "ExprNode_Macro");
}
@@ -606,12 +611,27 @@ namespace {
TODO(sp, "ExprNode_UniOp");
}
+ void visit_top_attrs(slice<const ::AST::Attribute>& attrs)
+ {
+ for(const auto& a : attrs)
+ {
+ if( m_pmi.attr_is_used(a.name()) )
+ {
+ DEBUG("Send " << a);
+ m_pmi.send_symbol("#");
+ m_pmi.send_symbol("[");
+ this->visit_meta_item(a);
+ m_pmi.send_symbol("]");
+ }
+ }
+ }
void visit_attrs(const ::AST::AttributeList& attrs)
{
for(const auto& a : attrs.m_items)
{
if( m_pmi.attr_is_used(a.name()) )
{
+ DEBUG("Send " << a);
m_pmi.send_symbol("#");
m_pmi.send_symbol("[");
this->visit_meta_item(a);
@@ -704,12 +724,15 @@ namespace {
{
this->visit_attrs(v.m_attrs);
m_pmi.send_ident(v.m_name.c_str());
- TU_MATCH(AST::EnumVariantData, (v.m_data), (e),
- (Value,
- m_pmi.send_symbol("=");
- this->visit_nodes(e.m_value);
- ),
- (Tuple,
+ TU_MATCH_HDRA( (v.m_data), { )
+ TU_ARMA(Value, e) {
+ if( e.m_value )
+ {
+ m_pmi.send_symbol("=");
+ this->visit_nodes(e.m_value);
+ }
+ }
+ TU_ARMA(Tuple, e) {
m_pmi.send_symbol("(");
for(const auto& st : e.m_sub_types)
{
@@ -718,8 +741,8 @@ namespace {
m_pmi.send_symbol(",");
}
m_pmi.send_symbol(")");
- ),
- (Struct,
+ }
+ TU_ARMA(Struct, e) {
m_pmi.send_symbol("{");
for(const auto& f : e.m_fields)
{
@@ -730,8 +753,8 @@ namespace {
m_pmi.send_symbol(",");
}
m_pmi.send_symbol("}");
- )
- )
+ }
+ }
m_pmi.send_symbol(",");
}
m_pmi.send_symbol("}");
@@ -742,38 +765,45 @@ namespace {
}
};
}
-::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Struct& i)
+::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, slice<const AST::Attribute> attrs, const ::std::string& item_name, const ::AST::Struct& i)
{
// 1. Create ProcMacroInv instance
auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path);
if( !pmi.check_good() )
return ::std::unique_ptr<TokenStream>();
// 2. Feed item as a token stream.
- Visitor(sp, pmi).visit_struct(item_name, false, i);
+ // TODO: Get attributes from the caller, filter based on the macro's options then pass to the child.
+ Visitor v(sp, pmi);
+ v.visit_top_attrs(attrs);
+ v.visit_struct(item_name, false, i);
pmi.send_done();
// 3. Return boxed invocation instance
return box$(pmi);
}
-::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Enum& i)
+::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, slice<const AST::Attribute> attrs, const ::std::string& item_name, const ::AST::Enum& i)
{
// 1. Create ProcMacroInv instance
auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path);
if( !pmi.check_good() )
return ::std::unique_ptr<TokenStream>();
// 2. Feed item as a token stream.
- Visitor(sp, pmi).visit_enum(item_name, false, i);
+ Visitor v(sp, pmi);
+ v.visit_top_attrs(attrs);
+ v.visit_enum(item_name, false, i);
pmi.send_done();
// 3. Return boxed invocation instance
return box$(pmi);
}
-::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Union& i)
+::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, slice<const AST::Attribute> attrs, const ::std::string& item_name, const ::AST::Union& i)
{
// 1. Create ProcMacroInv instance
auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path);
if( !pmi.check_good() )
return ::std::unique_ptr<TokenStream>();
// 2. Feed item as a token stream.
- Visitor(sp, pmi).visit_union(item_name, false, i);
+ Visitor v(sp, pmi);
+ v.visit_top_attrs(attrs);
+ v.visit_union(item_name, false, i);
pmi.send_done();
// 3. Return boxed invocation instance
return box$(pmi);
@@ -813,11 +843,12 @@ ProcMacroInv::ProcMacroInv(const Span& sp, const char* executable, const ::HIR::
posix_spawn_file_actions_addclose(&file_actions, stdout_pipes[1]);
char* argv[3] = { const_cast<char*>(executable), const_cast<char*>(proc_macro_desc.name.c_str()), nullptr };
+ DEBUG(argv[0] << " " << argv[1]);
//char* envp[] = { nullptr };
int rv = posix_spawn(&this->child_pid, executable, &file_actions, nullptr, argv, environ);
if( rv != 0 )
{
- BUG(sp, "Error in posix_spawn - " << rv);
+ BUG(sp, "Error in posix_spawn - " << rv << " - can't start `" << executable << "`");
}
posix_spawn_file_actions_destroy(&file_actions);
@@ -1015,11 +1046,11 @@ Token ProcMacroInv::realGetToken_() {
auto t = Lex_FindReservedWord(val);
if( t != TOK_NULL )
return t;
- return Token(TOK_IDENT, mv$(val));
+ return Token(TOK_IDENT, RcString::new_interned(val));
}
case TokenClass::Lifetime: {
auto val = this->recv_bytes();
- return Token(TOK_LIFETIME, mv$(val));
+ return Token(TOK_LIFETIME, RcString::new_interned(val));
}
case TokenClass::String: {
auto val = this->recv_bytes();