[Lldb-commits] [PATCH] D124113: [lldb] Adjust libc++ string formatter for changes in D123580

Pavel Labath via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 20 11:59:31 PDT 2022


labath created this revision.
labath added reviewers: shafik, JDevlieghere, philnik.
Herald added a project: All.
labath requested review of this revision.
Herald added a project: LLDB.

The code needs more TLC, but for now I've tried making only the changes
that are necessary to get the tests passing -- postponing the more
invasive changes after I create a more comprehensive test.

In a couple of places I have changed the index-based element accesses to
name-based ones (as these are less sensitive to code perturbations). I'm
not sure why the code was using indexes in the first place, but I've
(manually) tested the change with various libc++ versions, and found no
issues with this approach.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124113

Files:
  lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp


Index: lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -572,12 +572,24 @@
   ConstString g_size_name("__size_");
   bool short_mode = false; // this means the string is in short-mode and the
                            // data is stored inline
+  bool using_bitmasks = true; // Whether the class uses bitmasks for the mode
+                              // flag (pre-D123580).
+  uint64_t size;
   LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name)
                                       ? eLibcxxStringLayoutModeDSC
                                       : eLibcxxStringLayoutModeCSD;
   uint64_t size_mode_value = 0;
 
-  if (layout == eLibcxxStringLayoutModeDSC) {
+  if (ValueObjectSP is_long = D->GetChildAtNamePath(
+          {ConstString("__s"), ConstString("__is_long_")})) {
+    using_bitmasks = false;
+    short_mode = !is_long->GetValueAsUnsigned(/*fail_value=*/0);
+    if (ValueObjectSP size_member =
+            D->GetChildAtNamePath({ConstString("__s"), ConstString("__size_")}))
+      size = size_member->GetValueAsUnsigned(/*fail_value=*/0);
+    else
+      return {};
+  } else if (layout == eLibcxxStringLayoutModeDSC) {
     llvm::SmallVector<size_t, 3> size_mode_locations[] = {
         {1, 2}, // Post-c3d0205ee771 layout
         {1, 1, 0},
@@ -610,9 +622,10 @@
       return {};
     ValueObjectSP location_sp = s->GetChildAtIndex(
         (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
-    const uint64_t size = (layout == eLibcxxStringLayoutModeDSC)
-                              ? size_mode_value
-                              : ((size_mode_value >> 1) % 256);
+    if (using_bitmasks)
+      size = (layout == eLibcxxStringLayoutModeDSC)
+                 ? size_mode_value
+                 : ((size_mode_value >> 1) % 256);
 
     // When the small-string optimization takes place, the data must fit in the
     // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
@@ -631,18 +644,18 @@
   if (!l)
     return {};
   // we can use the layout_decider object as the data pointer
-  ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC)
-                                  ? layout_decider
-                                  : l->GetChildAtIndex(2, true);
-  ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
-  const unsigned capacity_index =
-      (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0;
-  ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
+  ValueObjectSP location_sp =
+      l->GetChildMemberWithName(ConstString("__data_"), true);
+  ValueObjectSP size_vo =
+      l->GetChildMemberWithName(ConstString("__size_"), true);
+  ValueObjectSP capacity_vo =
+      l->GetChildMemberWithName(ConstString("__cap_"), true);
   if (!size_vo || !location_sp || !capacity_vo)
     return {};
-  const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
-  const uint64_t capacity =
-      capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
+  size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
+  uint64_t capacity = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
+  if (!using_bitmasks)
+    capacity *= 2;
   if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
       capacity < size)
     return {};


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124113.423990.patch
Type: text/x-patch
Size: 3460 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220420/d8202dc8/attachment.bin>


More information about the lldb-commits mailing list