Michael137 updated this revision to Diff 471468.
Michael137 added a comment.

- Use the C++ language-plugin to format the function name


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136761/new/

https://reviews.llvm.org/D136761

Files:
  lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
  lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
  lldb/test/Shell/Settings/Inputs/names.cpp
  lldb/test/Shell/Settings/TestFrameFormatNameWithArgs.test

Index: lldb/test/Shell/Settings/TestFrameFormatNameWithArgs.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/Settings/TestFrameFormatNameWithArgs.test
@@ -0,0 +1,22 @@
+# RUN: %clangxx_host -g -O0 %S/Inputs/names.cpp -std=c++17 -o %t.out
+# RUN: %lldb -b -s %s %t.out | FileCheck %s
+settings set -f frame-format "frame ${function.name-with-args}\n"
+break set -n foo
+break set -n operator<<
+run
+# CHECK: frame int ns::foo<int ()>(t={{.*}})
+c
+# CHECK: frame int ns::foo<std::__1::function<int ()>>(t= Function = bar() )
+c
+# CHECK: frame int ns::foo<(anonymous namespace)::$_0>(t={{.*}})
+c
+# CHECK: frame int ns::foo<std::__1::function<int ()>>(t= Function = (anonymous namespace)::anon_bar() )
+c
+# CHECK: frame int ns::foo<void (Foo::*)(std::__1::function<int (int)> const&) const noexcept>(t={{.*}})
+c
+# CHECK: frame void Foo::foo<std::__1::function<int ()>>(this={{.*}}, t= Function = bar() ) const
+c
+# CHECK: frame void Foo::foo<std::__1::function<int ()>>(this={{.*}}, t= Function = (anonymous namespace)::anon_bar() ) const
+c
+# CHECK: frame void Foo::operator<<<1ul>(this={{.*}}, (null)=0)
+q
Index: lldb/test/Shell/Settings/Inputs/names.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/Settings/Inputs/names.cpp
@@ -0,0 +1,31 @@
+#include <functional>
+
+struct Foo {
+  template <typename T> void foo(T const &t) const noexcept(true) {}
+
+  template <size_t T> void operator<<(size_t) {}
+};
+
+namespace ns {
+template <typename T> int foo(T const &t) noexcept(false) { return 0; }
+} // namespace ns
+
+int bar() { return 1; }
+
+namespace {
+int anon_bar() { return 1; }
+auto anon_lambda = [](std::function<int(int (*)(int))>) mutable {};
+} // namespace
+
+int main() {
+  ns::foo(bar);
+  ns::foo(std::function{bar});
+  ns::foo(anon_lambda);
+  ns::foo(std::function{anon_bar});
+  ns::foo(&Foo::foo<std::function<int(int)>>);
+  Foo f;
+  f.foo(std::function{bar});
+  f.foo(std::function{anon_bar});
+  f.operator<< <(2 > 1)>(0);
+  return 0;
+}
Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -132,6 +132,11 @@
   ConstString
   GetDemangledFunctionNameWithoutArguments(Mangled mangled) const override;
 
+  bool GetFunctionDisplayName(const SymbolContext *sc,
+                              const ExecutionContext *exe_ctx,
+                              FunctionNameRepresentation representation,
+                              Stream &s) override;
+
   static bool IsCPPMangledName(llvm::StringRef name);
 
   // Extract C++ context and identifier from a string using heuristic matching
Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -23,11 +23,13 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/DataFormatters/CXXFunctionPointer.h"
 #include "lldb/DataFormatters/DataVisualization.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
 #include "lldb/DataFormatters/VectorType.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/VariableList.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
@@ -171,6 +173,39 @@
   return idx == basename.size();
 }
 
+/// Writes out the function name in 'full_name' to 'out_stream'
+/// but replaces each argument type with the variable name
+/// and the corresponding pretty-printed value
+static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,
+                                            char const *full_name,
+                                            ExecutionContextScope *exe_scope,
+                                            VariableList const &args) {
+  CPlusPlusLanguage::MethodName cpp_method{ConstString(full_name)};
+
+  if (!cpp_method.IsValid())
+    return false;
+
+  llvm::StringRef return_type = cpp_method.GetReturnType();
+  if (!return_type.empty()) {
+    out_stream.PutCString(return_type);
+    out_stream.PutChar(' ');
+  }
+  out_stream.PutCString(cpp_method.GetScopeQualifiedName());
+  out_stream.PutChar('(');
+
+  FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);
+
+  out_stream.PutChar(')');
+
+  llvm::StringRef qualifiers = cpp_method.GetQualifiers();
+  if (!qualifiers.empty()) {
+    out_stream.PutChar(' ');
+    out_stream.PutCString(qualifiers);
+  }
+
+  return true;
+}
+
 bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
   // This method tries to parse simple method definitions which are presumably
   // most comman in user programs. Definitions that can be parsed by this
@@ -1465,3 +1500,66 @@
   // that we could check for.
   return file_path.contains("/usr/include/c++/");
 }
+
+bool CPlusPlusLanguage::GetFunctionDisplayName(
+    const SymbolContext *sc, const ExecutionContext *exe_ctx,
+    FunctionNameRepresentation representation, Stream &s) {
+  switch (representation) {
+  case FunctionNameRepresentation::eNameWithArgs: {
+    // Print the function name with arguments in it
+    if (sc->function) {
+      ExecutionContextScope *exe_scope =
+          exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+      const char *cstr = sc->function->GetName().AsCString(nullptr);
+      if (cstr) {
+        const InlineFunctionInfo *inline_info = nullptr;
+        VariableListSP variable_list_sp;
+        bool get_function_vars = true;
+        if (sc->block) {
+          Block *inline_block = sc->block->GetContainingInlinedBlock();
+
+          if (inline_block) {
+            get_function_vars = false;
+            inline_info = sc->block->GetInlinedFunctionInfo();
+            if (inline_info)
+              variable_list_sp = inline_block->GetBlockVariableList(true);
+          }
+        }
+
+        if (get_function_vars) {
+          variable_list_sp =
+              sc->function->GetBlock(true).GetBlockVariableList(true);
+        }
+
+        if (inline_info) {
+          s.PutCString(cstr);
+          s.PutCString(" [inlined] ");
+          cstr = inline_info->GetName().GetCString();
+        }
+
+        VariableList args;
+        if (variable_list_sp)
+          variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
+                                                     args);
+        if (args.GetSize() > 0) {
+          if (!PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args))
+            return false;
+        } else {
+          s.PutCString(cstr);
+        }
+        return true;
+      }
+    } else if (sc->symbol) {
+      const char *cstr = sc->symbol->GetName().AsCString(nullptr);
+      if (cstr) {
+        s.PutCString(cstr);
+        return true;
+      }
+    }
+  } break;
+  default:
+    return false;
+  }
+
+  return false;
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to