Skip to content

Commit 35f6d0f

Browse files
committed
v0-mangling: Add base functions for mangling scheme
1 parent a2484d5 commit 35f6d0f

File tree

1 file changed

+65
-22
lines changed

1 file changed

+65
-22
lines changed

gcc/rust/backend/rust-mangle.cc

+65-22
Original file line numberDiff line numberDiff line change
@@ -157,41 +157,82 @@ v0_simple_type_prefix (const TyTy::BaseType *ty)
157157

158158
// FIXME: Is this present somewhere in libbiberty already?
159159
static std::string
160-
v0_base62_integer(uint64_t x)
160+
v0_base62_integer (uint64_t x)
161161
{
162162
const static std::string base_64
163163
= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
164-
std::string buffer(128, '\0');
164+
std::string buffer (128, '\0');
165165
size_t idx = 0;
166166
size_t base = 62;
167167

168168
do
169169
{
170170
buffer[idx] = base_64[(x % base)];
171171
idx++;
172-
x /= base;
173-
} while (x != 0);
172+
x = x / base;
173+
}
174+
while (x != 0);
174175

175-
std::reverse(buffer.begin(), buffer.begin() + idx);
176-
return buffer.substr(0, idx);
176+
std::reverse (buffer.begin (), buffer.begin () + idx);
177+
return buffer.substr (0, idx);
177178
}
178179

179-
static std::string
180-
v0_add_integer_62 (std::string mangled, std::string tag, uint64_t x)
180+
// Add an underscore-terminated base62 integer to the mangling string.
181+
// This corresponds to the `<base-62-number>` grammar in the v0 mangling RFC:
182+
// - 0 is encoded as "_"
183+
// - any other value is encoded as itself minus one in base 62, followed by "_"
184+
static void
185+
v0_add_integer_62 (std::string &mangled, uint64_t x)
181186
{
182-
// /// Push a `_`-terminated base 62 integer, using the format
183-
// /// specified in the RFC as `<base-62-number>`, that is:
184-
// /// * `x = 0` is encoded as just the `"_"` terminator
185-
// /// * `x > 0` is encoded as `x - 1` in base 62, followed by `"_"`,
186-
// /// e.g. `1` becomes `"0_"`, `62` becomes `"Z_"`, etc.
187-
// fn push_integer_62(&mut self, x: u64) {
188-
// if let Some(x) = x.checked_sub(1) {
189-
// base_n::push_str(x as u128, 62, &mut self.out);
190-
// }
191-
// self.push("_");
192-
// }
187+
if (x > 0)
188+
mangled.append (v0_base62_integer (x - 1));
189+
190+
mangled.append ("_");
193191
}
194192

193+
// Add a tag-prefixed base62 integer to the mangling string when the
194+
// integer is greater than 0:
195+
// - 0 is encoded as "" (nothing)
196+
// - any other value is encoded as <tag> + v0_add_integer_62(itself), that is
197+
// <tag> + base62(itself - 1) + '_'
198+
static void
199+
v0_add_opt_integer_62 (std::string &mangled, std::string tag, uint64_t x)
200+
{
201+
if (x > 0)
202+
{
203+
mangled.append (tag);
204+
v0_add_integer_62 (mangled, x);
205+
}
206+
}
207+
208+
static void
209+
v0_add_disambiguator (std::string &mangled, uint64_t dis)
210+
{
211+
v0_add_opt_integer_62 (mangled, "s", dis);
212+
}
213+
214+
// Add an identifier to the mangled string. This corresponds to the
215+
// `<identifier>` grammar in the v0 mangling RFC.
216+
static void
217+
v0_add_identifier (std::string &mangled, const std::string &identifier)
218+
{
219+
// FIXME: gccrs cannot handle unicode identifiers yet, so we never have to
220+
// create mangling for unicode values for now. However, this is handled
221+
// by the v0 mangling scheme. The grammar for unicode identifier is contained
222+
// in <undisambiguated-identifier>, right under the <identifier> one. If the
223+
// identifier contains unicode values, then an extra "u" needs to be added
224+
// to the mangling string and `punycode` must be used to encode the
225+
// characters.
226+
227+
mangled += std::to_string (identifier.size ());
228+
229+
// If the first character of the identifier is a digit or an underscore, we
230+
// add an extra underscore
231+
if (identifier[0] == '_')
232+
mangled.append ("_");
233+
234+
mangled.append (identifier);
235+
}
195236

196237
static std::string
197238
v0_type_prefix (const TyTy::BaseType *ty)
@@ -233,10 +274,12 @@ static std::string
233274
v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path,
234275
const std::string &crate_name)
235276
{
236-
auto def_id = ty->get_ref();
237-
auto ty_prefix = v0_type_prefix (ty);
238-
auto prefix = "_R";
277+
std::string mangled;
239278

279+
// FIXME: Add real algorithm once all pieces are implemented
280+
auto ty_prefix = v0_type_prefix (ty);
281+
v0_add_identifier (mangled, crate_name);
282+
v0_add_disambiguator (mangled, 62);
240283

241284
gcc_unreachable ();
242285
}

0 commit comments

Comments
 (0)