[Lldb-commits] [lldb] [lldb] fix single-character token not underlined correctly in diagnostics (PR #197658)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Fri May 15 02:20:01 PDT 2026


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

>From f33c2150dad648083386701c1d7a3f4423deaacf Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 14 May 2026 13:39:16 +0200
Subject: [PATCH 1/2] [lldb] fix single-character token not underlined
 correctly in diagnostics

---
 .../Clang/ClangExpressionParser.cpp                 | 13 ++++++++++++-
 .../Host/common/DiagnosticsRenderingTest.cpp        | 12 ++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index ae02fda33fe66..d304f3fa1cce0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -30,6 +30,7 @@
 #include "clang/Frontend/TextDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseAST.h"
 #include "clang/Rewrite/Core/Rewriter.h"
@@ -279,8 +280,16 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
           // Find the range of the primary location.
           for (const auto &range : Info.getRanges()) {
             if (range.getBegin() == sloc) {
+              SourceLocation end = range.getEnd();
+              if (range.isTokenRange())
+                end =
+                    clang::Lexer::getLocForEndOfToken(end, 0, sm, m_lang_opts);
+              // Ignore ranges that span multiple lines.
+              if (sm.getSpellingLineNumber(end) !=
+                  sm.getSpellingLineNumber(sloc))
+                break;
               // FIXME: This is probably not handling wide characters correctly.
-              unsigned end_col = sm.getSpellingColumnNumber(range.getEnd());
+              unsigned end_col = sm.getSpellingColumnNumber(end);
               if (end_col > loc.column)
                 loc.length = end_col - loc.column;
               break;
@@ -307,6 +316,7 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
   }
 
   void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
+    m_lang_opts = LO;
     m_passthrough->BeginSourceFile(LO, PP);
   }
 
@@ -315,6 +325,7 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
 private:
   DiagnosticManager *m_manager = nullptr;
   DiagnosticOptions m_options;
+  LangOptions m_lang_opts;
   /// Output string filled by m_os.
   std::string m_output;
   /// Output stream of m_passthrough.
diff --git a/lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp b/lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
index 896ce1995fe1c..da2372837acb2 100644
--- a/lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
+++ b/lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
@@ -26,6 +26,18 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
     ASSERT_TRUE(StringRef(result).contains("foo"));
   }
 
+  {
+    // Test that a single-character token (length=1) renders as just a caret
+    // with no underlines.
+    SourceLocation loc1 = {FileSpec{"a.c"}, 1, 6, 1, false, true};
+    std::string result =
+        Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"}});
+    llvm::SmallVector<StringRef> lines;
+    StringRef(result).split(lines, '\n');
+    //                123456
+    ASSERT_EQ(lines[0], "     ^");
+    ASSERT_EQ(lines[1], "     error: X");
+  }
   {
     // Test that diagnostics on the same column can be handled and all
     // three errors are diagnosed.

>From 8ba5258fc326a19a8cfa99456806ad384cb21129 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 15 May 2026 11:19:43 +0200
Subject: [PATCH 2/2] fixup! [lldb] fix single-character token not underlined
 correctly in diagnostics

---
 .../Clang/ClangExpressionParser.cpp           | 27 +++++++++----------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index d304f3fa1cce0..86664e72d54e8 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -279,21 +279,20 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
 
           // Find the range of the primary location.
           for (const auto &range : Info.getRanges()) {
-            if (range.getBegin() == sloc) {
-              SourceLocation end = range.getEnd();
-              if (range.isTokenRange())
-                end =
-                    clang::Lexer::getLocForEndOfToken(end, 0, sm, m_lang_opts);
-              // Ignore ranges that span multiple lines.
-              if (sm.getSpellingLineNumber(end) !=
-                  sm.getSpellingLineNumber(sloc))
-                break;
-              // FIXME: This is probably not handling wide characters correctly.
-              unsigned end_col = sm.getSpellingColumnNumber(end);
-              if (end_col > loc.column)
-                loc.length = end_col - loc.column;
+            if (range.getBegin() != sloc)
+              continue
+            SourceLocation end = range.getEnd();
+            if (range.isTokenRange())
+              end =
+                  clang::Lexer::getLocForEndOfToken(end, 0, sm, m_lang_opts);
+            // FIXME: This is probably not handling wide characters correctly.
+            unsigned end_col = sm.getSpellingColumnNumber(end);
+            // Ignore ranges that span multiple lines.
+            if (end_col != sm.getSpellingLineNumber(sloc))
               break;
-            }
+            if (end_col > loc.column)
+              loc.length = end_col - loc.column;
+            break;
           }
           detail.source_location = loc;
         }



More information about the lldb-commits mailing list