llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

<details>
<summary>Changes</summary>

This way we make sure that the logic to reconstruct demangled names in the 
tests is the same as the logic when reconstructing the actual frame-format 
variable.

`DemangledNameInfo::SuffixRange` is currently the only one which we can't test 
in the same way until we set it from inside the `TrackingOutputBuffer`. I added 
TODOs to track this.

---
Full diff: https://github.com/llvm/llvm-project/pull/152134.diff


4 Files Affected:

- (modified) lldb/source/Core/Mangled.cpp (+1) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
(+93-36) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h (+26) 
- (modified) lldb/unittests/Core/MangledTest.cpp (+40-17) 


``````````diff
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 0027bfaeda4f7..3663f430111c2 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -172,6 +172,7 @@ GetItaniumDemangledStr(const char *M) {
 
     TrackingOutputBuffer OB(demangled_cstr, demangled_size);
     demangled_cstr = ipd.finishDemangle(&OB);
+    // TODO: we should set the SuffixRange inside the TrackingOutputBuffer.
     OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
     OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
     info = std::move(OB.NameInfo);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 46753c5efc331..d9b8cc5278075 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Demangle/ItaniumDemangle.h"
 
+#include "lldb/Core/DemangledNameInfo.h"
 #include "lldb/Core/Mangled.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
@@ -271,8 +272,14 @@ GetDemangledBasename(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
-  return demangled_name.slice(info.BasenameRange.first,
-                              info.BasenameRange.second);
+  return CPlusPlusLanguage::GetDemangledBasename(demangled_name, info);
+}
+
+llvm::StringRef
+CPlusPlusLanguage::GetDemangledBasename(llvm::StringRef demangled,
+                                        const DemangledNameInfo &info) {
+  assert(info.hasBasename());
+  return demangled.slice(info.BasenameRange.first, info.BasenameRange.second);
 }
 
 static llvm::Expected<llvm::StringRef>
@@ -283,12 +290,27 @@ GetDemangledTemplateArguments(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
+  return CPlusPlusLanguage::GetDemangledTemplateArguments(demangled_name, 
info);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledTemplateArguments(
+    llvm::StringRef demangled, const DemangledNameInfo &info) {
   if (info.ArgumentsRange.first < info.BasenameRange.second)
     return llvm::createStringError("Arguments range for '%s' is invalid.",
-                                   demangled_name.data());
+                                   demangled.data());
 
-  return demangled_name.slice(info.BasenameRange.second,
-                              info.ArgumentsRange.first);
+  return demangled.slice(info.BasenameRange.second, info.ArgumentsRange.first);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledReturnTypeLHS(llvm::StringRef demangled,
+                                             const DemangledNameInfo &info) {
+  if (info.ScopeRange.first >= demangled.size())
+    return llvm::createStringError(
+        "Scope range for '%s' LHS return type is invalid.", demangled.data());
+
+  return demangled.substr(0, info.ScopeRange.first);
 }
 
 static llvm::Expected<llvm::StringRef>
@@ -299,12 +321,18 @@ GetDemangledReturnTypeLHS(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
-  if (info.ScopeRange.first >= demangled_name.size())
-    return llvm::createStringError(
-        "Scope range for '%s' LHS return type is invalid.",
-        demangled_name.data());
+  return CPlusPlusLanguage::GetDemangledReturnTypeLHS(demangled_name, info);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledFunctionQualifiers(
+    llvm::StringRef demangled, const DemangledNameInfo &info) {
+  if (!info.hasQualifiers())
+    return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+                                   demangled.data());
 
-  return demangled_name.substr(0, info.ScopeRange.first);
+  return demangled.slice(info.QualifiersRange.first,
+                         info.QualifiersRange.second);
 }
 
 static llvm::Expected<llvm::StringRef>
@@ -315,12 +343,20 @@ GetDemangledFunctionQualifiers(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
-  if (!info.hasQualifiers())
-    return llvm::createStringError("Qualifiers range for '%s' is invalid.",
-                                   demangled_name.data());
+  return CPlusPlusLanguage::GetDemangledFunctionQualifiers(demangled_name,
+                                                           info);
+}
+
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledReturnTypeRHS(llvm::StringRef demangled,
+                                             const DemangledNameInfo &info) {
+  if (info.QualifiersRange.first < info.ArgumentsRange.second)
+    return llvm::createStringError(
+        "Qualifiers range for '%s' RHS return type  is invalid.",
+        demangled.data());
 
-  return demangled_name.slice(info.QualifiersRange.first,
-                              info.QualifiersRange.second);
+  return demangled.slice(info.ArgumentsRange.second,
+                         info.QualifiersRange.first);
 }
 
 static llvm::Expected<llvm::StringRef>
@@ -331,13 +367,17 @@ GetDemangledReturnTypeRHS(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
-  if (info.QualifiersRange.first < info.ArgumentsRange.second)
-    return llvm::createStringError(
-        "Qualifiers range for '%s' RHS return type  is invalid.",
-        demangled_name.data());
+  return CPlusPlusLanguage::GetDemangledReturnTypeRHS(demangled_name, info);
+}
 
-  return demangled_name.slice(info.ArgumentsRange.second,
-                              info.QualifiersRange.first);
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledScope(llvm::StringRef demangled,
+                                     const DemangledNameInfo &info) {
+  if (!info.hasScope())
+    return llvm::createStringError("Scope range for '%s' is invalid.",
+                                   demangled.data());
+
+  return demangled.slice(info.ScopeRange.first, info.ScopeRange.second);
 }
 
 static llvm::Expected<llvm::StringRef>
@@ -348,15 +388,16 @@ GetDemangledScope(const SymbolContext &sc) {
 
   auto [demangled_name, info] = *info_or_err;
 
-  if (!info.hasScope())
-    return llvm::createStringError("Scope range for '%s' is invalid.",
-                                   demangled_name.data());
-
-  return demangled_name.slice(info.ScopeRange.first, info.ScopeRange.second);
+  return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
 }
 
 /// Handles anything printed after the FunctionEncoding ItaniumDemangle
-/// node. Most notably the DotSUffix node.
+/// node. Most notably the DotSuffix node.
+///
+/// FIXME: the suffix should also have an associated
+/// CPlusPlusLanguage::GetDemangledFunctionSuffix
+/// once we start setting the `DemangledNameInfo::SuffixRange`
+/// from inside the `TrackingOutputBuffer`.
 static llvm::Expected<llvm::StringRef>
 GetDemangledFunctionSuffix(const SymbolContext &sc) {
   auto info_or_err = GetAndValidateInfo(sc);
@@ -372,6 +413,16 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
   return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
 }
 
+llvm::Expected<llvm::StringRef>
+CPlusPlusLanguage::GetDemangledFunctionArguments(
+    llvm::StringRef demangled, const DemangledNameInfo &info) {
+  if (!info.hasArguments())
+    return llvm::createStringError(
+        "Function arguments range for '%s' is invalid.", demangled.data());
+
+  return demangled.slice(info.ArgumentsRange.first, 
info.ArgumentsRange.second);
+}
+
 static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
   assert(sc.symbol);
 
@@ -382,13 +433,19 @@ static bool PrintDemangledArgumentList(Stream &s, const 
SymbolContext &sc) {
                    "frame-format variable: {0}");
     return false;
   }
+
   auto [demangled_name, info] = *info_or_err;
 
-  if (!info.hasArguments())
+  auto args_or_err =
+      CPlusPlusLanguage::GetDemangledFunctionArguments(demangled_name, info);
+  if (!args_or_err) {
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Language), args_or_err.takeError(),
+                   "Failed to handle ${{function.formatted-arguments}} "
+                   "frame-format variable: {0}");
     return false;
