2424#include " rust-compile-type.h"
2525#include " rust-diagnostics.h"
2626#include " rust-hir-full-decls.h"
27+ #include " rust-attributes.h"
28+ #include " rust-attribute-values.h"
2729
2830namespace Rust {
2931namespace Compile {
@@ -57,8 +59,7 @@ class CompileExternItem : public HIRCompileBase,
5759 rust_assert (ok);
5860
5961 std::string name = item.get_item_name ().as_string ();
60- // FIXME this is assuming C ABI
61- std::string asm_name = name;
62+ GGC::Ident asm_name = get_link_name (item);
6263
6364 tree type = TyTyResolveCompile::compile (ctx, resolved_type);
6465 bool is_external = true ;
@@ -124,16 +125,7 @@ class CompileExternItem : public HIRCompileBase,
124125
125126 tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
126127 std::string ir_symbol_name = function.get_item_name ().as_string ();
127- std::string asm_name = function.get_item_name ().as_string ();
128- if (fntype->get_abi () == ABI::RUST)
129- {
130- // then we need to get the canonical path of it and mangle it
131- auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
132- function.get_mappings ().get_nodeid ());
133-
134- ir_symbol_name = canonical_path->get () + fntype->subst_as_string ();
135- asm_name = ctx->mangle_item (fntype, *canonical_path);
136- }
128+ GGC::Ident asm_name = get_link_name (function);
137129
138130 const unsigned int flags = Backend::function_is_declaration;
139131 tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name, asm_name,
@@ -158,6 +150,36 @@ class CompileExternItem : public HIRCompileBase,
158150 ref_locus (ref_locus)
159151 {}
160152
153+ template <typename T> static GGC::Ident get_link_name (T &obj)
154+ {
155+ AST::Attribute *use_attr = nullptr ;
156+
157+ for (auto &attr : obj.get_outer_attrs ())
158+ {
159+ if (attr.get_path ().as_string () == Values::Attributes::LINK_NAME)
160+ {
161+ // later attributes override earlier ones
162+ // TODO: add warning -- should duplicate
163+ // attributes be folded elsewhere?
164+ use_attr = &attr;
165+ }
166+ }
167+
168+ if (use_attr)
169+ {
170+ auto link_name
171+ = Analysis::Attributes::extract_string_literal (*use_attr);
172+
173+ if (!link_name.has_value ())
174+ rust_error_at (use_attr->get_locus (),
175+ " malformed %<link_name%> attribute input" );
176+ else
177+ return *link_name;
178+ }
179+
180+ return obj.get_item_name ();
181+ }
182+
161183 TyTy::BaseType *concrete;
162184 tree reference;
163185 location_t ref_locus;
0 commit comments