summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-12-18 10:44:29 -0800
committerRichard Smith <richard@metafoo.co.uk>2019-12-18 10:47:02 -0800
commitb6e90a1a1093210784ed3614b51ebcc31c2a1dcf (patch)
treecdbfdf3f040b04eb151b5b92952db95ed6a3487d
parentcfe316007fb8492535d697717c24ce72621a8d5e (diff)
downloadbcm5719-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.rst8
-rw-r--r--llvm/lib/Support/ItaniumManglingCanonicalizer.cpp28
-rw-r--r--llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp15
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>,
OpenPOWER on IntegriCloud