blob: 0dcef981e5e5cb2cc5d8756288a75ca102fc95a1 [file] [log] [blame]
Enrico Granatae85fe3a2014-10-22 20:34:38 +00001//===-- LibCxxInitializerList.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
Enrico Granatae85fe3a2014-10-22 20:34:38 +000010#include "lldb/DataFormatters/CXXFormatterFunctions.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/ValueObject.h"
14
15using namespace lldb;
16using namespace lldb_private;
17using namespace lldb_private::formatters;
18
19namespace lldb_private {
20 namespace formatters {
21 class LibcxxInitializerListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
22 {
23 public:
24 LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
25
26 virtual size_t
27 CalculateNumChildren ();
28
29 virtual lldb::ValueObjectSP
30 GetChildAtIndex (size_t idx);
31
32 virtual bool
33 Update();
34
35 virtual bool
36 MightHaveChildren ();
37
38 virtual size_t
39 GetIndexOfChildWithName (const ConstString &name);
40
41 virtual
42 ~LibcxxInitializerListSyntheticFrontEnd ();
43 private:
44 ValueObject* m_start;
45 ClangASTType m_element_type;
46 uint32_t m_element_size;
47 size_t m_num_elements;
48 std::map<size_t,lldb::ValueObjectSP> m_children;
49 };
50 }
51}
52
53lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
54SyntheticChildrenFrontEnd(*valobj_sp.get()),
55m_start(NULL),
56m_element_type(),
57m_element_size(0),
58m_num_elements(0),
59m_children()
60{
61 if (valobj_sp)
62 Update();
63}
64
65size_t
66lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::CalculateNumChildren ()
67{
68 static ConstString g___size_("__size_");
69 m_num_elements = 0;
70 ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true));
71 if (size_sp)
72 m_num_elements = size_sp->GetValueAsUnsigned(0);
73 return m_num_elements;
74}
75
76lldb::ValueObjectSP
77lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex (size_t idx)
78{
79 if (!m_start)
80 return lldb::ValueObjectSP();
81
82 auto cached = m_children.find(idx);
83 if (cached != m_children.end())
84 return cached->second;
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);
Enrico Granatae29df232014-12-09 19:51:20 +000090 ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
Enrico Granatae85fe3a2014-10-22 20:34:38 +000091 m_children[idx] = child_sp;
92 return child_sp;
93}
94
95bool
96lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update()
97{
98 static ConstString g___begin_("__begin_");
99
100 m_start = nullptr;
101 m_num_elements = 0;
102 m_children.clear();
103 lldb::TemplateArgumentKind kind;
104 m_element_type = m_backend.GetClangType().GetTemplateArgument(0, kind);
105 if (kind != lldb::eTemplateArgumentKindType || false == m_element_type.IsValid())
106 return false;
107
Enrico Granata1cd5e922015-01-28 00:07:51 +0000108 m_element_size = m_element_type.GetByteSize(nullptr);
Enrico Granatae85fe3a2014-10-22 20:34:38 +0000109
110 if (m_element_size > 0)
111 m_start = m_backend.GetChildMemberWithName(g___begin_,true).get(); // store raw pointers or end up with a circular dependency
112
113 return false;
114}
115
116bool
117lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::MightHaveChildren ()
118{
119 return true;
120}
121
122size_t
123lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
124{
125 if (!m_start)
126 return UINT32_MAX;
127 return ExtractIndexFromString(name.GetCString());
128}
129
130lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::~LibcxxInitializerListSyntheticFrontEnd ()
131{
132 // this needs to stay around because it's a child object who will follow its parent's life cycle
133 // delete m_start;
134}
135
136lldb_private::SyntheticChildrenFrontEnd*
137lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
138{
139 if (!valobj_sp)
140 return NULL;
141 return (new LibcxxInitializerListSyntheticFrontEnd(valobj_sp));
142}
143