From ccbf0e437b955f77098e65cb7b68fb26cd4732d1 Mon Sep 17 00:00:00 2001 From: James Henderson Date: Thu, 17 Jan 2019 15:18:44 +0000 Subject: [PATCH] Move demangling function from llvm-objdump to Demangle library This allows it to be used in an upcoming llvm-readobj change. A small change in internal behaviour of the function is to always call the microsoftDemangle function if the string does not have an itanium encoding prefix, rather than only if it starts with '?'. This is harmless because the microsoftDemangle function does the same check already. Reviewed by: grimar, erik.pilkington Differential Revision: https://reviews.llvm.org/D56721 llvm-svn: 351448 --- include/llvm/Demangle/Demangle.h | 8 ++++++++ lib/Demangle/CMakeLists.txt | 1 + lib/Demangle/Demangle.cpp | 30 +++++++++++++++++++++++++++++ tools/llvm-objdump/llvm-objdump.cpp | 15 --------------- tools/llvm-undname/llvm-undname.cpp | 6 +++--- unittests/Demangle/CMakeLists.txt | 1 + unittests/Demangle/DemangleTest.cpp | 19 ++++++++++++++++++ 7 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 lib/Demangle/Demangle.cpp create mode 100644 unittests/Demangle/DemangleTest.cpp diff --git a/include/llvm/Demangle/Demangle.h b/include/llvm/Demangle/Demangle.h index 4c9dc9569e1..9f3136cfcf4 100644 --- a/include/llvm/Demangle/Demangle.h +++ b/include/llvm/Demangle/Demangle.h @@ -11,6 +11,7 @@ #define LLVM_DEMANGLE_DEMANGLE_H #include +#include namespace llvm { /// This is a llvm local version of __cxa_demangle. Other than the name and @@ -36,6 +37,13 @@ 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); +/// Attempt to demangle a string using different demangling schemes. +/// The function uses heuristics to determine which demangling scheme to use. +/// \param MangledName - reference to string to demangle. +/// \returns - the demangled string, or a copy of the input string if no +/// demangling occurred. +std::string demangle(const std::string &MangledName); + /// "Partial" demangler. This supports demangling a string into an AST /// (typically an intermediate stage in itaniumDemangle) and querying certain /// properties or partially printing the demangled name. diff --git a/lib/Demangle/CMakeLists.txt b/lib/Demangle/CMakeLists.txt index a681af979e4..cde1a4c5c28 100644 --- a/lib/Demangle/CMakeLists.txt +++ b/lib/Demangle/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMDemangle + Demangle.cpp ItaniumDemangle.cpp MicrosoftDemangle.cpp MicrosoftDemangleNodes.cpp diff --git a/lib/Demangle/Demangle.cpp b/lib/Demangle/Demangle.cpp new file mode 100644 index 00000000000..8a37b92fc35 --- /dev/null +++ b/lib/Demangle/Demangle.cpp @@ -0,0 +1,30 @@ +//===-- Demangle.cpp - Common demangling functions ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file This file contains definitions of common demangling functions. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/Demangle/Demangle.h" + +std::string llvm::demangle(const std::string &MangledName) { + char *Demangled; + if (MangledName.compare(0, 2, "_Z") == 0) + Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); + else + Demangled = + microsoftDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); + + if (!Demangled) + return MangledName; + + std::string Ret = Demangled; + free(Demangled); + return Ret; +} diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 449d10cbb92..a4dbd07612f 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -463,21 +463,6 @@ bool llvm::isRelocAddressLess(RelocationRef A, RelocationRef B) { return A.getOffset() < B.getOffset(); } -static std::string demangle(StringRef Name) { - char *Demangled = nullptr; - if (Name.startswith("_Z")) - Demangled = itaniumDemangle(Name.data(), Demangled, nullptr, nullptr); - else if (Name.startswith("?")) - Demangled = microsoftDemangle(Name.data(), Demangled, nullptr, nullptr); - - if (!Demangled) - return Name; - - std::string Ret = Demangled; - free(Demangled); - return Ret; -} - template static std::error_code getRelocationValueString(const ELFObjectFile *Obj, const RelocationRef &RelRef, diff --git a/tools/llvm-undname/llvm-undname.cpp b/tools/llvm-undname/llvm-undname.cpp index 60520c8f7be..5009b94352b 100644 --- a/tools/llvm-undname/llvm-undname.cpp +++ b/tools/llvm-undname/llvm-undname.cpp @@ -33,7 +33,7 @@ cl::opt DumpBackReferences("backrefs", cl::Optional, cl::list Symbols(cl::Positional, cl::desc(""), cl::ZeroOrMore); -static void demangle(const std::string &S) { +static void msDemangle(const std::string &S) { int Status; MSDemangleFlags Flags = MSDF_None; if (DumpBackReferences) @@ -75,14 +75,14 @@ int main(int argc, char **argv) { outs() << Line << "\n"; outs().flush(); } - demangle(Line); + msDemangle(Line); outs() << "\n"; } } else { for (StringRef S : Symbols) { outs() << S << "\n"; outs().flush(); - demangle(S); + msDemangle(S); outs() << "\n"; } } diff --git a/unittests/Demangle/CMakeLists.txt b/unittests/Demangle/CMakeLists.txt index 954f3d05eac..c6291bb2a98 100644 --- a/unittests/Demangle/CMakeLists.txt +++ b/unittests/Demangle/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_unittest(DemangleTests + DemangleTest.cpp ItaniumDemangleTest.cpp PartialDemangleTest.cpp ) diff --git a/unittests/Demangle/DemangleTest.cpp b/unittests/Demangle/DemangleTest.cpp new file mode 100644 index 00000000000..f60122cc137 --- /dev/null +++ b/unittests/Demangle/DemangleTest.cpp @@ -0,0 +1,19 @@ +//===-- DemangleTest.cpp --------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Demangle/Demangle.h" +#include "gmock/gmock.h" + +using namespace llvm; + +TEST(Demangle, demangleTest) { + EXPECT_EQ(demangle("_Z3fooi"), "foo(int)"); + EXPECT_EQ(demangle("?foo@@YAXH@Z"), "void __cdecl foo(int)"); + EXPECT_EQ(demangle("foo"), "foo"); +}