Skip to content

Commit

Permalink
[llvm-cxxfilt] Add --quote option to quote demangled function names (#…
Browse files Browse the repository at this point in the history
…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]>
  • Loading branch information
keryell and jh7370 authored Oct 21, 2024
1 parent 923b8ee commit d582442
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
5 changes: 5 additions & 0 deletions llvm/docs/CommandGuide/llvm-cxxfilt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ OPTIONS
Do not strip a leading underscore. This is the default for all platforms
except Mach-O based hosts.

.. option:: --quote

Add `"` `"` around demangled function symbols. Do not quote already quoted
symbols.

.. option:: --strip-underscore, -_

Strip a single leading underscore, if present, from each input name before
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/tools/llvm-cxxfilt/quote.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Show that llvm-cxxfilt --quote adds quotes around demangled symbols, unless
// the symbol is already quoted.

RUN: split-file %s %t

RUN: llvm-cxxfilt --quote < %t/symbols-in-file.test | FileCheck --match-full-lines --check-prefix=CHECK-FILE %s
CHECK-FILE: "bar()" "bar()"
CHECK-FILE-NEXT: "bar()" "bar()"
CHECK-FILE: log()
CHECK-FILE: "import thunk for std::future<void>"

// Check it works with CLI symbols too. Since a quoted mangled name is not a
// mangled name, it should be unchanged.
RUN: llvm-cxxfilt --quote _Z3firv '"_Z3barv"' 'saw()' | FileCheck --match-full-lines --check-prefix=CHECK-CLI %s
CHECK-CLI: "fir()"
CHECK-CLI-NEXT: "_Z3barv"
CHECK-CLI-NEXT: saw()

//--- symbols-in-file.test
_Z3barv "_Z3barv"
"_Z3barv" _Z3barv
// This is not mangled, thus it should not be quoted.
log()
// Check that an "import thunk for" prefix can be quoted along the demangled
// name.
__imp__ZSt6futureIvE
1 change: 1 addition & 0 deletions llvm/tools/llvm-cxxfilt/Opts.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ multiclass Eq<string name, string help> {
}

def help : FF<"help", "Display this help">;
def quote : FF<"quote", "Quote demangled function names with \" \" if not already quoted">;
defm strip_underscore : BB<"strip-underscore", "Strip the leading underscore", "Don't strip the leading underscore">;
def types : FF<"types", "Attempt to demangle types as well as function names">;
def no_params : FF<"no-params", "Skip function parameters and return types">;
Expand Down
23 changes: 18 additions & 5 deletions llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class CxxfiltOptTable : public opt::GenericOptTable {
} // namespace

static bool ParseParams;
static bool Quote;
static bool StripUnderscore;
static bool Types;

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

static std::string demangle(const std::string &Mangled) {
// Quote Undecorated with "" if asked for and not already followed by a '"'.
static std::string optionalQuote(const std::string &Undecorated,
StringRef Delimiters) {
if (Quote && (Delimiters.empty() || Delimiters[0] != '"'))
return '"' + Undecorated + '"';
return Undecorated;
}

static std::string demangle(const std::string &Mangled, StringRef Delimiters) {
using llvm::itanium_demangle::starts_with;
std::string_view DecoratedStr = Mangled;
bool CanHaveLeadingDot = true;
Expand All @@ -76,7 +85,7 @@ static std::string demangle(const std::string &Mangled) {
std::string Result;
if (nonMicrosoftDemangle(DecoratedStr, Result, CanHaveLeadingDot,
ParseParams))
return Result;
return optionalQuote(Result, Delimiters);

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

Result = Undecorated ? Prefix + Undecorated : Mangled;
Result =
Undecorated ? optionalQuote(Prefix + Undecorated, Delimiters) : Mangled;
free(Undecorated);
return Result;
}
Expand Down Expand Up @@ -137,9 +147,10 @@ static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) {
SmallVector<std::pair<StringRef, StringRef>, 16> Words;
SplitStringDelims(Mangled, Words, IsLegalItaniumChar);
for (const auto &Word : Words)
Result += ::demangle(std::string(Word.first)) + Word.second.str();
Result +=
::demangle(std::string(Word.first), Word.second) + Word.second.str();
} else
Result = ::demangle(std::string(Mangled));
Result = ::demangle(std::string(Mangled), "");
OS << Result << '\n';
OS.flush();
}
Expand Down Expand Up @@ -170,6 +181,8 @@ int llvm_cxxfilt_main(int argc, char **argv, const llvm::ToolContext &) {

ParseParams = !Args.hasArg(OPT_no_params);

Quote = Args.hasArg(OPT_quote);

Types = Args.hasArg(OPT_types);

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

0 comments on commit d582442

Please sign in to comment.