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