]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
MFV 331710:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Language / CPlusPlus / LibCxxBitset.cpp
1 //===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "LibCxx.h"
11 #include "lldb/DataFormatters/FormattersHelpers.h"
12 #include "lldb/Symbol/ClangASTContext.h"
13 #include "lldb/Target/Target.h"
14
15 using namespace lldb;
16 using namespace lldb_private;
17
18 namespace {
19
20 class BitsetFrontEnd : public SyntheticChildrenFrontEnd {
21 public:
22   BitsetFrontEnd(ValueObject &valobj);
23
24   size_t GetIndexOfChildWithName(const ConstString &name) override {
25     return formatters::ExtractIndexFromString(name.GetCString());
26   }
27
28   bool MightHaveChildren() override { return true; }
29   bool Update() override;
30   size_t CalculateNumChildren() override { return m_elements.size(); }
31   ValueObjectSP GetChildAtIndex(size_t idx) override;
32
33 private:
34   std::vector<ValueObjectSP> m_elements;
35   ValueObjectSP m_first;
36   CompilerType m_bool_type;
37   ByteOrder m_byte_order = eByteOrderInvalid;
38   uint8_t m_byte_size = 0;
39 };
40 } // namespace
41
42 BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
43     : SyntheticChildrenFrontEnd(valobj) {
44   m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool);
45   if (auto target_sp = m_backend.GetTargetSP()) {
46     m_byte_order = target_sp->GetArchitecture().GetByteOrder();
47     m_byte_size = target_sp->GetArchitecture().GetAddressByteSize();
48     Update();
49   }
50 }
51
52 bool BitsetFrontEnd::Update() {
53   m_elements.clear();
54   m_first.reset();
55
56   TargetSP target_sp = m_backend.GetTargetSP();
57   if (!target_sp)
58     return false;
59   size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
60
61   size_t size = 0;
62   if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
63     size = arg->value.getLimitedValue(capping_size);
64
65   m_elements.assign(size, ValueObjectSP());
66
67   m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
68   return false;
69 }
70
71 ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
72   if (idx >= m_elements.size() || !m_first)
73     return ValueObjectSP();
74
75   if (m_elements[idx])
76     return m_elements[idx];
77
78   ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false);
79   CompilerType type;
80   ValueObjectSP chunk;
81   // For small bitsets __first_ is not an array, but a plain size_t.
82   if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr))
83     chunk = m_first->GetChildAtIndex(
84         idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true);
85   else {
86     type = m_first->GetCompilerType();
87     chunk = m_first;
88   }
89   if (!type || !chunk)
90     return ValueObjectSP();
91
92   size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope());
93   uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
94   DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);
95
96   m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(),
97                                               data, ctx, m_bool_type);
98
99   return m_elements[idx];
100 }
101
102 SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator(
103     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
104   if (valobj_sp)
105     return new BitsetFrontEnd(*valobj_sp);
106   return nullptr;
107 }