Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper #97544

Merged
merged 2 commits into from
Jul 3, 2024

Conversation

Michael137
Copy link
Member

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

… 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
@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

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

Full diff: https://github.com/llvm/llvm-project/pull/97544.diff

1 Files Affected:

  • (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+72-43)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 44fe294ced722..370dfa35e7703 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -17,6 +17,7 @@
 #include "lldb/Utility/Endian.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/Stream.h"
+#include "lldb/lldb-forward.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 
   void GetValueOffset(const lldb::ValueObjectSP &node);
 
+  /// Returns the ValueObject for the __tree_node type that
+  /// holds the key/value pair of the node at index \ref idx.
+  ///
+  /// \param[in] idx The child index that we're looking to get
+  ///                the key/value pair for.
+  ///
+  /// \param[in] max_depth The maximum search depth after which
+  ///                      we stop trying to find the key/value
+  ///                      pair for.
+  ///
+  /// \returns On success, returns the ValueObjectSP corresponding
+  ///          to the __tree_node's __value_ member (which holds
+  ///          the key/value pair the formatter wants to display).
+  ///          On failure, will return nullptr.
+  ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth);
+
   ValueObject *m_tree = nullptr;
   ValueObject *m_root_node = nullptr;
   CompilerType m_element_type;
@@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
   }
 }
 
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
-    uint32_t idx) {
-  static ConstString g_cc_("__cc_"), g_cc("__cc");
-  static ConstString g_nc("__nc");
-  uint32_t num_children = CalculateNumChildrenIgnoringErrors();
-  if (idx >= num_children)
-    return lldb::ValueObjectSP();
-  if (m_tree == nullptr || m_root_node == nullptr)
-    return lldb::ValueObjectSP();
-
-  MapIterator iterator(m_root_node, num_children);
+ValueObjectSP
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair(
+    size_t idx, size_t max_depth) {
+  MapIterator iterator(m_root_node, max_depth);
 
   const bool need_to_skip = (idx > 0);
-  size_t actual_advancde = idx;
+  size_t actual_advance = idx;
   if (need_to_skip) {
+    // If we have already created the iterator for the previous
+    // index, we can start from there and advance by 1.
     auto cached_iterator = m_iterators.find(idx - 1);
     if (cached_iterator != m_iterators.end()) {
       iterator = cached_iterator->second;
-      actual_advancde = 1;
+      actual_advance = 1;
     }
   }
 
-  ValueObjectSP iterated_sp(iterator.advance(actual_advancde));
-  if (!iterated_sp) {
+  ValueObjectSP iterated_sp(iterator.advance(actual_advance));
+  if (!iterated_sp)
     // this tree is garbage - stop
-    m_tree =
-        nullptr; // this will stop all future searches until an Update() happens
-    return iterated_sp;
-  }
+    return nullptr;
 
-  if (!GetDataType()) {
-    m_tree = nullptr;
-    return lldb::ValueObjectSP();
-  }
+  if (!GetDataType())
+    return nullptr;
 
   if (!need_to_skip) {
     Status error;
     iterated_sp = iterated_sp->Dereference(error);
-    if (!iterated_sp || error.Fail()) {
-      m_tree = nullptr;
-      return lldb::ValueObjectSP();
-    }
+    if (!iterated_sp || error.Fail())
+      return nullptr;
+
     GetValueOffset(iterated_sp);
     auto child_sp = iterated_sp->GetChildMemberWithName("__value_");
-    if (child_sp)
+    if (child_sp) {
+      // Old layout (pre 089a7cc5dea)
       iterated_sp = child_sp;
-    else
+    } else {
       iterated_sp = iterated_sp->GetSyntheticChildAtOffset(
           m_skip_size, m_element_type, true);
-    if (!iterated_sp) {
-      m_tree = nullptr;
-      return lldb::ValueObjectSP();
     }
+
+    if (!iterated_sp)
+      return nullptr;
   } else {
     // because of the way our debug info is made, we need to read item 0
     // first so that we can cache information used to generate other elements
     if (m_skip_size == UINT32_MAX)
       GetChildAtIndex(0);
-    if (m_skip_size == UINT32_MAX) {
-      m_tree = nullptr;
-      return lldb::ValueObjectSP();
-    }
+
+    if (m_skip_size == UINT32_MAX)
+      return nullptr;
+
     iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size,
                                                          m_element_type, true);
-    if (!iterated_sp) {
-      m_tree = nullptr;
-      return lldb::ValueObjectSP();
-    }
+    if (!iterated_sp)
+      return nullptr;
+  }
+
+  m_iterators[idx] = iterator;
+  assert(iterated_sp != nullptr &&
+         "Cached MapIterator for invalid ValueObject");
+
+  return iterated_sp;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
+    uint32_t idx) {
+  static ConstString g_cc_("__cc_"), g_cc("__cc");
+  static ConstString g_nc("__nc");
+  uint32_t num_children = CalculateNumChildrenIgnoringErrors();
+  if (idx >= num_children)
+    return nullptr;
+
+  if (m_tree == nullptr || m_root_node == nullptr)
+    return nullptr;
+
+  ValueObjectSP key_val_sp = GetKeyValuePair(idx, /*max_depth=*/num_children);
+  if (!key_val_sp) {
+    // this will stop all future searches until an Update() happens
+    m_tree = nullptr;
+    return nullptr;
   }
 
   // at this point we have a valid
@@ -375,7 +405,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
   // all items named __value_
   StreamString name;
   name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-  auto potential_child_sp = iterated_sp->Clone(ConstString(name.GetString()));
+  auto potential_child_sp = key_val_sp->Clone(ConstString(name.GetString()));
   if (potential_child_sp) {
     switch (potential_child_sp->GetNumChildrenIgnoringErrors()) {
     case 1: {
@@ -396,7 +426,6 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
     }
     }
   }
-  m_iterators[idx] = iterator;
   return potential_child_sp;
 }
 

Michael137 added a commit to Michael137/llvm-project that referenced this pull request Jul 3, 2024
…aluePair

This patch cleans up the core of the `std::map` libc++ formatter.

Depends on llvm#97544 and
llvm#97549.

Changes:
* Renamed `m_skip_size` to `m_value_type_offset` to better
  describe what it's actually for.
* Made updating `m_skip_size` (now `m_value_type_offset`)
  isolated to `GetKeyValuePair` (instead of doing so in the
  `GetValueOffset` helper).
* We don't need special logic for the 0th index, so I merged the
  two `need_to_skip` branches.
Michael137 added a commit to Michael137/llvm-project that referenced this pull request Jul 3, 2024
Depends on:
* llvm#97544
* llvm#97549
* llvm#97551

This patch tries to simplify the way in which the
`std::map` formatter goes from the root `__tree`
pointer to a specific key/value pair.

Previously we would synthesize a structure that
mimicked what `__iter_pointer` looked like
in memory, then called `GetChildCompilerTypeAtIndex`
on it to find the byte offset into that structure
at which the pair was located at, and finally
use that offset through a call to `GetSyntheticChildAtOffset`
to retrieve that pair. Not only was this logic hard to follow,
and encoded the libc++ layout in non-obvious ways, it was also
fragile to alignment miscalculations
(llvm#97443); this would
break after the new layout of std::map landed as part of
inhttps://github.com/llvm/issues/93069.

Instead, this patch simply casts the `__iter_pointer` to
the `__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value
we care about. This allows us to get rid of some support
infrastructure/class state.

Ideally we would fix the underlying alignment issue, but
this unblocks the libc++ refactor in the interim,
while also benefitting the formatter in terms of readability (in my opinion).
Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Michael137 Michael137 merged commit a017653 into llvm:main Jul 3, 2024
6 checks passed
@Michael137 Michael137 deleted the lldb/map-formatter-cleanup branch July 3, 2024 17:54
Michael137 added a commit to Michael137/llvm-project that referenced this pull request Jul 3, 2024
…aluePair

This patch cleans up the core of the `std::map` libc++ formatter.

Depends on llvm#97544 and
llvm#97549.

Changes:
* Renamed `m_skip_size` to `m_value_type_offset` to better
  describe what it's actually for.
* Made updating `m_skip_size` (now `m_value_type_offset`)
  isolated to `GetKeyValuePair` (instead of doing so in the
  `GetValueOffset` helper).
* We don't need special logic for the 0th index, so I merged the
  two `need_to_skip` branches.
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 3, 2024

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building lldb at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/1001

Here is the relevant piece of the build log for the reference:

Step 6 (test) failure: build (failure)
...
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-index-is-used.cpp (1606 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-implicit-const.s (1607 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-line-strp.s (1608 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5_locations.s (1609 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-split.s (1610 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-partial-index.cpp (1611 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5_tu_index_abbrev_offset.s (1612 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwo-not-found-warning.cpp (1613 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwo-type-in-main-file.s (1614 of 1989)
PASS: lldb-shell :: SymbolFile/DWARF/x86/dwp-debug-types.s (1615 of 1989)
FAIL: lldb-shell :: SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp (1616 of 1989)
******************** TEST 'lldb-shell :: SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 21: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf    -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o
+ /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o
RUN: at line 23: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -DVARIANT    -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o
+ /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -DVARIANT -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o
RUN: at line 25: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/ld.lld /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp
+ /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/ld.lld /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp
ld.lld: warning: cannot find entry symbol _start; not setting start address
RUN: at line 28: rm -f /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.dwp
+ rm -f /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.dwp
RUN: at line 29: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb --no-lldbinit -S /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/lit-lldb-init-quiet    -o "type lookup IntegerType"    -o "type lookup FloatType"    -o "type lookup CustomType"    -b /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp | /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/FileCheck /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp --check-prefix=NODWP
+ /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb --no-lldbinit -S /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/lit-lldb-init-quiet -o 'type lookup IntegerType' -o 'type lookup FloatType' -o 'type lookup CustomType' -b /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp
+ /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/FileCheck /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp --check-prefix=NODWP
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp:37:11: error: NODWP: expected string not found in input
// NODWP: (lldb) type lookup FloatType
          ^
<stdin>:20:22: note: scanning from here
 typedef unsigned int IntegerType;
                     ^
<stdin>:21:3: note: possible intended match here
 typedef float FloatType;
  ^

Input file: <stdin>
Check file: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            .
            .
            .
           15:  typedef double FloatType; 

kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
… helper (llvm#97544)

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
Michael137 added a commit to Michael137/llvm-project that referenced this pull request Jul 8, 2024
Depends on:
* llvm#97544
* llvm#97549
* llvm#97551

This patch tries to simplify the way in which the
`std::map` formatter goes from the root `__tree`
pointer to a specific key/value pair.

Previously we would synthesize a structure that
mimicked what `__iter_pointer` looked like
in memory, then called `GetChildCompilerTypeAtIndex`
on it to find the byte offset into that structure
at which the pair was located at, and finally
use that offset through a call to `GetSyntheticChildAtOffset`
to retrieve that pair. Not only was this logic hard to follow,
and encoded the libc++ layout in non-obvious ways, it was also
fragile to alignment miscalculations
(llvm#97443); this would
break after the new layout of std::map landed as part of
inhttps://github.com/llvm/issues/93069.

Instead, this patch simply casts the `__iter_pointer` to
the `__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value
we care about. This allows us to get rid of some support
infrastructure/class state.

Ideally we would fix the underlying alignment issue, but
this unblocks the libc++ refactor in the interim,
while also benefitting the formatter in terms of readability (in my opinion).
Michael137 added a commit to Michael137/llvm-project that referenced this pull request Jul 8, 2024
Depends on:
* llvm#97544
* llvm#97549
* llvm#97551

This patch tries to simplify the way in which the
`std::map` formatter goes from the root `__tree`
pointer to a specific key/value pair.

Previously we would synthesize a structure that
mimicked what `__iter_pointer` looked like
in memory, then called `GetChildCompilerTypeAtIndex`
on it to find the byte offset into that structure
at which the pair was located at, and finally
use that offset through a call to `GetSyntheticChildAtOffset`
to retrieve that pair. Not only was this logic hard to follow,
and encoded the libc++ layout in non-obvious ways, it was also
fragile to alignment miscalculations
(llvm#97443); this would
break after the new layout of std::map landed as part of
inhttps://github.com/llvm/issues/93069.

Instead, this patch simply casts the `__iter_pointer` to
the `__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value
we care about. This allows us to get rid of some support
infrastructure/class state.

Ideally we would fix the underlying alignment issue, but
this unblocks the libc++ refactor in the interim,
while also benefitting the formatter in terms of readability (in my opinion).
Michael137 added a commit that referenced this pull request Jul 8, 2024
Depends on:
* #97544
* #97549
* #97551

This patch tries to simplify the way in which the `std::map` formatter
goes from the root `__tree` pointer to a specific key/value pair.

Previously we would:
1. synthesize a structure that mimicked what `__iter_pointer` looked
like in memory
2. call `GetChildCompilerTypeAtIndex` on it to find the byte offset at
which the pair was located in the synthesized structure
3. finally, use that offset through a call to
`GetSyntheticChildAtOffset` to retrieve the key/value pair

Not only was this logic hard to follow, and encoded the libc++ layout in
non-obvious ways, it was also fragile to alignment miscalculations
(#97443); this would break once
the new layout of std::map landed as part of
#93069.

Instead, this patch simply casts the `__iter_pointer` to the
`__node_pointer` and uses a straightforward
`GetChildMemberWithName("__value_")` to get to the key/value we care
about. This allows us to get rid of some support infrastructure/class
state.

Ideally we would fix the underlying alignment issue, but this unblocks
the libc++ refactor in the interim, while also benefitting the formatter
in terms of readability (in my opinion).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants