Skip to content

Commit 18ad440

Browse files
powerboat9philberty
authored andcommitted
Handle link_name attribute
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]>
1 parent b33cf2b commit 18ad440

File tree

6 files changed

+59
-12
lines changed

6 files changed

+59
-12
lines changed

gcc/rust/backend/rust-compile-extern.h

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
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

2830
namespace Rust {
2931
namespace 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;

gcc/rust/util/rust-attribute-values.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Attributes
3636
static constexpr auto &DOC = "doc";
3737
static constexpr auto &MUST_USE = "must_use";
3838
static constexpr auto &LANG = "lang";
39+
static constexpr auto &LINK_NAME = "link_name";
3940
static constexpr auto &LINK_SECTION = "link_section";
4041
static constexpr auto &NO_MANGLE = "no_mangle";
4142
static constexpr auto &REPR = "repr";

gcc/rust/util/rust-attributes.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static const BuiltinAttrDefinition __definitions[]
7878
{Attrs::DOC, HIR_LOWERING},
7979
{Attrs::MUST_USE, STATIC_ANALYSIS},
8080
{Attrs::LANG, HIR_LOWERING},
81+
{Attrs::LINK_NAME, CODE_GENERATION},
8182
{Attrs::LINK_SECTION, CODE_GENERATION},
8283
{Attrs::NO_MANGLE, CODE_GENERATION},
8384
{Attrs::REPR, CODE_GENERATION},

gcc/rust/util/rust-ggc.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// <http://www.gnu.org/licenses/>.
1818

1919
#include "rust-ggc.h"
20+
#include "rust-ast.h"
2021
#include "stringpool.h"
2122

2223
namespace Rust {
@@ -29,6 +30,8 @@ Ident::Ident (const std::string &str)
2930
: inner (get_identifier_with_length (str.c_str (), str.length ()))
3031
{}
3132

33+
Ident::Ident (const Rust::Identifier &ident) : Ident (ident.as_string ()) {}
34+
3235
bool
3336
Ident::operator== (const std::string &other) const
3437
{

gcc/rust/util/rust-ggc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
namespace Rust {
2626

27+
// forward declare
28+
class Identifier;
29+
2730
namespace GGC {
2831

2932
class Ident
@@ -33,6 +36,7 @@ class Ident
3336
public:
3437
Ident (const char *str);
3538
Ident (const std::string &str);
39+
Ident (const Rust::Identifier &ident);
3640

3741
bool operator== (const Ident &other) const { return inner == other.inner; }
3842
bool operator== (const std::string &other) const;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// { dg-additional-options "-fdump-rtl-final" }
2+
// { dg-final { scan-rtl-dump "printf" "final" } }
3+
// { dg-output "gcc\r*\n" }
4+
5+
extern "C" {
6+
#[link_name = "printf"]
7+
fn druckt(fmt: *const i8, ...);
8+
}
9+
10+
fn main() -> i32 {
11+
let a = "gcc\0";
12+
13+
unsafe { druckt("%s\n\0" as *const str as *const i8, a as *const str as *const i8); }
14+
15+
0
16+
}

0 commit comments

Comments
 (0)