[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 18 08:56:03 PDT 2025


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/144731

>From fdff64cca23ab113c80ed431949d7a58bdedb8c7 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Wed, 18 Jun 2025 16:41:40 +0100
Subject: [PATCH 1/2] [lldb] upgrade HandleFrameFormatVariable callees to
 llvm::Expected

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 266 ++++++++----------
 1 file changed, 110 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 0f18abb47591d..1810c07652a2b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,
   return true;
 }
 
-static std::optional<llvm::StringRef>
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected<std::pair<llvm::StringRef, DemangledNameInfo>>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-    return std::nullopt;
+    return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-    return std::nullopt;
+    return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
   if (!info)
-    return std::nullopt;
+    return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-    return std::nullopt;
+    return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-                              info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional<llvm::StringRef>
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
+static llvm::Expected<llvm::StringRef>
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+                              info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
+static llvm::Expected<llvm::StringRef>
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-    return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+    return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-                              info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+                              info.ArgumentsRange.first);
 }
 
-static std::optional<llvm::StringRef>
+static llvm::Expected<llvm::StringRef>
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+    return llvm::createStringError("Scope range is invalid.");
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-    return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional<llvm::StringRef>
+static llvm::Expected<llvm::StringRef>
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
+  if (info.QualifiersRange.second < info.QualifiersRange.first)
+    return llvm::createStringError("Qualifiers range is invalid.");
 
-  if (info->QualifiersRange.second < info->QualifiersRange.first)
-    return std::nullopt;
-
-  return demangled_name.slice(info->QualifiersRange.first,
-                              info->QualifiersRange.second);
+  return demangled_name.slice(info.QualifiersRange.first,
+                              info.QualifiersRange.second);
 }
 
-static std::optional<llvm::StringRef>
+static llvm::Expected<llvm::StringRef>
 GetDemangledReturnTypeRHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
-
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->QualifiersRange.first < info->ArgumentsRange.second)
-    return std::nullopt;
+  if (info.QualifiersRange.first < info.ArgumentsRange.second)
+    return llvm::createStringError("Qualifiers range is invalid.");
 
-  return demangled_name.slice(info->ArgumentsRange.second,
-                              info->QualifiersRange.first);
+  return demangled_name.slice(info.ArgumentsRange.second,
+                              info.QualifiersRange.first);
 }
 
-static std::optional<llvm::StringRef>
+static llvm::Expected<llvm::StringRef>
 GetDemangledScope(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
-
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ScopeRange.second < info->ScopeRange.first)
-    return std::nullopt;
+  if (info.ScopeRange.second < info.ScopeRange.first)
+    return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->ScopeRange.first, info->ScopeRange.second);
+  return demangled_name.slice(info.ScopeRange.first, info.ScopeRange.second);
 }
 
 /// Handles anything printed after the FunctionEncoding ItaniumDemangle
 /// node. Most notably the DotSUffix node.
-static std::optional<llvm::StringRef>
+static llvm::Expected<llvm::StringRef>
 GetDemangledFunctionSuffix(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+    return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-    return std::nullopt;
-
-  return demangled_name.slice(info->SuffixRange.first,
-                              info->SuffixRange.second);
+  return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
 }
 
 static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
   assert(sc.symbol);
 
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-    return false;
-
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-    return false;
-
-  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
-  if (!info)
-    return false;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err) {
+    info_or_err.takeError();
     return false;
+  }
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.second < info->ArgumentsRange.first)
+  if (info.ArgumentsRange.second < info.ArgumentsRange.first)
     return false;
 
-  s << demangled_name.slice(info->ArgumentsRange.first,
-                            info->ArgumentsRange.second);
+  s << demangled_name.slice(info.ArgumentsRange.first,
+                            info.ArgumentsRange.second);
 
   return true;
 }
@@ -1954,32 +1895,37 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     FormatEntity::Entry::Type type, Stream &s) {
   switch (type) {
   case FormatEntity::Entry::Type::FunctionScope: {
-    std::optional<llvm::StringRef> scope = GetDemangledScope(sc);
-    if (!scope)
+    auto scope_or_err = GetDemangledScope(sc);
+    if (!scope_or_err) {
+      llvm::consumeError(scope_or_err.takeError());
       return false;
+    }
 
-    s << *scope;
+    s << *scope_or_err;
 
     return true;
   }
 
   case FormatEntity::Entry::Type::FunctionBasename: {
-    std::optional<llvm::StringRef> name = GetDemangledBasename(sc);
-    if (!name)
+    auto name_or_err = GetDemangledBasename(sc);
+    if (!name_or_err) {
+      llvm::consumeError(name_or_err.takeError());
       return false;
+    }
 
-    s << *name;
+    s << *name_or_err;
 
     return true;
   }
 
   case FormatEntity::Entry::Type::FunctionTemplateArguments: {
-    std::optional<llvm::StringRef> template_args =
-        GetDemangledTemplateArguments(sc);
-    if (!template_args)
+    auto template_args_or_err = GetDemangledTemplateArguments(sc);
+    if (!template_args_or_err) {
+      llvm::consumeError(template_args_or_err.takeError());
       return false;
+    }
 
-    s << *template_args;
+    s << *template_args_or_err;
 
     return true;
   }
@@ -2008,38 +1954,46 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
     return true;
   }
   case FormatEntity::Entry::Type::FunctionReturnRight: {
-    std::optional<llvm::StringRef> return_rhs = GetDemangledReturnTypeRHS(sc);
-    if (!return_rhs)
+    auto return_rhs_or_err = GetDemangledReturnTypeRHS(sc);
+    if (!return_rhs_or_err) {
+      llvm::consumeError(return_rhs_or_err.takeError());
       return false;
+    }
 
-    s << *return_rhs;
+    s << *return_rhs_or_err;
 
     return true;
   }
   case FormatEntity::Entry::Type::FunctionReturnLeft: {
-    std::optional<llvm::StringRef> return_lhs = GetDemangledReturnTypeLHS(sc);
-    if (!return_lhs)
+    auto return_lhs_or_err = GetDemangledReturnTypeLHS(sc);
+    if (!return_lhs_or_err) {
+      llvm::consumeError(return_lhs_or_err.takeError());
       return false;
+    }
 
-    s << *return_lhs;
+    s << *return_lhs_or_err;
 
     return true;
   }
   case FormatEntity::Entry::Type::FunctionQualifiers: {
-    std::optional<llvm::StringRef> quals = GetDemangledFunctionQualifiers(sc);
-    if (!quals)
+    auto quals_or_err = GetDemangledFunctionQualifiers(sc);
+    if (!quals_or_err) {
+      llvm::consumeError(quals_or_err.takeError());
       return false;
+    }
 
-    s << *quals;
+    s << *quals_or_err;
 
     return true;
   }
   case FormatEntity::Entry::Type::FunctionSuffix: {
-    std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
-    if (!suffix)
+    auto suffix_or_err = GetDemangledFunctionSuffix(sc);
+    if (!suffix_or_err) {
+      llvm::consumeError(suffix_or_err.takeError());
       return false;
+    }
 
-    s << *suffix;
+    s << *suffix_or_err;
 
     return true;
   }

>From 9ccf1babde561aa71826ccff238989b4710e755b Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Wed, 18 Jun 2025 16:55:49 +0100
Subject: [PATCH 2/2] fixup! [lldb] upgrade HandleFrameFormatVariable callees
 to llvm::Expected

---
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 1810c07652a2b..5859f07659297 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -360,7 +360,7 @@ static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
 
   auto info_or_err = GetAndValidateInfo(sc);
   if (!info_or_err) {
-    info_or_err.takeError();
+    llvm::consumeError(info_or_err.takeError());
     return false;
   }
   auto [demangled_name, info] = *info_or_err;



More information about the lldb-commits mailing list