1717#include " lldb/Utility/Endian.h"
1818#include " lldb/Utility/Status.h"
1919#include " lldb/Utility/Stream.h"
20+ #include " lldb/lldb-forward.h"
2021
2122using namespace lldb ;
2223using namespace lldb_private ;
@@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
184185
185186 void GetValueOffset (const lldb::ValueObjectSP &node);
186187
188+ // / Returns the ValueObject for the __tree_node type that
189+ // / holds the key/value pair of the node at index \ref idx.
190+ // /
191+ // / \param[in] idx The child index that we're looking to get
192+ // / the key/value pair for.
193+ // /
194+ // / \param[in] max_depth The maximum search depth after which
195+ // / we stop trying to find the key/value
196+ // / pair for.
197+ // /
198+ // / \returns On success, returns the ValueObjectSP corresponding
199+ // / to the __tree_node's __value_ member (which holds
200+ // / the key/value pair the formatter wants to display).
201+ // / On failure, will return nullptr.
202+ ValueObjectSP GetKeyValuePair (size_t idx, size_t max_depth);
203+
187204 ValueObject *m_tree = nullptr ;
188205 ValueObject *m_root_node = nullptr ;
189206 CompilerType m_element_type;
@@ -267,7 +284,7 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
267284 uint64_t bit_offset;
268285 if (node_type.GetIndexOfFieldWithName (" __value_" , nullptr , &bit_offset) !=
269286 UINT32_MAX) {
270- // Old layout (pre 089a7cc5dea )
287+ // Old layout (pre d05b10ab4fc65 )
271288 m_skip_size = bit_offset / 8u ;
272289 } else {
273290 auto ast_ctx = node_type.GetTypeSystem ().dyn_cast_or_null <TypeSystemClang>();
@@ -299,83 +316,96 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
299316 }
300317}
301318
302- lldb::ValueObjectSP
303- lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (
304- uint32_t idx) {
305- static ConstString g_cc_ (" __cc_" ), g_cc (" __cc" );
306- static ConstString g_nc (" __nc" );
307- uint32_t num_children = CalculateNumChildrenIgnoringErrors ();
308- if (idx >= num_children)
309- return lldb::ValueObjectSP ();
310- if (m_tree == nullptr || m_root_node == nullptr )
311- return lldb::ValueObjectSP ();
312-
313- MapIterator iterator (m_root_node, num_children);
319+ ValueObjectSP
320+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair (
321+ size_t idx, size_t max_depth) {
322+ MapIterator iterator (m_root_node, max_depth);
314323
315324 const bool need_to_skip = (idx > 0 );
316- size_t actual_advancde = idx;
325+ size_t actual_advance = idx;
317326 if (need_to_skip) {
327+ // If we have already created the iterator for the previous
328+ // index, we can start from there and advance by 1.
318329 auto cached_iterator = m_iterators.find (idx - 1 );
319330 if (cached_iterator != m_iterators.end ()) {
320331 iterator = cached_iterator->second ;
321- actual_advancde = 1 ;
332+ actual_advance = 1 ;
322333 }
323334 }
324335
325- ValueObjectSP iterated_sp (iterator.advance (actual_advancde ));
326- if (!iterated_sp) {
336+ ValueObjectSP iterated_sp (iterator.advance (actual_advance ));
337+ if (!iterated_sp)
327338 // this tree is garbage - stop
328- m_tree =
329- nullptr ; // this will stop all future searches until an Update() happens
330- return iterated_sp;
331- }
339+ return nullptr ;
332340
333- if (!GetDataType ()) {
334- m_tree = nullptr ;
335- return lldb::ValueObjectSP ();
336- }
341+ if (!GetDataType ())
342+ return nullptr ;
337343
338344 if (!need_to_skip) {
339345 Status error;
340346 iterated_sp = iterated_sp->Dereference (error);
341- if (!iterated_sp || error.Fail ()) {
342- m_tree = nullptr ;
343- return lldb::ValueObjectSP ();
344- }
347+ if (!iterated_sp || error.Fail ())
348+ return nullptr ;
349+
345350 GetValueOffset (iterated_sp);
346351 auto child_sp = iterated_sp->GetChildMemberWithName (" __value_" );
347- if (child_sp)
352+ if (child_sp) {
353+ // Old layout (pre 089a7cc5dea)
348354 iterated_sp = child_sp;
349- else
355+ } else {
350356 iterated_sp = iterated_sp->GetSyntheticChildAtOffset (
351357 m_skip_size, m_element_type, true );
352- if (!iterated_sp) {
353- m_tree = nullptr ;
354- return lldb::ValueObjectSP ();
355358 }
359+
360+ if (!iterated_sp)
361+ return nullptr ;
356362 } else {
357363 // because of the way our debug info is made, we need to read item 0
358364 // first so that we can cache information used to generate other elements
359365 if (m_skip_size == UINT32_MAX)
360366 GetChildAtIndex (0 );
361- if (m_skip_size == UINT32_MAX) {
362- m_tree = nullptr ;
363- return lldb::ValueObjectSP () ;
364- }
367+
368+ if (m_skip_size == UINT32_MAX)
369+ return nullptr ;
370+
365371 iterated_sp = iterated_sp->GetSyntheticChildAtOffset (m_skip_size,
366372 m_element_type, true );
367- if (!iterated_sp) {
368- m_tree = nullptr ;
369- return lldb::ValueObjectSP ();
370- }
373+ if (!iterated_sp)
374+ return nullptr ;
375+ }
376+
377+ m_iterators[idx] = iterator;
378+ assert (iterated_sp != nullptr &&
379+ " Cached MapIterator for invalid ValueObject" );
380+
381+ return iterated_sp;
382+ }
383+
384+ lldb::ValueObjectSP
385+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (
386+ uint32_t idx) {
387+ static ConstString g_cc_ (" __cc_" ), g_cc (" __cc" );
388+ static ConstString g_nc (" __nc" );
389+ uint32_t num_children = CalculateNumChildrenIgnoringErrors ();
390+ if (idx >= num_children)
391+ return nullptr ;
392+
393+ if (m_tree == nullptr || m_root_node == nullptr )
394+ return nullptr ;
395+
396+ ValueObjectSP key_val_sp = GetKeyValuePair (idx, /* max_depth=*/ num_children);
397+ if (!key_val_sp) {
398+ // this will stop all future searches until an Update() happens
399+ m_tree = nullptr ;
400+ return nullptr ;
371401 }
372402
373403 // at this point we have a valid
374404 // we need to copy current_sp into a new object otherwise we will end up with
375405 // all items named __value_
376406 StreamString name;
377407 name.Printf (" [%" PRIu64 " ]" , (uint64_t )idx);
378- auto potential_child_sp = iterated_sp ->Clone (ConstString (name.GetString ()));
408+ auto potential_child_sp = key_val_sp ->Clone (ConstString (name.GetString ()));
379409 if (potential_child_sp) {
380410 switch (potential_child_sp->GetNumChildrenIgnoringErrors ()) {
381411 case 1 : {
@@ -396,7 +426,6 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
396426 }
397427 }
398428 }
399- m_iterators[idx] = iterator;
400429 return potential_child_sp;
401430}
402431
0 commit comments