https://github.com/cor3ntin created 
https://github.com/llvm/llvm-project/pull/206990

In #206326, we introduced yet another way to format a codepoint, so we try to 
claw back some consistency.

- When we display a single character we do so inside quotes
- Non-decodable code units are displayed as <0xYY>
- In strings
    - we render printable and format characters
    - we print <U+XXXX> for non printable, non-format characters

- In characters
    - we only render non-format print characters
    - we always print the codepoint as U+XXXX for non-ascii characters

This does not change `WriteCharValueForDiagnostic` which is deeply weird and 
was contentious a while back.

So we still have 2 different formatting utilities. Which is better than 4!

I've also added a test for invalid utf-8 in \N{}

>From f2f1d661b57c287b9236ebe36ec80a2a95cb5a50 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Wed, 1 Jul 2026 15:43:48 +0200
Subject: [PATCH] [Clang] Reduce the number of ways we have to print a
 codepoint.

In #206326, we introduced yet another way to format a codepoint,
so we try to claw back some consistency.

- When we display a single character we do so inside quotes
- Non-decodable code units are displayed as <0xYY>
- In strings
    - we render printable and format characters
    - we print <U+XXXX> for non printable, non-format characters

- In characters
    - we only render non-format print characters
    - we always print the codepoint as U+XXXX

This does not change `WriteCharValueForDiagnostic` which is deeply weird
and was contentous a while back.

So we still have 2 different formatting utilities.
Which is better than 4!

I've also added a test for invalid utf-8 in \N{}
---
 clang/include/clang/Basic/Diagnostic.h        |  3 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 +-
 clang/lib/AST/ASTDiagnostic.cpp               |  8 +-
 clang/lib/Basic/Diagnostic.cpp                | 78 ++++++++++++-------
 clang/lib/Lex/LiteralSupport.cpp              | 12 +--
 .../char-escapes-delimited-invalid-utf8.c     |  5 ++
 clang/test/Lexer/char-escapes-delimited.c     |  2 +-
 clang/test/SemaCXX/static-assert-cxx26.cpp    |  2 +-
 clang/test/SemaCXX/static-assert.cpp          |  8 +-
 .../warn-implicit-unicode-conversions.cpp     | 28 +++----
 clang/unittests/Basic/DiagnosticTest.cpp      | 24 +++---
 llvm/include/llvm/Support/ConvertUTF.h        |  4 +
 llvm/lib/Support/ConvertUTF.cpp               |  5 +-
 13 files changed, 103 insertions(+), 80 deletions(-)
 create mode 100644 clang/test/Lexer/char-escapes-delimited-invalid-utf8.c

diff --git a/clang/include/clang/Basic/Diagnostic.h 
b/clang/include/clang/Basic/Diagnostic.h
index c033320687078..66e79e3b4300b 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -1877,7 +1877,8 @@ void ProcessWarningOptions(DiagnosticsEngine &Diags,
                            const DiagnosticOptions &Opts,
                            llvm::vfs::FileSystem &VFS, bool ReportDiags = 
true);
 void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl<char> &OutStr);
-llvm::SmallString<16> DisplayCodePointForDiagnostic(llvm::UTF32 CodePoint);
+SmallString<16> EscapeSingleCodepointForDiagnostic(StringRef Str);
+SmallString<16> EscapeSingleCodepointForDiagnostic(llvm::UTF32 CP);
 } // namespace clang
 
 #endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 86b765fdf1fab..05f49a4dbd1ca 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4664,7 +4664,7 @@ def warn_impcast_unicode_precision
       InGroup<CharacterConversion>;
 def warn_impcast_unicode_char_type_constant
     : Warning<"implicit conversion from %0 to %1 changes the meaning of the "
-              "%select{code unit|code point}2 '%3'">,
+              "%select{code unit|code point}2 %3">,
       InGroup<CharacterConversion>;
 
 def warn_comparison_unicode_mixed_types
