diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-13 16:37:47 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-13 16:37:47 +0000 |
commit | ac6a801ccab90cc1889f6ababb1b44dbdee2baf7 (patch) | |
tree | 0764f1d2e049d715806528900075cd0766d90a1c | |
parent | d379f39e18ca26c63fa725b4a214ec7006862948 (diff) | |
download | bcm5719-llvm-ac6a801ccab90cc1889f6ababb1b44dbdee2baf7.tar.gz bcm5719-llvm-ac6a801ccab90cc1889f6ababb1b44dbdee2baf7.zip |
[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
-rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 6 | ||||
-rw-r--r-- | llvm/include/llvm/Demangle/Demangle.h | 6 | ||||
-rw-r--r-- | llvm/lib/Demangle/ItaniumDemangle.cpp | 16 | ||||
-rw-r--r-- | llvm/unittests/Demangle/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/Demangle/FindTypesInMangledNameTest.cpp | 34 | ||||
-rw-r--r-- | llvm/unittests/Demangle/PartialDemangleTest.cpp | 4 |
6 files changed, 64 insertions, 3 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 3a7ee061c94..9f58a0c6e4c 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -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': diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h index b118631fbcf..b9b4d158e2a 100644 --- a/llvm/include/llvm/Demangle/Demangle.h +++ b/llvm/include/llvm/Demangle/Demangle.h @@ -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); diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp index 98b92b04a26..887e9be9b49 100644 --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -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(); } - } diff --git a/llvm/unittests/Demangle/CMakeLists.txt b/llvm/unittests/Demangle/CMakeLists.txt index 3633d3212eb..48d959c0852 100644 --- a/llvm/unittests/Demangle/CMakeLists.txt +++ b/llvm/unittests/Demangle/CMakeLists.txt @@ -4,4 +4,5 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(DemangleTests PartialDemangleTest.cpp + FindTypesInMangledNameTest.cpp ) diff --git a/llvm/unittests/Demangle/FindTypesInMangledNameTest.cpp b/llvm/unittests/Demangle/FindTypesInMangledNameTest.cpp new file mode 100644 index 00000000000..42e96ebeffd --- /dev/null +++ b/llvm/unittests/Demangle/FindTypesInMangledNameTest.cpp @@ -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. +} diff --git a/llvm/unittests/Demangle/PartialDemangleTest.cpp b/llvm/unittests/Demangle/PartialDemangleTest.cpp index 98d9f86ccea..8bb4a3abcdd 100644 --- a/llvm/unittests/Demangle/PartialDemangleTest.cpp +++ b/llvm/unittests/Demangle/PartialDemangleTest.cpp @@ -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")); |