LibCxxUnorderedMap.cpp revision 269024
1139823Simp//===-- LibCxxUnorderedMap.cpp -----------------------------------*- C++ -*-===//
21541Srgrimes//
31541Srgrimes//                     The LLVM Compiler Infrastructure
4137668Smlaier//
51541Srgrimes// This file is distributed under the University of Illinois Open Source
61541Srgrimes// License. See LICENSE.TXT for details.
71541Srgrimes//
81541Srgrimes//===----------------------------------------------------------------------===//
91541Srgrimes
101541Srgrimes#include "lldb/lldb-python.h"
111541Srgrimes
121541Srgrimes#include "lldb/DataFormatters/CXXFormatterFunctions.h"
131541Srgrimes
141541Srgrimes#include "lldb/Core/DataBufferHeap.h"
151541Srgrimes#include "lldb/Core/Error.h"
161541Srgrimes#include "lldb/Core/Stream.h"
171541Srgrimes#include "lldb/Core/ValueObject.h"
181541Srgrimes#include "lldb/Core/ValueObjectConstResult.h"
191541Srgrimes#include "lldb/Host/Endian.h"
201541Srgrimes#include "lldb/Symbol/ClangASTContext.h"
211541Srgrimes#include "lldb/Target/ObjCLanguageRuntime.h"
221541Srgrimes#include "lldb/Target/Target.h"
231541Srgrimes
241541Srgrimesusing namespace lldb;
251541Srgrimesusing namespace lldb_private;
261541Srgrimesusing namespace lldb_private::formatters;
271541Srgrimes
281541Srgrimeslldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
291541SrgrimesSyntheticChildrenFrontEnd(*valobj_sp.get()),
3010939Swollmanm_tree(NULL),
3150477Speterm_num_elements(0),
321541Srgrimesm_next_element(nullptr),
331541Srgrimesm_children(),
34143868Sglebiusm_elements_cache()
35143868Sglebius{
361541Srgrimes    if (valobj_sp)
371549Srgrimes        Update();
3824204Sbde}
391541Srgrimes
401541Srgrimessize_t
4112704Sphklldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
4212704Sphk{
431541Srgrimes    if (m_num_elements != UINT32_MAX)
441541Srgrimes        return m_num_elements;
4555009Sshin    return 0;
461541Srgrimes}
471541Srgrimes
481541Srgrimeslldb::ValueObjectSP
491541Srgrimeslldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
5081127Sume{
511541Srgrimes    if (idx >= CalculateNumChildren())
526363Sphk        return lldb::ValueObjectSP();
536363Sphk    if (m_tree == NULL)
5430354Sphk        return lldb::ValueObjectSP();
5530309Sphk
5692723Salfred    auto cached = m_children.find(idx);
5792723Salfred    if (cached != m_children.end())
5892723Salfred        return cached->second;
5992723Salfred
6055009Sshin    while (idx >= m_elements_cache.size())
61137628Smlaier    {
62137628Smlaier        if (m_next_element == nullptr)
6392723Salfred            return lldb::ValueObjectSP();
6492723Salfred
6592723Salfred        Error error;
661541Srgrimes        ValueObjectSP node_sp = m_next_element->Dereference(error);
6718193Swollman        if (!node_sp || error.Fail())
68133874Srwatson            return lldb::ValueObjectSP();
69123998Sru
70149221Sglebius        ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
71149221Sglebius        ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
72149221Sglebius        if (!hash_sp || !value_sp)
73149221Sglebius            return lldb::ValueObjectSP();
7421666Swollman        m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)});
75148682Srwatson        m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get();
76148682Srwatson        if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
77148682Srwatson            m_next_element = nullptr;
78148682Srwatson    }
79148682Srwatson
80148682Srwatson    std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
81148682Srwatson    if (!val_hash.first)
8221666Swollman        return lldb::ValueObjectSP();
83148682Srwatson    StreamString stream;
84148682Srwatson    stream.Printf("[%zu]",idx);
8521666Swollman    DataExtractor data;
8681127Sume    val_hash.first->GetData(data);
8781127Sume    const bool thread_and_frame_only_if_stopped = true;
8881127Sume    ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
891541Srgrimes    return val_hash.first->CreateValueObjectFromData(stream.GetData(),
901541Srgrimes                                                     data,
911541Srgrimes                                                     exe_ctx,
921541Srgrimes                                                     val_hash.first->GetClangType());
931541Srgrimes}
941541Srgrimes
951549Srgrimesbool
961541Srgrimeslldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
971541Srgrimes{
981541Srgrimes    m_num_elements = UINT32_MAX;
991541Srgrimes    m_next_element = nullptr;
1001541Srgrimes    m_elements_cache.clear();
1011541Srgrimes    m_children.clear();
1021541Srgrimes    ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
10374362Sphk    if (!table_sp)
1041541Srgrimes        return false;
1051541Srgrimes    ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
1061541Srgrimes    if (!num_elements_sp)
10772012Sphk        return false;
1081541Srgrimes    m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
1091541Srgrimes    m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
1101541Srgrimes    if (m_num_elements > 0)
1111541Srgrimes        m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
1121541Srgrimes    return false;
1131541Srgrimes}
1141541Srgrimes
115133486Sandrebool
116133486Sandrelldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
117133486Sandre{
118133486Sandre    return true;
119133486Sandre}
120133486Sandre
121133486Sandresize_t
122133486Sandrelldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
123133486Sandre{
124133486Sandre    return ExtractIndexFromString(name.GetCString());
125133486Sandre}
126133486Sandre
127133486Sandrelldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::~LibcxxStdUnorderedMapSyntheticFrontEnd ()
128133486Sandre{}
129133486Sandre
130133486SandreSyntheticChildrenFrontEnd*
131133486Sandrelldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
1321541Srgrimes{
1331541Srgrimes    if (!valobj_sp)
1341541Srgrimes        return NULL;
1351541Srgrimes    return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));
1361549Srgrimes}
1371541Srgrimes