summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cxxfilt
diff options
context:
space:
mode:
authorMatt Davis <Matthew.Davis@sony.com>2019-02-27 16:29:50 +0000
committerMatt Davis <Matthew.Davis@sony.com>2019-02-27 16:29:50 +0000
commit5cd5f8f2563395f8767f94604eb4c4bea8dcbea0 (patch)
tree45264447b48ec5afdcbab0c363dee3cabcf78876 /llvm/tools/llvm-cxxfilt
parenta54fe15610d6d592590659186731daf1063dc153 (diff)
downloadbcm5719-llvm-5cd5f8f2563395f8767f94604eb4c4bea8dcbea0.tar.gz
bcm5719-llvm-5cd5f8f2563395f8767f94604eb4c4bea8dcbea0.zip
[llvm-cxxfilt] Split and demangle stdin input on certain non-alphanumerics.
Summary: This patch attempts to replicate GNU c++-filt behavior when splitting stdin input for demangling. Previously, cxx-filt would split input only on spaces. Each delimited item is then demangled. From what I have tested, GNU c++filt also splits input on any character that does not make up the mangled name (notably commas, but also a large set of non-alphanumeric characters). This patch splits stdin input on any character that does not belong to the Itanium mangling format (since Itanium is currently the only supported format in llvm-cxxfilt). This is an update to PR39990 Reviewers: jhenderson, tejohnson, compnerd Reviewed By: compnerd Subscribers: erik.pilkington, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58416 llvm-svn: 354998
Diffstat (limited to 'llvm/tools/llvm-cxxfilt')
-rw-r--r--llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp45
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
index e0850444d6f..a082dc7cfe8 100644
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
@@ -78,19 +78,50 @@ static std::string demangle(llvm::raw_ostream &OS, const std::string &Mangled) {
return Result;
}
+// Split 'Source' on any character that fails to pass 'IsLegalChar'. The
+// returned vector consists of pairs where 'first' is the delimited word, and
+// 'second' are the delimiters following that word.
+static void SplitStringDelims(
+ StringRef Source,
+ SmallVectorImpl<std::pair<StringRef, StringRef>> &OutFragments,
+ function_ref<bool(char)> IsLegalChar) {
+ // The beginning of the input string.
+ const auto Head = Source.begin();
+
+ // Obtain any leading delimiters.
+ auto Start = std::find_if(Head, Source.end(), IsLegalChar);
+ if (Start != Head)
+ OutFragments.push_back({"", Source.slice(0, Start - Head)});
+
+ // Capture each word and the delimiters following that word.
+ while (Start != Source.end()) {
+ Start = std::find_if(Start, Source.end(), IsLegalChar);
+ auto End = std::find_if_not(Start, Source.end(), IsLegalChar);
+ auto DEnd = std::find_if(End, Source.end(), IsLegalChar);
+ OutFragments.push_back({Source.slice(Start - Head, End - Head),
+ Source.slice(End - Head, DEnd - Head)});
+ Start = DEnd;
+ }
+}
+
+// This returns true if 'C' is a character that can show up in an
+// Itanium-mangled string.
+static bool IsLegalItaniumChar(char C) {
+ // Itanium CXX ABI [External Names]p5.1.1:
+ // '$' and '.' in mangled names are reserved for private implementations.
+ return isalnum(C) || C == '.' || C == '$' || C == '_';
+}
+
// 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();
+ SmallVector<std::pair<StringRef, StringRef>, 16> Words;
+ SplitStringDelims(Mangled, Words, IsLegalItaniumChar);
+ for (const auto &Word : Words)
+ Result += demangle(OS, Word.first) + Word.second.str();
} else
Result = demangle(OS, Mangled);
OS << Result << '\n';
OpenPOWER on IntegriCloud