@@ -4674,7 +4674,7 @@ def warn_comparison_unicode_mixed_types
 
 def warn_comparison_unicode_mixed_types_constant
     : Warning<"comparing values of different Unicode code unit types %0 and %1 
"
-              "compares unrelated code units '%2' and '%3'">,
+              "compares unrelated code units %2 and %3">,
       InGroup<CharacterConversion>;
 
 def warn_xor_used_as_pow : Warning<
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index b8023cb6fa10f..f7888f58985db 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -2212,10 +2212,6 @@ std::string clang::FormatUTFCodeUnitAsCodepoint(unsigned 
Value, QualType T) {
     return std::string(Str.begin(), Str.end());
   }
 
-  char Buffer[UNI_MAX_UTF8_BYTES_PER_CODE_POINT];
-  char *Ptr = Buffer;
-  [[maybe_unused]] bool Converted = llvm::ConvertCodePointToUTF8(Value, Ptr);
-  assert(Converted && "trying to encode invalid code unit");
-  EscapeStringForDiagnostic(StringRef(Buffer, Ptr - Buffer), Str);
-  return std::string(Str.begin(), Str.end());
+  llvm::SmallString<16> Escaped = EscapeSingleCodepointForDiagnostic(Value);
+  return std::string(Escaped.begin(), Escaped.end());
 }
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 57fa8a16d3a50..4c63e54964ed6 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SpecialCaseList.h"
 #include "llvm/Support/Unicode.h"
