-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[LLDB] Add formatters for MSVC STL std::atomic #149801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-lldb Author: nerix (Nerixyz) ChangesAdds synthetic children and a summary provider for Towards #24834. Full diff: https://github.com/llvm/llvm-project/pull/149801.diff 5 Files Affected:
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 5905d9b9a6d03..ce4e2d6f0f5af 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -34,6 +34,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
LibStdcppTuple.cpp
LibStdcppUniquePointer.cpp
MsvcStl.cpp
+ MsvcStlAtomic.cpp
MsvcStlSmartPointer.cpp
MsvcStlTuple.cpp
MsvcStlVector.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index a0d5e1dfe3227..16b4d55d2db73 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1763,6 +1763,9 @@ static void LoadMsvcStlFormatters(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;
@@ -1784,6 +1787,17 @@ static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags,
MsvcStlStringSummaryProvider<StringElementType::UTF32>,
"MSVC STL std::u32string summary provider"));
+
+ stl_summary_flags.SetDontShowChildren(false);
+ stl_summary_flags.SetSkipPointers(false);
+
+ AddCXXSynthetic(cpp_category_sp, MsvcStlAtomicSyntheticFrontEndCreator,
+ "MSVC STL std::atomic synthetic children",
+ "^std::atomic<.+>$", stl_synth_flags, true);
+
+ AddCXXSummary(cpp_category_sp, MsvcStlAtomicSummaryProvider,
+ "MSVC STL std::atomic summary provider", "^std::atomic<.+>$",
+ stl_summary_flags, true);
}
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index c08eecfdecee7..3ac12c17a96e1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -71,6 +71,13 @@ SyntheticChildrenFrontEnd *
MsvcStlOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP valobj_sp);
+// MSVC STL std::atomic<>
+bool MsvcStlAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+SyntheticChildrenFrontEnd *
+MsvcStlAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp
new file mode 100644
index 0000000000000..3ec324577ac76
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp
@@ -0,0 +1,102 @@
+//===-- MsvcStlAtomic.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/TypeSynthetic.h"
+
+using namespace lldb;
+
+namespace lldb_private {
+namespace formatters {
+
+class MsvcStlAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ MsvcStlAtomicSyntheticFrontEnd(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_storage = nullptr;
+ CompilerType m_element_type;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::
+ MsvcStlAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
+ if (valobj_sp)
+ Update();
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+ MsvcStlAtomicSyntheticFrontEnd::CalculateNumChildren() {
+ return m_storage ? 1 : 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::GetChildAtIndex(
+ uint32_t idx) {
+ if (idx == 0)
+ return m_storage->Cast(m_element_type)->Clone(ConstString("Value"));
+ return nullptr;
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::Update() {
+ m_storage = nullptr;
+ m_element_type.Clear();
+
+ ValueObjectSP storage_sp = m_backend.GetChildMemberWithName("_Storage");
+ if (!storage_sp)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
+ if (!m_element_type)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_storage = storage_sp.get();
+ return lldb::ChildCacheState::eRefetch;
+}
+
+llvm::Expected<size_t> lldb_private::formatters::
+ MsvcStlAtomicSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
+ if (name == "Value")
+ return 0;
+ return llvm::createStringError("Type has no child named '%s'",
+ name.AsCString());
+}
+
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
+}
+
+bool lldb_private::formatters::MsvcStlAtomicSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ auto synth_sp = valobj.GetSyntheticValue();
+ if (!synth_sp)
+ return false;
+
+ auto value_sp = synth_sp->GetChildAtIndex(0);
+ std::string summary;
+ if (value_sp->GetSummaryAsCString(summary, options) && !summary.empty()) {
+ stream << summary;
+ return true;
+ }
+ return false;
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/atomic/TestDataFormatterStdAtomic.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/atomic/TestDataFormatterStdAtomic.py
index 8186e1d66985b..bdf12ca3b86db 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/atomic/TestDataFormatterStdAtomic.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/atomic/TestDataFormatterStdAtomic.py
@@ -67,3 +67,9 @@ def do_test(self):
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()
+ self.do_test()
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| stl_summary_flags.SetSkipPointers(false); |
We already set this above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if you don't set this? I think we probably do want this to be true? Would that make std::atomic look like:
(std::atomic<int>) val = 5
?
(i.e., just not print the synthetic child?)
I know that's not what libc++/libstdc++ does, but we probably should?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be done separately since that's what libc++ and libstdc++ already do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would that make
std::atomiclook like:(std::atomic<int>) val = 5?
Yes. I don't think that's always desired. Atomics can store structs as well (not sure why) and users might want to inspect these. This is also done in the tests here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I wondered if for summaries that can't be formatted without children this would then fall back to showing the children. But yea maybe not. Either way, not something you have to deal with here
679f4fa to
6d27113
Compare
Adds synthetic children and a summary provider for `std::atomic` on MSVC's STL. This currently only supports DWARF because it relies on the template argument. Once there are PDB tests, this will probably use the return type of some method like `value()` because template types aren't available there. Towards llvm#24834.
Adds synthetic children and a summary provider for
std::atomicon MSVC's STL. This currently only supports DWARF because it relies on the template argument. Once there are PDB tests, this will probably use the return type of some method likevalue()because template types aren't available there.Towards #24834.