[Lldb-commits] [lldb] f98cf07 - [LLDB] Convert libstdc++ std::variant summary to C++ (#148929)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 16 02:07:48 PDT 2025
Author: nerix
Date: 2025-07-16T10:07:45+01:00
New Revision: f98cf07b7dc7af7716e1da9a1257b8c6416f9a46
URL: https://github.com/llvm/llvm-project/commit/f98cf07b7dc7af7716e1da9a1257b8c6416f9a46
DIFF: https://github.com/llvm/llvm-project/commit/f98cf07b7dc7af7716e1da9a1257b8c6416f9a46.diff
LOG: [LLDB] Convert libstdc++ std::variant summary to C++ (#148929)
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.
Added:
Modified:
lldb/examples/synthetic/gnu_libstdcpp.py
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
Removed:
################################################################################
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 8724e829835c1..4a3fdede84d32 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);
More information about the lldb-commits
mailing list