diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc index 7f09d46a6503..8d104846b847 100644 --- a/gcc/rust/backend/rust-mangle.cc +++ b/gcc/rust/backend/rust-mangle.cc @@ -351,6 +351,10 @@ v0_identifier (const std::string &identifier) // , right under the one. If the // identifier contains unicode values, then an extra "u" needs to be added to // the mangling string and `punycode` must be used to encode the characters. + + if (!is_ascii_only (identifier)) + mangled << "u"; + tl::optional uident_opt = Utf8String::make_utf8_string (identifier); rust_assert (uident_opt.has_value ()); @@ -358,28 +362,19 @@ v0_identifier (const std::string &identifier) = encode_punycode (uident_opt.value ()); rust_assert (punycode_opt.has_value ()); - bool is_ascii_ident = true; - for (auto c : uident_opt.value ().get_chars ()) - if (c.value > 127) - { - is_ascii_ident = false; - break; - } - std::string punycode = punycode_opt.value (); - // remove tailing hyphen + + // remove a tailing hyphen if (punycode.back () == '-') punycode.pop_back (); - // replace hyphens in punycode with underscores - std::replace (punycode.begin (), punycode.end (), '-', '_'); - if (!is_ascii_ident) - mangled << "u"; + // replace a hyphen in punycode with a underscore + std::replace (punycode.begin (), punycode.end (), '-', '_'); mangled << std::to_string (punycode.size ()); - // If the first character of the identifier is a digit or an underscore, we - // add an extra underscore - if (punycode[0] == '_') + + // Add extra '_' + if (punycode[0] == '_' || ('0' <= punycode[0] && punycode[0] <= '9')) mangled << "_"; mangled << punycode; @@ -417,11 +412,11 @@ v0_function_path (V0Path path, Rust::Compile::Context *ctx, } static V0Path -v0_scope_path (V0Path path, std::string ident) +v0_scope_path (V0Path path, std::string ident, std::string ns) { V0Path v0path; v0path.prefix = "N"; - v0path.ns = "v"; + v0path.ns = ns; v0path.path = path.as_string (); v0path.ident = ident; return v0path; @@ -507,7 +502,7 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, } break; case HIR::ImplItem::CONSTANT: - v0path = v0_scope_path (v0path, v0_identifier (seg.get ())); + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); break; default: rust_internal_error_at (UNDEF_LOCATION, "Attempt to mangle '%s'", @@ -526,7 +521,7 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, } break; case HIR::TraitItem::CONST: - v0path = v0_scope_path (v0path, v0_identifier (seg.get ())); + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); break; default: rust_internal_error_at (UNDEF_LOCATION, "Attempt to mangle '%s'", @@ -544,10 +539,12 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty, } break; case HIR::Item::ItemKind::Module: - case HIR::Item::ItemKind::Trait: + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "t"); + break; + case HIR::Item::ItemKind::Trait: // FIXME: correct? case HIR::Item::ItemKind::Static: case HIR::Item::ItemKind::Constant: - v0path = v0_scope_path (v0path, v0_identifier (seg.get ())); + v0path = v0_scope_path (v0path, v0_identifier (seg.get ()), "v"); break; case HIR::Item::ItemKind::Struct: case HIR::Item::ItemKind::Enum: diff --git a/gcc/testsuite/rust/compile/v0-mangle1.rs b/gcc/testsuite/rust/compile/v0-mangle1.rs new file mode 100644 index 000000000000..a34f1a70112a --- /dev/null +++ b/gcc/testsuite/rust/compile/v0-mangle1.rs @@ -0,0 +1,70 @@ +// { dg-additional-options -frust-mangling=v0 } +#[lang = "sized"] +pub trait Sized {} + +pub fn foo() {} + +pub mod module_a { + pub fn bar() {} + + pub mod module_b { + pub fn baz() {} + } +} + +struct S; // { dg-warning "struct is never constructed" } + +// name starting with underscore. +pub fn _uc() {} + +pub fn generic1() {} + +pub fn generic2() {} + +pub fn 初音ミク() {} + +pub fn іржа() {} + +pub fn あ1() {} + +fn main() { + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle13foo" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle13foo + foo(); + + // { dg-final { scan-assembler "_R.*NvNtC.*10v0_mangle18module_a3bar" } } + // cf. rustc 1.72.0: _RNvNtCshIBIgX6Bzox_10v0_mangle18module_a3bar + module_a::bar(); + + // { dg-final { scan-assembler "_R.*NvNtNtC10v0_mangle18module_a8module_b3baz" } } + // cf. rustc 1.72.0: _RNvNtNtCshIBIgX6Bzox_10v0_mangle18module_a8module_b3baz + module_a::module_b::baz(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle13__uc" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle13__uc + _uc(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic1lE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic1lEB2_ + generic1::(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic1NtC.*10v0_mangle11SE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic1NtB2_1SEB2_ + generic1::(); + + // { dg-final { scan-assembler "_R.*INvC.*10v0_mangle18generic2hfjE.*" } } + // cf. rustc 1.72.0: _RINvCshIBIgX6Bzox_10v0_mangle18generic2hfjEB2_ + generic2::(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u13pck1ew32ihn2d" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u13pck1ew32ihn2d + 初音ミク(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u8_80al3a6f" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u8_80al3a6f + іржа(); + + // { dg-final { scan-assembler "_R.*NvC.*10v0_mangle1u5_1_w7t" } } + // cf. rustc 1.72.0: _RNvCshIBIgX6Bzox_10v0_mangle1u5_1_w7t + あ1(); +}