zturner created this revision.
zturner added a reviewer: jingham.

char16, char32, and wchar_t were previously broken.  If you had a simple 
variable like `wchar_t x = L'1'` and wrote `p x` LLDB would output `(wchar_t) x 
= 1\0`.  This is because it was using `eFormatChar` with a size of 2.  What we 
needed was to introduce a special format specifically for `wchar_t`.  The only 
valid sizes of `wchar_t` on all existing compilers are 2 and 4, so there's no 
real point trying to handle sizes of 1 and 8.

Along the way, I accidentally stumbled across the reason that references that 
char16 and char32 types were also formatting incorrectly, so I fixed that as 
well.


https://reviews.llvm.org/D53989

Files:
  lldb/include/lldb/lldb-enumerations.h
  lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp
  lldb/source/Commands/CommandObjectMemory.cpp
  lldb/source/Core/DumpDataExtractor.cpp
  lldb/source/Core/ValueObject.cpp
  lldb/source/DataFormatters/FormatManager.cpp
  lldb/source/DataFormatters/VectorType.cpp
  lldb/source/Symbol/ClangASTContext.cpp

Index: lldb/source/Symbol/ClangASTContext.cpp
===================================================================
--- lldb/source/Symbol/ClangASTContext.cpp
+++ lldb/source/Symbol/ClangASTContext.cpp
@@ -5257,11 +5257,12 @@
       return lldb::eFormatBoolean;
     case clang::BuiltinType::Char_S:
     case clang::BuiltinType::SChar:
-    case clang::BuiltinType::WChar_S:
     case clang::BuiltinType::Char_U:
     case clang::BuiltinType::UChar:
-    case clang::BuiltinType::WChar_U:
       return lldb::eFormatChar;
+    case clang::BuiltinType::WChar_S:
+    case clang::BuiltinType::WChar_U:
+      return lldb::eFormatWchar;
     case clang::BuiltinType::Char16:
       return lldb::eFormatUnicode16;
     case clang::BuiltinType::Char32:
Index: lldb/source/DataFormatters/VectorType.cpp
===================================================================
--- lldb/source/DataFormatters/VectorType.cpp
+++ lldb/source/DataFormatters/VectorType.cpp
@@ -64,9 +64,12 @@
   case lldb::eFormatHexFloat:
     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
 
+  case lldb::eFormatWchar:
+    return type_system->GetBasicTypeFromAST(lldb::eBasicTypeWChar);
   case lldb::eFormatUnicode16:
+    return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar16);
   case lldb::eFormatUnicode32:
-
+    return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar32);
   case lldb::eFormatUnsigned:
     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
 
Index: lldb/source/DataFormatters/FormatManager.cpp
===================================================================
--- lldb/source/DataFormatters/FormatManager.cpp
+++ lldb/source/DataFormatters/FormatManager.cpp
@@ -43,6 +43,7 @@
     {eFormatBytesWithASCII, 'Y', "bytes with ASCII"},
     {eFormatChar, 'c', "character"},
     {eFormatCharPrintable, 'C', "printable character"},
+    {eFormatWchar, 'L', "wide character"},
     {eFormatComplexFloat, 'F', "complex float"},
     {eFormatCString, 's', "c-string"},
     {eFormatDecimal, 'd', "decimal"},
Index: lldb/source/Core/ValueObject.cpp
===================================================================
--- lldb/source/Core/ValueObject.cpp
+++ lldb/source/Core/ValueObject.cpp
@@ -1383,6 +1383,7 @@
           (custom_format == eFormatOSType) ||
           (custom_format == eFormatUnicode16) ||
           (custom_format == eFormatUnicode32) ||
+          (custom_format == eFormatWchar) ||
           (custom_format == eFormatUnsigned) ||
           (custom_format == eFormatPointer) ||
           (custom_format == eFormatComplexInteger) ||
Index: lldb/source/Core/DumpDataExtractor.cpp
===================================================================
--- lldb/source/Core/DumpDataExtractor.cpp
+++ lldb/source/Core/DumpDataExtractor.cpp
@@ -637,6 +637,23 @@
       }
     } break;
 
+    case eFormatWchar: {
+      s->PutChar('L');
+      s->PutChar(item_count == 1 ? '\'' : '\"');
+
+      const uint64_t ch = DE.GetMaxU64(&offset, item_byte_size);
+      // wchar_t semantics vary across platforms, and this is complicated even
+      // more by the fact that the host may not be the same as the target, so to
+      // be faithful we would have to follow the target's semantics.  For
+      // simplicity, just print the character if it's ascii.
+      if (ch <= CHAR_MAX && llvm::isPrint(ch))
+        s->PutChar(ch);
+      else
+        s->PutChar(NON_PRINTABLE_CHAR);
+
+      s->PutChar(item_count == 1 ? '\'' : '\"');
+    } break;
+
     case eFormatUnicode16:
       s->Printf("U+%4.4x", DE.GetU16(&offset));
       break;