+  }
 
-  s << demangled_name.slice(info.ArgumentsRange.first,
-                            info.ArgumentsRange.second);
+  s << *args_or_err;
 
   return true;
 }
@@ -2261,7 +2318,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     FormatEntity::Entry::Type type, Stream &s) {
   switch (type) {
   case FormatEntity::Entry::Type::FunctionScope: {
-    auto scope_or_err = GetDemangledScope(sc);
+    auto scope_or_err = ::GetDemangledScope(sc);
     if (!scope_or_err) {
       LLDB_LOG_ERROR(
           GetLog(LLDBLog::Language), scope_or_err.takeError(),
@@ -2275,7 +2332,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
   }
 
   case FormatEntity::Entry::Type::FunctionBasename: {
-    auto name_or_err = GetDemangledBasename(sc);
+    auto name_or_err = ::GetDemangledBasename(sc);
     if (!name_or_err) {
       LLDB_LOG_ERROR(
           GetLog(LLDBLog::Language), name_or_err.takeError(),
@@ -2289,7 +2346,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
   }
 
   case FormatEntity::Entry::Type::FunctionTemplateArguments: {
-    auto template_args_or_err = GetDemangledTemplateArguments(sc);
+    auto template_args_or_err = ::GetDemangledTemplateArguments(sc);
     if (!template_args_or_err) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Language),
                      template_args_or_err.takeError(),
@@ -2327,7 +2384,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     return true;
   }
   case FormatEntity::Entry::Type::FunctionReturnRight: {
-    auto return_rhs_or_err = GetDemangledReturnTypeRHS(sc);
+    auto return_rhs_or_err = ::GetDemangledReturnTypeRHS(sc);
     if (!return_rhs_or_err) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(),
                      "Failed to handle ${{function.return-right}} frame-format 
"
@@ -2340,7 +2397,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     return true;
   }
   case FormatEntity::Entry::Type::FunctionReturnLeft: {
-    auto return_lhs_or_err = GetDemangledReturnTypeLHS(sc);
+    auto return_lhs_or_err = ::GetDemangledReturnTypeLHS(sc);
     if (!return_lhs_or_err) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(),
                      "Failed to handle ${{function.return-left}} frame-format "
@@ -2353,7 +2410,7 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     return true;
   }
   case FormatEntity::Entry::Type::FunctionQualifiers: {
-    auto quals_or_err = GetDemangledFunctionQualifiers(sc);
+    auto quals_or_err = ::GetDemangledFunctionQualifiers(sc);
     if (!quals_or_err) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Language), quals_or_err.takeError(),
                      "Failed to handle ${{function.qualifiers}} frame-format "
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 22acdf3e8efe9..4f449f11257a6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -112,6 +112,32 @@ class CPlusPlusLanguage : public Language {
 
   static bool IsCPPMangledName(llvm::StringRef name);
 
+  static llvm::StringRef GetDemangledBasename(llvm::StringRef demangled,
+                                              const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledTemplateArguments(llvm::StringRef demangled,
+                                const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledReturnTypeLHS(llvm::StringRef demangled,
+                            const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledFunctionQualifiers(llvm::StringRef demangled,
+                                 const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledScope(llvm::StringRef demangled, const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledReturnTypeRHS(llvm::StringRef demangled,
+                            const DemangledNameInfo &info);
+
+  static llvm::Expected<llvm::StringRef>
+  GetDemangledFunctionArguments(llvm::StringRef demangled,
+                                const DemangledNameInfo &info);
+
   // Extract C++ context and identifier from a string using heuristic matching
   // (as opposed to
   // CPlusPlusLanguage::CxxMethodName which has to have a fully qualified C++
diff --git a/lldb/unittests/Core/MangledTest.cpp 
b/lldb/unittests/Core/MangledTest.cpp
index 4bda657047541..92bd04699303b 100644
--- a/lldb/unittests/Core/MangledTest.cpp
+++ b/lldb/unittests/Core/MangledTest.cpp
@@ -6,6 +6,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusNameParser.h"
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
 #include "TestingSupport/SubsystemRAII.h"
@@ -19,6 +21,7 @@
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/SymbolContext.h"
 
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
@@ -748,25 +751,45 @@ TEST_P(DemanglingInfoCorrectnessTestFixutre, Correctness) 
{
 
   auto tracked_name = llvm::StringRef(*OB);
 
-  auto return_left = tracked_name.slice(0, OB->NameInfo.ScopeRange.first);
-  auto scope = tracked_name.slice(OB->NameInfo.ScopeRange.first,
-                                  OB->NameInfo.ScopeRange.second);
-  auto basename = tracked_name.slice(OB->NameInfo.BasenameRange.first,
-                                     OB->NameInfo.BasenameRange.second);
-  auto template_args = tracked_name.slice(OB->NameInfo.BasenameRange.second,
-                                          OB->NameInfo.ArgumentsRange.first);
-  auto args = tracked_name.slice(OB->NameInfo.ArgumentsRange.first,
-                                 OB->NameInfo.ArgumentsRange.second);
-  auto return_right = tracked_name.slice(OB->NameInfo.ArgumentsRange.second,
-                                         OB->NameInfo.QualifiersRange.first);
-  auto qualifiers = tracked_name.slice(OB->NameInfo.QualifiersRange.first,
-                                       OB->NameInfo.QualifiersRange.second);
+  std::string reconstructed_name;
+
+  auto return_left =
+      CPlusPlusLanguage::GetDemangledReturnTypeLHS(tracked_name, OB->NameInfo);
+  EXPECT_THAT_EXPECTED(return_left, llvm::Succeeded());
+  reconstructed_name += *return_left;
+
+  auto scope = CPlusPlusLanguage::GetDemangledScope(tracked_name, 
OB->NameInfo);
+  EXPECT_THAT_EXPECTED(scope, llvm::Succeeded());
+  reconstructed_name += *scope;
+
+  auto basename =
+      CPlusPlusLanguage::GetDemangledBasename(tracked_name, OB->NameInfo);
+  reconstructed_name += basename;
+
+  auto template_args = CPlusPlusLanguage::GetDemangledTemplateArguments(
+      tracked_name, OB->NameInfo);
+  EXPECT_THAT_EXPECTED(template_args, llvm::Succeeded());
+  reconstructed_name += *template_args;
+
+  auto args = CPlusPlusLanguage::GetDemangledFunctionArguments(tracked_name,
+                                                               OB->NameInfo);
+  EXPECT_THAT_EXPECTED(args, llvm::Succeeded());
+  reconstructed_name += *args;
+
+  auto return_right =
+      CPlusPlusLanguage::GetDemangledReturnTypeRHS(tracked_name, OB->NameInfo);
+  EXPECT_THAT_EXPECTED(return_right, llvm::Succeeded());
+  reconstructed_name += *return_right;
+
+  auto qualifiers = CPlusPlusLanguage::GetDemangledFunctionQualifiers(
+      tracked_name, OB->NameInfo);
+  EXPECT_THAT_EXPECTED(qualifiers, llvm::Succeeded());
+  reconstructed_name += *qualifiers;
+
+  // TODO: should retrieve suffix using the plugin too.
   auto suffix = tracked_name.slice(OB->NameInfo.QualifiersRange.second,
                                    llvm::StringRef::npos);
-
-  auto reconstructed_name =
-      llvm::join_items("", return_left, scope, basename, template_args, args,
-                       return_right, qualifiers, suffix);
+  reconstructed_name += suffix;
 
   EXPECT_EQ(reconstructed_name, demangled);
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/152134
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to