1 //===-- LibCxxUnorderedMap.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
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"
23 using namespace lldb_private;
24 using namespace lldb_private::formatters;
26 namespace lldb_private {
27 namespace formatters {
28 class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
31 LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
34 CalculateNumChildren ();
36 virtual lldb::ValueObjectSP
37 GetChildAtIndex (size_t idx);
46 GetIndexOfChildWithName (const ConstString &name);
49 ~LibcxxStdUnorderedMapSyntheticFrontEnd ();
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;
61 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
62 SyntheticChildrenFrontEnd(*valobj_sp.get()),
65 m_next_element(nullptr),
74 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
76 if (m_num_elements != UINT32_MAX)
77 return m_num_elements;
82 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
84 if (idx >= CalculateNumChildren())
85 return lldb::ValueObjectSP();
87 return lldb::ValueObjectSP();
89 auto cached = m_children.find(idx);
90 if (cached != m_children.end())
91 return cached->second;
93 while (idx >= m_elements_cache.size())
95 if (m_next_element == nullptr)
96 return lldb::ValueObjectSP();
99 ValueObjectSP node_sp = m_next_element->Dereference(error);
100 if (!node_sp || error.Fail())
101 return lldb::ValueObjectSP();
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;
113 std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
115 return lldb::ValueObjectSP();
117 stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
120 val_hash.first->GetData(data, error);
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(),
128 val_hash.first->GetClangType());
132 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
134 m_num_elements = UINT32_MAX;
135 m_next_element = nullptr;
136 m_elements_cache.clear();
138 ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
141 ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
142 if (!num_elements_sp)
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();
152 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
158 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
160 return ExtractIndexFromString(name.GetCString());
163 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::~LibcxxStdUnorderedMapSyntheticFrontEnd ()
166 SyntheticChildrenFrontEnd*
167 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
171 return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));