[llvm] b6e90a1 - llvm-cxxmap: fix support for remapping non-mangled names.

Richard Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 18 10:47:41 PST 2019


Author: Richard Smith
Date: 2019-12-18T10:47:02-08:00
New Revision: b6e90a1a1093210784ed3614b51ebcc31c2a1dcf

URL: https://github.com/llvm/llvm-project/commit/b6e90a1a1093210784ed3614b51ebcc31c2a1dcf
DIFF: https://github.com/llvm/llvm-project/commit/b6e90a1a1093210784ed3614b51ebcc31c2a1dcf.diff

LOG: 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.)

Added: 
    

Modified: 
    llvm/docs/CommandGuide/llvm-cxxmap.rst
    llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
    llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-cxxmap.rst b/llvm/docs/CommandGuide/llvm-cxxmap.rst
index b0bf1c49fc20..dd38f3194b17 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 3db27c3f9ff3..bbc06d186fba 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 91432899d145..b20cdcf340b1 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>,


        


More information about the llvm-commits mailing list