Skip to content

Commit f98cf07

Browse files
authored
[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.
1 parent 5ae4939 commit f98cf07

File tree

4 files changed

+53
-37
lines changed

4 files changed

+53
-37
lines changed

lldb/examples/synthetic/gnu_libstdcpp.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -882,38 +882,6 @@ def update(self):
882882
return False
883883

884884

885-
def VariantSummaryProvider(valobj, dict):
886-
raw_obj = valobj.GetNonSyntheticValue()
887-
index_obj = raw_obj.GetChildMemberWithName("_M_index")
888-
data_obj = raw_obj.GetChildMemberWithName("_M_u")
889-
if not (index_obj and index_obj.IsValid() and data_obj and data_obj.IsValid()):
890-
return "<Can't find _M_index or _M_u>"
891-
892-
def get_variant_npos_value(index_byte_size):
893-
if index_byte_size == 1:
894-
return 0xFF
895-
elif index_byte_size == 2:
896-
return 0xFFFF
897-
else:
898-
return 0xFFFFFFFF
899-
900-
npos_value = get_variant_npos_value(index_obj.GetByteSize())
901-
index = index_obj.GetValueAsUnsigned(0)
902-
if index == npos_value:
903-
return " No Value"
904-
905-
# Strip references and typedefs.
906-
variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType()
907-
template_arg_count = variant_type.GetNumberOfTemplateArguments()
908-
909-
# Invalid index can happen when the variant is not initialized yet.
910-
if index >= template_arg_count:
911-
return " <Invalid>"
912-
913-
active_type = variant_type.GetTemplateArgumentType(index)
914-
return f" Active Type = {active_type.GetDisplayTypeName()} "
915-
916-
917885
class VariantSynthProvider:
918886
def __init__(self, valobj, dict):
919887
self.raw_obj = valobj.GetNonSyntheticValue()

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,11 +1513,9 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
15131513
TypeSummaryImplSP(new ScriptSummaryFormat(
15141514
stl_summary_flags,
15151515
"lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
1516-
cpp_category_sp->AddTypeSummary(
1517-
"^std::variant<.+>$", eFormatterMatchRegex,
1518-
TypeSummaryImplSP(new ScriptSummaryFormat(
1519-
stl_summary_flags,
1520-
"lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider")));
1516+
AddCXXSummary(cpp_category_sp, LibStdcppVariantSummaryProvider,
1517+
"libstdc++ std::variant summary provider", "^std::variant<.+>$",
1518+
stl_summary_flags, true);
15211519

15221520
AddCXXSynthetic(
15231521
cpp_category_sp,

lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,49 @@ bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(
366366

367367
return true;
368368
}
369+
370+
static uint64_t LibStdcppVariantNposValue(size_t index_byte_size) {
371+
switch (index_byte_size) {
372+
case 1:
373+
return 0xff;
374+
case 2:
375+
return 0xffff;
376+
default:
377+
return 0xffff'ffff;
378+
}
379+
}
380+
381+
bool formatters::LibStdcppVariantSummaryProvider(
382+
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
383+
ValueObjectSP valobj_sp = valobj.GetNonSyntheticValue();
384+
if (!valobj_sp)
385+
return false;
386+
387+
ValueObjectSP index_obj = valobj_sp->GetChildMemberWithName("_M_index");
388+
ValueObjectSP data_obj = valobj_sp->GetChildMemberWithName("_M_u");
389+
if (!index_obj || !data_obj)
390+
return false;
391+
392+
auto index_bytes = index_obj->GetByteSize();
393+
if (!index_bytes)
394+
return false;
395+
auto npos_value = LibStdcppVariantNposValue(*index_bytes);
396+
auto index = index_obj->GetValueAsUnsigned(0);
397+
if (index == npos_value) {
398+
stream.Printf(" No Value");
399+
return true;
400+
}
401+
402+
auto variant_type =
403+
valobj_sp->GetCompilerType().GetCanonicalType().GetNonReferenceType();
404+
if (!variant_type)
405+
return false;
406+
if (index >= variant_type.GetNumTemplateArguments(true)) {
407+
stream.Printf(" <Invalid>");
408+
return true;
409+
}
410+
411+
auto active_type = variant_type.GetTypeTemplateArgument(index, true);
412+
stream << " Active Type = " << active_type.GetDisplayTypeName() << " ";
413+
return true;
414+
}

lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ bool LibStdcppUniquePointerSummaryProvider(
2929
ValueObject &valobj, Stream &stream,
3030
const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<>
3131

32+
bool LibStdcppVariantSummaryProvider(
33+
ValueObject &valobj, Stream &stream,
34+
const TypeSummaryOptions &options); // libstdc++ std::variant<>
35+
3236
SyntheticChildrenFrontEnd *
3337
LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
3438
lldb::ValueObjectSP);

0 commit comments

Comments
 (0)