[llvm] [llvm-cxxfilt] Add --quote option to quote demangled function names (PR #111871)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 10:00:18 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Ronan Keryell (keryell)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/111871.diff
4 Files Affected:
- (modified) llvm/docs/CommandGuide/llvm-cxxfilt.rst (+5)
- (added) llvm/test/tools/llvm-cxxfilt/quote.test (+12)
- (modified) llvm/tools/llvm-cxxfilt/Opts.td (+2)
- (modified) llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp (+19-5)
``````````diff
diff --git a/llvm/docs/CommandGuide/llvm-cxxfilt.rst b/llvm/docs/CommandGuide/llvm-cxxfilt.rst
index 0933f0b5bed878..ea90a05bcd4338 100644
--- a/llvm/docs/CommandGuide/llvm-cxxfilt.rst
+++ b/llvm/docs/CommandGuide/llvm-cxxfilt.rst
@@ -52,6 +52,11 @@ OPTIONS
Do not demangle function parameters or return types.
+.. option:: --quote, -q
+
+ Add `"` `"` around demangled function symbols, typically to keep LLVM/MLIR
+ assembly files with `@<symbols>` valid. Do not quote already quoted symbols.
+
.. option:: --no-strip-underscore, -n
Do not strip a leading underscore. This is the default for all platforms
diff --git a/llvm/test/tools/llvm-cxxfilt/quote.test b/llvm/test/tools/llvm-cxxfilt/quote.test
new file mode 100644
index 00000000000000..1420c14efbbfbc
--- /dev/null
+++ b/llvm/test/tools/llvm-cxxfilt/quote.test
@@ -0,0 +1,12 @@
+// Show that llvm-cxxfilt --quote can emit quoted demangled symbols but not
+// without double-quoting in the case they are already quoted
+
+RUN: llvm-cxxfilt --quote < %s | FileCheck %s
+ cir.call @_ZN3aie4tileILi1ELi4EE7programIZ4mainE3$_0EEvOT_(%2, %7) : (!cir.ptr<!ty_aie3A3Atile3C12C_43E>, !cir.ptr<!ty_anon2E0_>) -> () loc(#loc74)
+ cir.func lambda internal private @_ZZ4mainENK3$_1clEv(%arg0: !cir.ptr<!ty_anon2E1_> loc("example.cpp":31:26)) extra(#fn_attr) {
+module @"example.cpp" attributes {cir.global_annotations = #cir<global_annotations [["_ZN3aie6deviceILNS_3$_0E42EE4tileILi1ELi4EEENS_4tileIXT_EXT0_EEEv", #cir.annotation<name = "aie.device.tile", args = [1 : i32, 4 : i32, 42 : i8, 42 : i8]>]]}
+
+CHECK: cir.call @"void aie::tile<1, 4>::program<main::$_0>(main::$_0&&)"(%2, %7)
+CHECK-NEXT: cir.func lambda internal private @"main::$_1::operator()() const"(%arg0: !cir.ptr<!ty_anon2E1_>
+// \todo Is there a simpler way to escape these [[ leading to "error: invalid variable name" otherwise?
+CHECK-NEXT: module @"example.cpp" attributes {cir.global_annotations = #cir<global_annotations {{[[]}}["aie::tile<1, 4> aie::device<(aie::$_0)42>::tile<1, 4>()", #cir.annotation<name = "aie.device.tile", args = [1 : i32, 4 : i32, 42 : i8, 42 : i8]>]]}
diff --git a/llvm/tools/llvm-cxxfilt/Opts.td b/llvm/tools/llvm-cxxfilt/Opts.td
index 034cb267aab800..e69082ba05e3a4 100644
--- a/llvm/tools/llvm-cxxfilt/Opts.td
+++ b/llvm/tools/llvm-cxxfilt/Opts.td
@@ -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. Useful for symbols appearing after an @ in MLIR/LLVM assembly">;
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">;
@@ -27,4 +28,5 @@ def : F<"_", "Alias for --strip-underscore">, Alias<strip_underscore>;
def : F<"h", "Alias for --help">, Alias<help>;
def : F<"n", "Alias for --no-strip-underscore">, Alias<no_strip_underscore>;
def : F<"p", "Alias for --no-params">, Alias<no_params>;
+def : F<"q", "Alias for --quote">, Alias<quote>;
def : F<"t", "Alias for --types">, Alias<types>;
diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
index f90adb6cacb990..f3f11e488d2c3d 100644
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
@@ -20,6 +20,7 @@
#include "llvm/TargetParser/Triple.h"
#include <cstdlib>
#include <iostream>
+#include <string>
using namespace llvm;
@@ -54,6 +55,7 @@ class CxxfiltOptTable : public opt::GenericOptTable {
} // namespace
static bool ParseParams;
+static bool Quote;
static bool StripUnderscore;
static bool Types;
@@ -64,7 +66,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(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;
@@ -76,7 +86,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;
@@ -89,7 +99,8 @@ static std::string demangle(const std::string &Mangled) {
Undecorated = itaniumDemangle(DecoratedStr.substr(6), ParseParams);
}
- Result = Undecorated ? Prefix + Undecorated : Mangled;
+ Result =
+ Undecorated ? Prefix + optionalQuote(Undecorated, Delimiters) : Mangled;
free(Undecorated);
return Result;
}
@@ -137,9 +148,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();
}
@@ -172,6 +184,8 @@ int llvm_cxxfilt_main(int argc, char **argv, const llvm::ToolContext &) {
Types = Args.hasArg(OPT_types);
+ Quote = Args.hasArg(OPT_quote);
+
std::vector<std::string> Decorated = Args.getAllArgValues(OPT_INPUT);
if (Decorated.empty())
for (std::string Mangled; std::getline(std::cin, Mangled);)
``````````
</details>
https://github.com/llvm/llvm-project/pull/111871
More information about the llvm-commits
mailing list