[Lldb-commits] [lldb] 1056c56 - [lldb] Adjust libc++ string formatter for changes in D123580

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 21 05:18:10 PDT 2022


Author: Pavel Labath
Date: 2022-04-21T14:07:56+02:00
New Revision: 1056c56786c10866ffd7e878f8c75ad1f0914c07

URL: https://github.com/llvm/llvm-project/commit/1056c56786c10866ffd7e878f8c75ad1f0914c07
DIFF: https://github.com/llvm/llvm-project/commit/1056c56786c10866ffd7e878f8c75ad1f0914c07.diff

LOG: [lldb] Adjust libc++ string formatter for changes in D123580

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.

Differential Revision: https://reviews.llvm.org/D124113

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 2fd69452217c7..be2e4da80881a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -555,6 +555,7 @@ enum LibcxxStringLayoutMode {
 
 /// Determine the size in bytes of \p valobj (a libc++ std::string object) and
 /// extract its data payload. Return the size + payload pair.
+// TODO: Support big-endian architectures.
 static llvm::Optional<std::pair<uint64_t, ValueObjectSP>>
 ExtractLibcxxStringInfo(ValueObject &valobj) {
   ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
@@ -572,14 +573,27 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
   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, 2}, // Post-c3d0205ee771 layout. This was in use for only a brief
+                // period, so we can delete it if it becomes a burden.
         {1, 1, 0},
         {1, 1, 1},
     };
@@ -610,9 +624,10 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
       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 +646,18 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
   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_"), /*can_create=*/true);
+  ValueObjectSP size_vo =
+      l->GetChildMemberWithName(ConstString("__size_"), /*can_create=*/true);
+  ValueObjectSP capacity_vo =
+      l->GetChildMemberWithName(ConstString("__cap_"), /*can_create=*/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 && layout == eLibcxxStringLayoutModeCSD)
+    capacity *= 2;
   if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
       capacity < size)
     return {};


        


More information about the lldb-commits mailing list