Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LibCxxAtomic.cpp --------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "LibCxxAtomic.h"
10
#include "lldb/DataFormatters/FormattersHelpers.h"
11
12
using namespace lldb;
13
using namespace lldb_private;
14
using namespace lldb_private::formatters;
15
16
//
17
// We are supporting two versions of libc++ std::atomic
18
//
19
// Given std::atomic<int> i;
20
//
21
// The previous version of std::atomic was laid out like this
22
//
23
// (lldb) frame var -L -R i
24
// 0x00007ffeefbff9a0: (std::__1::atomic<int>) i = {
25
// 0x00007ffeefbff9a0:   std::__1::__atomic_base<int, true> = {
26
// 0x00007ffeefbff9a0:     std::__1::__atomic_base<int, false> = {
27
// 0x00007ffeefbff9a0:       __a_ = 5
28
//        }
29
//    }
30
// }
31
//
32
// In this case we need to obtain __a_ and the current version is laid out as so
33
//
34
// (lldb) frame var -L -R i
35
// 0x00007ffeefbff9b0: (std::__1::atomic<int>) i = {
36
// 0x00007ffeefbff9b0:   std::__1::__atomic_base<int, true> = {
37
// 0x00007ffeefbff9b0:     std::__1::__atomic_base<int, false> = {
38
// 0x00007ffeefbff9b0:       __a_ = {
39
// 0x00007ffeefbff9b0:         std::__1::__cxx_atomic_base_impl<int> = {
40
// 0x00007ffeefbff9b0:           __a_value = 5
41
//                }
42
//          }
43
//       }
44
//    }
45
//}
46
//
47
// In this case we need to obtain __a_value
48
//
49
// The below method covers both cases and returns the relevant member as a
50
// ValueObjectSP
51
//
52
ValueObjectSP
53
33
lldb_private::formatters::GetLibCxxAtomicValue(ValueObject &valobj) {
54
33
  ValueObjectSP non_sythetic = valobj.GetNonSyntheticValue();
55
33
  if (!non_sythetic)
56
0
    return {};
57
58
33
  ValueObjectSP member__a_ =
59
33
      non_sythetic->GetChildMemberWithName(ConstString("__a_"), true);
60
33
  if (!member__a_)
61
0
    return {};
62
63
33
  ValueObjectSP member__a_value =
64
33
      member__a_->GetChildMemberWithName(ConstString("__a_value"), true);
65
33
  if (!member__a_value)
66
0
    return member__a_;
67
68
33
  return member__a_value;
69
33
}
70
71
bool lldb_private::formatters::LibCxxAtomicSummaryProvider(
72
15
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
73
74
15
  if (ValueObjectSP atomic_value = GetLibCxxAtomicValue(valobj)) {
75
15
    std::string summary;
76
15
    if (atomic_value->GetSummaryAsCString(summary, options) &&
77
15
        
summary.size() > 00
) {
78
0
      stream.Printf("%s", summary.c_str());
79
0
      return true;
80
0
    }
81
15
  }
82
83
15
  return false;
84
15
}
85
86
namespace lldb_private {
87
namespace formatters {
88
class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
89
public:
90
  LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
91
92
9
  ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
93
94
  size_t CalculateNumChildren() override;
95
96
  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
97
98
  bool Update() override;
99
100
  bool MightHaveChildren() override;
101
102
  size_t GetIndexOfChildWithName(ConstString name) override;
103
104
private:
105
  ValueObject *m_real_child;
106
};
107
} // namespace formatters
108
} // namespace lldb_private
109
110
lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
111
    LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
112
9
    : SyntheticChildrenFrontEnd(*valobj_sp), m_real_child(nullptr) {}
113
114
9
bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() {
115
9
  ValueObjectSP atomic_value = GetLibCxxAtomicValue(m_backend);
116
9
  if (atomic_value)
117
9
    m_real_child = GetLibCxxAtomicValue(m_backend).get();
118
119
9
  return false;
120
9
}
121
122
bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
123
6
    MightHaveChildren() {
124
6
  return true;
125
6
}
126
127
size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
128
9
    CalculateNumChildren() {
129
9
  return m_real_child ? 1 : 
00
;
130
9
}
131
132
lldb::ValueObjectSP
133
lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(
134
9
    size_t idx) {
135
9
  if (idx == 0)
136
9
    return m_real_child->GetSP()->Clone(ConstString("Value"));
137
0
  return nullptr;
138
9
}
139
140
size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
141
0
    GetIndexOfChildWithName(ConstString name) {
142
0
  return formatters::ExtractIndexFromString(name.GetCString());
143
0
}
144
145
SyntheticChildrenFrontEnd *
146
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
147
9
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
148
9
  if (valobj_sp)
149
9
    return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
150
0
  return nullptr;
151
9
}