[itanium demangler] Add llvm::itaniumFindTypesInMangledName()

This function calls a callback whenever a <type> is parsed.

This is necessary to implement FindAlternateFunctionManglings in LLDB, which
uses a similar hack in FastDemangle. Once that function has been updated to use
this version, FastDemangle can finally be removed.

Differential revision: https://reviews.llvm.org/D50586

llvm-svn: 339580
This commit is contained in:
Erik Pilkington 2018-08-13 16:37:47 +00:00
parent d379f39e18
commit ac6a801cca
6 changed files with 64 additions and 3 deletions

View File

@ -1976,6 +1976,9 @@ struct Db {
// conversion operator's type, and are resolved in the enclosing <encoding>.
PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
void (*TypeCallback)(void *, const char *) = nullptr;
void *TypeCallbackContext = nullptr;
bool TryToParseTemplateArgs = true;
bool PermitForwardTemplateReferences = false;
bool ParsingLambdaParams = false;
@ -3218,6 +3221,9 @@ Node *Db::parseQualifiedType() {
Node *Db::parseType() {
Node *Result = nullptr;
if (TypeCallback != nullptr)
TypeCallback(TypeCallbackContext, First);
switch (look()) {
// ::= <qualified-type>
case 'r':

View File

@ -31,6 +31,12 @@ enum : int {
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
/// Calls the callback \c Callback with \c Ctx as an argument whenever a type is
/// encountered. Returns true if \c MangledName couldn't be parsed.
bool itaniumFindTypesInMangledName(const char *MangledName, void *Ctx,
void (*Callback)(void *, const char *));
enum MSDemangleFlags { MSDF_None = 0, MSDF_DumpBackrefs = 1 << 0 };
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
int *status, MSDemangleFlags Flags = MSDF_None);

View File

@ -1965,6 +1965,9 @@ struct Db {
// conversion operator's type, and are resolved in the enclosing <encoding>.
PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
void (*TypeCallback)(void *, const char *) = nullptr;
void *TypeCallbackContext = nullptr;
bool TryToParseTemplateArgs = true;
bool PermitForwardTemplateReferences = false;
bool ParsingLambdaParams = false;
@ -3207,6 +3210,9 @@ Node *Db::parseQualifiedType() {
Node *Db::parseType() {
Node *Result = nullptr;
if (TypeCallback != nullptr)
TypeCallback(TypeCallbackContext, First);
switch (look()) {
// ::= <qualified-type>
case 'r':
@ -4986,6 +4992,15 @@ char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
return InternalStatus == demangle_success ? Buf : nullptr;
}
bool llvm::itaniumFindTypesInMangledName(const char *MangledName, void *Ctx,
void (*Callback)(void *,
const char *)) {
Db Parser(MangledName, MangledName + std::strlen(MangledName));
Parser.TypeCallback = Callback;
Parser.TypeCallbackContext = Ctx;
return Parser.parse() == nullptr;
}
namespace llvm {
ItaniumPartialDemangler::ItaniumPartialDemangler()
@ -5206,5 +5221,4 @@ bool ItaniumPartialDemangler::isSpecialName() const {
bool ItaniumPartialDemangler::isData() const {
return !isFunction() && !isSpecialName();
}
}

View File

@ -4,4 +4,5 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(DemangleTests
PartialDemangleTest.cpp
FindTypesInMangledNameTest.cpp
)

View File

@ -0,0 +1,34 @@
//===------------------ FindTypesInMangledNameTest.cpp --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstdlib>
#include <vector>
#include "llvm/Demangle/Demangle.h"
#include "gtest/gtest.h"
TEST(FindTypesInMangledNameTest, Test) {
std::vector<const char *> Types;
const char *Mangled = "_Z1fiv";
EXPECT_FALSE(llvm::itaniumFindTypesInMangledName(
Mangled, static_cast<void *>(&Types), +[](void *Ty, const char *P) {
static_cast<std::vector<const char *> *>(Ty)->push_back(P);
}));
EXPECT_EQ(Types.size(), size_t(2));
EXPECT_EQ(Mangled + 4, Types.front());
EXPECT_EQ(Mangled + 5, Types.back());
EXPECT_TRUE(llvm::itaniumFindTypesInMangledName(
"Not a mangled name!", nullptr, +[](void *, const char *) {}));
int TC = 0;
EXPECT_FALSE(llvm::itaniumFindTypesInMangledName(
"_Z1fPRic", static_cast<void *>(&TC),
+[](void *Ctx, const char *) { ++*static_cast<int *>(Ctx); }));
EXPECT_EQ(TC, 4); // pointer, reference, int, char.
}

View File

@ -58,7 +58,7 @@ static ChoppedName NamesToTest[] = {
"mfn", "void", "(int, char, float, unsigned int, char, double)"},
};
TEST(PartialDemangleTest, TestNameChopping) {
TEST(PartialDemanglerTest, TestNameChopping) {
size_t Size = 1;
char *Buf = static_cast<char *>(std::malloc(Size));
@ -86,7 +86,7 @@ TEST(PartialDemangleTest, TestNameChopping) {
std::free(Buf);
}
TEST(PartialDemangleTest, TestNameMeta) {
TEST(PartialDemanglerTest, TestNameMeta) {
llvm::ItaniumPartialDemangler Demangler;
EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv"));