summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp')
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
new file mode 100644
index 0000000000000..b4e7a1703e46a
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
@@ -0,0 +1,159 @@
+//===-- LibCxxAtomic.cpp ------------------------------------------*- C++
+//-*-===//
+//
+// 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 "LibCxxAtomic.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+//
+// We are supporting two versions of libc++ std::atomic
+//
+// Given std::atomic<int> i;
+//
+// The previous version of std::atomic was laid out like this
+//
+// (lldb) frame var -L -R i
+// 0x00007ffeefbff9a0: (std::__1::atomic<int>) i = {
+// 0x00007ffeefbff9a0: std::__1::__atomic_base<int, true> = {
+// 0x00007ffeefbff9a0: std::__1::__atomic_base<int, false> = {
+// 0x00007ffeefbff9a0: __a_ = 5
+// }
+// }
+// }
+//
+// In this case we need to obtain __a_ and the current version is laid out as so
+//
+// (lldb) frame var -L -R i
+// 0x00007ffeefbff9b0: (std::__1::atomic<int>) i = {
+// 0x00007ffeefbff9b0: std::__1::__atomic_base<int, true> = {
+// 0x00007ffeefbff9b0: std::__1::__atomic_base<int, false> = {
+// 0x00007ffeefbff9b0: __a_ = {
+// 0x00007ffeefbff9b0: std::__1::__cxx_atomic_base_impl<int> = {
+// 0x00007ffeefbff9b0: __a_value = 5
+// }
+// }
+// }
+// }
+//}
+//
+// In this case we need to obtain __a_value
+//
+// The below method covers both cases and returns the relevant member as a
+// ValueObjectSP
+//
+ValueObjectSP
+lldb_private::formatters::GetLibCxxAtomicValue(ValueObject &valobj) {
+ ValueObjectSP non_sythetic = valobj.GetNonSyntheticValue();
+ if (!non_sythetic)
+ return {};
+
+ ValueObjectSP member__a_ =
+ non_sythetic->GetChildMemberWithName(ConstString("__a_"), true);
+ if (!member__a_)
+ return {};
+
+ ValueObjectSP member__a_value =
+ member__a_->GetChildMemberWithName(ConstString("__a_value"), true);
+ if (!member__a_value)
+ return member__a_;
+
+ return member__a_value;
+}
+
+bool lldb_private::formatters::LibCxxAtomicSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+
+ if (ValueObjectSP atomic_value = GetLibCxxAtomicValue(valobj)) {
+ std::string summary;
+ if (atomic_value->GetSummaryAsCString(summary, options) &&
+ summary.size() > 0) {
+ stream.Printf("%s", summary.c_str());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+namespace lldb_private {
+namespace formatters {
+class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+ lldb::ValueObjectSP GetSyntheticValue() override;
+
+private:
+ ValueObject *m_real_child;
+};
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_real_child(nullptr) {}
+
+bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() {
+ ValueObjectSP atomic_value = GetLibCxxAtomicValue(m_backend);
+ if (atomic_value)
+ m_real_child = GetLibCxxAtomicValue(m_backend).get();
+
+ return false;
+}
+
+bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
+}
+
+size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return m_real_child ? m_real_child->GetNumChildren() : 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;
+}
+
+size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ return m_real_child ? m_real_child->GetIndexOfChildWithName(name)
+ : UINT32_MAX;
+}
+
+lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ GetSyntheticValue() {
+ if (m_real_child && m_real_child->CanProvideValue())
+ return m_real_child->GetSP();
+ return nullptr;
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
+ return nullptr;
+}