#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<ConstString> item_names);
size_t CalculateNumChildren() override;
private:
ExecutionContextRef m_exe_ctx_ref;
- ConstString m_item_name;
+ llvm::SmallVector<ConstString, 2> m_item_names;
lldb::ValueObjectSP m_item_sp;
};
using namespace lldb_private;
using namespace lldb_private::formatters;
+lldb::ValueObjectSP lldb_private::formatters::GetChildMemberWithName(
+ ValueObject &obj, llvm::ArrayRef<ConstString> 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());
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::
static std::tuple<bool, ValueObjectSP, size_t>
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<bool,ValueObjectSP,size_t>(false, {}, {});
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<ConstString> alternative_names);
+
bool LibcxxStringSummaryProviderASCII(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options); // libc++ std::string
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_");
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;
}
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;
}
// 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)) {
//===----------------------------------------------------------------------===//
#include "LibCxxVariant.h"
+#include "LibCxx.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "llvm/ADT/Optional.h"
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;
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;
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"));
}
-//===-- 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.
//===----------------------------------------------------------------------===//
#include "LibStdcpp.h"
+#include "LibCxx.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
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<ConstString> 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();
}
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)
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()
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."""
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."""
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.
@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()