diff --git a/lldb/include/lldb/DataFormatters/VectorIterator.h b/lldb/include/lldb/DataFormatters/VectorIterator.h --- a/lldb/include/lldb/DataFormatters/VectorIterator.h +++ b/lldb/include/lldb/DataFormatters/VectorIterator.h @@ -15,13 +15,14 @@ #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/ConstString.h" +#include "llvm/ADT/SmallVector.h" namespace lldb_private { namespace formatters { class VectorIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp, - ConstString item_name); + llvm::ArrayRef item_names); size_t CalculateNumChildren() override; @@ -35,7 +36,7 @@ private: ExecutionContextRef m_exe_ctx_ref; - ConstString m_item_name; + llvm::SmallVector m_item_names; lldb::ValueObjectSP m_item_sp; }; diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -18,6 +18,11 @@ namespace lldb_private { namespace formatters { +/// Find a child member of \c obj_sp, trying all alternative names in order. +lldb::ValueObjectSP +GetChildMemberWithName(ValueObject &obj, + llvm::ArrayRef alternative_names); + bool LibcxxStringSummaryProviderASCII( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options); // libc++ std::string diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -34,6 +34,17 @@ using namespace lldb_private; using namespace lldb_private::formatters; +lldb::ValueObjectSP lldb_private::formatters::GetChildMemberWithName( + ValueObject &obj, llvm::ArrayRef alternative_names) { + for (ConstString name : alternative_names) { + lldb::ValueObjectSP child_sp = obj.GetChildMemberWithName(name, true); + + if (child_sp) + return child_sp; + } + return {}; +} + bool lldb_private::formatters::LibcxxOptionalSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); @@ -538,12 +549,9 @@ SyntheticChildrenFrontEnd * lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - static ConstString g_item_name; - if (!g_item_name) - g_item_name.SetCString("__i"); - return (valobj_sp - ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) - : nullptr); + return (valobj_sp ? new VectorIteratorSyntheticFrontEnd( + valobj_sp, {ConstString("__i_"), ConstString("__i")}) + : nullptr); } lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: @@ -992,11 +1000,10 @@ static std::tuple LibcxxExtractStringViewData(ValueObject& valobj) { - ConstString g_data_name("__data"); - ConstString g_size_name("__size"); - auto dataobj = valobj.GetChildMemberWithName(g_data_name, true); - auto sizeobj = valobj.GetChildMemberWithName(g_size_name, true); - + auto dataobj = GetChildMemberWithName( + valobj, {ConstString("__data_"), ConstString("__data")}); + auto sizeobj = GetChildMemberWithName( + valobj, {ConstString("__size_"), ConstString("__size")}); if (!dataobj || !sizeobj) return std::make_tuple(false, {}, {}); diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -328,7 +328,7 @@ lldb::ValueObjectSP lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( size_t idx) { - static ConstString g_cc("__cc"); + static ConstString g_cc_("__cc_"), g_cc("__cc"); static ConstString g_nc("__nc"); static ConstString g_value_("__value_"); @@ -414,15 +414,17 @@ switch (potential_child_sp->GetNumChildren()) { case 1: { auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); - if (child0_sp && child0_sp->GetName() == g_cc) + if (child0_sp && + (child0_sp->GetName() == g_cc_ || child0_sp->GetName() == g_cc)) potential_child_sp = child0_sp->Clone(ConstString(name.GetString())); break; } case 2: { auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); auto child1_sp = potential_child_sp->GetChildAtIndex(1, true); - if (child0_sp && child0_sp->GetName() == g_cc && child1_sp && - child1_sp->GetName() == g_nc) + if (child0_sp && + (child0_sp->GetName() == g_cc_ || child0_sp->GetName() == g_cc) && + child1_sp && child1_sp->GetName() == g_nc) potential_child_sp = child0_sp->Clone(ConstString(name.GetString())); break; } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp @@ -94,8 +94,8 @@ bool lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::Update() { // Get element type. - ValueObjectSP data_type_finder_sp( - m_backend.GetChildMemberWithName(ConstString("__data"), true)); + ValueObjectSP data_type_finder_sp = GetChildMemberWithName( + m_backend, {ConstString("__data_"), ConstString("__data")}); if (!data_type_finder_sp) return false; @@ -111,8 +111,8 @@ } // Get number of elements. - if (auto size_sp = - m_backend.GetChildMemberWithName(ConstString("__size"), true)) { + if (auto size_sp = GetChildMemberWithName( + m_backend, {ConstString("__size_"), ConstString("__size")})) { m_num_elements = size_sp->GetValueAsUnsigned(0); } else if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(1)) { diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h @@ -1,5 +1,4 @@ -//===-- LibCxxVariant.h -------------------------------------------*- C++ -//-*-===// +//===-- LibCxxVariant.h ----------------------------------------*- C++ -*--===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LibCxxVariant.h" +#include "LibCxx.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "llvm/ADT/Optional.h" @@ -121,8 +122,8 @@ if (!valobj_sp) return false; - ValueObjectSP impl_sp( - valobj_sp->GetChildMemberWithName(ConstString("__impl"), true)); + ValueObjectSP impl_sp = GetChildMemberWithName( + *valobj_sp, {ConstString("__impl_"), ConstString("__impl")}); if (!impl_sp) return false; @@ -189,8 +190,8 @@ bool VariantFrontEnd::Update() { m_size = 0; - ValueObjectSP impl_sp( - m_backend.GetChildMemberWithName(ConstString("__impl"), true)); + ValueObjectSP impl_sp = formatters::GetChildMemberWithName( + m_backend, {ConstString("__impl_"), ConstString("__impl")}); if (!impl_sp) return false; @@ -209,38 +210,40 @@ ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) { if (idx >= m_size) - return ValueObjectSP(); + return {}; - ValueObjectSP impl_sp( - m_backend.GetChildMemberWithName(ConstString("__impl"), true)); + ValueObjectSP impl_sp = formatters::GetChildMemberWithName( + m_backend, {ConstString("__impl_"), ConstString("__impl")}); + if (!impl_sp) + return {}; auto optional_index_value = LibcxxVariantIndexValue(impl_sp); if (!optional_index_value) - return ValueObjectSP(); + return {}; uint64_t index_value = *optional_index_value; ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value); if (!nth_head) - return ValueObjectSP(); + return {}; CompilerType head_type = nth_head->GetCompilerType(); if (!head_type) - return ValueObjectSP(); + return {}; CompilerType template_type = head_type.GetTypeTemplateArgument(1); if (!template_type) - return ValueObjectSP(); + return {}; ValueObjectSP head_value( nth_head->GetChildMemberWithName(ConstString("__value"), true)); if (!head_value) - return ValueObjectSP(); + return {}; return head_value->Clone(ConstString("Value")); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LibStdcpp.h" +#include "LibCxx.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" @@ -169,19 +170,16 @@ SyntheticChildrenFrontEnd * lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - static ConstString g_item_name; - if (!g_item_name) - g_item_name.SetCString("_M_current"); - return (valobj_sp - ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) - : nullptr); + return (valobj_sp ? new VectorIteratorSyntheticFrontEnd( + valobj_sp, {ConstString("_M_current")}) + : nullptr); } lldb_private::formatters::VectorIteratorSyntheticFrontEnd:: VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp, - ConstString item_name) + llvm::ArrayRef item_names) : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), - m_item_name(item_name), m_item_sp() { + m_item_names(item_names), m_item_sp() { if (valobj_sp) Update(); } @@ -196,7 +194,8 @@ if (!valobj_sp) return false; - ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name, true)); + ValueObjectSP item_ptr = + formatters::GetChildMemberWithName(*valobj_sp, m_item_names); if (!item_ptr) return false; if (item_ptr->GetValueAsUnsigned(0) == 0) diff --git a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py --- a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py @@ -10,7 +10,7 @@ class TestBasicDeque(TestBase): @add_test_categories(["libc++"]) - @expectedFailureDarwin + @expectedFailureDarwin # FIXME: May need to force system libcxx here. @skipIf(compiler=no_match("clang")) def test(self): self.build() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py @@ -19,7 +19,6 @@ self.line = line_number('main.cpp', '// Set break point at this line.') self.namespace = 'std' - @expectedFailureDarwin # FIXME: May need to force system libcxx here. @add_test_categories(["libc++"]) def test_with_run_command(self): """Test that libc++ iterators format properly.""" diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/span/TestDataFormatterLibcxxSpan.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/span/TestDataFormatterLibcxxSpan.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/span/TestDataFormatterLibcxxSpan.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/span/TestDataFormatterLibcxxSpan.py @@ -43,7 +43,6 @@ self.expect_var_path(f'{var_name}[4]', type='int', value='12345') @add_test_categories(['libc++']) - @expectedFailureDarwin # FIXME: May need to force system libcxx here. @skipIf(compiler='clang', compiler_version=['<', '11.0']) def test_with_run_command(self): """Test that std::span variables are formatted correctly when printed.""" diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py @@ -21,7 +21,6 @@ self.line2 = line_number('main.cpp', '// Break here to look at bad string view.' ) @add_test_categories(["libc++"]) - @expectedFailureDarwin # FIXME: May need to force system libcxx here. @expectedFailureAll(bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android") # Inline namespace is randomly ignored as Clang due to broken lookup inside # the std namespace. diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py @@ -19,7 +19,6 @@ @skipIf(compiler="gcc", compiler_version=['<', '5.1']) ## std::get is unavailable for std::variant before macOS 10.14 @skipIf(macos_version=["<", "10.14"]) - @expectedFailureDarwin # FIXME: May need to force system libcxx here. def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build()