@@ -1042,19 +1043,33 @@ void Diagnostic::FormatDiagnostic(SmallVectorImpl<char> 
&OutStr) const {
 
 /// EscapeStringForDiagnostic - Append Str to the diagnostic buffer,
 /// escaping non-printable characters and ill-formed code unit sequences.
-void clang::EscapeStringForDiagnostic(StringRef Str,
-                                      SmallVectorImpl<char> &OutStr) {
+static void EscapeStringForDiagnostic(StringRef Str,
+                                      SmallVectorImpl<char> &OutStr,
+                                      bool ForCodepoint) {
   OutStr.reserve(OutStr.size() + Str.size());
   auto *Begin = reinterpret_cast<const unsigned char *>(Str.data());
   llvm::raw_svector_ostream OutStream(OutStr);
-  const unsigned char *End = Begin + Str.size();
+  unsigned Size = Str.size();
+  const unsigned char *End = Begin + Size;
+  if (ForCodepoint) {
+    unsigned Size = llvm::getUTF8SequenceSize(Begin, End);
+    if (Size == 0)
+      Size = llvm::findMaximalSubpartOfIllFormedUTF8Sequence(Begin, End);
+    End = Begin + Size;
+  }
   while (Begin != End) {
-    // ASCII case
-    if (isPrintable(*Begin) || isWhitespace(*Begin)) {
+    if (!ForCodepoint && (isPrintable(*Begin) || isWhitespace(*Begin))) {
       OutStream << *Begin;
       ++Begin;
       continue;
     }
+    if (ForCodepoint && *Begin < 0x80) {
+      if (isPrintable(*Begin)) {
+        OutStream << "'" << *Begin << "'";
+        ++Begin;
+        continue;
+      }
+    }
     if (llvm::isLegalUTF8Sequence(Begin, End)) {
       llvm::UTF32 CodepointValue;
       llvm::UTF32 *CpPtr = &CodepointValue;
@@ -1069,40 +1084,49 @@ void clang::EscapeStringForDiagnostic(StringRef Str,
           "the sequence is legal UTF-8 but we couldn't convert it to UTF-32");
       assert(Begin == CodepointEnd &&
              "we must be further along in the string now");
+
       if (llvm::sys::unicode::isPrintable(CodepointValue) ||
-          llvm::sys::unicode::isFormatting(CodepointValue)) {
-        OutStr.append(CodepointBegin, CodepointEnd);
-        continue;
+          (!ForCodepoint && llvm::sys::unicode::isFormatting(CodepointValue))) 
{
+        OutStream << (ForCodepoint ? "'" : "")
+                  << StringRef(reinterpret_cast<const char *>(CodepointBegin),
+                               std::distance(CodepointBegin, CodepointEnd))
+                  << (ForCodepoint ? "' " : "");
+        if (!ForCodepoint)
+          continue;
       }
       // Unprintable code point.
-      OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true)
-                << ">";
+      OutStream << (ForCodepoint ? "" : "<") << "U+"
+                << llvm::format_hex_no_prefix(CodepointValue, 4, true)
+                << (ForCodepoint ? "" : ">");
       continue;
     }
     // Invalid code unit.
-    OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
+    OutStream << "<0x" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
     ++Begin;
   }
 }
 
+/// EscapeStringForDiagnostic - Append Str to the diagnostic buffer,
+/// escaping non-printable characters and ill-formed code unit sequences.
+void clang::EscapeStringForDiagnostic(StringRef Str,
+                                      SmallVectorImpl<char> &OutStr) {
+  ::EscapeStringForDiagnostic(Str, OutStr, /*ForCodepoint=*/false);
+}
+
 /// Displays a single Unicode codepoint in U+NNNN notation, optionally
 /// prepending the quoted codepoint itself if printable.
-llvm::SmallString<16>
-clang::DisplayCodePointForDiagnostic(llvm::UTF32 CodePoint) {
-  llvm::SmallString<16> Result;
-  if (llvm::sys::unicode::isPrintable(CodePoint)) {
-    std::string CharUTF8;
-    llvm::convertUTF32ToUTF8String(llvm::ArrayRef<llvm::UTF32>(&CodePoint, 1),
-                                   CharUTF8);
-    Result.append("'");
-    Result.append(CharUTF8);
-    Result.append("' U+");
-  } else {
-    Result.append("U+");
-  }
-  llvm::raw_svector_ostream OS(Result);
-  llvm::write_hex(OS, CodePoint, llvm::HexPrintStyle::Upper, 4);
-  return Result;
+SmallString<16> clang::EscapeSingleCodepointForDiagnostic(StringRef Str) {
+  SmallString<16> CP;
+  ::EscapeStringForDiagnostic(Str, CP, /*ForCodepoint=*/true);
+  return CP;
+}
+
+SmallString<16> clang::EscapeSingleCodepointForDiagnostic(llvm::UTF32 CP) {
+  std::string Str;
+  bool Converted = convertUTF32ToUTF8String(ArrayRef<llvm::UTF32>(&CP, 1), 
Str);
+  if (!Converted)
+    return SmallString<16>(llvm::formatv("<{0:X+}>", CP).str());
+  return EscapeSingleCodepointForDiagnostic(Str);
 }
 
 void Diagnostic::FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 72a65dd156b19..54db19859d32f 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -561,17 +561,12 @@ static void DiagnoseInvalidUnicodeCharacterName(
       ++P;
       continue;
     }
-    const auto *Src = reinterpret_cast<const llvm::UTF8 *>(P);
-    const auto *SrcEnd = reinterpret_cast<const llvm::UTF8 *>(E);
-    llvm::UTF32 CodePoint = 0;
-    if (llvm::convertUTF8Sequence(&Src, SrcEnd, &CodePoint,
-                                  llvm::strictConversion) != 
llvm::conversionOK)
-      break;
     SourceLocation CharLoc = Lexer::AdvanceToTokenCharacter(
         Loc, (TokRangeBegin - TokBegin) + (P - Name.begin()), Loc.getManager(),
         Features);
     Diags->Report(CharLoc, diag::note_invalid_ucn_name_character)
-        << DisplayCodePointForDiagnostic(CodePoint);
+        << EscapeSingleCodepointForDiagnostic(
+               StringRef(P, std::distance(P, E)));
     HasIllegalCharacter = true;
     break;
   }
@@ -607,10 +602,9 @@ static void DiagnoseInvalidUnicodeCharacterName(
         3)
       break;
     Distance = Match.Distance;
-
     Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
          diag::note_invalid_ucn_name_candidate)
-        << Match.Name << DisplayCodePointForDiagnostic(Match.Value)
+        << Match.Name << EscapeSingleCodepointForDiagnostic(Match.Value)
         << FixItHint::CreateReplacement(
                MakeCharSourceRange(Features, Loc, TokBegin, TokRangeBegin,
                                    TokRangeEnd),
diff --git a/clang/test/Lexer/char-escapes-delimited-invalid-utf8.c 
b/clang/test/Lexer/char-escapes-delimited-invalid-utf8.c
new file mode 100644
index 0000000000000..301302e1c786a
--- /dev/null
+++ b/clang/test/Lexer/char-escapes-delimited-invalid-utf8.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -x c++ -std=c++23
+
+unsigned h = U'\N{INVALID�}'; \
+//expected-error {{'INVALID<0x80>' is not a valid Unicode character name}}
+//expected-note  {{character <0x80> cannot appear in a Unicode character name}}
diff --git a/clang/test/Lexer/char-escapes-delimited.c 
b/clang/test/Lexer/char-escapes-delimited.c
index 1c20456701d75..d581c9760a364 100644
--- a/clang/test/Lexer/char-escapes-delimited.c
+++ b/clang/test/Lexer/char-escapes-delimited.c
@@ -83,7 +83,7 @@ void named(void) {
   char b  = '\N{DOLLAR SIGN}'; // ext-warning {{extension}} cxx23-warning 
{{C++23}}
   char b_ = '\N{ DOL-LAR _SIGN }'; // expected-error {{' DOL-LAR _SIGN ' is 
not a valid Unicode character name}} \
                                // expected-note {{character names in Unicode 
escape sequences are sensitive to case and whitespaces}} \
-                               // expected-note {{character '_' U+005F cannot 
appear in a Unicode character name}}
+                               // expected-note {{character '_' cannot appear 
in a Unicode character name}}
 
   char c = '\N{NOTATHING}'; // expected-error {{'NOTATHING' is not a valid 
