1254721Semaste//===-- LibCxx.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/Debugger.h" 16254721Semaste#include "lldb/Core/Error.h" 17254721Semaste#include "lldb/Core/Stream.h" 18254721Semaste#include "lldb/Core/ValueObject.h" 19254721Semaste#include "lldb/Core/ValueObjectConstResult.h" 20254721Semaste#include "lldb/Host/Endian.h" 21254721Semaste#include "lldb/Symbol/ClangASTContext.h" 22254721Semaste#include "lldb/Target/ObjCLanguageRuntime.h" 23254721Semaste#include "lldb/Target/Target.h" 24254721Semaste 25254721Semasteusing namespace lldb; 26254721Semasteusing namespace lldb_private; 27254721Semasteusing namespace lldb_private::formatters; 28254721Semaste 29269024Semastebool 30269024Semastelldb_private::formatters::LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream) 31269024Semaste{ 32269024Semaste ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); 33269024Semaste if (!valobj_sp) 34269024Semaste return false; 35269024Semaste ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); 36269024Semaste ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_owners_")} )); 37269024Semaste ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_weak_owners_")} )); 38269024Semaste 39269024Semaste if (!ptr_sp) 40269024Semaste return false; 41269024Semaste 42269024Semaste if (ptr_sp->GetValueAsUnsigned(0) == 0) 43269024Semaste { 44269024Semaste stream.Printf("nullptr"); 45269024Semaste return true; 46269024Semaste } 47269024Semaste else 48269024Semaste { 49269024Semaste bool print_pointee = false; 50269024Semaste Error error; 51269024Semaste ValueObjectSP pointee_sp = ptr_sp->Dereference(error); 52269024Semaste if (pointee_sp && error.Success()) 53269024Semaste { 54269024Semaste if (pointee_sp->DumpPrintableRepresentation(stream, 55269024Semaste ValueObject::eValueObjectRepresentationStyleSummary, 56269024Semaste lldb::eFormatInvalid, 57269024Semaste ValueObject::ePrintableRepresentationSpecialCasesDisable, 58269024Semaste false)) 59269024Semaste print_pointee = true; 60269024Semaste } 61269024Semaste if (!print_pointee) 62269024Semaste stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); 63269024Semaste } 64269024Semaste 65269024Semaste if (count_sp) 66269024Semaste stream.Printf(" strong=%" PRIu64, 1+count_sp->GetValueAsUnsigned(0)); 67269024Semaste 68269024Semaste if (weakcount_sp) 69269024Semaste stream.Printf(" weak=%" PRIu64, 1+weakcount_sp->GetValueAsUnsigned(0)); 70269024Semaste 71269024Semaste return true; 72269024Semaste} 73269024Semaste 74254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 75254721SemasteSyntheticChildrenFrontEnd(*valobj_sp.get()), 76269024Semastem_bool_type(), 77254721Semastem_exe_ctx_ref(), 78254721Semastem_count(0), 79254721Semastem_base_data_address(0), 80269024Semastem_children() 81254721Semaste{ 82254721Semaste if (valobj_sp) 83269024Semaste { 84254721Semaste Update(); 85269024Semaste m_bool_type = valobj_sp->GetClangType().GetBasicTypeFromAST(lldb::eBasicTypeBool); 86269024Semaste } 87254721Semaste} 88254721Semaste 89254721Semastesize_t 90254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren () 91254721Semaste{ 92254721Semaste return m_count; 93254721Semaste} 94254721Semaste 95254721Semastelldb::ValueObjectSP 96254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx) 97254721Semaste{ 98269024Semaste auto iter = m_children.find(idx), 99269024Semaste end = m_children.end(); 100269024Semaste if (iter != end) 101269024Semaste return iter->second; 102254721Semaste if (idx >= m_count) 103254721Semaste return ValueObjectSP(); 104254721Semaste if (m_base_data_address == 0 || m_count == 0) 105254721Semaste return ValueObjectSP(); 106269024Semaste if (!m_bool_type) 107269024Semaste return ValueObjectSP(); 108254721Semaste size_t byte_idx = (idx >> 3); // divide by 8 to get byte index 109254721Semaste size_t bit_index = (idx & 7); // efficient idx % 8 for bit index 110254721Semaste lldb::addr_t byte_location = m_base_data_address + byte_idx; 111254721Semaste ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); 112254721Semaste if (!process_sp) 113254721Semaste return ValueObjectSP(); 114254721Semaste uint8_t byte = 0; 115254721Semaste uint8_t mask = 0; 116254721Semaste Error err; 117254721Semaste size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); 118254721Semaste if (err.Fail() || bytes_read == 0) 119254721Semaste return ValueObjectSP(); 120254721Semaste switch (bit_index) 121254721Semaste { 122254721Semaste case 0: 123254721Semaste mask = 1; break; 124254721Semaste case 1: 125254721Semaste mask = 2; break; 126254721Semaste case 2: 127254721Semaste mask = 4; break; 128254721Semaste case 3: 129254721Semaste mask = 8; break; 130254721Semaste case 4: 131254721Semaste mask = 16; break; 132254721Semaste case 5: 133254721Semaste mask = 32; break; 134254721Semaste case 6: 135254721Semaste mask = 64; break; 136254721Semaste case 7: 137254721Semaste mask = 128; break; 138254721Semaste default: 139254721Semaste return ValueObjectSP(); 140254721Semaste } 141254721Semaste bool bit_set = ((byte & mask) != 0); 142254721Semaste ValueObjectSP retval_sp; 143269024Semaste DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(),0)); 144269024Semaste if (bit_set && buffer_sp && buffer_sp->GetBytes()) 145269024Semaste *(buffer_sp->GetBytes()) = 1; // regardless of endianness, anything non-zero is true 146254721Semaste StreamString name; name.Printf("[%zu]",idx); 147269024Semaste DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); 148269024Semaste retval_sp = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_exe_ctx_ref, m_bool_type); 149254721Semaste if (retval_sp) 150269024Semaste m_children[idx] = retval_sp; 151254721Semaste return retval_sp; 152254721Semaste} 153254721Semaste 154254721Semaste/*(std::__1::vector<std::__1::allocator<bool> >) vBool = { 155254721Semaste __begin_ = 0x00000001001000e0 156254721Semaste __size_ = 56 157254721Semaste __cap_alloc_ = { 158254721Semaste std::__1::__libcpp_compressed_pair_imp<unsigned long, std::__1::allocator<unsigned long> > = { 159254721Semaste __first_ = 1 160254721Semaste } 161254721Semaste } 162254721Semaste }*/ 163254721Semaste 164254721Semastebool 165254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() 166254721Semaste{ 167269024Semaste m_children.clear(); 168254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 169254721Semaste if (!valobj_sp) 170254721Semaste return false; 171254721Semaste if (!valobj_sp) 172254721Semaste return false; 173254721Semaste m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 174254721Semaste ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName(ConstString("__size_"), true)); 175254721Semaste if (!size_sp) 176254721Semaste return false; 177254721Semaste m_count = size_sp->GetValueAsUnsigned(0); 178254721Semaste if (!m_count) 179254721Semaste return true; 180254721Semaste ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true)); 181254721Semaste if (!begin_sp) 182254721Semaste { 183254721Semaste m_count = 0; 184254721Semaste return false; 185254721Semaste } 186254721Semaste m_base_data_address = begin_sp->GetValueAsUnsigned(0); 187254721Semaste if (!m_base_data_address) 188254721Semaste { 189254721Semaste m_count = 0; 190254721Semaste return false; 191254721Semaste } 192254721Semaste return false; 193254721Semaste} 194254721Semaste 195254721Semastebool 196254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::MightHaveChildren () 197254721Semaste{ 198254721Semaste return true; 199254721Semaste} 200254721Semaste 201254721Semastesize_t 202254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 203254721Semaste{ 204254721Semaste if (!m_count || !m_base_data_address) 205254721Semaste return UINT32_MAX; 206254721Semaste const char* item_name = name.GetCString(); 207254721Semaste uint32_t idx = ExtractIndexFromString(item_name); 208254721Semaste if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 209254721Semaste return UINT32_MAX; 210254721Semaste return idx; 211254721Semaste} 212254721Semaste 213254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd () 214254721Semaste{} 215254721Semaste 216254721SemasteSyntheticChildrenFrontEnd* 217254721Semastelldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 218254721Semaste{ 219254721Semaste if (!valobj_sp) 220254721Semaste return NULL; 221254721Semaste return (new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp)); 222254721Semaste} 223254721Semaste 224254721Semaste/* 225254721Semaste (lldb) fr var ibeg --raw --ptr-depth 1 226254721Semaste (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void *> *, long> >) ibeg = { 227254721Semaste __i_ = { 228254721Semaste __ptr_ = 0x0000000100103870 { 229254721Semaste std::__1::__tree_node_base<void *> = { 230254721Semaste std::__1::__tree_end_node<std::__1::__tree_node_base<void *> *> = { 231254721Semaste __left_ = 0x0000000000000000 232254721Semaste } 233254721Semaste __right_ = 0x0000000000000000 234254721Semaste __parent_ = 0x00000001001038b0 235254721Semaste __is_black_ = true 236254721Semaste } 237254721Semaste __value_ = { 238254721Semaste first = 0 239254721Semaste second = { std::string } 240254721Semaste */ 241254721Semaste 242254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 243254721SemasteSyntheticChildrenFrontEnd(*valobj_sp.get()), 244254721Semastem_pair_ptr() 245254721Semaste{ 246254721Semaste if (valobj_sp) 247254721Semaste Update(); 248254721Semaste} 249254721Semaste 250254721Semastebool 251254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() 252254721Semaste{ 253254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 254254721Semaste if (!valobj_sp) 255254721Semaste return false; 256254721Semaste 257254721Semaste TargetSP target_sp(valobj_sp->GetTargetSP()); 258254721Semaste 259254721Semaste if (!target_sp) 260254721Semaste return false; 261254721Semaste 262254721Semaste if (!valobj_sp) 263254721Semaste return false; 264254721Semaste 265254721Semaste // this must be a ValueObject* because it is a child of the ValueObject we are producing children for 266254721Semaste // it if were a ValueObjectSP, we would end up with a loop (iterator -> synthetic -> child -> parent == iterator) 267254721Semaste // and that would in turn leak memory by never allowing the ValueObjects to die and free their memory 268254721Semaste m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_->__value_", 269254721Semaste NULL, 270254721Semaste NULL, 271254721Semaste NULL, 272254721Semaste ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().DontAllowSyntheticChildren(), 273254721Semaste NULL).get(); 274254721Semaste 275254721Semaste return false; 276254721Semaste} 277254721Semaste 278254721Semastesize_t 279254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::CalculateNumChildren () 280254721Semaste{ 281254721Semaste return 2; 282254721Semaste} 283254721Semaste 284254721Semastelldb::ValueObjectSP 285254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) 286254721Semaste{ 287254721Semaste if (!m_pair_ptr) 288254721Semaste return lldb::ValueObjectSP(); 289254721Semaste return m_pair_ptr->GetChildAtIndex(idx, true); 290254721Semaste} 291254721Semaste 292254721Semastebool 293254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::MightHaveChildren () 294254721Semaste{ 295254721Semaste return true; 296254721Semaste} 297254721Semaste 298254721Semastesize_t 299254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 300254721Semaste{ 301254721Semaste if (name == ConstString("first")) 302254721Semaste return 0; 303254721Semaste if (name == ConstString("second")) 304254721Semaste return 1; 305254721Semaste return UINT32_MAX; 306254721Semaste} 307254721Semaste 308254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::~LibCxxMapIteratorSyntheticFrontEnd () 309254721Semaste{ 310254721Semaste // this will be deleted when its parent dies (since it's a child object) 311254721Semaste //delete m_pair_ptr; 312254721Semaste} 313254721Semaste 314254721SemasteSyntheticChildrenFrontEnd* 315254721Semastelldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 316254721Semaste{ 317254721Semaste if (!valobj_sp) 318254721Semaste return NULL; 319254721Semaste return (new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp)); 320254721Semaste} 321254721Semaste 322254721Semaste/* 323254721Semaste (lldb) fr var ibeg --raw --ptr-depth 1 -T 324254721Semaste (std::__1::__wrap_iter<int *>) ibeg = { 325254721Semaste (std::__1::__wrap_iter<int *>::iterator_type) __i = 0x00000001001037a0 { 326254721Semaste (int) *__i = 1 327254721Semaste } 328254721Semaste } 329254721Semaste*/ 330254721Semaste 331254721SemasteSyntheticChildrenFrontEnd* 332254721Semastelldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 333254721Semaste{ 334254721Semaste static ConstString g_item_name; 335254721Semaste if (!g_item_name) 336254721Semaste g_item_name.SetCString("__i"); 337254721Semaste if (!valobj_sp) 338254721Semaste return NULL; 339254721Semaste return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name)); 340254721Semaste} 341254721Semaste 342254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 343254721SemasteSyntheticChildrenFrontEnd(*valobj_sp.get()), 344254721Semastem_cntrl(NULL), 345254721Semastem_count_sp(), 346254721Semastem_weak_count_sp(), 347254721Semastem_ptr_size(0), 348254721Semastem_byte_order(lldb::eByteOrderInvalid) 349254721Semaste{ 350254721Semaste if (valobj_sp) 351254721Semaste Update(); 352254721Semaste} 353254721Semaste 354254721Semastesize_t 355254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren () 356254721Semaste{ 357254721Semaste return (m_cntrl ? 1 : 0); 358254721Semaste} 359254721Semaste 360254721Semastelldb::ValueObjectSP 361254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (size_t idx) 362254721Semaste{ 363254721Semaste if (!m_cntrl) 364254721Semaste return lldb::ValueObjectSP(); 365254721Semaste 366254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 367254721Semaste if (!valobj_sp) 368254721Semaste return lldb::ValueObjectSP(); 369254721Semaste 370254721Semaste if (idx == 0) 371254721Semaste return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); 372254721Semaste 373254721Semaste if (idx > 2) 374254721Semaste return lldb::ValueObjectSP(); 375254721Semaste 376254721Semaste if (idx == 1) 377254721Semaste { 378254721Semaste if (!m_count_sp) 379254721Semaste { 380254721Semaste ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_owners_"),true)); 381254721Semaste if (!shared_owners_sp) 382254721Semaste return lldb::ValueObjectSP(); 383254721Semaste uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); 384254721Semaste DataExtractor data(&count, 8, m_byte_order, m_ptr_size); 385254721Semaste m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_owners_sp->GetClangType()); 386254721Semaste } 387254721Semaste return m_count_sp; 388254721Semaste } 389254721Semaste else /* if (idx == 2) */ 390254721Semaste { 391254721Semaste if (!m_weak_count_sp) 392254721Semaste { 393254721Semaste ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_weak_owners_"),true)); 394254721Semaste if (!shared_weak_owners_sp) 395254721Semaste return lldb::ValueObjectSP(); 396254721Semaste uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); 397254721Semaste DataExtractor data(&count, 8, m_byte_order, m_ptr_size); 398254721Semaste m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_weak_owners_sp->GetClangType()); 399254721Semaste } 400254721Semaste return m_weak_count_sp; 401254721Semaste } 402254721Semaste} 403254721Semaste 404254721Semastebool 405254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() 406254721Semaste{ 407254721Semaste m_count_sp.reset(); 408254721Semaste m_weak_count_sp.reset(); 409254721Semaste m_cntrl = NULL; 410254721Semaste 411254721Semaste ValueObjectSP valobj_sp = m_backend.GetSP(); 412254721Semaste if (!valobj_sp) 413254721Semaste return false; 414254721Semaste 415254721Semaste TargetSP target_sp(valobj_sp->GetTargetSP()); 416254721Semaste if (!target_sp) 417254721Semaste return false; 418254721Semaste 419254721Semaste m_byte_order = target_sp->GetArchitecture().GetByteOrder(); 420254721Semaste m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); 421254721Semaste 422254721Semaste lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"),true)); 423254721Semaste 424254721Semaste m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular dependency 425254721Semaste return false; 426254721Semaste} 427254721Semaste 428254721Semastebool 429254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::MightHaveChildren () 430254721Semaste{ 431254721Semaste return true; 432254721Semaste} 433254721Semaste 434254721Semastesize_t 435254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 436254721Semaste{ 437254721Semaste if (name == ConstString("__ptr_")) 438254721Semaste return 0; 439254721Semaste if (name == ConstString("count")) 440254721Semaste return 1; 441254721Semaste if (name == ConstString("weak_count")) 442254721Semaste return 2; 443254721Semaste return UINT32_MAX; 444254721Semaste} 445254721Semaste 446254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd () 447254721Semaste{} 448254721Semaste 449254721SemasteSyntheticChildrenFrontEnd* 450254721Semastelldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 451254721Semaste{ 452254721Semaste if (!valobj_sp) 453254721Semaste return NULL; 454254721Semaste return (new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp)); 455254721Semaste} 456254721Semaste 457254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 458254721Semaste SyntheticChildrenFrontEnd(*valobj_sp.get()), 459254721Semaste m_start(NULL), 460254721Semaste m_finish(NULL), 461254721Semaste m_element_type(), 462254721Semaste m_element_size(0), 463254721Semaste m_children() 464254721Semaste{ 465254721Semaste if (valobj_sp) 466254721Semaste Update(); 467254721Semaste} 468254721Semaste 469254721Semastesize_t 470254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren () 471254721Semaste{ 472254721Semaste if (!m_start || !m_finish) 473254721Semaste return 0; 474254721Semaste uint64_t start_val = m_start->GetValueAsUnsigned(0); 475254721Semaste uint64_t finish_val = m_finish->GetValueAsUnsigned(0); 476254721Semaste 477254721Semaste if (start_val == 0 || finish_val == 0) 478254721Semaste return 0; 479254721Semaste 480254721Semaste if (start_val >= finish_val) 481254721Semaste return 0; 482254721Semaste 483254721Semaste size_t num_children = (finish_val - start_val); 484254721Semaste if (num_children % m_element_size) 485254721Semaste return 0; 486254721Semaste return num_children/m_element_size; 487254721Semaste} 488254721Semaste 489254721Semastelldb::ValueObjectSP 490254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx) 491254721Semaste{ 492254721Semaste if (!m_start || !m_finish) 493254721Semaste return lldb::ValueObjectSP(); 494254721Semaste 495254721Semaste auto cached = m_children.find(idx); 496254721Semaste if (cached != m_children.end()) 497254721Semaste return cached->second; 498254721Semaste 499254721Semaste uint64_t offset = idx * m_element_size; 500254721Semaste offset = offset + m_start->GetValueAsUnsigned(0); 501254721Semaste StreamString name; 502254721Semaste name.Printf("[%zu]",idx); 503254721Semaste ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); 504254721Semaste m_children[idx] = child_sp; 505254721Semaste return child_sp; 506254721Semaste} 507254721Semaste 508254721Semastebool 509254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() 510254721Semaste{ 511254721Semaste m_start = m_finish = NULL; 512254721Semaste m_children.clear(); 513254721Semaste ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true)); 514254721Semaste if (!data_type_finder_sp) 515254721Semaste return false; 516254721Semaste data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); 517254721Semaste if (!data_type_finder_sp) 518254721Semaste return false; 519254721Semaste m_element_type = data_type_finder_sp->GetClangType().GetPointeeType(); 520254721Semaste m_element_size = m_element_type.GetByteSize(); 521254721Semaste 522254721Semaste if (m_element_size > 0) 523254721Semaste { 524254721Semaste // store raw pointers or end up with a circular dependency 525254721Semaste m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get(); 526254721Semaste m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get(); 527254721Semaste } 528254721Semaste return false; 529254721Semaste} 530254721Semaste 531254721Semastebool 532254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren () 533254721Semaste{ 534254721Semaste return true; 535254721Semaste} 536254721Semaste 537254721Semastesize_t 538254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 539254721Semaste{ 540254721Semaste if (!m_start || !m_finish) 541254721Semaste return UINT32_MAX; 542254721Semaste return ExtractIndexFromString(name.GetCString()); 543254721Semaste} 544254721Semaste 545254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd () 546254721Semaste{ 547254721Semaste // these need to stay around because they are child objects who will follow their parent's life cycle 548254721Semaste // delete m_start; 549254721Semaste // delete m_finish; 550254721Semaste} 551254721Semaste 552254721SemasteSyntheticChildrenFrontEnd* 553254721Semastelldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 554254721Semaste{ 555254721Semaste if (!valobj_sp) 556254721Semaste return NULL; 557254721Semaste return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)); 558254721Semaste} 559254721Semaste 560254721Semastebool 561254721Semastelldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream) 562254721Semaste{ 563254721Semaste if (valobj.IsPointerType()) 564254721Semaste { 565254721Semaste uint64_t value = valobj.GetValueAsUnsigned(0); 566254721Semaste if (!value) 567254721Semaste return false; 568254721Semaste stream.Printf("0x%016" PRIx64 " ", value); 569254721Semaste } 570254721Semaste return Debugger::FormatPrompt("size=${svar%#}", NULL, NULL, NULL, stream, &valobj); 571254721Semaste} 572