Skip to content

Commit d582442

Browse files
keryelljh7370
andauthored
[llvm-cxxfilt] Add --quote option to quote demangled function names (#111871)
This is useful when looking at LLVM/MLIR assembly produced from C++ sources. For example cir.call @_ZN3aie4tileILi1ELi4EE7programIZ4mainE3$_0EEvOT_(%2, %7) : will be translated to cir.call @"void aie::tile<1, 4>::program<main::$_0>(main::$_0&&)"(%2, %7) : which can be parsed as valid MLIR by the right mlir-lsp-server. If a symbol is already quoted, do not quote it more. --------- Co-authored-by: James Henderson <[email protected]>
1 parent 923b8ee commit d582442

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

llvm/docs/CommandGuide/llvm-cxxfilt.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ OPTIONS
5757
Do not strip a leading underscore. This is the default for all platforms
5858
except Mach-O based hosts.
5959

60+
.. option:: --quote
61+
62+
Add `"` `"` around demangled function symbols. Do not quote already quoted
63+
symbols.
64+
6065
.. option:: --strip-underscore, -_
6166

6267
Strip a single leading underscore, if present, from each input name before
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Show that llvm-cxxfilt --quote adds quotes around demangled symbols, unless
2+
// the symbol is already quoted.
3+
4+
RUN: split-file %s %t
5+
6+
RUN: llvm-cxxfilt --quote < %t/symbols-in-file.test | FileCheck --match-full-lines --check-prefix=CHECK-FILE %s
7+
CHECK-FILE: "bar()" "bar()"
8+
CHECK-FILE-NEXT: "bar()" "bar()"
9+
CHECK-FILE: log()
10+
CHECK-FILE: "import thunk for std::future<void>"
11+
12+
// Check it works with CLI symbols too. Since a quoted mangled name is not a
13+
// mangled name, it should be unchanged.
14+
RUN: llvm-cxxfilt --quote _Z3firv '"_Z3barv"' 'saw()' | FileCheck --match-full-lines --check-prefix=CHECK-CLI %s
15+
CHECK-CLI: "fir()"
16+
CHECK-CLI-NEXT: "_Z3barv"
17+
CHECK-CLI-NEXT: saw()
18+
19+
//--- symbols-in-file.test
20+
_Z3barv "_Z3barv"
21+
"_Z3barv" _Z3barv
22+
// This is not mangled, thus it should not be quoted.
23+
log()
24+
// Check that an "import thunk for" prefix can be quoted along the demangled
25+
// name.
26+
__imp__ZSt6futureIvE

llvm/tools/llvm-cxxfilt/Opts.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ multiclass Eq<string name, string help> {
1515
}
1616

1717
def help : FF<"help", "Display this help">;
18+
def quote : FF<"quote", "Quote demangled function names with \" \" if not already quoted">;
1819
defm strip_underscore : BB<"strip-underscore", "Strip the leading underscore", "Don't strip the leading underscore">;
1920
def types : FF<"types", "Attempt to demangle types as well as function names">;
2021
def no_params : FF<"no-params", "Skip function parameters and return types">;

llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class CxxfiltOptTable : public opt::GenericOptTable {
5454
} // namespace
5555

5656
static bool ParseParams;
57+
static bool Quote;
5758
static bool StripUnderscore;
5859
static bool Types;
5960

@@ -64,7 +65,15 @@ static void error(const Twine &Message) {
6465
exit(1);
6566
}
6667

67-
static std::string demangle(const std::string &Mangled) {
68+
// Quote Undecorated with "" if asked for and not already followed by a '"'.
69+
static std::string optionalQuote(const std::string &Undecorated,
70+
StringRef Delimiters) {
71+
if (Quote && (Delimiters.empty() || Delimiters[0] != '"'))
72+
return '"' + Undecorated + '"';
73+
return Undecorated;
74+
}
75+
76+
static std::string demangle(const std::string &Mangled, StringRef Delimiters) {
6877
using llvm::itanium_demangle::starts_with;
6978
std::string_view DecoratedStr = Mangled;
7079
bool CanHaveLeadingDot = true;
@@ -76,7 +85,7 @@ static std::string demangle(const std::string &Mangled) {
7685
std::string Result;
7786
if (nonMicrosoftDemangle(DecoratedStr, Result, CanHaveLeadingDot,
7887
ParseParams))
79-
return Result;
88+
return optionalQuote(Result, Delimiters);
8089

8190
std::string Prefix;
8291
char *Undecorated = nullptr;
@@ -89,7 +98,8 @@ static std::string demangle(const std::string &Mangled) {
8998
Undecorated = itaniumDemangle(DecoratedStr.substr(6), ParseParams);
9099
}
91100

92-
Result = Undecorated ? Prefix + Undecorated : Mangled;
101+
Result =
102+
Undecorated ? optionalQuote(Prefix + Undecorated, Delimiters) : Mangled;
93103
free(Undecorated);
94104
return Result;
95105
}
@@ -137,9 +147,10 @@ static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) {
137147
SmallVector<std::pair<StringRef, StringRef>, 16> Words;
138148
SplitStringDelims(Mangled, Words, IsLegalItaniumChar);
139149
for (const auto &Word : Words)
140-
Result += ::demangle(std::string(Word.first)) + Word.second.str();
150+
Result +=
151+
::demangle(std::string(Word.first), Word.second) + Word.second.str();
141152
} else
142-
Result = ::demangle(std::string(Mangled));
153+
Result = ::demangle(std::string(Mangled), "");
143154
OS << Result << '\n';
144155
OS.flush();
145156
}
@@ -170,6 +181,8 @@ int llvm_cxxfilt_main(int argc, char **argv, const llvm::ToolContext &) {
170181

171182
ParseParams = !Args.hasArg(OPT_no_params);
172183

184+
Quote = Args.hasArg(OPT_quote);
185+
173186
Types = Args.hasArg(OPT_types);
174187

175188
std::vector<std::string> Decorated = Args.getAllArgValues(OPT_INPUT);

0 commit comments

Comments
 (0)