Unicode character name}} \
                             // expected-note 5{{did you mean}}
diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp 
b/clang/test/SemaCXX/static-assert-cxx26.cpp
index e9eb98dc72e04..644805a9e84c7 100644
--- a/clang/test/SemaCXX/static-assert-cxx26.cpp
+++ b/clang/test/SemaCXX/static-assert-cxx26.cpp
@@ -309,7 +309,7 @@ namespace EscapeInDiagnostic {
 static_assert('\u{9}' == (char)1, ""); // expected-error {{failed}} \
                                        // expected-note {{evaluates to ''\t' 
(0x09, 9) == '<U+0001>' (0x01, 1)'}}
 static_assert((char8_t)-128 == (char8_t)-123, ""); // expected-error 
{{failed}} \
-                                                   // expected-note 
{{evaluates to 'u8'<80>' (0x80, 128) == u8'<85>' (0x85, 133)'}}
+                                                   // expected-note 
{{evaluates to 'u8'<0x80>' (0x80, 128) == u8'<0x85>' (0x85, 133)'}}
 static_assert((char16_t)0xFEFF == (char16_t)0xDB93, ""); // expected-error 
{{failed}} \
                                                          // expected-note 
{{evaluates to 'u'' (0xFEFF, 65279) == u'\xDB93' (0xDB93, 56211)'}}
 }
