]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/LibCxxUnorderedMap.cpp
Update llvm/clang to r241361.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / LibCxxUnorderedMap.cpp
1 //===-- LibCxxUnorderedMap.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
10 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
11
12 #include "lldb/Core/DataBufferHeap.h"
13 #include "lldb/Core/Error.h"
14 #include "lldb/Core/Stream.h"
15 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/Host/Endian.h"
18 #include "lldb/Symbol/ClangASTContext.h"
19 #include "lldb/Target/ObjCLanguageRuntime.h"
20 #include "lldb/Target/Target.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24 using namespace lldb_private::formatters;
25
26 namespace lldb_private {
27     namespace formatters {
28         class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
29         {
30         public:
31             LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
32             
33             virtual size_t
34             CalculateNumChildren ();
35             
36             virtual lldb::ValueObjectSP
37             GetChildAtIndex (size_t idx);
38             
39             virtual bool
40             Update();
41             
42             virtual bool
43             MightHaveChildren ();
44             
45             virtual size_t
46             GetIndexOfChildWithName (const ConstString &name);
47             
48             virtual
49             ~LibcxxStdUnorderedMapSyntheticFrontEnd ();
50         private:
51             
52             ValueObject* m_tree;
53             size_t m_num_elements;
54             ValueObject* m_next_element;
55             std::map<size_t,lldb::ValueObjectSP> m_children;
56             std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache;
57         };
58     }
59 }
60
61 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
62 SyntheticChildrenFrontEnd(*valobj_sp.get()),
63 m_tree(NULL),
64 m_num_elements(0),
65 m_next_element(nullptr),
66 m_children(),
67 m_elements_cache()
68 {
69     if (valobj_sp)
70         Update();
71 }
72
73 size_t
74 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
75 {
76     if (m_num_elements != UINT32_MAX)
77         return m_num_elements;
78     return 0;
79 }
80
81 lldb::ValueObjectSP
82 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
83 {
84     if (idx >= CalculateNumChildren())
85         return lldb::ValueObjectSP();
86     if (m_tree == NULL)
87         return lldb::ValueObjectSP();
88     
89     auto cached = m_children.find(idx);
90     if (cached != m_children.end())
91         return cached->second;
92     
93     while (idx >= m_elements_cache.size())
94     {
95         if (m_next_element == nullptr)
96             return lldb::ValueObjectSP();
97         
98         Error error;
99         ValueObjectSP node_sp = m_next_element->Dereference(error);
100         if (!node_sp || error.Fail())
101             return lldb::ValueObjectSP();
102         
103         ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
104         ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
105         if (!hash_sp || !value_sp)
106             return lldb::ValueObjectSP();
107         m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)});
108         m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get();
109         if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
110             m_next_element = nullptr;
111     }
112     
113     std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
114     if (!val_hash.first)
115         return lldb::ValueObjectSP();
116     StreamString stream;
117     stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
118     DataExtractor data;
119     Error error;
120     val_hash.first->GetData(data, error);
121     if (error.Fail())
122         return lldb::ValueObjectSP();
123     const bool thread_and_frame_only_if_stopped = true;
124     ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
125     return val_hash.first->CreateValueObjectFromData(stream.GetData(),
126                                                      data,
127                                                      exe_ctx,
128                                                      val_hash.first->GetClangType());
129 }
130
131 bool
132 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
133 {
134     m_num_elements = UINT32_MAX;
135     m_next_element = nullptr;
136     m_elements_cache.clear();
137     m_children.clear();
138     ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
139     if (!table_sp)
140         return false;
141     ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
142     if (!num_elements_sp)
143         return false;
144     m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
145     m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
146     if (m_num_elements > 0)
147         m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
148     return false;
149 }
150
151 bool
152 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
153 {
154     return true;
155 }
156
157 size_t
158 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
159 {
160     return ExtractIndexFromString(name.GetCString());
161 }
162
163 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::~LibcxxStdUnorderedMapSyntheticFrontEnd ()
164 {}
165
166 SyntheticChildrenFrontEnd*
167 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
168 {
169     if (!valobj_sp)
170         return NULL;
171     return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));
172 }