llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: nerix (Nerixyz) <details> <summary>Changes</summary> This PR converts the `std::variant` summary from Python to C++. Split from #<!-- -->148554. MSVC's STL and libstdc++ use the same type name for `std::variant`, thus they need one "dispatcher" function that checks the type and calls the appropriate summary. For summaries, both need to be implemented in C++. This is mostly a 1:1 translation. The main difference is that in C++, the summary returns `false` if it can't inspect the object properly (e.g. a member could not be found). In Python, this wasn't possible. --- Full diff: https://github.com/llvm/llvm-project/pull/148929.diff 4 Files Affected: - (modified) lldb/examples/synthetic/gnu_libstdcpp.py (-32) - (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+3-5) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp (+46) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h (+4) ``````````diff diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py index 20b9488af5597..f42a009c21f48 100644 --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -882,38 +882,6 @@ def update(self): return False -def VariantSummaryProvider(valobj, dict): - raw_obj = valobj.GetNonSyntheticValue() - index_obj = raw_obj.GetChildMemberWithName("_M_index") - data_obj = raw_obj.GetChildMemberWithName("_M_u") - if not (index_obj and index_obj.IsValid() and data_obj and data_obj.IsValid()): - return "<Can't find _M_index or _M_u>" - - def get_variant_npos_value(index_byte_size): - if index_byte_size == 1: - return 0xFF - elif index_byte_size == 2: - return 0xFFFF - else: - return 0xFFFFFFFF - - npos_value = get_variant_npos_value(index_obj.GetByteSize()) - index = index_obj.GetValueAsUnsigned(0) - if index == npos_value: - return " No Value" - - # Strip references and typedefs. - variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType() - template_arg_count = variant_type.GetNumberOfTemplateArguments() - - # Invalid index can happen when the variant is not initialized yet. - if index >= template_arg_count: - return " <Invalid>" - - active_type = variant_type.GetTemplateArgumentType(index) - return f" Active Type = {active_type.GetDisplayTypeName()} " - - class VariantSynthProvider: def __init__(self, valobj, dict): self.raw_obj = valobj.GetNonSyntheticValue() diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index bf4139119a76b..b36cb9b777fa5 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1513,11 +1513,9 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { TypeSummaryImplSP(new ScriptSummaryFormat( stl_summary_flags, "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider"))); - cpp_category_sp->AddTypeSummary( - "^std::variant<.+>$", eFormatterMatchRegex, - TypeSummaryImplSP(new ScriptSummaryFormat( - stl_summary_flags, - "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider"))); + AddCXXSummary(cpp_category_sp, LibStdcppVariantSummaryProvider, + "libstdc++ std::variant summary provider", "^std::variant<.+>$", + stl_summary_flags, true); AddCXXSynthetic( cpp_category_sp, diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index c80a52d0f9ed6..595e835b37df9 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -366,3 +366,49 @@ bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( return true; } + +static uint64_t LibStdcppVariantNposValue(size_t index_byte_size) { + switch (index_byte_size) { + case 1: + return 0xff; + case 2: + return 0xffff; + default: + return 0xffff'ffff; + } +} + +bool formatters::LibStdcppVariantSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp = valobj.GetNonSyntheticValue(); + if (!valobj_sp) + return false; + + ValueObjectSP index_obj = valobj_sp->GetChildMemberWithName("_M_index"); + ValueObjectSP data_obj = valobj_sp->GetChildMemberWithName("_M_u"); + if (!index_obj || !data_obj) + return false; + + auto index_bytes = index_obj->GetByteSize(); + if (!index_bytes) + return false; + auto npos_value = LibStdcppVariantNposValue(*index_bytes); + auto index = index_obj->GetValueAsUnsigned(0); + if (index == npos_value) { + stream.Printf(" No Value"); + return true; + } + + auto variant_type = + valobj_sp->GetCompilerType().GetCanonicalType().GetNonReferenceType(); + if (!variant_type) + return false; + if (index >= variant_type.GetNumTemplateArguments(true)) { + stream.Printf(" <Invalid>"); + return true; + } + + auto active_type = variant_type.GetTypeTemplateArgument(index, true); + stream << " Active Type = " << active_type.GetDisplayTypeName() << " "; + return true; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index 8d4d777edee88..8d2025e940ead 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -29,6 +29,10 @@ bool LibStdcppUniquePointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<> +bool LibStdcppVariantSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libstdc++ std::variant<> + SyntheticChildrenFrontEnd * LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); `````````` </details> https://github.com/llvm/llvm-project/pull/148929 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits