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

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 20 04:24:35 PDT 2025


================
@@ -236,199 +236,158 @@ 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 '%s' does not have a demangled name.",
+        mangled.GetMangledName().AsCString(""));
 
   const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
   if (!info)
-    return std::nullopt;
+    return llvm::createStringError(
+        "Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-    return std::nullopt;
+    return llvm::createStringError(
+        "DemangledInfo for '%s does not have basename range.",
+        demangled_name.data());
 
-  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 range for '%s' is invalid.",
+                                   demangled_name.data());
 
-  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 for '%s' LHS return type is invalid.",
+        demangled_name.data());
 
-  // 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.hasQualifiers())
+    return llvm::createStringError("Qualifiers range for '%s' is invalid.",
----------------
charles-zablit wrote:

We could add another method called `areQualifiersEmpty` (or better name) which checks if `QualifiersRange.start == QualifiersRange.end`. The check would look like
```cpp
if(!hasQualifiers() && !areQualifiersEmpty())
    return createStringError(...);

return demangled_name.slice(...);
```

This way we keep the semantic meaning of `hasQualifiers` and we can still surface parsing errors, which we would not be able to do if we remove the check.

https://github.com/llvm/llvm-project/pull/144731


More information about the lldb-commits mailing list