[Lldb-commits] [lldb] [llvm] [lldb] improve the heuristics for checking if a terminal supports Unicode (PR #168603)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Wed Nov 19 04:35:07 PST 2025


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/168603

>From 2cc2c6b71bd9074464f3a979a1327f0d61ecdb5e Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Wed, 19 Nov 2025 12:10:08 +0100
Subject: [PATCH 1/3] [NFC][lldb] move DiagnosticsRendering to Host

---
 lldb/include/lldb/Expression/DiagnosticManager.h                | 2 +-
 .../lldb/{Utility => Host/common}/DiagnosticsRendering.h        | 0
 lldb/include/lldb/Interpreter/CommandReturnObject.h             | 2 +-
 lldb/include/lldb/ValueObject/DILParser.h                       | 2 +-
 lldb/source/Commands/CommandObjectExpression.cpp                | 2 +-
 lldb/source/Host/CMakeLists.txt                                 | 1 +
 lldb/source/{Utility => Host/common}/DiagnosticsRendering.cpp   | 2 +-
 lldb/source/Interpreter/CommandReturnObject.cpp                 | 2 +-
 lldb/source/Interpreter/Options.cpp                             | 2 +-
 lldb/source/Utility/CMakeLists.txt                              | 1 -
 lldb/source/ValueObject/DILParser.cpp                           | 2 +-
 lldb/unittests/Utility/DiagnosticsRenderingTest.cpp             | 2 +-
 llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn               | 1 +
 llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn            | 1 -
 14 files changed, 11 insertions(+), 11 deletions(-)
 rename lldb/include/lldb/{Utility => Host/common}/DiagnosticsRendering.h (100%)
 rename lldb/source/{Utility => Host/common}/DiagnosticsRendering.cpp (99%)

diff --git a/lldb/include/lldb/Expression/DiagnosticManager.h b/lldb/include/lldb/Expression/DiagnosticManager.h
index fc49349d1b7c3..c7e02d80cf750 100644
--- a/lldb/include/lldb/Expression/DiagnosticManager.h
+++ b/lldb/include/lldb/Expression/DiagnosticManager.h
@@ -12,7 +12,7 @@
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-types.h"
 
-#include "lldb/Utility/DiagnosticsRendering.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Status.h"
 
diff --git a/lldb/include/lldb/Utility/DiagnosticsRendering.h b/lldb/include/lldb/Host/common/DiagnosticsRendering.h
similarity index 100%
rename from lldb/include/lldb/Utility/DiagnosticsRendering.h
rename to lldb/include/lldb/Host/common/DiagnosticsRendering.h
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index d53aeb81be2ba..0742f1b836f5e 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -10,7 +10,7 @@
 #define LLDB_INTERPRETER_COMMANDRETURNOBJECT_H
 
 #include "lldb/Host/StreamFile.h"
-#include "lldb/Utility/DiagnosticsRendering.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StreamTee.h"
 #include "lldb/Utility/StructuredData.h"
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index d17ed66d9b3ee..c9d28333ffed1 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -9,8 +9,8 @@
 #ifndef LLDB_VALUEOBJECT_DILPARSER_H
 #define LLDB_VALUEOBJECT_DILPARSER_H
 
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Target/ExecutionContextScope.h"
-#include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/ValueObject/DILAST.h"
 #include "lldb/ValueObject/DILLexer.h"
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 197bffe9c982f..4919bd3639d3e 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Expression/UserExpression.h"
 #include "lldb/Host/OptionParser.h"
 #include "lldb/Host/StreamFile.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
@@ -21,7 +22,6 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
-#include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private-enumerations.h"
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index c9e8afe48fcde..3184d3a1ead0d 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -17,6 +17,7 @@ macro(add_host_subdirectory group)
 endmacro()
 
 add_host_subdirectory(common
+  common/DiagnosticsRendering.cpp
   common/FileAction.cpp
   common/FileCache.cpp
   common/File.cpp
diff --git a/lldb/source/Utility/DiagnosticsRendering.cpp b/lldb/source/Host/common/DiagnosticsRendering.cpp
similarity index 99%
rename from lldb/source/Utility/DiagnosticsRendering.cpp
rename to lldb/source/Host/common/DiagnosticsRendering.cpp
index 8c21e661ce764..f2cd3968967fb 100644
--- a/lldb/source/Utility/DiagnosticsRendering.cpp
+++ b/lldb/source/Host/common/DiagnosticsRendering.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/Utility/DiagnosticsRendering.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include <cstdint>
 
 using namespace lldb_private;
diff --git a/lldb/source/Interpreter/CommandReturnObject.cpp b/lldb/source/Interpreter/CommandReturnObject.cpp
index 0a2948e8e6ca4..ef5bfae1bd1bd 100644
--- a/lldb/source/Interpreter/CommandReturnObject.cpp
+++ b/lldb/source/Interpreter/CommandReturnObject.cpp
@@ -8,7 +8,7 @@
 
 #include "lldb/Interpreter/CommandReturnObject.h"
 
-#include "lldb/Utility/DiagnosticsRendering.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StreamString.h"
 
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp
index cae617813d2fd..73b817ece16be 100644
--- a/lldb/source/Interpreter/Options.cpp
+++ b/lldb/source/Interpreter/Options.cpp
@@ -14,13 +14,13 @@
 #include <set>
 
 #include "lldb/Host/OptionParser.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Interpreter/CommandCompletions.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/AnsiTerminal.h"
-#include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/STLExtras.h"
 
diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt
index 1dd4d63f7016f..338b8bd8b0ef1 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -38,7 +38,6 @@ add_lldb_library(lldbUtility NO_INTERNAL_DEPENDENCIES
   DataEncoder.cpp
   DataExtractor.cpp
   Diagnostics.cpp
-  DiagnosticsRendering.cpp
   Environment.cpp
   ErrorMessages.cpp
   Event.cpp
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index 566bcaf81094a..82b97aafe2261 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -12,8 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/ValueObject/DILParser.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Target/ExecutionContextScope.h"
-#include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/ValueObject/DILAST.h"
 #include "lldb/ValueObject/DILEval.h"
 #include "llvm/ADT/StringRef.h"
diff --git a/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp b/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
index 4e5e0bb7dc355..851b478def32e 100644
--- a/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
+++ b/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
@@ -1,4 +1,4 @@
-#include "lldb/Utility/DiagnosticsRendering.h"
+#include "lldb/Host/common/DiagnosticsRendering.h"
 #include "lldb/Utility/StreamString.h"
 #include "gtest/gtest.h"
 
diff --git a/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn
index 10c5f95edf5fd..af4533285d3e9 100644
--- a/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn
@@ -16,6 +16,7 @@ static_library("Host") {
   ]
   public_deps = [ "//llvm/utils/gn/build/libs/xml" ]
   sources = [
+    "common/DiagnosticsRendering.cpp",
     "common/File.cpp",
     "common/FileAction.cpp",
     "common/FileCache.cpp",
diff --git a/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn
index 4221fab1e237b..5faa365bb7bdb 100644
--- a/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn
@@ -21,7 +21,6 @@ static_library("Utility") {
     "DataEncoder.cpp",
     "DataExtractor.cpp",
     "Diagnostics.cpp",
-    "DiagnosticsRendering.cpp",
     "Environment.cpp",
     "ErrorMessages.cpp",
     "Event.cpp",

>From 80e4d5bb544bed2d1da979fae9f0009198553e38 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Wed, 19 Nov 2025 12:42:03 +0100
Subject: [PATCH 2/3] fixup! [NFC][lldb] move DiagnosticsRendering to Host

---
 lldb/unittests/Host/common/CMakeLists.txt                        | 1 +
 .../{Utility => Host/common}/DiagnosticsRenderingTest.cpp        | 0
 lldb/unittests/Utility/CMakeLists.txt                            | 1 -
 3 files changed, 1 insertion(+), 1 deletion(-)
 rename lldb/unittests/{Utility => Host/common}/DiagnosticsRenderingTest.cpp (100%)

diff --git a/lldb/unittests/Host/common/CMakeLists.txt b/lldb/unittests/Host/common/CMakeLists.txt
index 2934e6f0b4315..8aa2dfb4e8e1e 100644
--- a/lldb/unittests/Host/common/CMakeLists.txt
+++ b/lldb/unittests/Host/common/CMakeLists.txt
@@ -1,4 +1,5 @@
 set (FILES
+  DiagnosticsRenderingTest.cpp
   ZipFileResolverTest.cpp
 )
 
diff --git a/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp b/lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
similarity index 100%
rename from lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
rename to lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
diff --git a/lldb/unittests/Utility/CMakeLists.txt b/lldb/unittests/Utility/CMakeLists.txt
index aed4177f5edee..2bdd50291d2ae 100644
--- a/lldb/unittests/Utility/CMakeLists.txt
+++ b/lldb/unittests/Utility/CMakeLists.txt
@@ -10,7 +10,6 @@ add_lldb_unittest(UtilityTests
   DataBufferTest.cpp
   DataEncoderTest.cpp
   DataExtractorTest.cpp
-  DiagnosticsRenderingTest.cpp
   EnvironmentTest.cpp
   EventTest.cpp
   FileSpecListTest.cpp

>From 41676badbd630bdc67bedb99a6facc39825323df Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Tue, 18 Nov 2025 22:41:43 +0100
Subject: [PATCH 3/3] [lldb] improve the heuristics for checking if a terminal
 supports Unicode

---
 lldb/include/lldb/Host/Terminal.h                | 11 +++++++++++
 lldb/source/Host/common/DiagnosticsRendering.cpp |  8 +++-----
 lldb/source/Host/common/Terminal.cpp             | 15 +++++++++++++++
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/lldb/include/lldb/Host/Terminal.h b/lldb/include/lldb/Host/Terminal.h
index da0d05e8bd265..6da5d45644b28 100644
--- a/lldb/include/lldb/Host/Terminal.h
+++ b/lldb/include/lldb/Host/Terminal.h
@@ -169,6 +169,17 @@ class TerminalState {
   lldb::pid_t m_process_group = -1;       ///< Cached process group information.
 };
 
+/// Returns whether or not the current terminal supports Unicode rendering.
+///
+/// The value is cached after the first computation.
+///
+/// On POSIX systems, we check if the LANG environment variable contains the
+/// substring "UTF-8";
+///
+/// On Windows, we check that we are running from the Windows Terminal
+/// application.
+bool TerminalSupportsUnicode();
+
 } // namespace lldb_private
 
 #endif // LLDB_HOST_TERMINAL_H
diff --git a/lldb/source/Host/common/DiagnosticsRendering.cpp b/lldb/source/Host/common/DiagnosticsRendering.cpp
index f2cd3968967fb..c7e083573c631 100644
--- a/lldb/source/Host/common/DiagnosticsRendering.cpp
+++ b/lldb/source/Host/common/DiagnosticsRendering.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Host/common/DiagnosticsRendering.h"
+#include "lldb/Host/Terminal.h"
+
 #include <cstdint>
 
 using namespace lldb_private;
@@ -97,12 +99,8 @@ void RenderDiagnosticDetails(Stream &stream,
     return;
   }
 
-  // Since there is no other way to find this out, use the color
-  // attribute as a proxy for whether the terminal supports Unicode
-  // characters.  In the future it might make sense to move this into
-  // Host so it can be customized for a specific platform.
   llvm::StringRef cursor, underline, vbar, joint, hbar, spacer;
-  if (stream.AsRawOstream().colors_enabled()) {
+  if (TerminalSupportsUnicode()) {
     cursor = "˄";
     underline = "˜";
     vbar = "│";
diff --git a/lldb/source/Host/common/Terminal.cpp b/lldb/source/Host/common/Terminal.cpp
index 436dfd8130d9b..825e9e0aee78e 100644
--- a/lldb/source/Host/common/Terminal.cpp
+++ b/lldb/source/Host/common/Terminal.cpp
@@ -472,3 +472,18 @@ bool TerminalState::TTYStateIsValid() const { return bool(m_data); }
 bool TerminalState::ProcessGroupIsValid() const {
   return static_cast<int32_t>(m_process_group) != -1;
 }
+
+bool lldb_private::TerminalSupportsUnicode() {
+  static std::optional<bool> result;
+  if (result)
+    return result.value();
+#ifdef _WIN32
+  return true;
+#else
+  const char *lang_var = std::getenv("LANG");
+  if (!lang_var)
+    return false;
+  result = llvm::StringRef(lang_var).lower().find("utf-8") != std::string::npos;
+#endif
+  return result.value();
+}



More information about the lldb-commits mailing list