mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
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.)
This commit is contained in:
parent
a0b4517f3d
commit
762e58de3b
@ -71,6 +71,14 @@ indicating whether the following mangled name fragments are
|
|||||||
respectively.
|
respectively.
|
||||||
Blank lines and lines starting with ``#`` are ignored.
|
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``
|
For convenience, built-in <substitution>s such as ``St`` and ``Ss``
|
||||||
are accepted as <name>s (even though they technically are not <name>s).
|
are accepted as <name>s (even though they technically are not <name>s).
|
||||||
|
|
||||||
|
@ -296,16 +296,32 @@ ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First,
|
|||||||
return EquivalenceError::Success;
|
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::Key
|
||||||
ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) {
|
ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) {
|
||||||
P->Demangler.ASTAllocator.setCreateNewNodes(true);
|
return parseMaybeMangledName(P->Demangler, Mangling, true);
|
||||||
P->Demangler.reset(Mangling.begin(), Mangling.end());
|
|
||||||
return reinterpret_cast<Key>(P->Demangler.parse());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ItaniumManglingCanonicalizer::Key
|
ItaniumManglingCanonicalizer::Key
|
||||||
ItaniumManglingCanonicalizer::lookup(StringRef Mangling) {
|
ItaniumManglingCanonicalizer::lookup(StringRef Mangling) {
|
||||||
P->Demangler.ASTAllocator.setCreateNewNodes(false);
|
return parseMaybeMangledName(P->Demangler, Mangling, false);
|
||||||
P->Demangler.reset(Mangling.begin(), Mangling.end());
|
|
||||||
return reinterpret_cast<Key>(P->Demangler.parse());
|
|
||||||
}
|
}
|
||||||
|
@ -249,6 +249,19 @@ static std::vector<Testcase> getTestcases() {
|
|||||||
{"_Z1fRA1_i"}, {"_Z1fRA_f"},
|
{"_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);
|
EquivalenceError::InvalidSecondMangling);
|
||||||
EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"),
|
EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"),
|
||||||
llvm::ItaniumManglingCanonicalizer::Key());
|
llvm::ItaniumManglingCanonicalizer::Key());
|
||||||
EXPECT_EQ(Canonicalizer.canonicalize("foo"),
|
EXPECT_EQ(Canonicalizer.canonicalize("_Zfoo"),
|
||||||
llvm::ItaniumManglingCanonicalizer::Key());
|
llvm::ItaniumManglingCanonicalizer::Key());
|
||||||
|
|
||||||
// A reference to a template parameter ('T_' etc) cannot appear in a <name>,
|
// A reference to a template parameter ('T_' etc) cannot appear in a <name>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user