summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/ast.hpp1
-rw-r--r--src/ast/attrs.hpp2
-rw-r--r--src/expand/mod.cpp12
-rw-r--r--src/hir/from_ast.cpp13
-rw-r--r--src/trans/codegen_c.cpp8
5 files changed, 31 insertions, 5 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 597d9bdc..4b48aa01 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -390,6 +390,7 @@ public:
// Accessors
const Span& span() const { return m_span; }
const MetaItems& attrs() const { return m_attrs; }
+ MetaItems& attrs() { return m_attrs; }
const GenericParams& params() const { return m_params; }
GenericParams& params() { return m_params; }
diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp
index f4e6af8d..372d888a 100644
--- a/src/ast/attrs.hpp
+++ b/src/ast/attrs.hpp
@@ -87,7 +87,7 @@ public:
bool has_sub_items() const { return m_data.is_List(); }
const ::std::vector<MetaItem>& items() const { return m_data.as_List().sub_items; }
- //::std::vector<MetaItem>& items() { return m_data.as_List().sub_items; }
+ ::std::vector<MetaItem>& items() { return m_data.as_List().sub_items; }
friend ::std::ostream& operator<<(::std::ostream& os, const MetaItem& x) {
os << x.m_name;
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index 8cc4ea2e..ab016b95 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -47,13 +47,17 @@ void Expand_Attr(const Span& sp, const ::AST::MetaItem& a, AttrStage stage, ::s
}
}
}
-void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::MetaItem& a)> f)
+void Expand_Attrs(/*const */::AST::MetaItems& attrs, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::MetaItem& a)> f)
{
for( auto& a : attrs.m_items )
{
if( a.name() == "cfg_attr" ) {
if( check_cfg(attrs.m_span, a.items().at(0)) ) {
- Expand_Attr(attrs.m_span, a.items().at(1), stage, f);
+ auto inner_attr = mv$(a.items().at(1));
+ Expand_Attr(attrs.m_span, inner_attr, stage, f);
+ a = mv$(inner_attr);
+ }
+ else {
}
}
else {
@@ -61,11 +65,11 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::functi
}
}
}
-void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item)
+void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item)
{
Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, path, mod, item); });
}
-void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl)
+void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl)
{
Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mod, impl); });
}
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 729b0f45..a80ac887 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1060,6 +1060,19 @@ namespace {
::HIR::Linkage linkage;
+ if( const auto* a = attrs.get("link_name") )
+ {
+ if( !a->has_string() )
+ ERROR(sp, E0000, "#[link_name] requires a string");
+ linkage.name = a->string();
+ }
+ // TODO: Convert #[link/link_name/no_mangle] attributes into linkage
+ // - Also, if there's no code, it's an external linkage?
+ if( linkage.name == "" && ! f.code().is_valid() )
+ {
+ linkage.name = p.get_name();
+ }
+
return ::HIR::Function {
mv$(linkage),
receiver,
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 6f729c32..937db11f 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -373,10 +373,18 @@ namespace {
m_of << "// extern \"" << item.m_abi << "\" " << p << "\n";
m_of << "extern ";
emit_function_header(p, item, params);
+ if( item.m_linkage.name != "" )
+ {
+ m_of << " asm(\"" << item.m_linkage.name << "\")";
+ }
m_of << ";\n";
}
void emit_function_proto(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params) override
{
+ if( item.m_linkage.name != "" )
+ {
+ m_of << "#define " << Trans_Mangle(p) << " " << item.m_linkage.name << "\n";
+ }
emit_function_header(p, item, params);
m_of << ";\n";
}