Index: lldb/source/Commands/CommandObjectMemory.cpp
===================================================================
--- lldb/source/Commands/CommandObjectMemory.cpp
+++ lldb/source/Commands/CommandObjectMemory.cpp
@@ -167,6 +167,15 @@
         format_options.GetCountValue() = 8;
       break;
 
+    case eFormatWchar:
+      if (!byte_size_option_set)
+        byte_size_value =
+            target->GetArchitecture().GetTriple().isOSWindows() ? 2 : 4;
+      if (!num_per_line_option_set)
+        m_num_per_line = 1;
+      if (!count_option_set)
+        format_options.GetCountValue() = 8;
+      break;
     case eFormatBinary:
     case eFormatFloat:
     case eFormatOctal:
@@ -1412,6 +1421,7 @@
       case eFormatBytesWithASCII:
       case eFormatComplex:
       case eFormatEnum:
+      case eFormatWchar:
       case eFormatUnicode16:
       case eFormatUnicode32:
       case eFormatVectorOfChar:
Index: lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp
===================================================================
--- lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp
+++ lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp
@@ -637,32 +637,32 @@
 
 char16_t &RC16_24 = C16_24;
 // CHECK: (lldb) target variable RC16_24
-// FIXME: (char16_t &) RC16_24 = {{.*}} (&::RC16_24 = U+0014)
+// CHECK: (char16_t &) RC16_24 = {{.*}} (&::RC16_24 = U+0014)
 char32_t &RC32_42 = C32_42;
 // CHECK: (lldb) target variable RC32_42
-// FIXME: (char32_t &) RC32_42 = {{.*}} (&::RC32_42 = U+0x00000022)
+// CHECK: (char32_t &) RC32_42 = {{.*}} (&::RC32_42 = U+0x00000022)
 wchar_t &RWC1 = WC1;
 // CHECK: (lldb) target variable RWC1
-// FIXME: (wchar_t &) RWC1 = {{.*}} (&::RWC1 = L'1')
+// CHECK: (wchar_t &) RWC1 = {{.*}} (&::RWC1 = L'1')
 wchar_t &RWCP = WCP;
 // CHECK: (lldb) target variable RWCP
-// FIXME: (wchar_t &) RWCP = {{.*}} (&::RWCP = L'P')
+// CHECK: (wchar_t &) RWCP = {{.*}} (&::RWCP = L'P')
 const char16_t &CRC16_24 = C16_24;
 // CHECK: (lldb) target variable CRC16_24
-// FIXME: (const char16_t &) CRC16_24 = {{.*}} (&::CRC16_24 = U+0014)
+// CHECK: (const char16_t &) CRC16_24 = {{.*}} (&::CRC16_24 = U+0014)
 const char32_t &CRC32_42 = C32_42;
 // CHECK: (lldb) target variable CRC32_42
-// FIXME: (const char32_t &) CRC32_42 = {{.*}} (&::CRC32_42 = U+0x00000022)
+// CHECK: (const char32_t &) CRC32_42 = {{.*}} (&::CRC32_42 = U+0x00000022)
 const wchar_t &CRWC1 = WC1;
 // CHECK: (lldb) target variable CRWC1
-// FIXME: (const wchar_t &) CRWC1 = {{.*}} (&::CRWC1 = L'1')
+// CHECK: (const wchar_t &) CRWC1 = {{.*}} (&::CRWC1 = L'1')
 const wchar_t &CRWCP = WCP;
 // CHECK: (lldb) target variable CRWCP
-// FIXME: (const wchar_t &) CRWCP = {{.*}} (&::CRWCP = L'P')
+// CHECK: (const wchar_t &) CRWCP = {{.*}} (&::CRWCP = L'P')
 
 
 // CHECK: (lldb) quit
 
 int main(int argc, char **argv) {
   return CIMax;
 }
\ No newline at end of file
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -162,6 +162,7 @@
   eFormatBytes,
   eFormatBytesWithASCII,
   eFormatChar,
+  eFormatWchar,
   eFormatCharPrintable, // Only printable characters, space if not printable
   eFormatComplex,       // Floating point complex type
   eFormatComplexFloat = eFormatComplex,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to