LLDB mainline
MsvcStlValarray.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 "MsvcStl.h"
10
14#include "llvm/Support/ErrorExtras.h"
15#include <cinttypes>
16#include <optional>
17
18using namespace lldb;
19using namespace lldb_private;
20using namespace lldb_private::formatters;
21
22namespace {
23class MsvcStlValarraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
24public:
25 MsvcStlValarraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
26 : SyntheticChildrenFrontEnd(*valobj_sp) {
27 if (valobj_sp)
28 Update();
29 }
30
31 llvm::Expected<uint32_t> CalculateNumChildren() override {
32 if (!m_start || m_element_size == 0)
33 return 0;
34 return m_count;
35 }
36
37 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
38 if (!m_start || idx >= m_count)
39 return {};
40
41 uint64_t offset = m_start->GetValueAsUnsigned(0) +
42 static_cast<uint64_t>(idx) * m_element_size;
43 StreamString name;
44 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
45 return CreateChildValueObjectFromAddress(name.GetString(), offset,
46 m_backend.GetExecutionContextRef(),
47 m_element_type);
48 }
49
50 lldb::ChildCacheState Update() override {
51 m_start = nullptr;
52 m_count = 0;
53 m_element_size = 0;
54
55 ValueObjectSP start = m_backend.GetChildMemberWithName("_Myptr");
56 ValueObjectSP size_sp = m_backend.GetChildMemberWithName("_Mysize");
57 if (!start || !size_sp)
58 return ChildCacheState::eRefetch;
59
60 // Prefer the pointer's pointee type: template arguments are missing on
61 // references unless the frontend asked for a dereference, and PDB may
62 // omit them entirely.
63 m_element_type = start->GetCompilerType().GetPointeeType();
64 if (!m_element_type.IsValid()) {
65 CompilerType type = m_backend.GetCompilerType().GetNonReferenceType();
66 m_element_type = type.GetTypeTemplateArgument(0);
67 }
68 if (!m_element_type.IsValid())
69 return ChildCacheState::eRefetch;
70
71 if (std::optional<uint64_t> size =
72 llvm::expectedToOptional(m_element_type.GetByteSize(nullptr)))
73 m_element_size = *size;
74
75 if (m_element_size == 0)
76 return ChildCacheState::eRefetch;
77
78 m_start = start.get();
79 m_count = size_sp->GetValueAsUnsigned(0);
80 return ChildCacheState::eRefetch;
81 }
82
83 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
84 if (!m_start)
85 return llvm::createStringErrorV("type has no child named '{0}'", name);
86 auto optional_idx = ExtractIndexFromString(name.GetCString());
87 if (!optional_idx)
88 return llvm::createStringErrorV("type has no child named '{0}'", name);
89 return *optional_idx;
90 }
91
92private:
93 /// A non-owning pointer to valarray's _Myptr member.
94 ValueObject *m_start = nullptr;
95 CompilerType m_element_type;
96 uint32_t m_element_size = 0;
97 uint64_t m_count = 0;
98};
99} // namespace
100
102 if (auto valobj_sp = valobj.GetNonSyntheticValue())
103 return valobj_sp->GetChildMemberWithName("_Myptr") != nullptr;
104 return false;
105}
106
109 if (!valobj_sp)
110 return nullptr;
111 return new MsvcStlValarraySyntheticFrontEnd(valobj_sp);
112}
static std::optional< size_t > CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements, CompilerType element_type)
Calculates the number of elements stored in a container (with element type 'container_elem_type') as ...
CompilerType GetTypeTemplateArgument(size_t idx, bool expand_pack=false) const
const char * GetCString() const
Get the string value as a C string.
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
virtual lldb::ValueObjectSP GetNonSyntheticValue()
SyntheticChildrenFrontEnd * MsvcStlValarraySyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
std::optional< size_t > ExtractIndexFromString(const char *item_name)
bool IsMsvcStlValarray(ValueObject &valobj)
A class that represents a running process on the host machine.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP