diff options
author | Richard Smith <richard@metafoo.co.uk> | 2019-12-18 10:44:29 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2019-12-18 10:47:02 -0800 |
commit | b6e90a1a1093210784ed3614b51ebcc31c2a1dcf (patch) | |
tree | cdbfdf3f040b04eb151b5b92952db95ed6a3487d | |
parent | cfe316007fb8492535d697717c24ce72621a8d5e (diff) | |
download | bcm5719-llvm-b6e90a1a1093210784ed3614b51ebcc31c2a1dcf.tar.gz bcm5719-llvm-b6e90a1a1093210784ed3614b51ebcc31c2a1dcf.zip |
llvm-cxxmap: fix support for remapping non-mangled names.
Remappings involving extern "C" names were already supported in the
context of <local-name>s, but this support didn't work for remapping the
complete mangling itself. (Eg, we would remap X<foo> but not foo itself,
if foo is an extern "C" function.)
-rw-r--r-- | llvm/docs/CommandGuide/llvm-cxxmap.rst | 8 | ||||
-rw-r--r-- | llvm/lib/Support/ItaniumManglingCanonicalizer.cpp | 28 | ||||
-rw-r--r-- | llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp | 15 |
3 files changed, 44 insertions, 7 deletions
diff --git a/llvm/docs/CommandGuide/llvm-cxxmap.rst b/llvm/docs/CommandGuide/llvm-cxxmap.rst index b0bf1c49fc2..dd38f3194b1 100644 --- a/llvm/docs/CommandGuide/llvm-cxxmap.rst +++ b/llvm/docs/CommandGuide/llvm-cxxmap.rst @@ -71,6 +71,14 @@ indicating whether the following mangled name fragments are respectively. Blank lines and lines starting with ``#`` are ignored. +Unmangled C names can be expressed as an ``encoding`` that is a (length-prefixed) +<`source-name <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.source-name>`_>: + +.. code-block:: none + + # C function "void foo_bar()" is remapped to C++ function "void foo::bar()". + encoding 7foo_bar _Z3foo3barv + For convenience, built-in <substitution>s such as ``St`` and ``Ss`` are accepted as <name>s (even though they technically are not <name>s). diff --git a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp index 3db27c3f9ff..bbc06d186fb 100644 --- a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp +++ b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp @@ -296,16 +296,32 @@ ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First, return EquivalenceError::Success; } +static ItaniumManglingCanonicalizer::Key +parseMaybeMangledName(CanonicalizingDemangler &Demangler, StringRef Mangling, + bool CreateNewNodes) { + Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes); + Demangler.reset(Mangling.begin(), Mangling.end()); + // Attempt demangling only for names that look like C++ mangled names. + // Otherwise, treat them as extern "C" names. We permit the latter to + // be remapped by (eg) + // encoding 6memcpy 7memmove + // consistent with how they are encoded as local-names inside a C++ mangling. + Node *N; + if (Mangling.startswith("_Z") || Mangling.startswith("__Z") || + Mangling.startswith("___Z") || Mangling.startswith("____Z")) + N = Demangler.parse(); + else + N = Demangler.make<itanium_demangle::NameType>( + StringView(Mangling.data(), Mangling.size())); + return reinterpret_cast<ItaniumManglingCanonicalizer::Key>(N); +} + ItaniumManglingCanonicalizer::Key ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) { - P->Demangler.ASTAllocator.setCreateNewNodes(true); - P->Demangler.reset(Mangling.begin(), Mangling.end()); - return reinterpret_cast<Key>(P->Demangler.parse()); + return parseMaybeMangledName(P->Demangler, Mangling, true); } ItaniumManglingCanonicalizer::Key ItaniumManglingCanonicalizer::lookup(StringRef Mangling) { - P->Demangler.ASTAllocator.setCreateNewNodes(false); - P->Demangler.reset(Mangling.begin(), Mangling.end()); - return reinterpret_cast<Key>(P->Demangler.parse()); + return parseMaybeMangledName(P->Demangler, Mangling, false); } diff --git a/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp index 91432899d14..b20cdcf340b 100644 --- a/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp +++ b/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp @@ -249,6 +249,19 @@ static std::vector<Testcase> getTestcases() { {"_Z1fRA1_i"}, {"_Z1fRA_f"}, } }, + + // Unmangled names can be remapped as complete encodings. + { + { + {FragmentKind::Encoding, "3foo", "3bar"}, + }, + { + // foo == bar + {"foo", "bar"}, + // void f<foo>() == void f<bar>() + {"_Z1fIL_Z3fooEEvv", "_Z1fIL_Z3barEEvv"}, + } + }, }; } @@ -343,7 +356,7 @@ TEST(ItaniumManglingCanonicalizerTest, TestInvalidManglings) { EquivalenceError::InvalidSecondMangling); EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"), llvm::ItaniumManglingCanonicalizer::Key()); - EXPECT_EQ(Canonicalizer.canonicalize("foo"), + EXPECT_EQ(Canonicalizer.canonicalize("_Zfoo"), llvm::ItaniumManglingCanonicalizer::Key()); // A reference to a template parameter ('T_' etc) cannot appear in a <name>, |