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_zab...@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_zab...@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; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits