danilashtefan updated this revision to Diff 382453.
danilashtefan added a comment.
With this changes I substitute the verbose long printed check with ValueCheck
approach
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112180/new/
https://reviews.llvm.org/D112180
Files:
lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/Makefile
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/main.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/Makefile
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/main.cpp
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""
-Test lldb data formatter subsystem.
-"""
-
-
-
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class TestDataFormatterLibcxxBitset(TestBase):
-
- mydir = TestBase.compute_mydir(__file__)
-
- def setUp(self):
- TestBase.setUp(self)
-
- primes = [1]*300
- primes[0] = primes[1] = 0
- for i in range(2, len(primes)):
- for j in range(2*i, len(primes), i):
- primes[j] = 0
- self.primes = primes
-
- def check(self, name, size):
- var = self.frame().FindVariable(name)
- self.assertTrue(var.IsValid())
- self.assertEqual(var.GetNumChildren(), size)
- for i in range(size):
- child = var.GetChildAtIndex(i)
- self.assertEqual(child.GetValueAsUnsigned(), self.primes[i],
- "variable: %s, index: %d"%(name, size))
-
- @add_test_categories(["libc++"])
- def test_value(self):
- """Test that std::bitset is displayed correctly"""
- self.build()
- lldbutil.run_to_source_breakpoint(self, '// break here',
- lldb.SBFileSpec("main.cpp", False))
-
- self.check("empty", 0)
- self.check("small", 13)
- self.check("large", 200)
-
- @add_test_categories(["libc++"])
- def test_ptr_and_ref(self):
- """Test that ref and ptr to std::bitset is displayed correctly"""
- self.build()
- (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self,
- 'Check ref and ptr',
- lldb.SBFileSpec("main.cpp", False))
-
- self.check("ref", 13)
- self.check("ptr", 13)
-
- lldbutil.continue_to_breakpoint(process, bkpt)
-
- self.check("ref", 200)
- self.check("ptr", 200)
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/main.cpp
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/main.cpp
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/main.cpp
@@ -1,29 +1,28 @@
#include <bitset>
#include <stdio.h>
-template<std::size_t N>
-void fill(std::bitset<N> &b) {
+template <std::size_t N> void fill(std::bitset<N> &b) {
b.set();
b[0] = b[1] = false;
for (std::size_t i = 2; i < N; ++i) {
- for (std::size_t j = 2*i; j < N; j+=i)
+ for (std::size_t j = 2 * i; j < N; j += i)
b[j] = false;
}
}
-template<std::size_t N>
+template <std::size_t N>
void by_ref_and_ptr(std::bitset<N> &ref, std::bitset<N> *ptr) {
- // Check ref and ptr
- return;
+ // Check ref and ptr
+ return;
}
int main() {
std::bitset<0> empty;
std::bitset<13> small;
fill(small);
- std::bitset<200> large;
+ std::bitset<70> large;
fill(large);
by_ref_and_ptr(small, &small); // break here
- by_ref_and_ptr(large, &large);
+ by_ref_and_ptr(large, &large);
return 0;
}
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
@@ -0,0 +1,89 @@
+"""
+Test lldb data formatter subsystem for bitset for libcxx and libstdcpp.
+"""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+USE_LIBSTDCPP = "USE_LIBSTDCPP"
+USE_LIBCPP = "USE_LIBCPP"
+value="value"
+reference="reference"
+pointer="pointer"
+
+class GenericBitsetDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ primes = [1]*300
+ primes[0] = primes[1] = 0
+ for i in range(2, len(primes)):
+ for j in range(2*i, len(primes), i):
+ primes[j] = 0
+ self.primes = primes
+
+ def check(self, name, size,type):
+ var = self.frame().FindVariable(name)
+ self.assertTrue(var.IsValid())
+ self.assertEqual(var.GetNumChildren(), size)
+ children = []
+ for i in range(size):
+ child = var.GetChildAtIndex(i)
+ children.append(ValueCheck(value=str(bool(child.GetValueAsUnsigned())).lower()))
+ self.assertEqual(child.GetValueAsUnsigned(), self.primes[i],
+ "variable: %s, index: %d"%(name, size))
+ if type==value:
+ self.expect_var_path(name,type="std::bitset<" + str(size) + ">",children=children)
+ elif type==reference:
+ self.expect_var_path(name,type="std::bitset<" + str(size) + "> &",children=children)
+ elif type==pointer:
+ self.expect_var_path(name,type="std::bitset<" + str(size) + "> *",children=children)
+
+ def do_test_value(self, stdlib_type):
+ """Test that std::bitset is displayed correctly"""
+ self.build(dictionary={stdlib_type: "1"})
+
+ lldbutil.run_to_source_breakpoint(self, '// break here',
+ lldb.SBFileSpec("main.cpp", False))
+
+ self.check("empty", 0, value)
+ self.check("small", 13, value)
+ self.check("large", 70, value)
+
+ @add_test_categories(["libstdcxx"])
+ def test_value_libstdcpp(self):
+ self.do_test_value(USE_LIBSTDCPP)
+
+ @add_test_categories(["libc++"])
+ def test_value_libcpp(self):
+ self.do_test_value(USE_LIBCPP)
+
+ def do_test_ptr_and_ref(self, stdlib_type):
+ """Test that ref and ptr to std::bitset is displayed correctly"""
+ self.build(dictionary={stdlib_type: "1"})
+
+ (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ 'Check ref and ptr',
+ lldb.SBFileSpec("main.cpp", False))
+
+ self.check("ref", 13, reference)
+ self.check("ptr", 13, pointer)
+
+ lldbutil.continue_to_breakpoint(process, bkpt)
+
+ self.check("ref", 70, reference)
+ self.check("ptr", 70, pointer)
+
+ @add_test_categories(["libstdcxx"])
+ def test_ptr_and_ref_libstdcpp(self):
+ self.do_test_ptr_and_ref(USE_LIBSTDCPP)
+
+ @add_test_categories(["libc++"])
+ def test_ptr_and_ref_libcpp(self):
+ self.do_test_ptr_and_ref(USE_LIBCPP)
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/Makefile
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/Makefile
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/Makefile
@@ -1,4 +1,3 @@
CXX_SOURCES := main.cpp
-USE_LIBCPP := 1
include Makefile.rules
Index: lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -41,6 +41,10 @@
LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+LibStdcppBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
SyntheticChildrenFrontEnd *
LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
Index: lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxBitset.cpp --------------------------------------------------===//
+//===-- GenericBitset.cpp //-----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "LibCxx.h"
+#include "LibStdcpp.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Target/Target.h"
@@ -16,9 +17,15 @@
namespace {
-class BitsetFrontEnd : public SyntheticChildrenFrontEnd {
+/// This class can be used for handling bitsets from both libcxx and libstdcpp.
+class GenericBitsetFrontEnd : public SyntheticChildrenFrontEnd {
public:
- BitsetFrontEnd(ValueObject &valobj);
+ enum class StdLib {
+ LibCxx,
+ LibStdcpp,
+ };
+
+ GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib);
size_t GetIndexOfChildWithName(ConstString name) override {
return formatters::ExtractIndexFromString(name.GetCString());
@@ -30,6 +37,8 @@
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
+ ConstString GetDataContainerMemberName();
+
// The lifetime of a ValueObject and all its derivative ValueObjects
// (children, clones, etc.) is managed by a ClusterManager. These
// objects are only destroyed when every shared pointer to any of them
@@ -38,15 +47,16 @@
// Value objects created from raw data (i.e. in a different cluster) must
// be referenced via shared pointer to keep them alive, however.
std::vector<ValueObjectSP> m_elements;
- ValueObject* m_first = nullptr;
+ ValueObject *m_first = nullptr;
CompilerType m_bool_type;
ByteOrder m_byte_order = eByteOrderInvalid;
uint8_t m_byte_size = 0;
+ StdLib m_stdlib;
};
} // namespace
-BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
- : SyntheticChildrenFrontEnd(valobj) {
+GenericBitsetFrontEnd::GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib)
+ : SyntheticChildrenFrontEnd(valobj), m_stdlib(stdlib) {
m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool);
if (auto target_sp = m_backend.GetTargetSP()) {
m_byte_order = target_sp->GetArchitecture().GetByteOrder();
@@ -55,7 +65,16 @@
}
}
-bool BitsetFrontEnd::Update() {
+ConstString GenericBitsetFrontEnd::GetDataContainerMemberName() {
+ switch (m_stdlib) {
+ case StdLib::LibCxx:
+ return ConstString("__first_");
+ case StdLib::LibStdcpp:
+ return ConstString("_M_w");
+ }
+}
+
+bool GenericBitsetFrontEnd::Update() {
m_elements.clear();
m_first = nullptr;
@@ -65,16 +84,17 @@
size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
size_t size = 0;
+
if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
size = arg->value.getLimitedValue(capping_size);
m_elements.assign(size, ValueObjectSP());
-
- m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get();
+ m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true)
+ .get();
return false;
}
-ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
+ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(size_t idx) {
if (idx >= m_elements.size() || !m_first)
return ValueObjectSP();
@@ -112,9 +132,18 @@
return m_elements[idx];
}
+SyntheticChildrenFrontEnd *formatters::LibStdcppBitsetSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new GenericBitsetFrontEnd(*valobj_sp,
+ GenericBitsetFrontEnd::StdLib::LibStdcpp);
+ return nullptr;
+}
+
SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
if (valobj_sp)
- return new BitsetFrontEnd(*valobj_sp);
+ return new GenericBitsetFrontEnd(*valobj_sp,
+ GenericBitsetFrontEnd::StdLib::LibCxx);
return nullptr;
}
Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -905,6 +905,8 @@
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
+ SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
+ stl_deref_flags.SetFrontEndWantsDereference();
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::vector<.+>(( )?&)?$"),
@@ -923,6 +925,10 @@
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(true);
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::bitset<.+>(( )?&)?$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::vector<.+>(( )?&)?$"),
TypeSummaryImplSP(
@@ -969,6 +975,12 @@
"std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
+ "std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"),
+ stl_deref_flags, true);
+
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
"libstdc++ std::unique_ptr summary provider",
Index: lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -3,9 +3,9 @@
CPlusPlusLanguage.cpp
CPlusPlusNameParser.cpp
CxxStringTypes.cpp
+ GenericBitset.cpp
LibCxx.cpp
LibCxxAtomic.cpp
- LibCxxBitset.cpp
LibCxxInitializerList.cpp
LibCxxList.cpp
LibCxxMap.cpp
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits