LLDB  mainline
LibCxxSpan.cpp
Go to the documentation of this file.
1 //===-- LibCxxSpan.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 "LibCxx.h"
10 
11 #include "lldb/Core/ValueObject.h"
14 #include "llvm/ADT/APSInt.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 using namespace lldb_private::formatters;
19 
20 namespace lldb_private {
21 namespace formatters {
22 
24 public:
25  LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
26 
27  ~LibcxxStdSpanSyntheticFrontEnd() override = default;
28 
29  size_t CalculateNumChildren() override;
30 
31  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
32 
33  /// Determines properties of the std::span<> associated with this object
34  //
35  // std::span can either be instantiated with a compile-time known
36  // extent or a std::dynamic_extent (this is the default if only the
37  // type template argument is provided). The layout of std::span
38  // depends on whether the extent is dynamic or not. For static
39  // extents (e.g., std::span<int, 9>):
40  //
41  // (std::__1::span<const int, 9>) s = {
42  // __data = 0x000000016fdff494
43  // }
44  //
45  // For dynamic extents, e.g., std::span<int>, the layout is:
46  //
47  // (std::__1::span<const int, 18446744073709551615>) s = {
48  // __data = 0x000000016fdff494
49  // __size = 6
50  // }
51  //
52  // This function checks for a '__size' member to determine the number
53  // of elements in the span. If no such member exists, we get the size
54  // from the only other place it can be: the template argument.
55  bool Update() override;
56 
57  bool MightHaveChildren() override;
58 
59  size_t GetIndexOfChildWithName(ConstString name) override;
60 
61 private:
62  ValueObject *m_start = nullptr; ///< First element of span. Held, not owned.
63  CompilerType m_element_type{}; ///< Type of span elements.
64  size_t m_num_elements = 0; ///< Number of elements in span.
65  uint32_t m_element_size = 0; ///< Size in bytes of each span element.
66 };
67 
69  LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
70  : SyntheticChildrenFrontEnd(*valobj_sp) {
71  if (valobj_sp)
72  Update();
73 }
74 
77  return m_num_elements;
78 }
79 
80 lldb::ValueObjectSP
82  size_t idx) {
83  if (!m_start)
84  return {};
85 
86  uint64_t offset = idx * m_element_size;
87  offset = offset + m_start->GetValueAsUnsigned(0);
88  StreamString name;
89  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
90  return CreateValueObjectFromAddress(name.GetString(), offset,
91  m_backend.GetExecutionContextRef(),
92  m_element_type);
93 }
94 
96  // Get element type.
97  ValueObjectSP data_type_finder_sp(
98  m_backend.GetChildMemberWithName(ConstString("__data"), true));
99  if (!data_type_finder_sp)
100  return false;
101 
102  m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
103 
104  // Get element size.
105  if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) {
106  m_element_size = *size;
107 
108  // Get data.
109  if (m_element_size > 0) {
110  m_start = data_type_finder_sp.get();
111  }
112 
113  // Get number of elements.
114  if (auto size_sp =
115  m_backend.GetChildMemberWithName(ConstString("__size"), true)) {
116  m_num_elements = size_sp->GetValueAsUnsigned(0);
117  } else if (auto arg =
118  m_backend.GetCompilerType().GetIntegralTemplateArgument(1)) {
119 
120  m_num_elements = arg->value.getLimitedValue();
121  }
122  }
123 
124  return true;
125 }
126 
129  return true;
130 }
131 
134  if (!m_start)
135  return UINT32_MAX;
136  return ExtractIndexFromString(name.GetCString());
137 }
138 
141  lldb::ValueObjectSP valobj_sp) {
142  if (!valobj_sp)
143  return nullptr;
144  CompilerType type = valobj_sp->GetCompilerType();
145  if (!type.IsValid() || type.GetNumTemplateArguments() != 2)
146  return nullptr;
147  return new LibcxxStdSpanSyntheticFrontEnd(valobj_sp);
148 }
149 
150 } // namespace formatters
151 } // namespace lldb_private
lldb_private::CompilerType::GetNumTemplateArguments
size_t GetNumTemplateArguments() const
Definition: CompilerType.cpp:662
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd
Definition: LibCxxSpan.cpp:23
CalculateNumChildren
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:169
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::Update
bool Update() override
Determines properties of the std::span<> associated with this object.
Definition: LibCxxSpan.cpp:95
lldb_private::SyntheticChildrenFrontEnd
Definition: TypeSynthetic.h:27
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::GetIndexOfChildWithName
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibCxxSpan.cpp:133
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::CompilerType::IsValid
bool IsValid() const
Definition: CompilerType.h:72
ValueObject.h
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator
SyntheticChildrenFrontEnd * LibcxxStdSpanSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxSpan.cpp:140
uint32_t
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::MightHaveChildren
bool MightHaveChildren() override
Definition: LibCxxSpan.cpp:128
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::formatters
Definition: CXXFunctionPointer.h:15
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::CalculateNumChildren
size_t CalculateNumChildren() override
Definition: LibCxxSpan.cpp:76
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
LibCxx.h
ConstString.h
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::LibcxxStdSpanSyntheticFrontEnd
LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: LibCxxSpan.cpp:69
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::GetChildAtIndex
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibCxxSpan.cpp:81
lldb_private::CXXSyntheticChildren
Definition: TypeSynthetic.h:358
FormattersHelpers.h
lldb
Definition: SBAddress.h:15
lldb_private::formatters::ExtractIndexFromString
size_t ExtractIndexFromString(const char *item_name)
Definition: FormattersHelpers.cpp:119