diff options
-rw-r--r-- | src/ast/ast.hpp | 1 | ||||
-rw-r--r-- | src/ast/attrs.hpp | 2 | ||||
-rw-r--r-- | src/expand/mod.cpp | 12 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 13 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 8 |
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"; } |