diff --git a/clang/test/SemaCXX/static-assert.cpp 
b/clang/test/SemaCXX/static-assert.cpp
index 354016db36432..c48791203733b 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -278,13 +278,13 @@ namespace Diagnostics {
   // The note above is intended to match "evaluates to '\n' (0x0A, 10) == 
'<U+0000>' (0x00, 0)'", but if we write it as it is,
   // the "\n" cannot be consumed by the diagnostic consumer.
   static_assert((signed char)10 == (char)-123, ""); // expected-error 
{{failed}} \
-                                                    // expected-note 
{{evaluates to '10 == '<85>' (0x85, -123)'}}
+                                                    // expected-note 
{{evaluates to '10 == '<0x85>' (0x85, -123)'}}
   static_assert((char)-4 == (unsigned char)-8, ""); // expected-error 
{{failed}} \
-                                                    // expected-note 
{{evaluates to ''<FC>' (0xFC, -4) == 248'}}
+                                                    // expected-note 
{{evaluates to ''<0xFC>' (0xFC, -4) == 248'}}
   static_assert((char)-128 == (char)-123, ""); // expected-error {{failed}} \
-                                               // expected-note {{evaluates to 
''<80>' (0x80, -128) == '<85>' (0x85, -123)'}}
+                                               // expected-note {{evaluates to 
''<0x80>' (0x80, -128) == '<0x85>' (0x85, -123)'}}
   static_assert('\xA0' == (char)'\x20', ""); // expected-error {{failed}} \
-                                             // expected-note {{evaluates to 
''<A0>' (0xA0, -96) == ' ' (0x20, 32)'}}
+                                             // expected-note {{evaluates to 
''<0xA0>' (0xA0, -96) == ' ' (0x20, 32)'}}
   static_assert((char16_t)L'ゆ' == L"C̵̭̯̠̎͌ͅť̺"[1], ""); // expected-error 
{{failed}} \
                                                   // expected-note {{evaluates 
to 'u'ゆ' (0x3086, 12422) == L'̵' (0x335, 821)'}}
   static_assert(L"\/"[1] == u'\xFFFD', ""); // expected-error {{failed}} \
diff --git a/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp 
b/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp
index f17f20ca25295..6f9f8f3898625 100644
--- a/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp
+++ b/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp
@@ -19,12 +19,12 @@ void test(char8_t u8, char16_t u16, char32_t u32) {
 
 
     c8(char32_t(0x7f));
-    c8(char32_t(0x80));   // expected-warning {{implicit conversion from 
'char32_t' to 'char8_t' changes the meaning of the code point '<U+0080>'}}
+    c8(char32_t(0x80));   // expected-warning {{implicit conversion from 
'char32_t' to 'char8_t' changes the meaning of the code point U+0080}}
 
     c8(char16_t(0x7f));
-    c8(char16_t(0x80));   // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code point '<U+0080>'}}
-    c8(char16_t(0xD800)); // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code unit '<0xD800>'}}
-    c8(char16_t(0xE000)); // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code point '<U+E000>'}}
+    c8(char16_t(0x80));   // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code point U+0080}}
+    c8(char16_t(0xD800)); // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code unit <0xD800>}}
+    c8(char16_t(0xE000)); // expected-warning {{implicit conversion from 
'char16_t' to 'char8_t' changes the meaning of the code point U+E000}}
 
 
     c16(char32_t(0x7f));
@@ -36,8 +36,8 @@ void test(char8_t u8, char16_t u16, char32_t u32) {
 
 
     c32(char8_t(0x7f));
-    c32(char8_t(0x80)); // expected-warning {{implicit conversion from 
'char8_t' to 'char32_t' changes the meaning of the code unit '<0x80>'}}
-    c32(char8_t(0xFF)); // expected-warning {{implicit conversion from 
'char8_t' to 'char32_t' changes the meaning of the code unit '<0xFF>'}}
+    c32(char8_t(0x80)); // expected-warning {{implicit conversion from 
'char8_t' to 'char32_t' changes the meaning of the code unit <0x80>}}
+    c32(char8_t(0xFF)); // expected-warning {{implicit conversion from 
'char8_t' to 'char32_t' changes the meaning of the code unit <0xFF>}}
 
 
     c32(char16_t(0x7f));
