1254721Semaste//===-- LibStdcpp.cpp ---------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "lldb/DataFormatters/CXXFormatterFunctions.h" 13254721Semaste 14254721Semaste#include "lldb/Core/DataBufferHeap.h" 15254721Semaste#include "lldb/Core/Error.h" 16254721Semaste#include "lldb/Core/Stream.h" 17254721Semaste#include "lldb/Core/ValueObject.h" 18254721Semaste#include "lldb/Core/ValueObjectConstResult.h" 19254721Semaste#include "lldb/Host/Endian.h" 20254721Semaste#include "lldb/Symbol/ClangASTContext.h" 21254721Semaste#include "lldb/Target/ObjCLanguageRuntime.h" 22254721Semaste#include "lldb/Target/Target.h" 23254721Semaste 24254721Semasteusing namespace lldb; 25254721Semasteusing namespace lldb_private; 26254721Semasteusing namespace lldb_private::formatters; 27254721Semaste 28254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::LibstdcppVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 29254721SemasteSyntheticChildrenFrontEnd(*valobj_sp.get()), 30254721Semastem_exe_ctx_ref(), 31254721Semastem_count(0), 32254721Semastem_base_data_address(0), 33254721Semastem_options() 34254721Semaste{ 35254721Semaste if (valobj_sp) 36254721Semaste Update(); 37263367Semaste m_options.SetCoerceToId(false); 38263367Semaste m_options.SetUnwindOnError(true); 39263367Semaste m_options.SetKeepInMemory(true); 40263367Semaste m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); 41254721Semaste} 42254721Semaste 43254721Semastesize_t 44254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::CalculateNumChildren () 45254721Semaste{ 46254721Semaste return m_count; 47254721Semaste} 48254721Semaste 49254721Semastelldb::ValueObjectSP 50254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx) 51254721Semaste{ 52254721Semaste if (idx >= m_count) 53254721Semaste return ValueObjectSP(); 54254721Semaste if (m_base_data_address == 0 || m_count == 0) 55254721Semaste return ValueObjectSP(); 56254721Semaste size_t byte_idx = (idx >> 3); // divide by 8 to get byte index 57254721Semaste size_t bit_index = (idx & 7); // efficient idx % 8 for bit index 58254721Semaste lldb::addr_t byte_location = m_base_data_address + byte_idx; 59254721Semaste ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); 60254721Semaste if (!process_sp) 61254721Semaste return ValueObjectSP(); 62254721Semaste uint8_t byte = 0; 63254721Semaste uint8_t mask = 0; 64254721Semaste Error err; 65254721Semaste size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); 66254721Semaste if (err.Fail() || bytes_read == 0) 67254721Semaste return ValueObjectSP(); 68254721Semaste switch (bit_index) 69254721Semaste { 70254721Semaste case 0: 71254721Semaste mask = 1; break; 72254721Semaste case 1: 73254721Semaste mask = 2; break; 74254721Semaste case 2: 75254721Semaste mask = 4; break; 76254721Semaste case 3: 77254721Semaste mask = 8; break; 78254721Semaste case 4: 79254721Semaste mask = 16; break; 80254721Semaste case 5: 81254721Semaste mask = 32; break; 82254721Semaste case 6: 83254721Semaste mask = 64; break; 84254721Semaste case 7: 85254721Semaste mask = 128; break; 86254721Semaste default: 87254721Semaste return ValueObjectSP(); 88254721Semaste } 89254721Semaste bool bit_set = ((byte & mask) != 0); 90254721Semaste Target& target(process_sp->GetTarget()); 91254721Semaste ValueObjectSP retval_sp; 92254721Semaste if (bit_set) 93254721Semaste target.EvaluateExpression("(bool)true", NULL, retval_sp); 94254721Semaste else 95254721Semaste target.EvaluateExpression("(bool)false", NULL, retval_sp); 96254721Semaste StreamString name; name.Printf("[%zu]",idx); 97254721Semaste if (retval_sp) 98254721Semaste retval_sp->SetName(ConstString(name.GetData())); 99254721Semaste return retval_sp; 100254721Semaste} 101254721Semaste 102254721Semaste/*((std::vector<std::allocator<bool> >) vBool = { 103254721Semaste (std::_Bvector_base<std::allocator<bool> >) std::_Bvector_base<std::allocator<bool> > = { 104254721Semaste (std::_Bvector_base<std::allocator<bool> >::_Bvector_impl) _M_impl = { 105254721Semaste (std::_Bit_iterator) _M_start = { 106254721Semaste (std::_Bit_iterator_base) std::_Bit_iterator_base = { 107254721Semaste (_Bit_type *) _M_p = 0x0016b160 108254721Semaste (unsigned int) _M_offset = 0 109254721Semaste } 110254721Semaste } 111254721Semaste (std::_Bit_iterator) _M_finish = { 112254721Semaste (std::_Bit_iterator_base) std::_Bit_iterator_base = { 113254721Semaste (_Bit_type *) _M_p = 0x0016b16c 114254721Semaste (unsigned int) _M_offset = 16 115254721Semaste } 116254721Semaste } 117254721Semaste (_Bit_type *) _M_end_of_storage = 0x0016b170 118254721Semaste } 119254721Semaste } 120254721Semaste } 121254721Semaste */ 122254721Semaste 123254721Semastebool 124254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::Update() 125254721Semaste{ 126254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 127254721Semaste if (!valobj_sp) 128254721Semaste return false; 129254721Semaste if (!valobj_sp) 130254721Semaste return false; 131254721Semaste m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 132254721Semaste 133254721Semaste ValueObjectSP m_impl_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_impl"), true)); 134254721Semaste if (!m_impl_sp) 135254721Semaste return false; 136254721Semaste 137254721Semaste ValueObjectSP m_start_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_start"), true)); 138254721Semaste ValueObjectSP m_finish_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_finish"), true)); 139254721Semaste 140254721Semaste ValueObjectSP start_p_sp, finish_p_sp, finish_offset_sp; 141254721Semaste 142254721Semaste if (!m_start_sp || !m_finish_sp) 143254721Semaste return false; 144254721Semaste 145254721Semaste start_p_sp = m_start_sp->GetChildMemberWithName(ConstString("_M_p"), true); 146254721Semaste finish_p_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_p"), true); 147254721Semaste finish_offset_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_offset"), true); 148254721Semaste 149254721Semaste if (!start_p_sp || !finish_offset_sp || !finish_p_sp) 150254721Semaste return false; 151254721Semaste 152254721Semaste m_base_data_address = start_p_sp->GetValueAsUnsigned(0); 153254721Semaste if (!m_base_data_address) 154254721Semaste return false; 155254721Semaste 156254721Semaste lldb::addr_t end_data_address(finish_p_sp->GetValueAsUnsigned(0)); 157254721Semaste if (!end_data_address) 158254721Semaste return false; 159254721Semaste 160254721Semaste if (end_data_address < m_base_data_address) 161254721Semaste return false; 162254721Semaste else 163254721Semaste m_count = finish_offset_sp->GetValueAsUnsigned(0) + (end_data_address-m_base_data_address)*8; 164254721Semaste 165254721Semaste return true; 166254721Semaste} 167254721Semaste 168254721Semastebool 169254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::MightHaveChildren () 170254721Semaste{ 171254721Semaste return true; 172254721Semaste} 173254721Semaste 174254721Semastesize_t 175254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 176254721Semaste{ 177254721Semaste if (!m_count || !m_base_data_address) 178254721Semaste return UINT32_MAX; 179254721Semaste const char* item_name = name.GetCString(); 180254721Semaste uint32_t idx = ExtractIndexFromString(item_name); 181254721Semaste if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 182254721Semaste return UINT32_MAX; 183254721Semaste return idx; 184254721Semaste} 185254721Semaste 186254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::~LibstdcppVectorBoolSyntheticFrontEnd () 187254721Semaste{} 188254721Semaste 189254721SemasteSyntheticChildrenFrontEnd* 190254721Semastelldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 191254721Semaste{ 192254721Semaste if (!valobj_sp) 193254721Semaste return NULL; 194254721Semaste return (new LibstdcppVectorBoolSyntheticFrontEnd(valobj_sp)); 195254721Semaste} 196254721Semaste 197254721Semaste/* 198254721Semaste (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = { 199254721Semaste (_Base_ptr) _M_node = 0x0000000100103910 { 200254721Semaste (std::_Rb_tree_color) _M_color = _S_black 201254721Semaste (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0 202254721Semaste (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000 203254721Semaste (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000 204254721Semaste } 205254721Semaste } 206254721Semaste */ 207254721Semaste 208254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 209254721Semaste SyntheticChildrenFrontEnd(*valobj_sp.get()), 210254721Semaste m_exe_ctx_ref(), 211254721Semaste m_pair_address(0), 212254721Semaste m_pair_type(), 213254721Semaste m_options(), 214254721Semaste m_pair_sp() 215254721Semaste{ 216254721Semaste if (valobj_sp) 217254721Semaste Update(); 218263367Semaste m_options.SetCoerceToId(false); 219263367Semaste m_options.SetUnwindOnError(true); 220263367Semaste m_options.SetKeepInMemory(true); 221263367Semaste m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); 222254721Semaste} 223254721Semaste 224254721Semastebool 225254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::Update() 226254721Semaste{ 227254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 228254721Semaste if (!valobj_sp) 229254721Semaste return false; 230254721Semaste 231254721Semaste TargetSP target_sp(valobj_sp->GetTargetSP()); 232254721Semaste 233254721Semaste if (!target_sp) 234254721Semaste return false; 235254721Semaste 236254721Semaste bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8); 237254721Semaste 238254721Semaste if (!valobj_sp) 239254721Semaste return false; 240254721Semaste m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 241254721Semaste 242254721Semaste ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true)); 243254721Semaste if (!_M_node_sp) 244254721Semaste return false; 245254721Semaste 246254721Semaste m_pair_address = _M_node_sp->GetValueAsUnsigned(0); 247254721Semaste if (m_pair_address == 0) 248254721Semaste return false; 249254721Semaste 250254721Semaste m_pair_address += (is_64bit ? 32 : 16); 251254721Semaste 252254721Semaste ClangASTType my_type(valobj_sp->GetClangType()); 253254721Semaste if (my_type.GetNumTemplateArguments() >= 1) 254254721Semaste { 255254721Semaste TemplateArgumentKind kind; 256254721Semaste ClangASTType pair_type = my_type.GetTemplateArgument(0, kind); 257254721Semaste if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion) 258254721Semaste return false; 259254721Semaste m_pair_type = pair_type; 260254721Semaste } 261254721Semaste else 262254721Semaste return false; 263254721Semaste 264254721Semaste return true; 265254721Semaste} 266254721Semaste 267254721Semastesize_t 268254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren () 269254721Semaste{ 270254721Semaste return 2; 271254721Semaste} 272254721Semaste 273254721Semastelldb::ValueObjectSP 274254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) 275254721Semaste{ 276254721Semaste if (m_pair_address != 0 && m_pair_type) 277254721Semaste { 278254721Semaste if (!m_pair_sp) 279254721Semaste m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); 280254721Semaste if (m_pair_sp) 281254721Semaste return m_pair_sp->GetChildAtIndex(idx, true); 282254721Semaste } 283254721Semaste return lldb::ValueObjectSP(); 284254721Semaste} 285254721Semaste 286254721Semastebool 287254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren () 288254721Semaste{ 289254721Semaste return true; 290254721Semaste} 291254721Semaste 292254721Semastesize_t 293254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 294254721Semaste{ 295254721Semaste if (name == ConstString("first")) 296254721Semaste return 0; 297254721Semaste if (name == ConstString("second")) 298254721Semaste return 1; 299254721Semaste return UINT32_MAX; 300254721Semaste} 301254721Semaste 302254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::~LibstdcppMapIteratorSyntheticFrontEnd () 303254721Semaste{} 304254721Semaste 305254721SemasteSyntheticChildrenFrontEnd* 306254721Semastelldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 307254721Semaste{ 308254721Semaste if (!valobj_sp) 309254721Semaste return NULL; 310254721Semaste return (new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp)); 311254721Semaste} 312254721Semaste 313254721Semaste/* 314254721Semaste (lldb) fr var ibeg --ptr-depth 1 315254721Semaste (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) ibeg = { 316254721Semaste _M_current = 0x00000001001037a0 { 317254721Semaste *_M_current = 1 318254721Semaste } 319254721Semaste } 320254721Semaste */ 321254721Semaste 322254721SemasteSyntheticChildrenFrontEnd* 323254721Semastelldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 324254721Semaste{ 325254721Semaste static ConstString g_item_name; 326254721Semaste if (!g_item_name) 327254721Semaste g_item_name.SetCString("_M_current"); 328254721Semaste if (!valobj_sp) 329254721Semaste return NULL; 330254721Semaste return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name)); 331254721Semaste} 332