xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- LibCxxAtomic.cpp --------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "LibCxxAtomic.h"
10dda28197Spatrick #include "lldb/DataFormatters/FormattersHelpers.h"
11061da546Spatrick 
12061da546Spatrick using namespace lldb;
13061da546Spatrick using namespace lldb_private;
14061da546Spatrick using namespace lldb_private::formatters;
15061da546Spatrick 
16061da546Spatrick //
17061da546Spatrick // We are supporting two versions of libc++ std::atomic
18061da546Spatrick //
19061da546Spatrick // Given std::atomic<int> i;
20061da546Spatrick //
21061da546Spatrick // The previous version of std::atomic was laid out like this
22061da546Spatrick //
23061da546Spatrick // (lldb) frame var -L -R i
24061da546Spatrick // 0x00007ffeefbff9a0: (std::__1::atomic<int>) i = {
25061da546Spatrick // 0x00007ffeefbff9a0:   std::__1::__atomic_base<int, true> = {
26061da546Spatrick // 0x00007ffeefbff9a0:     std::__1::__atomic_base<int, false> = {
27061da546Spatrick // 0x00007ffeefbff9a0:       __a_ = 5
28061da546Spatrick //        }
29061da546Spatrick //    }
30061da546Spatrick // }
31061da546Spatrick //
32061da546Spatrick // In this case we need to obtain __a_ and the current version is laid out as so
33061da546Spatrick //
34061da546Spatrick // (lldb) frame var -L -R i
35061da546Spatrick // 0x00007ffeefbff9b0: (std::__1::atomic<int>) i = {
36061da546Spatrick // 0x00007ffeefbff9b0:   std::__1::__atomic_base<int, true> = {
37061da546Spatrick // 0x00007ffeefbff9b0:     std::__1::__atomic_base<int, false> = {
38061da546Spatrick // 0x00007ffeefbff9b0:       __a_ = {
39061da546Spatrick // 0x00007ffeefbff9b0:         std::__1::__cxx_atomic_base_impl<int> = {
40061da546Spatrick // 0x00007ffeefbff9b0:           __a_value = 5
41061da546Spatrick //                }
42061da546Spatrick //          }
43061da546Spatrick //       }
44061da546Spatrick //    }
45061da546Spatrick //}
46061da546Spatrick //
47061da546Spatrick // In this case we need to obtain __a_value
48061da546Spatrick //
49061da546Spatrick // The below method covers both cases and returns the relevant member as a
50061da546Spatrick // ValueObjectSP
51061da546Spatrick //
52061da546Spatrick ValueObjectSP
GetLibCxxAtomicValue(ValueObject & valobj)53061da546Spatrick lldb_private::formatters::GetLibCxxAtomicValue(ValueObject &valobj) {
54061da546Spatrick   ValueObjectSP non_sythetic = valobj.GetNonSyntheticValue();
55061da546Spatrick   if (!non_sythetic)
56061da546Spatrick     return {};
57061da546Spatrick 
58061da546Spatrick   ValueObjectSP member__a_ =
59061da546Spatrick       non_sythetic->GetChildMemberWithName(ConstString("__a_"), true);
60061da546Spatrick   if (!member__a_)
61061da546Spatrick     return {};
62061da546Spatrick 
63061da546Spatrick   ValueObjectSP member__a_value =
64061da546Spatrick       member__a_->GetChildMemberWithName(ConstString("__a_value"), true);
65061da546Spatrick   if (!member__a_value)
66061da546Spatrick     return member__a_;
67061da546Spatrick 
68061da546Spatrick   return member__a_value;
69061da546Spatrick }
70061da546Spatrick 
LibCxxAtomicSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions & options)71061da546Spatrick bool lldb_private::formatters::LibCxxAtomicSummaryProvider(
72061da546Spatrick     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
73061da546Spatrick 
74061da546Spatrick   if (ValueObjectSP atomic_value = GetLibCxxAtomicValue(valobj)) {
75061da546Spatrick     std::string summary;
76061da546Spatrick     if (atomic_value->GetSummaryAsCString(summary, options) &&
77061da546Spatrick         summary.size() > 0) {
78061da546Spatrick       stream.Printf("%s", summary.c_str());
79061da546Spatrick       return true;
80061da546Spatrick     }
81061da546Spatrick   }
82061da546Spatrick 
83061da546Spatrick   return false;
84061da546Spatrick }
85061da546Spatrick 
86061da546Spatrick namespace lldb_private {
87061da546Spatrick namespace formatters {
88061da546Spatrick class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
89061da546Spatrick public:
90061da546Spatrick   LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
91061da546Spatrick 
92061da546Spatrick   ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
93061da546Spatrick 
94061da546Spatrick   size_t CalculateNumChildren() override;
95061da546Spatrick 
96061da546Spatrick   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
97061da546Spatrick 
98061da546Spatrick   bool Update() override;
99061da546Spatrick 
100061da546Spatrick   bool MightHaveChildren() override;
101061da546Spatrick 
102061da546Spatrick   size_t GetIndexOfChildWithName(ConstString name) override;
103061da546Spatrick 
104061da546Spatrick private:
105*f6aab3d8Srobert   ValueObject *m_real_child = nullptr;
106061da546Spatrick };
107061da546Spatrick } // namespace formatters
108061da546Spatrick } // namespace lldb_private
109061da546Spatrick 
110061da546Spatrick lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)111061da546Spatrick     LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
112*f6aab3d8Srobert     : SyntheticChildrenFrontEnd(*valobj_sp) {}
113061da546Spatrick 
Update()114061da546Spatrick bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() {
115061da546Spatrick   ValueObjectSP atomic_value = GetLibCxxAtomicValue(m_backend);
116061da546Spatrick   if (atomic_value)
117061da546Spatrick     m_real_child = GetLibCxxAtomicValue(m_backend).get();
118061da546Spatrick 
119061da546Spatrick   return false;
120061da546Spatrick }
121061da546Spatrick 
122061da546Spatrick bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
MightHaveChildren()123061da546Spatrick     MightHaveChildren() {
124061da546Spatrick   return true;
125061da546Spatrick }
126061da546Spatrick 
127061da546Spatrick size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
CalculateNumChildren()128061da546Spatrick     CalculateNumChildren() {
129dda28197Spatrick   return m_real_child ? 1 : 0;
130061da546Spatrick }
131061da546Spatrick 
132061da546Spatrick lldb::ValueObjectSP
GetChildAtIndex(size_t idx)133061da546Spatrick lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(
134061da546Spatrick     size_t idx) {
135dda28197Spatrick   if (idx == 0)
136dda28197Spatrick     return m_real_child->GetSP()->Clone(ConstString("Value"));
137dda28197Spatrick   return nullptr;
138061da546Spatrick }
139061da546Spatrick 
140061da546Spatrick size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name)141061da546Spatrick     GetIndexOfChildWithName(ConstString name) {
142dda28197Spatrick   return formatters::ExtractIndexFromString(name.GetCString());
143061da546Spatrick }
144061da546Spatrick 
145061da546Spatrick SyntheticChildrenFrontEnd *
LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)146061da546Spatrick lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
147061da546Spatrick     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
148061da546Spatrick   if (valobj_sp)
149061da546Spatrick     return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
150061da546Spatrick   return nullptr;
151061da546Spatrick }
152