180814287SRaphael Isemann //===-- LibCxxInitializerList.cpp -----------------------------------------===//
233e97e63SEnrico Granata //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
633e97e63SEnrico Granata //
733e97e63SEnrico Granata //===----------------------------------------------------------------------===//
833e97e63SEnrico Granata 
933e97e63SEnrico Granata #include "LibCxx.h"
1033e97e63SEnrico Granata 
1133e97e63SEnrico Granata #include "lldb/Core/ValueObject.h"
1233e97e63SEnrico Granata #include "lldb/DataFormatters/FormattersHelpers.h"
13bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h"
1433e97e63SEnrico Granata 
1533e97e63SEnrico Granata using namespace lldb;
1633e97e63SEnrico Granata using namespace lldb_private;
1733e97e63SEnrico Granata using namespace lldb_private::formatters;
1833e97e63SEnrico Granata 
1933e97e63SEnrico Granata namespace lldb_private {
2033e97e63SEnrico Granata namespace formatters {
21b9c1b51eSKate Stone class LibcxxInitializerListSyntheticFrontEnd
22b9c1b51eSKate Stone     : public SyntheticChildrenFrontEnd {
2333e97e63SEnrico Granata public:
2433e97e63SEnrico Granata   LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
2533e97e63SEnrico Granata 
268d15f33bSEugene Zelenko   ~LibcxxInitializerListSyntheticFrontEnd() override;
2733e97e63SEnrico Granata 
28b9c1b51eSKate Stone   size_t CalculateNumChildren() override;
2933e97e63SEnrico Granata 
30b9c1b51eSKate Stone   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
3133e97e63SEnrico Granata 
32b9c1b51eSKate Stone   bool Update() override;
3333e97e63SEnrico Granata 
34b9c1b51eSKate Stone   bool MightHaveChildren() override;
3533e97e63SEnrico Granata 
360e4c4821SAdrian Prantl   size_t GetIndexOfChildWithName(ConstString name) override;
378d15f33bSEugene Zelenko 
3833e97e63SEnrico Granata private:
39*28c878aeSShafik Yaghmour   ValueObject *m_start = nullptr;
4033e97e63SEnrico Granata   CompilerType m_element_type;
41*28c878aeSShafik Yaghmour   uint32_t m_element_size = 0;
42*28c878aeSShafik Yaghmour   size_t m_num_elements = 0;
4333e97e63SEnrico Granata };
448d15f33bSEugene Zelenko } // namespace formatters
458d15f33bSEugene Zelenko } // namespace lldb_private
4633e97e63SEnrico Granata 
47b9c1b51eSKate Stone lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)48b9c1b51eSKate Stone     LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
49*28c878aeSShafik Yaghmour     : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
5033e97e63SEnrico Granata   if (valobj_sp)
5133e97e63SEnrico Granata     Update();
5233e97e63SEnrico Granata }
5333e97e63SEnrico Granata 
54b9c1b51eSKate Stone lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
~LibcxxInitializerListSyntheticFrontEnd()55b9c1b51eSKate Stone     ~LibcxxInitializerListSyntheticFrontEnd() {
56b9c1b51eSKate Stone   // this needs to stay around because it's a child object who will follow its
57b9c1b51eSKate Stone   // parent's life cycle
588d15f33bSEugene Zelenko   // delete m_start;
598d15f33bSEugene Zelenko }
608d15f33bSEugene Zelenko 
61b9c1b51eSKate Stone size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
CalculateNumChildren()62b9c1b51eSKate Stone     CalculateNumChildren() {
6380a11e08SShafik Yaghmour   static ConstString g_size_("__size_");
6433e97e63SEnrico Granata   m_num_elements = 0;
6580a11e08SShafik Yaghmour   ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g_size_, true));
6633e97e63SEnrico Granata   if (size_sp)
6733e97e63SEnrico Granata     m_num_elements = size_sp->GetValueAsUnsigned(0);
6833e97e63SEnrico Granata   return m_num_elements;
6933e97e63SEnrico Granata }
7033e97e63SEnrico Granata 
71b9c1b51eSKate Stone lldb::ValueObjectSP lldb_private::formatters::
GetChildAtIndex(size_t idx)72b9c1b51eSKate Stone     LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
7333e97e63SEnrico Granata   if (!m_start)
7433e97e63SEnrico Granata     return lldb::ValueObjectSP();
7533e97e63SEnrico Granata 
7633e97e63SEnrico Granata   uint64_t offset = idx * m_element_size;
7733e97e63SEnrico Granata   offset = offset + m_start->GetValueAsUnsigned(0);
7833e97e63SEnrico Granata   StreamString name;
7933e97e63SEnrico Granata   name.Printf("[%" PRIu64 "]", (uint64_t)idx);
80c156427dSZachary Turner   return CreateValueObjectFromAddress(name.GetString(), offset,
81b9c1b51eSKate Stone                                       m_backend.GetExecutionContextRef(),
82b9c1b51eSKate Stone                                       m_element_type);
8333e97e63SEnrico Granata }
8433e97e63SEnrico Granata 
85b9c1b51eSKate Stone bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
Update()86b9c1b51eSKate Stone     Update() {
8780a11e08SShafik Yaghmour   static ConstString g_begin_("__begin_");
8833e97e63SEnrico Granata 
8933e97e63SEnrico Granata   m_start = nullptr;
9033e97e63SEnrico Granata   m_num_elements = 0;
91769b21eaSPavel Labath   m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
92769b21eaSPavel Labath   if (!m_element_type.IsValid())
9333e97e63SEnrico Granata     return false;
9433e97e63SEnrico Granata 
95d6a9bbf6SAdrian Prantl   if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) {
96d963a7c3SAdrian Prantl     m_element_size = *size;
97d963a7c3SAdrian Prantl     // Store raw pointers or end up with a circular dependency.
9880a11e08SShafik Yaghmour     m_start = m_backend.GetChildMemberWithName(g_begin_, true).get();
99d963a7c3SAdrian Prantl   }
10033e97e63SEnrico Granata 
10133e97e63SEnrico Granata   return false;
10233e97e63SEnrico Granata }
10333e97e63SEnrico Granata 
104b9c1b51eSKate Stone bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
MightHaveChildren()105b9c1b51eSKate Stone     MightHaveChildren() {
10633e97e63SEnrico Granata   return true;
10733e97e63SEnrico Granata }
10833e97e63SEnrico Granata 
109b9c1b51eSKate Stone size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name)1100e4c4821SAdrian Prantl     GetIndexOfChildWithName(ConstString name) {
11133e97e63SEnrico Granata   if (!m_start)
11233e97e63SEnrico Granata     return UINT32_MAX;
11333e97e63SEnrico Granata   return ExtractIndexFromString(name.GetCString());
11433e97e63SEnrico Granata }
11533e97e63SEnrico Granata 
11633e97e63SEnrico Granata lldb_private::SyntheticChildrenFrontEnd *
LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)117b9c1b51eSKate Stone lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator(
118b9c1b51eSKate Stone     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
119b9c1b51eSKate Stone   return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp)
120b9c1b51eSKate Stone                     : nullptr);
12133e97e63SEnrico Granata }
122