[Lldb-commits] [lldb] [LLDB] Add formatters for MSVC STL std::vector (PR #147538)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 8 07:26:42 PDT 2025
https://github.com/Nerixyz created https://github.com/llvm/llvm-project/pull/147538
This adds synthetic child providers for `std::vector<T>` and `std::vector<bool>` for MSVC's STL.
The structure of a `std::vector<T>` is relatively similar to libc++'s implementation that uses `__begin` and `__end`.
`std::vector<bool>` is different. It's a `std::vector<unsigned int>` wrapper instead of `std::vector<uint8_t>`. This makes the calculation slightly less simple. I put a comment in the `GetChildAtIndex` to make this clear.
- [NatVis for `std::vector<T>`](https://github.com/microsoft/STL/blob/313964b78a8fd5a52e7965e13781f735bcce13c5/stl/debugger/STL.natvis#L1193-L1205)
- [NatVis for `std::vector<bool>`](https://github.com/microsoft/STL/blob/313964b78a8fd5a52e7965e13781f735bcce13c5/stl/debugger/STL.natvis#L1167-L1179)
Towards #24834.
>From 7d68227afefe36978de890645702cbac857ee41d Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Sat, 21 Jun 2025 17:35:23 +0200
Subject: [PATCH] [LLDB] Add formatters for MSVC STL std::vector
---
.../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 +
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 36 ++-
.../Plugins/Language/CPlusPlus/MsvcStl.h | 3 +
.../Language/CPlusPlus/MsvcStlVector.cpp | 295 ++++++++++++++++++
.../vbool/TestDataFormatterStdVBool.py | 24 +-
.../data-formatter-stl/generic/vbool/main.cpp | 39 ++-
.../vector/TestDataFormatterStdVector.py | 11 +
7 files changed, 401 insertions(+), 8 deletions(-)
create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStlVector.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index bbfc31a722f27..6869e4b56ebee 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -33,6 +33,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
LibStdcppTuple.cpp
LibStdcppUniquePointer.cpp
MsvcStl.cpp
+ MsvcStlVector.cpp
MSVCUndecoratedNameParser.cpp
LINK_COMPONENTS
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 17963c0273ba8..5a9fcba05ddbc 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1404,7 +1404,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags.SetFrontEndWantsDereference();
cpp_category_sp->AddTypeSynthetic(
- "^std::(__debug::)?vector<.+>(( )?&)?$", eFormatterMatchRegex,
+ "^std::__debug::vector<.+>(( )?&)?$", eFormatterMatchRegex,
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
@@ -1465,10 +1465,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libstdc++ std::bitset summary provider",
"^std::(__debug::)?bitset<.+>(( )?&)?$", stl_summary_flags, true);
- AddCXXSummary(
- cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
- "libstdc++ std::vector summary provider",
- "^std::(__debug::)?vector<.+>(( )?&)?$", stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::ContainerSizeSummaryProvider,
+ "libstdc++ std::__debug::vector summary provider",
+ "^std::__debug::vector<.+>(( )?&)?$", stl_summary_flags, true);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
@@ -1611,6 +1611,10 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
.SetDontShowValue(false)
.SetShowMembersOneLiner(false)
.SetHideItemNames(false);
+ SyntheticChildren::Flags stl_synth_flags;
+ stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
+ false);
+
using StringElementType = StringPrinter::StringElementType;
RegisterStdStringSummaryProvider(
@@ -1636,6 +1640,28 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
return LibStdcppStringSummaryProvider(valobj, stream, options);
},
"MSVC STL/libstdc++ std::wstring summary provider"));
+
+ stl_summary_flags.SetDontShowChildren(false);
+ stl_summary_flags.SetSkipPointers(false);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::ContainerSizeSummaryProvider,
+ "MSVC/libstdc++ std::vector summary provider",
+ "^std::vector<.+>(( )?&)?$", stl_summary_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ [](CXXSyntheticChildren *,
+ ValueObjectSP valobj_sp) -> SyntheticChildrenFrontEnd * {
+ if (!valobj_sp)
+ return nullptr;
+ if (auto *msvc = MsvcStlVectorSyntheticFrontEndCreator(valobj_sp))
+ return msvc;
+ return new ScriptedSyntheticChildren::FrontEnd(
+ "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider",
+ *valobj_sp);
+ },
+ "MSVC/libstdc++ std::vector synthetic provider",
+ "^std::vector<.+>(( )?&)?$", stl_synth_flags, true);
}
static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index e4ed923033aa7..78b9e56d65e28 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -29,6 +29,9 @@ bool MsvcStlWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // VC 2015+ std::wstring
+lldb_private::SyntheticChildrenFrontEnd *
+MsvcStlVectorSyntheticFrontEndCreator(lldb::ValueObjectSP valobj_sp);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVector.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVector.cpp
new file mode 100644
index 0000000000000..f845aa30ebe1a
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVector.cpp
@@ -0,0 +1,295 @@
+//===-- MsvcStlVector.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MsvcStl.h"
+
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+using namespace lldb;
+
+namespace lldb_private {
+namespace formatters {
+
+class MsvcStlVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ MsvcStlVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ llvm::Expected<uint32_t> CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
+
+ lldb::ChildCacheState Update() override;
+
+ llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
+
+private:
+ ValueObject *m_start = nullptr;
+ ValueObject *m_finish = nullptr;
+ CompilerType m_element_type;
+ uint32_t m_element_size = 0;
+};
+
+class MsvcStlVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ MsvcStlVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ llvm::Expected<uint32_t> CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
+
+ lldb::ChildCacheState Update() override;
+
+ llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
+
+private:
+ CompilerType m_bool_type;
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count = 0;
+ uint64_t m_element_bit_size = 0;
+ lldb::addr_t m_base_data_address = 0;
+ std::map<size_t, lldb::ValueObjectSP> m_children;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::MsvcStlVectorSyntheticFrontEnd::
+ MsvcStlVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
+ if (valobj_sp)
+ Update();
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+ MsvcStlVectorSyntheticFrontEnd::CalculateNumChildren() {
+ if (!m_start || !m_finish)
+ return llvm::createStringError(
+ "Failed to determine start/end of vector data.");
+
+ uint64_t start_val = m_start->GetValueAsUnsigned(0);
+ uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
+
+ // A default-initialized empty vector.
+ if (start_val == 0 && finish_val == 0)
+ return 0;
+
+ if (start_val == 0)
+ return llvm::createStringError("Invalid value for start of vector.");
+
+ if (finish_val == 0)
+ return llvm::createStringError("Invalid value for end of vector.");
+
+ if (start_val > finish_val)
+ return llvm::createStringError(
+ "Start of vector data begins after end pointer.");
+
+ size_t num_children = (finish_val - start_val);
+ if (num_children % m_element_size)
+ return llvm::createStringError("Size not multiple of element size.");
+
+ return num_children / m_element_size;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::MsvcStlVectorSyntheticFrontEnd::GetChildAtIndex(
+ uint32_t idx) {
+ if (!m_start || !m_finish)
+ return lldb::ValueObjectSP();
+
+ uint64_t offset = idx * m_element_size;
+ offset = offset + m_start->GetValueAsUnsigned(0);
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromAddress(name.GetString(), offset,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::MsvcStlVectorSyntheticFrontEnd::Update() {
+ m_start = m_finish = nullptr;
+ ValueObjectSP data_sp(m_backend.GetChildAtNamePath({"_Mypair", "_Myval2"}));
+
+ if (!data_sp)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_start = data_sp->GetChildMemberWithName("_Myfirst").get();
+ m_finish = data_sp->GetChildMemberWithName("_Mylast").get();
+ if (!m_start || !m_finish)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_element_type = m_start->GetCompilerType().GetPointeeType();
+ llvm::Expected<uint64_t> size_or_err = m_element_type.GetByteSize(nullptr);
+ if (size_or_err)
+ m_element_size = *size_or_err;
+ else
+ LLDB_LOG_ERRORV(GetLog(LLDBLog::DataFormatters), size_or_err.takeError(),
+ "{0}");
+
+ return lldb::ChildCacheState::eRefetch;
+}
+
+llvm::Expected<size_t> lldb_private::formatters::
+ MsvcStlVectorSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
+ if (!m_start || !m_finish)
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+ auto optional_idx = ExtractIndexFromString(name.GetCString());
+ if (!optional_idx) {
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+ }
+ return *optional_idx;
+}
+
+lldb_private::formatters::MsvcStlVectorBoolSyntheticFrontEnd::
+ MsvcStlVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(),
+ m_children() {
+ if (valobj_sp) {
+ Update();
+ m_bool_type =
+ valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
+ }
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+ MsvcStlVectorBoolSyntheticFrontEnd::CalculateNumChildren() {
+ return m_count;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::MsvcStlVectorBoolSyntheticFrontEnd::GetChildAtIndex(
+ uint32_t idx) {
+ auto iter = m_children.find(idx), end = m_children.end();
+ if (iter != end)
+ return iter->second;
+ if (idx >= m_count)
+ return {};
+ if (m_base_data_address == 0 || m_count == 0)
+ return {};
+ if (!m_bool_type)
+ return {};
+
+ // The vector<bool> is represented as a sequence of `int`s.
+ // The size of an `int` is in `m_element_bit_size` (most often 32b).
+ // To access the element at index `i`:
+ // (bool)((data_address[i / bit_size] >> (i % bit_size)) & 1)
+
+ // int *byte_location = &data_address[i / bit_size]
+ size_t byte_idx = (idx / m_element_bit_size) * (m_element_bit_size / 8);
+ lldb::addr_t byte_location = m_base_data_address + byte_idx;
+
+ ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
+ if (!process_sp)
+ return {};
+ Status err;
+ Scalar scalar;
+ size_t bytes_read = process_sp->ReadScalarIntegerFromMemory(
+ byte_location, m_element_bit_size / 8, false, scalar, err);
+ if (err.Fail() || bytes_read == 0 || !scalar.IsValid())
+ return {};
+
+ size_t bit_index = idx % m_element_bit_size;
+ bool bit_set = scalar.GetAPSInt()[bit_index];
+ std::optional<uint64_t> size =
+ llvm::expectedToOptional(m_bool_type.GetByteSize(nullptr));
+ if (!size)
+ return {};
+ WritableDataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
+ if (bit_set && buffer_sp && buffer_sp->GetBytes()) {
+ // regardless of endianness, anything non-zero is true
+ *(buffer_sp->GetBytes()) = 1;
+ }
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ ValueObjectSP retval_sp(CreateValueObjectFromData(
+ name.GetString(),
+ DataExtractor(buffer_sp, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize()),
+ m_exe_ctx_ref, m_bool_type));
+ if (retval_sp)
+ m_children[idx] = retval_sp;
+ return retval_sp;
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::MsvcStlVectorBoolSyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return lldb::ChildCacheState::eRefetch;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ ValueObjectSP size_sp = valobj_sp->GetChildMemberWithName("_Mysize");
+ if (!size_sp)
+ return lldb::ChildCacheState::eRefetch;
+ m_count = size_sp->GetValueAsUnsigned(0);
+ if (!m_count)
+ return lldb::ChildCacheState::eReuse;
+
+ ValueObjectSP begin_sp(valobj_sp->GetChildAtNamePath(
+ {"_Myvec", "_Mypair", "_Myval2", "_Myfirst"}));
+ if (!begin_sp) {
+ m_count = 0;
+ return lldb::ChildCacheState::eRefetch;
+ }
+
+ // FIXME: the STL exposes _EEN_VBITS as a constant - it should be used instead
+ CompilerType begin_ty = begin_sp->GetCompilerType().GetPointeeType();
+ if (!begin_ty.IsValid())
+ return lldb::ChildCacheState::eRefetch;
+ llvm::Expected<uint64_t> bit_size = begin_ty.GetBitSize(nullptr);
+ if (!bit_size)
+ return lldb::ChildCacheState::eRefetch;
+ m_element_bit_size = *bit_size;
+
+ m_base_data_address = begin_sp->GetValueAsUnsigned(0);
+ if (!m_base_data_address) {
+ m_count = 0;
+ return lldb::ChildCacheState::eRefetch;
+ }
+ return lldb::ChildCacheState::eRefetch;
+}
+
+llvm::Expected<size_t>
+lldb_private::formatters::MsvcStlVectorBoolSyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ if (!m_count || !m_base_data_address)
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+ auto optional_idx = ExtractIndexFromString(name.AsCString());
+ if (!optional_idx) {
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+ }
+ uint32_t idx = *optional_idx;
+ if (idx >= CalculateNumChildrenIgnoringErrors())
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+ return idx;
+}
+
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::MsvcStlVectorSyntheticFrontEndCreator(
+ lldb::ValueObjectSP valobj_sp) {
+ CompilerType type = valobj_sp->GetCompilerType();
+ if (!type.IsValid())
+ return nullptr;
+
+ std::vector<uint32_t> indexes;
+ // vector<T>
+ if (type.GetIndexOfChildMemberWithName("_Mypair", true, indexes) > 0)
+ return new MsvcStlVectorSyntheticFrontEnd(valobj_sp);
+ // vector<bool>
+ if (type.GetIndexOfChildMemberWithName("_Myvec", true, indexes) > 0)
+ return new MsvcStlVectorBoolSyntheticFrontEnd(valobj_sp);
+
+ return nullptr;
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/TestDataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/TestDataFormatterStdVBool.py
index 56c86d1edde25..b4d6ce15b1af0 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/TestDataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/TestDataFormatterStdVBool.py
@@ -47,7 +47,7 @@ def cleanup():
self.expect(
"frame variable -A vBool",
substrs=[
- "size=49",
+ "size=73",
"[0] = false",
"[1] = true",
"[18] = false",
@@ -55,13 +55,20 @@ def cleanup():
"[36] = false",
"[47] = true",
"[48] = true",
+ "[49] = true",
+ "[50] = false",
+ "[56] = false",
+ "[65] = true",
+ "[70] = false",
+ "[71] = true",
+ "[72] = true",
],
)
self.expect(
"expr -A -- vBool",
substrs=[
- "size=49",
+ "size=73",
"[0] = false",
"[1] = true",
"[18] = false",
@@ -69,6 +76,13 @@ def cleanup():
"[36] = false",
"[47] = true",
"[48] = true",
+ "[49] = true",
+ "[50] = false",
+ "[56] = false",
+ "[65] = true",
+ "[70] = false",
+ "[71] = true",
+ "[72] = true",
],
)
@@ -88,3 +102,9 @@ def test_libstdcxx_debug(self):
dictionary={"USE_LIBSTDCPP": 1, "CXXFLAGS_EXTRAS": "-D_GLIBCXX_DEBUG"}
)
self.do_test()
+
+ @add_test_categories(["msvcstl"])
+ def test_libstdcxx(self):
+ # No flags, because the "msvcstl" category checks that the MSVC STL is used by default.
+ self.build(dictionary={})
+ self.do_test()
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/main.cpp
index 22fc6c89ca8a2..2c54166ace7cc 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vbool/main.cpp
@@ -1,10 +1,10 @@
#include <cstdio>
-#include <string>
#include <vector>
int main() {
std::vector<bool> vBool;
+ // 0..=7
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -14,6 +14,7 @@ int main() {
vBool.push_back(false);
vBool.push_back(true);
+ // 8..=15
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -23,6 +24,7 @@ int main() {
vBool.push_back(false);
vBool.push_back(true);
+ // 16..=23
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -32,6 +34,7 @@ int main() {
vBool.push_back(false);
vBool.push_back(true);
+ // 24..=31
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -41,6 +44,7 @@ int main() {
vBool.push_back(false);
vBool.push_back(true);
+ // 32..=39
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -50,6 +54,7 @@ int main() {
vBool.push_back(false);
vBool.push_back(true);
+ // 40..=47
vBool.push_back(false);
vBool.push_back(true);
vBool.push_back(false);
@@ -58,6 +63,38 @@ int main() {
vBool.push_back(true);
vBool.push_back(false);
vBool.push_back(true);
+
+ // 48..=55
+ vBool.push_back(true);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ // 56..=63
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ // 64..=71
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(true);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ // 72
vBool.push_back(true);
std::puts("// Set break point at this line.");
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vector/TestDataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vector/TestDataFormatterStdVector.py
index ba8b10450f4fc..353f5fe4dcbad 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vector/TestDataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/vector/TestDataFormatterStdVector.py
@@ -184,6 +184,12 @@ def test_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
self.do_test()
+ @add_test_categories(["msvcstl"])
+ def test_msvcstl(self):
+ # No flags, because the "msvcstl" category checks that the MSVC STL is used by default.
+ self.build(dictionary={})
+ self.do_test()
+
def do_test_ref_and_ptr(self):
"""Test that that file and class static variables display correctly."""
(self.target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
@@ -215,3 +221,8 @@ def test_ref_and_ptr_libstdcxx_debug(self):
def test_ref_and_ptr_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
self.do_test_ref_and_ptr()
+
+ @add_test_categories(["msvcstl"])
+ def test_ref_and_ptr_msvcstl(self):
+ self.build(dictionary={})
+ self.do_test_ref_and_ptr()
More information about the lldb-commits
mailing list