1cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//===-- LibCxxList.cpp -------------------------------------------*- C++ -*-===//
2cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//
3cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//                     The LLVM Compiler Infrastructure
4cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//
5cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata// This file is distributed under the University of Illinois Open Source
6cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata// License. See LICENSE.TXT for details.
7cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//
8cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata//===----------------------------------------------------------------------===//
9cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
10884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec#include "lldb/lldb-python.h"
11884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec
12cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/DataFormatters/CXXFormatterFunctions.h"
13cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
14cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Core/DataBufferHeap.h"
15cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Core/Error.h"
16cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Core/Stream.h"
17cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Core/ValueObject.h"
18cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Core/ValueObjectConstResult.h"
19cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Host/Endian.h"
20cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Symbol/ClangASTContext.h"
21cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Target/ObjCLanguageRuntime.h"
22cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata#include "lldb/Target/Target.h"
23cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
24cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatausing namespace lldb;
25cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatausing namespace lldb_private;
26cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatausing namespace lldb_private::formatters;
27cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
28cc5d27417b9f958d596a438290a9adb17674b487Enrico Granataclass MapEntry
29cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
30cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatapublic:
31cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapEntry () {}
32cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
33cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapEntry (const MapEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
34cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
35cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
36cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
37cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    left ()
38cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
39cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (!m_entry_sp)
40cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return m_entry_sp;
41cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry_sp->GetChildMemberWithName(ConstString("__left_"), true);
42cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
43cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
44cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
45cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    right ()
46cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
47cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (!m_entry_sp)
48cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return m_entry_sp;
49cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry_sp->GetChildMemberWithName(ConstString("__right_"), true);
50cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
51cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
52cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
53cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    parent ()
54cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
55cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (!m_entry_sp)
56cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return m_entry_sp;
57cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry_sp->GetChildMemberWithName(ConstString("__parent_"), true);
58cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
59cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
60cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    uint64_t
61cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    value ()
62cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
63cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (!m_entry_sp)
64cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return 0;
65cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry_sp->GetValueAsUnsigned(0);
66cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
67cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
68cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    bool
69c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    error ()
70c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    {
7101400dc75cddb838e04c4cb898ac137677ec9cb6Enrico Granata        if (!m_entry_sp)
7201400dc75cddb838e04c4cb898ac137677ec9cb6Enrico Granata            return true;
73c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata        return m_entry_sp->GetError().Fail();
74c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    }
75c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata
76c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    bool
77cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    null()
78cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
79cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return (value() == 0);
80cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
81cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
82cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
83cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    GetEntry ()
84cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
85cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry_sp;
86cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
87cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
88cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    void
89cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    SetEntry (ValueObjectSP entry)
90cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
91cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        m_entry_sp = entry;
92cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
93cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
94cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    bool
95cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    operator == (const MapEntry& rhs) const
96cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
97cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return (rhs.m_entry_sp.get() == m_entry_sp.get());
98cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
99cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
100cc5d27417b9f958d596a438290a9adb17674b487Enrico Granataprivate:
101cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP m_entry_sp;
102cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata};
103cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
104cc5d27417b9f958d596a438290a9adb17674b487Enrico Granataclass MapIterator
105cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
106cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatapublic:
107cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapIterator () {}
108c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    MapIterator (MapEntry entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
109c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    MapIterator (ValueObjectSP entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
110c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    MapIterator (const MapIterator& rhs) : m_entry(rhs.m_entry),m_max_depth(rhs.m_max_depth), m_error(false) {}
111c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    MapIterator (ValueObject* entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
112cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
113cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
114cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    value ()
115cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
116cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry.GetEntry();
117cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
118cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
119cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
120cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    advance (size_t count)
121cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
122c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata        if (m_error)
123c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            return lldb::ValueObjectSP();
124cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (count == 0)
125cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return m_entry.GetEntry();
126cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (count == 1)
127cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
128cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            next ();
129cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return m_entry.GetEntry();
130cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
131cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        size_t steps = 0;
132cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        while (count > 0)
133cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
134c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            if (m_error)
135c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                return lldb::ValueObjectSP();
136cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            next ();
137cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            count--;
138cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (m_entry.null())
139cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
140cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            steps++;
141cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (steps > m_max_depth)
142cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
143cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
144cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_entry.GetEntry();
145cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
146cc5d27417b9f958d596a438290a9adb17674b487Enrico Granataprotected:
147cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    void
148cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    next ()
149cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
150cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        m_entry.SetEntry(increment(m_entry.GetEntry()));
151cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
152cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
153cc5d27417b9f958d596a438290a9adb17674b487Enrico Granataprivate:
154cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
155cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    tree_min (ValueObjectSP x_sp)
156cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
157cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry x(x_sp);
158cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (x.null())
159cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return ValueObjectSP();
160cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry left(x.left());
161cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        size_t steps = 0;
162cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        while (left.null() == false)
163cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
164c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            if (left.error())
165c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            {
166c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                m_error = true;
167c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                return lldb::ValueObjectSP();
168c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            }
169cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            x.SetEntry(left.GetEntry());
170cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            left.SetEntry(x.left());
171cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            steps++;
172cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (steps > m_max_depth)
173cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
174cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
175cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return x.GetEntry();
176cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
177cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
178cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
179cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    tree_max (ValueObjectSP x_sp)
180cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
181cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry x(x_sp);
182cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (x.null())
183cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return ValueObjectSP();
184cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry right(x.right());
185cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        size_t steps = 0;
186cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        while (right.null() == false)
187cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
188c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            if (right.error())
189c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                return lldb::ValueObjectSP();
190cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            x.SetEntry(right.GetEntry());
191cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            right.SetEntry(x.right());
192cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            steps++;
193cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (steps > m_max_depth)
194cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
195cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
196cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return x.GetEntry();
197cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
198cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
199cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    bool
200cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    is_left_child (ValueObjectSP x_sp)
201cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
202cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry x(x_sp);
203cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (x.null())
204cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return false;
205cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry rhs(x.parent());
206cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        rhs.SetEntry(rhs.left());
207cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return x.value() == rhs.value();
208cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
209cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
210cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP
211cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    increment (ValueObjectSP x_sp)
212cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
213cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry node(x_sp);
214cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (node.null())
215cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return ValueObjectSP();
216cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        MapEntry right(node.right());
217cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (right.null() == false)
218cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            return tree_min(right.GetEntry());
219cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        size_t steps = 0;
220cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        while (!is_left_child(node.GetEntry()))
221cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
222c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            if (node.error())
223c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            {
224c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                m_error = true;
225c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata                return lldb::ValueObjectSP();
226c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata            }
227cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            node.SetEntry(node.parent());
228cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            steps++;
229cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (steps > m_max_depth)
230cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
231cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
232cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return node.parent();
233cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
234cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
235cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapEntry m_entry;
236cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    size_t m_max_depth;
237c881c1d5bbaee9b985cf52f5d32291f1344133e9Enrico Granata    bool m_error;
238cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata};
239cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
240cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
241cc5d27417b9f958d596a438290a9adb17674b487Enrico GranataSyntheticChildrenFrontEnd(*valobj_sp.get()),
242cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_tree(NULL),
243cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_root_node(NULL),
244cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_element_type(),
245cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_skip_size(UINT32_MAX),
246cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_count(UINT32_MAX),
247cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatam_children()
248cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
249cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (valobj_sp)
250cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        Update();
251cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
252cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
253cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatasize_t
254cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren ()
255cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
256cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (m_count != UINT32_MAX)
257cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return m_count;
258cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (m_tree == NULL)
259cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return 0;
260cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP m_item(m_tree->GetChildMemberWithName(ConstString("__pair3_"), true));
261cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!m_item)
262cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return 0;
263cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_item = m_item->GetChildMemberWithName(ConstString("__first_"), true);
264cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!m_item)
265cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return 0;
266cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_count = m_item->GetValueAsUnsigned(0);
267cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return m_count;
268cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
269cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
270cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatabool
271cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
272cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
273cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (m_element_type.GetOpaqueQualType() && m_element_type.GetASTContext())
274cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return true;
275cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_element_type.Clear();
276cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP deref;
277cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    Error error;
278cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    deref = m_root_node->Dereference(error);
279cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!deref || error.Fail())
280cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return false;
281cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    deref = deref->GetChildMemberWithName(ConstString("__value_"), true);
282cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!deref)
283cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return false;
28452f792329be5db8e38961350589e97e8f2823acdGreg Clayton    m_element_type = deref->GetClangType();
285cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return true;
286cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
287cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
288cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatavoid
289cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const lldb::ValueObjectSP& node)
290cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
291cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (m_skip_size != UINT32_MAX)
292cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return;
293cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!node)
294cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return;
29552f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType node_type(node->GetClangType());
296cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    uint64_t bit_offset;
29752f792329be5db8e38961350589e97e8f2823acdGreg Clayton    if (node_type.GetIndexOfFieldWithName("__value_", NULL, &bit_offset) == UINT32_MAX)
298cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return;
299cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_skip_size = bit_offset / 8u;
300cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
301cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
302cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb::ValueObjectSP
303cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
304cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
305cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (idx >= CalculateNumChildren())
306cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return lldb::ValueObjectSP();
307cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (m_tree == NULL || m_root_node == NULL)
308cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return lldb::ValueObjectSP();
309cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
310cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    auto cached = m_children.find(idx);
311cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (cached != m_children.end())
312cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return cached->second;
313cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
314cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    bool need_to_skip = (idx > 0);
315cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    MapIterator iterator(m_root_node, CalculateNumChildren());
316cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    ValueObjectSP iterated_sp(iterator.advance(idx));
317cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (iterated_sp.get() == NULL)
318cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
319cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        // this tree is garbage - stop
320cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        m_tree = NULL; // this will stop all future searches until an Update() happens
321cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return iterated_sp;
322cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
323cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (GetDataType())
324cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
325cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        if (!need_to_skip)
326cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
327cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            Error error;
328cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            iterated_sp = iterated_sp->Dereference(error);
329cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (!iterated_sp || error.Fail())
330cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            {
331cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                m_tree = NULL;
332cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
333cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            }
334cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            GetValueOffset(iterated_sp);
335cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            iterated_sp = iterated_sp->GetChildMemberWithName(ConstString("__value_"), true);
336cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (!iterated_sp)
337cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            {
338cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                m_tree = NULL;
339cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
340cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            }
341cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
342cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        else
343cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        {
344cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            // because of the way our debug info is made, we need to read item 0 first
345cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            // so that we can cache information used to generate other elements
346cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (m_skip_size == UINT32_MAX)
347cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                GetChildAtIndex(0);
348cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (m_skip_size == UINT32_MAX)
349cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            {
350cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                m_tree = NULL;
351cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
352cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            }
353cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true);
354cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            if (!iterated_sp)
355cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            {
356cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                m_tree = NULL;
357cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata                return lldb::ValueObjectSP();
358cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata            }
359cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        }
360cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
361cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    else
362cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    {
363cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        m_tree = NULL;
364cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return lldb::ValueObjectSP();
365cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    }
366cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    // at this point we have a valid
367cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
368cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    DataExtractor data;
369cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    iterated_sp->GetData(data);
370cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    StreamString name;
371cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    name.Printf("[%zu]",idx);
372cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return (m_children[idx] = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
373cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
374cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
375cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatabool
376cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update()
377cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
378cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_count = UINT32_MAX;
379cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_tree = m_root_node = NULL;
380cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_children.clear();
381cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_tree = m_backend.GetChildMemberWithName(ConstString("__tree_"), true).get();
382cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!m_tree)
383884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec        return false;
384cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    m_root_node = m_tree->GetChildMemberWithName(ConstString("__begin_node_"), true).get();
385cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return false;
386cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
387cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
388cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatabool
389cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::MightHaveChildren ()
390cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
391cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return true;
392cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
393cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
394cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatasize_t
395cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
396cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
397cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return ExtractIndexFromString(name.GetCString());
398cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
399cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
400cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::~LibcxxStdMapSyntheticFrontEnd ()
401cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{}
402cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata
403cc5d27417b9f958d596a438290a9adb17674b487Enrico GranataSyntheticChildrenFrontEnd*
404cc5d27417b9f958d596a438290a9adb17674b487Enrico Granatalldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
405cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata{
406cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    if (!valobj_sp)
407cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata        return NULL;
408cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata    return (new LibcxxStdMapSyntheticFrontEnd(valobj_sp));
409cc5d27417b9f958d596a438290a9adb17674b487Enrico Granata}
410