#include "rust-compile-type.h"
#include "rust-diagnostics.h"
#include "rust-hir-full-decls.h"
+#include "rust-attributes.h"
+#include "rust-attribute-values.h"
namespace Rust {
namespace Compile {
rust_assert (ok);
std::string name = item.get_item_name ().as_string ();
- // FIXME this is assuming C ABI
- std::string asm_name = name;
+ GGC::Ident asm_name = get_link_name (item);
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
bool is_external = true;
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
std::string ir_symbol_name = function.get_item_name ().as_string ();
- std::string asm_name = function.get_item_name ().as_string ();
- if (fntype->get_abi () == ABI::RUST)
- {
- // then we need to get the canonical path of it and mangle it
- auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
- function.get_mappings ().get_nodeid ());
-
- ir_symbol_name = canonical_path->get () + fntype->subst_as_string ();
- asm_name = ctx->mangle_item (fntype, *canonical_path);
- }
+ GGC::Ident asm_name = get_link_name (function);
const unsigned int flags = Backend::function_is_declaration;
tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name, asm_name,
ref_locus (ref_locus)
{}
+ template <typename T> static GGC::Ident get_link_name (T &obj)
+ {
+ AST::Attribute *use_attr = nullptr;
+
+ for (auto &attr : obj.get_outer_attrs ())
+ {
+ if (attr.get_path ().as_string () == Values::Attributes::LINK_NAME)
+ {
+ // later attributes override earlier ones
+ // TODO: add warning -- should duplicate
+ // attributes be folded elsewhere?
+ use_attr = &attr;
+ }
+ }
+
+ if (use_attr)
+ {
+ auto link_name
+ = Analysis::Attributes::extract_string_literal (*use_attr);
+
+ if (!link_name.has_value ())
+ rust_error_at (use_attr->get_locus (),
+ "malformed %<link_name%> attribute input");
+ else
+ return *link_name;
+ }
+
+ return obj.get_item_name ();
+ }
+
TyTy::BaseType *concrete;
tree reference;
location_t ref_locus;
{Attrs::DOC, HIR_LOWERING},
{Attrs::MUST_USE, STATIC_ANALYSIS},
{Attrs::LANG, HIR_LOWERING},
+ {Attrs::LINK_NAME, CODE_GENERATION},
{Attrs::LINK_SECTION, CODE_GENERATION},
{Attrs::NO_MANGLE, CODE_GENERATION},
{Attrs::REPR, CODE_GENERATION},
--- /dev/null
+// { dg-additional-options "-fdump-rtl-final" }
+// { dg-final { scan-rtl-dump "printf" "final" } }
+// { dg-output "gcc\r*\n" }
+
+extern "C" {
+ #[link_name = "printf"]
+ fn druckt(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+ let a = "gcc\0";
+
+ unsafe { druckt("%s\n\0" as *const str as *const i8, a as *const str as *const i8); }
+
+ 0
+}