#include "rust-mangle.h"
#include "fnv-hash.h"
+#include "optional.h"
#include "rust-base62.h"
#include "rust-unicode.h"
-#include "optional.h"
+#include "rust-diagnostics.h"
+#include "rust-unicode.h"
+#include "rust-punycode.h"
// FIXME: Rename those to legacy_*
static const std::string kMangledSymbolPrefix = "_ZN";
static void
v0_add_identifier (std::string &mangled, const std::string &identifier)
{
- // FIXME: gccrs cannot handle unicode identifiers yet, so we never have to
- // create mangling for unicode values for now. However, this is handled
- // by the v0 mangling scheme. The grammar for unicode identifier is
- // contained in <undisambiguated-identifier>, right under the <identifier>
- // 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.
-
- mangled += std::to_string (identifier.size ());
-
+ // The grammar for unicode identifier is contained in
+ // <undisambiguated-identifier>, right under the <identifier> 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.
+ tl::optional<Utf8String> uident_opt
+ = Utf8String::make_utf8_string (identifier);
+ rust_assert (uident_opt.has_value ());
+ tl::optional<std::string> punycode_opt
+ = 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
+ if (punycode.back () == '-')
+ punycode.pop_back ();
+ // replace hyphens in punycode with underscores
+ std::replace (punycode.begin (), punycode.end (), '-', '_');
+
+ if (!is_ascii_ident)
+ mangled.append ("u");
+
+ 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 (identifier[0] == '_')
- mangled.append ("_");
+ if (punycode[0] == '_')
+ mangled += "_";
- mangled.append (identifier);
+ mangled += punycode;
}
static std::string
std::string mangled;
// FIXME: Add real algorithm once all pieces are implemented
- auto ty_prefix = v0_type_prefix (ty);
v0_add_identifier (mangled, crate_name);
v0_add_disambiguator (mangled, 62);
+ auto ty_prefix = v0_type_prefix (ty);
rust_unreachable ();
}
namespace selftest {
// Checks if `src` has the same contents as the given characters
-void
-assert_source_content (Rust::InputSource &src, std::vector<uint32_t> expected)
+static void
+assert_source_content (Rust::InputSource &src,
+ const std::vector<uint32_t> &expected)
{
Rust::Codepoint src_char = src.next ();
for (auto expected_char : expected)
ASSERT_TRUE (src_char.is_eof ());
}
-void
-test_buffer_input_source (std::string str, std::vector<uint32_t> expected)
+static void
+test_buffer_input_source (std::string str,
+ const std::vector<uint32_t> &expected)
{
Rust::BufferInputSource source (str, 0);
assert_source_content (source, expected);
}
-void
-test_file_input_source (std::string str, std::vector<uint32_t> expected)
+static void
+test_file_input_source (std::string str, const std::vector<uint32_t> &expected)
{
FILE *tmpf = tmpfile ();
// Moves to the first character
}
else
{
- CrateNum found_crate_num = UNKNOWN_CREATENUM;
+ CrateNum found_crate_num = UNKNOWN_CRATENUM;
bool found
= mappings->lookup_crate_name (extern_crate.get_referenced_crate (),
found_crate_num);
Session::load_extern_crate (const std::string &crate_name, location_t locus)
{
// has it already been loaded?
- CrateNum found_crate_num = UNKNOWN_CREATENUM;
+ CrateNum found_crate_num = UNKNOWN_CRATENUM;
bool found = mappings->lookup_crate_name (crate_name, found_crate_num);
if (found)
{
{
rust_assert (!path.empty ());
return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
- UNKNOWN_CREATENUM);
+ UNKNOWN_CRATENUM);
}
static CanonicalPath
static CanonicalPath create_empty ()
{
- return CanonicalPath ({}, UNKNOWN_CREATENUM);
+ return CanonicalPath ({}, UNKNOWN_CRATENUM);
}
bool is_empty () const { return segs.size () == 0; }
CrateNum get_crate_num () const
{
- rust_assert (crate_num != UNKNOWN_CREATENUM);
+ rust_assert (crate_num != UNKNOWN_CRATENUM);
return crate_num;
}
NodeMapping
NodeMapping::get_error ()
{
- return NodeMapping (UNKNOWN_CREATENUM, UNKNOWN_NODEID, UNKNOWN_HIRID,
+ return NodeMapping (UNKNOWN_CRATENUM, UNKNOWN_NODEID, UNKNOWN_HIRID,
UNKNOWN_LOCAL_DEFID);
}
static const HirId kDefaultCrateNumBegin = 0;
Mappings::Mappings ()
- : crateNumItr (kDefaultCrateNumBegin), currentCrateNum (UNKNOWN_CREATENUM),
+ : crateNumItr (kDefaultCrateNumBegin), currentCrateNum (UNKNOWN_CRATENUM),
hirIdIter (kDefaultHirIdBegin), nodeIdIter (kDefaultNodeIdBegin)
{
Analysis::NodeMapping node (0, 0, 0, 0);
}
};
-#define UNKNOWN_CREATENUM ((uint32_t) (0))
+#define UNKNOWN_CRATENUM ((uint32_t) (UINT32_MAX))
#define UNKNOWN_NODEID ((uint32_t) (0))
#define UNKNOWN_HIRID ((uint32_t) (0))
#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0))