@@ -90,19 +90,19 @@ void test_comp(char8_t u8, char16_t u16, char32_t u32) {
     (void)(char8_t(0x7f) == char32_t(0x7f));
 
     (void)(char8_t(0x80) == char8_t(0x80));
-    (void)(char8_t(0x80) == char16_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char16_t' compares 
unrelated code units '<0x80>' and '<U+0080>}}
-    (void)(char8_t(0x80) == char32_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char32_t' compares 
unrelated code units '<0x80>' and '<U+0080>}}
+    (void)(char8_t(0x80) == char16_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char16_t' compares 
unrelated code units <0x80> and U+0080}}
+    (void)(char8_t(0x80) == char32_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char32_t' compares 
unrelated code units <0x80> and U+0080}}
 
     (void)(char8_t(0x80) == char8_t(0x7f));
-    (void)(char8_t(0x80) == char16_t(0x7f)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char16_t' compares 
unrelated code units '<0x80>' and '<U+007F>'}}
-    (void)(char8_t(0x80) == char32_t(0x7f)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char32_t' compares 
unrelated code units '<0x80>' and '<U+007F>'}}
+    (void)(char8_t(0x80) == char16_t(0x7f)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char16_t' compares 
unrelated code units <0x80> and U+007F}}
+    (void)(char8_t(0x80) == char32_t(0x7f)); // expected-warning{{comparing 
values of different Unicode code unit types 'char8_t' and 'char32_t' compares 
unrelated code units <0x80> and U+007F}}
 
 
     (void)(char16_t(0x7f) < char8_t(0x7f));
     (void)(char16_t(0x7f) < char16_t(0x7f));
     (void)(char16_t(0x7f) < char32_t(0x7f));
 
-    (void)(char16_t(0x80) < char8_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char16_t' and 'char8_t' compares 
unrelated code units '<U+0080>' and '<0x80>'}}
+    (void)(char16_t(0x80) < char8_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char16_t' and 'char8_t' compares 
unrelated code units U+0080 and <0x80>}}
     (void)(char16_t(0x80) < char16_t(0x80));
     (void)(char16_t(0x80) < char32_t(0x80));
 
@@ -115,7 +115,7 @@ void test_comp(char8_t u8, char16_t u16, char32_t u32) {
     (void)(char32_t(0x7f) < char16_t(0x7f));
     (void)(char32_t(0x7f) < char32_t(0x7f));
 
-    (void)(char32_t(0x80) < char8_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char32_t' and 'char8_t' compares 
unrelated code units '<U+0080>' and '<0x80>'}}
+    (void)(char32_t(0x80) < char8_t(0x80)); // expected-warning{{comparing 
values of different Unicode code unit types 'char32_t' and 'char8_t' compares 
unrelated code units U+0080 and <0x80>}}
     (void)(char32_t(0x80) < char16_t(0x80));
     (void)(char32_t(0x80) < char32_t(0x80));
 
@@ -124,10 +124,10 @@ void test_comp(char8_t u8, char16_t u16, char32_t u32) {
     (void)(char32_t(0x80) < char32_t(0x7f));
 
 
-    (void)(char32_t(U'🐉') <= char16_t(0xD800)); // expected-warning{{comparing 
values of different Unicode code unit types 'char32_t' and 'char16_t' compares 
unrelated code units '🐉' and '<0xD800>'}}
+    (void)(char32_t(U'🐉') <= char16_t(0xD800)); // expected-warning{{comparing 
values of different Unicode code unit types 'char32_t' and 'char16_t' compares 
unrelated code units '🐉' U+1F409 and <0xD800>}}
     (void)(char32_t(U'🐉') <= char16_t(0xD7FF));
 
-    (void)(char16_t(0xD800) >= char32_t(U'🐉')); // expected-warning{{comparing 
values of different Unicode code unit types 'char16_t' and 'char32_t' compares 
unrelated code units '<0xD800>' and '🐉'}}
+    (void)(char16_t(0xD800) >= char32_t(U'🐉')); // expected-warning{{comparing 
values of different Unicode code unit types 'char16_t' and 'char32_t' compares 
unrelated code units <0xD800> and '🐉' U+1F409}}
     (void)(char16_t(0xD7FF) >= char32_t(U'🐉'));
 }
 
