diff options
author | Matt Davis <Matthew.Davis@sony.com> | 2019-02-11 20:30:53 +0000 |
---|---|---|
committer | Matt Davis <Matthew.Davis@sony.com> | 2019-02-11 20:30:53 +0000 |
commit | 22c21934cefc83a8f911728eea24ebe79df49af1 (patch) | |
tree | 76f0cd15afa4c8959d653d4d3ac90d44161582f3 /llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp | |
parent | 7c8952197b86790b31731d34d559281840916e1f (diff) | |
download | bcm5719-llvm-22c21934cefc83a8f911728eea24ebe79df49af1.tar.gz bcm5719-llvm-22c21934cefc83a8f911728eea24ebe79df49af1.zip |
[llvm-cxxfilt] Split and demangle stdin input
Summary:
Originally, llvm-cxxfilt would treat a line as a single mangled item to be demangled.
If a mangled name appears in the middle of that string, that name would not be demangled.
GNU c++filt splits and demangles every word in a string that is piped to it via stdin.
Prior to this patch llvm-cxxfilt would never split strings piped to it.
This patch replicates the GNU behavior and splits strings that are piped to it via stdin.
This fixes PR39990
Reviewers: compnerd, jhenderson, davide
Reviewed By: compnerd, jhenderson
Subscribers: erik.pilkington, jhenderson, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57350
llvm-svn: 353743
Diffstat (limited to 'llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp')
-rw-r--r-- | llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp index 780ec6e3d52..821c705b95b 100644 --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringExtras.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InitLLVM.h" @@ -51,7 +52,7 @@ static cl::alias TypesShort("t", cl::desc("alias for --types"), static cl::list<std::string> Decorated(cl::Positional, cl::desc("<mangled>"), cl::ZeroOrMore); -static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) { +static std::string demangle(llvm::raw_ostream &OS, const std::string &Mangled) { int Status; const char *Decorated = Mangled.c_str(); @@ -72,10 +73,28 @@ static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) { Undecorated = itaniumDemangle(Decorated + 6, nullptr, nullptr, &Status); } - OS << (Undecorated ? Undecorated : Mangled) << '\n'; - OS.flush(); - + std::string Result(Undecorated ? Undecorated : Mangled); free(Undecorated); + return Result; +} + +// If 'Split' is true, then 'Mangled' is broken into individual words and each +// word is demangled. Otherwise, the entire string is treated as a single +// mangled item. The result is output to 'OS'. +static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) { + std::string Result; + if (Split) { + SmallVector<StringRef, 16> Words; + SplitString(Mangled, Words); + for (auto Word : Words) + Result += demangle(OS, Word) + ' '; + // Remove the trailing space character. + if (Result.back() == ' ') + Result.pop_back(); + } else + Result = demangle(OS, Mangled); + OS << Result << '\n'; + OS.flush(); } int main(int argc, char **argv) { @@ -85,10 +104,10 @@ int main(int argc, char **argv) { if (Decorated.empty()) for (std::string Mangled; std::getline(std::cin, Mangled);) - demangle(llvm::outs(), Mangled); + demangleLine(llvm::outs(), Mangled, true); else for (const auto &Symbol : Decorated) - demangle(llvm::outs(), Symbol); + demangleLine(llvm::outs(), Symbol, false); return EXIT_SUCCESS; } |