Skip to content

Commit 9dabd3a

Browse files
committed
[lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper
This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state
1 parent e89890e commit 9dabd3a

File tree

1 file changed

+72
-43
lines changed

1 file changed

+72
-43
lines changed

lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
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

2122
using namespace lldb;
2223
using 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;
@@ -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

Comments
 (0)