diff --git a/clang/unittests/Basic/DiagnosticTest.cpp 
b/clang/unittests/Basic/DiagnosticTest.cpp
index 5cc0c39e5cb51..e986cbaceaa19 100644
--- a/clang/unittests/Basic/DiagnosticTest.cpp
+++ b/clang/unittests/Basic/DiagnosticTest.cpp
@@ -449,24 +449,24 @@ TEST_F(SuppressionMappingTest, 
CanonicalizesSlashesOnWindows) {
 }
 #endif
 
-TEST(DisplayCodePointForDiagnosticTest, printableDisplaysQuoted) {
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U'A'), "'A' U+0041");
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U'🤡'), "'🤡' U+1F921");
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U' '), "' ' U+0020");
+TEST(EscapeSingleCodepointForDiagnosticTest, printableDisplaysQuoted) {
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U'A'), "'A'");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U'🤡'), "'🤡' U+1F921");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U' '), "' '");
 }
 
-TEST(DisplayCodePointForDiagnosticTest, nonPrintableDisplaysNoQuoted) {
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U'\n'), "U+000A");
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U'\0'), "U+0000");
-  EXPECT_EQ(DisplayCodePointForDiagnostic(U'\x1B'), "U+001B");
+TEST(EscapeSingleCodepointForDiagnosticTest, nonPrintableDisplaysNoQuoted) {
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U'\n'), "U+000A");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U'\0'), "U+0000");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(U'\x1B'), "U+001B");
 }
 
-TEST(DisplayCodePointForDiagnosticTest, nonScalarValues) {
+TEST(EscapeSingleCodepointForDiagnosticTest, nonScalarValues) {
   // Low and high surrogates:
-  EXPECT_EQ(DisplayCodePointForDiagnostic(0xD800), "U+D800");
-  EXPECT_EQ(DisplayCodePointForDiagnostic(0xDFFF), "U+DFFF");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(0xD800), "<0xD800>");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(0xDFFF), "<0xDFFF>");
   // Overly large values:
-  EXPECT_EQ(DisplayCodePointForDiagnostic(0x110000), "U+110000");
+  EXPECT_EQ(EscapeSingleCodepointForDiagnostic(0x110000), "<0x110000>");
 }
 
 } // namespace
diff --git a/llvm/include/llvm/Support/ConvertUTF.h 
b/llvm/include/llvm/Support/ConvertUTF.h
index 5252336f8aa98..42329b9066dc9 100644
--- a/llvm/include/llvm/Support/ConvertUTF.h
+++ b/llvm/include/llvm/Support/ConvertUTF.h
@@ -212,6 +212,10 @@ LLVM_ABI Boolean isLegalUTF8String(const UTF8 **source, 
const UTF8 *sourceEnd);
 LLVM_ABI unsigned getUTF8SequenceSize(const UTF8 *source,
                                       const UTF8 *sourceEnd);
 
+LLVM_ABI unsigned
+findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source,
+                                          const UTF8 *sourceEnd);
+
 LLVM_ABI unsigned getNumBytesForUTF8(UTF8 firstByte);
 
 /*************************************************************************/
diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp
index 63f92631d5b47..0641e3cc6e53d 100644
--- a/llvm/lib/Support/ConvertUTF.cpp
+++ b/llvm/lib/Support/ConvertUTF.cpp
@@ -445,9 +445,8 @@ unsigned getUTF8SequenceSize(const UTF8 *source, const UTF8 
*sourceEnd) {
 
 /* --------------------------------------------------------------------- */
 
-static unsigned
-findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source,
-                                          const UTF8 *sourceEnd) {
+unsigned findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source,
+                                                   const UTF8 *sourceEnd) {
   UTF8 b1, b2, b3;
 
   assert(!isLegalUTF8Sequence(source, sourceEnd));

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to