From: Owen Avery <[email protected]>
gcc/rust/ChangeLog:
* backend/rust-compile-extern.h: Add includes.
(CompileExternItem::visit): Use get_link_name.
(CompileExternItem::get_link_name): New static member function.
* util/rust-attribute-values.h (Attributes::LINK_NAME): New
static constexpr member variable.
* util/rust-attributes.cc (__definitions): New entry for
LINK_NAME.
* util/rust-ggc.cc: Include "rust-ast.h".
(Ident::Ident): Add overload for Rust::Identifier.
* util/rust-ggc.h (class Identifier): Forward declare.
(Ident::Ident): Add overload for Rust::Identifier.
gcc/testsuite/ChangeLog:
* rust/execute/torture/link-name.rs: New test.
Signed-off-by: Owen Avery <[email protected]>
---
gcc/rust/backend/rust-compile-extern.h | 46 ++++++++++++++-----
gcc/rust/util/rust-attribute-values.h | 1 +
gcc/rust/util/rust-attributes.cc | 1 +
gcc/rust/util/rust-ggc.cc | 3 ++
gcc/rust/util/rust-ggc.h | 4 ++
.../rust/execute/torture/link-name.rs | 16 +++++++
6 files changed, 59 insertions(+), 12 deletions(-)
create mode 100644 gcc/testsuite/rust/execute/torture/link-name.rs
diff --git a/gcc/rust/backend/rust-compile-extern.h
b/gcc/rust/backend/rust-compile-extern.h
index d6aa5899f62..a78f9eeeefe 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -24,6 +24,8 @@
#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 {
@@ -57,8 +59,7 @@ public:
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;
@@ -124,16 +125,7 @@ public:
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,
@@ -158,6 +150,36 @@ private:
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;
diff --git a/gcc/rust/util/rust-attribute-values.h
b/gcc/rust/util/rust-attribute-values.h
index 3b09e8493d1..0f35f56f798 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -36,6 +36,7 @@ public:
static constexpr auto &DOC = "doc";
static constexpr auto &MUST_USE = "must_use";
static constexpr auto &LANG = "lang";
+ static constexpr auto &LINK_NAME = "link_name";
static constexpr auto &LINK_SECTION = "link_section";
static constexpr auto &NO_MANGLE = "no_mangle";
static constexpr auto &REPR = "repr";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 716af3af699..bd91fdd5d03 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -78,6 +78,7 @@ static const BuiltinAttrDefinition __definitions[]
{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},
diff --git a/gcc/rust/util/rust-ggc.cc b/gcc/rust/util/rust-ggc.cc
index 0722af2b718..46220a2acd8 100644
--- a/gcc/rust/util/rust-ggc.cc
+++ b/gcc/rust/util/rust-ggc.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ggc.h"
+#include "rust-ast.h"
#include "stringpool.h"
namespace Rust {
@@ -29,6 +30,8 @@ Ident::Ident (const std::string &str)
: inner (get_identifier_with_length (str.c_str (), str.length ()))
{}
+Ident::Ident (const Rust::Identifier &ident) : Ident (ident.as_string ()) {}
+
bool
Ident::operator== (const std::string &other) const
{
diff --git a/gcc/rust/util/rust-ggc.h b/gcc/rust/util/rust-ggc.h
index da28edeffe0..da4ede15985 100644
--- a/gcc/rust/util/rust-ggc.h
+++ b/gcc/rust/util/rust-ggc.h
@@ -24,6 +24,9 @@
namespace Rust {
+// forward declare
+class Identifier;
+
namespace GGC {
class Ident
@@ -33,6 +36,7 @@ class Ident
public:
Ident (const char *str);
Ident (const std::string &str);
+ Ident (const Rust::Identifier &ident);
bool operator== (const Ident &other) const { return inner == other.inner; }
bool operator== (const std::string &other) const;
diff --git a/gcc/testsuite/rust/execute/torture/link-name.rs
b/gcc/testsuite/rust/execute/torture/link-name.rs
new file mode 100644
index 00000000000..1ab1ac1b351
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/link-name.rs
@@ -0,0 +1,16 @@
+// { 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
+}
--
2.50.1