17
17
#include " lldb/Utility/Endian.h"
18
18
#include " lldb/Utility/Status.h"
19
19
#include " lldb/Utility/Stream.h"
20
+ #include " lldb/lldb-forward.h"
20
21
21
22
using namespace lldb ;
22
23
using namespace lldb_private ;
@@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
184
185
185
186
void GetValueOffset (const lldb::ValueObjectSP &node);
186
187
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
+
187
204
ValueObject *m_tree = nullptr ;
188
205
ValueObject *m_root_node = nullptr ;
189
206
CompilerType m_element_type;
@@ -299,83 +316,96 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
299
316
}
300
317
}
301
318
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);
314
323
315
324
const bool need_to_skip = (idx > 0 );
316
- size_t actual_advancde = idx;
325
+ size_t actual_advance = idx;
317
326
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.
318
329
auto cached_iterator = m_iterators.find (idx - 1 );
319
330
if (cached_iterator != m_iterators.end ()) {
320
331
iterator = cached_iterator->second ;
321
- actual_advancde = 1 ;
332
+ actual_advance = 1 ;
322
333
}
323
334
}
324
335
325
- ValueObjectSP iterated_sp (iterator.advance (actual_advancde ));
326
- if (!iterated_sp) {
336
+ ValueObjectSP iterated_sp (iterator.advance (actual_advance ));
337
+ if (!iterated_sp)
327
338
// 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 ;
332
340
333
- if (!GetDataType ()) {
334
- m_tree = nullptr ;
335
- return lldb::ValueObjectSP ();
336
- }
341
+ if (!GetDataType ())
342
+ return nullptr ;
337
343
338
344
if (!need_to_skip) {
339
345
Status error;
340
346
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
+
345
350
GetValueOffset (iterated_sp);
346
351
auto child_sp = iterated_sp->GetChildMemberWithName (" __value_" );
347
- if (child_sp)
352
+ if (child_sp) {
353
+ // Old layout (pre 089a7cc5dea)
348
354
iterated_sp = child_sp;
349
- else
355
+ } else {
350
356
iterated_sp = iterated_sp->GetSyntheticChildAtOffset (
351
357
m_skip_size, m_element_type, true );
352
- if (!iterated_sp) {
353
- m_tree = nullptr ;
354
- return lldb::ValueObjectSP ();
355
358
}
359
+
360
+ if (!iterated_sp)
361
+ return nullptr ;
356
362
} else {
357
363
// because of the way our debug info is made, we need to read item 0
358
364
// first so that we can cache information used to generate other elements
359
365
if (m_skip_size == UINT32_MAX)
360
366
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
+
365
371
iterated_sp = iterated_sp->GetSyntheticChildAtOffset (m_skip_size,
366
372
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 ;
371
401
}
372
402
373
403
// at this point we have a valid
374
404
// we need to copy current_sp into a new object otherwise we will end up with
375
405
// all items named __value_
376
406
StreamString name;
377
407
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 ()));
379
409
if (potential_child_sp) {
380
410
switch (potential_child_sp->GetNumChildrenIgnoringErrors ()) {
381
411
case 1 : {
@@ -396,7 +426,6 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
396
426
}
397
427
}
398
428
}
399
- m_iterators[idx] = iterator;
400
429
return potential_child_sp;
401
430
}
402
431
0 commit comments