summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2018-08-13 16:37:47 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2018-08-13 16:37:47 +0000
commitac6a801ccab90cc1889f6ababb1b44dbdee2baf7 (patch)
tree0764f1d2e049d715806528900075cd0766d90a1c
parentd379f39e18ca26c63fa725b4a214ec7006862948 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--llvm/include/llvm/Demangle/Demangle.h6
-rw-r--r--llvm/lib/Demangle/ItaniumDemangle.cpp16
-rw-r--r--llvm/unittests/Demangle/CMakeLists.txt1
-rw-r--r--llvm/unittests/Demangle/FindTypesInMangledNameTest.cpp34
-rw-r--r--llvm/unittests/Demangle/PartialDemangleTest.cpp4
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"));
OpenPOWER on IntegriCloud