https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/88265

>From 40e533e6f58acbe832b3fa4e14ca9fd600cf77cf Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Wed, 10 Apr 2024 14:36:23 +0200
Subject: [PATCH 1/6] [Clang] Allow raw string literals in C as an extension

---
 clang/docs/ReleaseNotes.rst               |  3 +++
 clang/include/clang/Basic/LangOptions.def |  2 ++
 clang/include/clang/Basic/LangStandard.h  |  6 ++++++
 clang/include/clang/Driver/Options.td     |  6 ++++++
 clang/lib/Basic/LangOptions.cpp           |  1 +
 clang/lib/Driver/ToolChains/Clang.cpp     |  2 ++
 clang/lib/Format/Format.cpp               |  1 +
 clang/lib/Lex/Lexer.cpp                   | 10 +++++-----
 clang/test/Lexer/raw-string-ext.c         | 18 ++++++++++++++++++
 9 files changed, 44 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Lexer/raw-string-ext.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f96cebbde3d82..20d14130fb62b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -43,6 +43,9 @@ code bases.
 C/C++ Language Potentially Breaking Changes
 -------------------------------------------
 
+- Clang now supports raw string literals in ``-std=gnuXY`` mode as an 
extension in
+  C. This behaviour can also be overridden using 
``-f[no-]raw-string-literals``.
+
 C++ Specific Potentially Breaking Changes
 -----------------------------------------
 - Clang now diagnoses function/variable templates that shadow their own 
template parameters, e.g. ``template<class T> void T();``.
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 8ef6700ecdc78..96bd339bb1851 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -454,6 +454,8 @@ LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin 
matrix type")
 
 LANGOPT(CXXAssumptions, 1, 1, "Enable or disable codegen and compile-time 
checks for C++23's [[assume]] attribute")
 
+LANGOPT(RawStringLiterals, 1, 0, "Enable or disable raw string literals")
+
 ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
              StrictFlexArraysLevelKind::Default,
              "Rely on strict definition of flexible arrays")
diff --git a/clang/include/clang/Basic/LangStandard.h 
b/clang/include/clang/Basic/LangStandard.h
index 8e25afc833661..0a308b93ada74 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -130,6 +130,12 @@ struct LangStandard {
   /// hasDigraphs - Language supports digraphs.
   bool hasDigraphs() const { return Flags & Digraphs; }
 
+  /// hasRawStringLiterals - Language supports R"()" raw string literals.
+  bool hasRawStringLiterals() const {
+    // GCC supports raw string literals in C, but not in C++ before C++11.
+    return isCPlusPlus11() || (!isCPlusPlus() && isGNUMode());
+  }
+
   /// isGNUMode - Language includes GNU extensions.
   bool isGNUMode() const { return Flags & GNUMode; }
 
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index f745e573eb268..32e6c10e1251b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4142,6 +4142,12 @@ def fenable_matrix : Flag<["-"], "fenable-matrix">, 
Group<f_Group>,
     HelpText<"Enable matrix data type and related builtin functions">,
     MarshallingInfoFlag<LangOpts<"MatrixTypes">>;
 
+defm raw_string_literals : BoolFOption<"raw-string-literals",
+    LangOpts<"RawStringLiterals">, Default<std#".hasRawStringLiterals()">,
+    PosFlag<SetTrue, [], [], "Enable">,
+    NegFlag<SetFalse, [], [], "Disable">,
+    BothFlags<[], [ClangOption, CC1Option], " raw string literals">>;
+
 def fzero_call_used_regs_EQ
     : Joined<["-"], "fzero-call-used-regs=">, Group<f_Group>,
     Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index a0adfbf61840e..c34f0ed5ed717 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -124,6 +124,7 @@ void LangOptions::setLangDefaults(LangOptions &Opts, 
Language Lang,
   Opts.HexFloats = Std.hasHexFloats();
   Opts.WChar = Std.isCPlusPlus();
   Opts.Digraphs = Std.hasDigraphs();
+  Opts.RawStringLiterals = Std.hasRawStringLiterals();
 
   Opts.HLSL = Lang == Language::HLSL;
   if (Opts.HLSL && Opts.IncludeDefaultHeader)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 766a9b91e3c0a..c99bfe4efc413 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6536,6 +6536,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
   Args.AddLastArg(CmdArgs, options::OPT_fdigraphs, options::OPT_fno_digraphs);
   Args.AddLastArg(CmdArgs, options::OPT_fzero_call_used_regs_EQ);
+  Args.AddLastArg(CmdArgs, options::OPT_fraw_string_literals,
+                  options::OPT_fno_raw_string_literals);
 
   if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
                    Triple.hasDefaultEmulatedTLS()))
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 89e6c19b0af45..71865bb061f57 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3850,6 +3850,7 @@ LangOptions getFormattingLangOpts(const FormatStyle 
&Style) {
   // the sequence "<::" will be unconditionally treated as "[:".
   // Cf. Lexer::LexTokenInternal.
   LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
+  LangOpts.RawStringLiterals = LexingStd >= FormatStyle::LS_Cpp11;
 
   LangOpts.LineComment = 1;
   bool AlternativeOperators = Style.isCpp();
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index c98645993abe0..67d75c1140b23 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3867,7 +3867,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
                                tok::utf16_char_constant);
 
       // UTF-16 raw string literal
-      if (Char == 'R' && LangOpts.CPlusPlus11 &&
+      if (Char == 'R' && LangOpts.RawStringLiterals &&
           getCharAndSize(CurPtr + SizeTmp, SizeTmp2) == '"')
         return LexRawStringLiteral(Result,
                                ConsumeChar(ConsumeChar(CurPtr, SizeTmp, 
Result),
@@ -3889,7 +3889,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
                                   SizeTmp2, Result),
               tok::utf8_char_constant);
 
-        if (Char2 == 'R' && LangOpts.CPlusPlus11) {
+        if (Char2 == 'R' && LangOpts.RawStringLiterals) {
           unsigned SizeTmp3;
           char Char3 = getCharAndSize(CurPtr + SizeTmp + SizeTmp2, SizeTmp3);
           // UTF-8 raw string literal
@@ -3925,7 +3925,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
                                tok::utf32_char_constant);
 
       // UTF-32 raw string literal
-      if (Char == 'R' && LangOpts.CPlusPlus11 &&
+      if (Char == 'R' && LangOpts.RawStringLiterals &&
           getCharAndSize(CurPtr + SizeTmp, SizeTmp2) == '"')
         return LexRawStringLiteral(Result,
                                ConsumeChar(ConsumeChar(CurPtr, SizeTmp, 
Result),
@@ -3940,7 +3940,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
     // Notify MIOpt that we read a non-whitespace/non-comment token.
     MIOpt.ReadToken();
 
-    if (LangOpts.CPlusPlus11) {
+    if (LangOpts.RawStringLiterals) {
       Char = getCharAndSize(CurPtr, SizeTmp);
 
       if (Char == '"')
@@ -3963,7 +3963,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
                               tok::wide_string_literal);
 
     // Wide raw string literal.
-    if (LangOpts.CPlusPlus11 && Char == 'R' &&
+    if (LangOpts.RawStringLiterals && Char == 'R' &&
         getCharAndSize(CurPtr + SizeTmp, SizeTmp2) == '"')
       return LexRawStringLiteral(Result,
                                ConsumeChar(ConsumeChar(CurPtr, SizeTmp, 
Result),
diff --git a/clang/test/Lexer/raw-string-ext.c 
b/clang/test/Lexer/raw-string-ext.c
new file mode 100644
index 0000000000000..45e3990cadf3d
--- /dev/null
+++ b/clang/test/Lexer/raw-string-ext.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -verify=gnu -DGNU %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -fraw-string-literals -verify=gnu 
-DGNU %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify=std %s
+// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -fno-raw-string-literals 
-verify=std %s
+
+void f() {
+  (void) R"foo()foo"; // std-error {{use of undeclared identifier 'R'}}
+  (void) LR"foo()foo"; // std-error {{use of undeclared identifier 'LR'}}
+  (void) uR"foo()foo"; // std-error {{use of undeclared identifier 'uR'}}
+  (void) u8R"foo()foo"; // std-error {{use of undeclared identifier 'u8R'}}
+  (void) UR"foo()foo"; // std-error {{use of undeclared identifier 'UR'}}
+}
+
+// gnu-error@* {{missing terminating delimiter}}
+// gnu-error@* {{expected expression}}
+// gnu-error@* {{expected ';' after top level declarator}}
+#define R "bar"
+const char* s =  R"foo(";

>From f4f2294e6050168223d52a03e97f512ddab54764 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Mon, 22 Apr 2024 20:13:03 +0200
Subject: [PATCH 2/6] [Clang] Ignore '-f[no-]raw-string-literals' in C++ mode

---
 clang/docs/ReleaseNotes.rst                   |  3 +-
 .../clang/Basic/DiagnosticDriverKinds.td      |  2 +
 clang/include/clang/Basic/LangStandard.h      |  5 ++-
 clang/lib/Frontend/CompilerInvocation.cpp     |  9 ++++
 .../test/Driver/fraw-string-literals-cxx.cpp  | 11 +++++
 clang/test/Lexer/raw-string-ext.c             | 45 ++++++++++++++-----
 6 files changed, 60 insertions(+), 15 deletions(-)
 create mode 100644 clang/test/Driver/fraw-string-literals-cxx.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 20d14130fb62b..e98c0cde2e6b3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -44,7 +44,8 @@ C/C++ Language Potentially Breaking Changes
 -------------------------------------------
 
 - Clang now supports raw string literals in ``-std=gnuXY`` mode as an 
extension in
-  C. This behaviour can also be overridden using 
``-f[no-]raw-string-literals``.
+  C99 and later. This behaviour can also be overridden using 
``-f[no-]raw-string-literals``.
+  Support of raw string literals in C++ is not affected. Fixes (#GH85703).
 
 C++ Specific Potentially Breaking Changes
 -----------------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ed3fd9b1c4a55..6185dd4691d8a 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -375,6 +375,8 @@ def err_drv_negative_columns : Error<
   "invalid value '%1' in '%0', value must be 'none' or a positive integer">;
 def err_drv_small_columns : Error<
   "invalid value '%1' in '%0', value must be '%2' or greater">;
+def warn_drv_fraw_string_literals_in_cxx : Warning<
+  "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C">;
 
 def err_drv_invalid_malign_branch_EQ : Error<
   "invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
diff --git a/clang/include/clang/Basic/LangStandard.h 
b/clang/include/clang/Basic/LangStandard.h
index 0a308b93ada74..49594a49e9f37 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -132,8 +132,9 @@ struct LangStandard {
 
   /// hasRawStringLiterals - Language supports R"()" raw string literals.
   bool hasRawStringLiterals() const {
-    // GCC supports raw string literals in C, but not in C++ before C++11.
-    return isCPlusPlus11() || (!isCPlusPlus() && isGNUMode());
+    // GCC supports raw string literals in C99 and later, but not in C++
+    // before C++11.
+    return isCPlusPlus11() || (!isCPlusPlus() && isC99() && isGNUMode());
   }
 
   /// isGNUMode - Language includes GNU extensions.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 1f1f5440ddd75..963f1d1bc34f5 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -610,6 +610,15 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
     LangOpts.NewAlignOverride = 0;
   }
 
+  // The -f[no-]raw-string-literals option is only valid in C.
+  if ((Args.hasArg(OPT_fraw_string_literals) ||
+       Args.hasArg(OPT_fno_raw_string_literals)) &&
+      LangOpts.CPlusPlus) {
+    Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx)
+        << bool(LangOpts.RawStringLiterals);
+    LangOpts.RawStringLiterals = LangOpts.CPlusPlus11;
+  }
+
   // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host.
   if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost)
     Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device"
diff --git a/clang/test/Driver/fraw-string-literals-cxx.cpp 
b/clang/test/Driver/fraw-string-literals-cxx.cpp
new file mode 100644
index 0000000000000..cb1133711a030
--- /dev/null
+++ b/clang/test/Driver/fraw-string-literals-cxx.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++11 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++11 %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+
+// CHECK-POS: ignoring '-fraw-string-literals', which is only valid for C
+// CHECK-NEG: ignoring '-fno-raw-string-literals', which is only valid for C
diff --git a/clang/test/Lexer/raw-string-ext.c 
b/clang/test/Lexer/raw-string-ext.c
index 45e3990cadf3d..feac8d0c4beaf 100644
--- a/clang/test/Lexer/raw-string-ext.c
+++ b/clang/test/Lexer/raw-string-ext.c
@@ -1,18 +1,39 @@
-// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -verify=gnu -DGNU %s
-// RUN: %clang_cc1 -fsyntax-only -std=c11 -fraw-string-literals -verify=gnu 
-DGNU %s
-// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify=std %s
-// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -fno-raw-string-literals 
-verify=std %s
+// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -verify=supported %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -fraw-string-literals 
-verify=supported %s
+// RUN: %clang_cc1 -fsyntax-only -std=gnu89 -verify=unsupported %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify=unsupported %s
+// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -fno-raw-string-literals 
-verify=unsupported %s
+
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-verify=unsupported,cxx-unsupported %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-verify=unsupported,cxx-unsupported %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-fraw-string-literals -verify=unsupported,cxx-unsupported,yes %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-fraw-string-literals -verify=unsupported,cxx-unsupported,yes %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-verify=supported,cxx %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 
-verify=supported,cxx %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-fno-raw-string-literals -verify=supported,no %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 
-fno-raw-string-literals -verify=supported,no %s
+
+// GCC supports raw string literals in C99 and later in '-std=gnuXY' mode; we
+// additionally provide '-f[no-]raw-string-literals' to enable/disable them
+// explicitly in C.
+//
+// We do not allow disabling or enabling raw string literals in C++ mode if
+// they’re not already enabled by the language standard.
+
+// Driver warnings.
+// yes-warning@* {{ignoring '-fraw-string-literals', which is only valid for 
C}}
+// no-warning@* {{ignoring '-fno-raw-string-literals', which is only valid for 
C}}
 
 void f() {
-  (void) R"foo()foo"; // std-error {{use of undeclared identifier 'R'}}
-  (void) LR"foo()foo"; // std-error {{use of undeclared identifier 'LR'}}
-  (void) uR"foo()foo"; // std-error {{use of undeclared identifier 'uR'}}
-  (void) u8R"foo()foo"; // std-error {{use of undeclared identifier 'u8R'}}
-  (void) UR"foo()foo"; // std-error {{use of undeclared identifier 'UR'}}
+  (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 
'R'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'LR'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'uR'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 
'u8R'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'UR'}} cxx-unsupported-error {{expected ';' after expression}}
 }
 
-// gnu-error@* {{missing terminating delimiter}}
-// gnu-error@* {{expected expression}}
-// gnu-error@* {{expected ';' after top level declarator}}
+// supported-error@* {{missing terminating delimiter}}
+// supported-error@* {{expected expression}}
+// supported-error@* {{expected ';' after top level declarator}}
 #define R "bar"
 const char* s =  R"foo(";

>From a660165aca3db6cbda965a2f7cef976e76975f0e Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Mon, 20 May 2024 18:20:01 +0200
Subject: [PATCH 3/6] [Clang] Address review feedback

---
 .../clang/Basic/DiagnosticDriverKinds.td       |  5 +++--
 clang/include/clang/Basic/LangOptions.def      |  2 +-
 clang/lib/Format/Format.cpp                    |  1 -
 clang/lib/Frontend/CompilerInvocation.cpp      | 10 ++++++----
 clang/test/Driver/fraw-string-literals-cxx.cpp | 18 ++++++++++++------
 clang/test/Lexer/raw-string-ext.c              |  4 ++--
 6 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 6185dd4691d8a..395ddb4a117a2 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -375,8 +375,9 @@ def err_drv_negative_columns : Error<
   "invalid value '%1' in '%0', value must be 'none' or a positive integer">;
 def err_drv_small_columns : Error<
   "invalid value '%1' in '%0', value must be '%2' or greater">;
-def warn_drv_fraw_string_literals_in_cxx : Warning<
-  "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C">;
+def warn_drv_fraw_string_literals_in_cxx11 : Warning<
+  "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C 
and C++ standards before C++11">,
+  InGroup<UnusedCommandLineArgument>;
 
 def err_drv_invalid_malign_branch_EQ : Error<
   "invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 96bd339bb1851..6037a41104e69 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -454,7 +454,7 @@ LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin 
matrix type")
 
 LANGOPT(CXXAssumptions, 1, 1, "Enable or disable codegen and compile-time 
checks for C++23's [[assume]] attribute")
 
-LANGOPT(RawStringLiterals, 1, 0, "Enable or disable raw string literals")
+LANGOPT(RawStringLiterals, 1, 1, "Enable or disable raw string literals")
 
 ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
              StrictFlexArraysLevelKind::Default,
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 71865bb061f57..89e6c19b0af45 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3850,7 +3850,6 @@ LangOptions getFormattingLangOpts(const FormatStyle 
&Style) {
   // the sequence "<::" will be unconditionally treated as "[:".
   // Cf. Lexer::LexTokenInternal.
   LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
-  LangOpts.RawStringLiterals = LexingStd >= FormatStyle::LS_Cpp11;
 
   LangOpts.LineComment = 1;
   bool AlternativeOperators = Style.isCpp();
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 963f1d1bc34f5..67f9d8294b1e5 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -610,13 +610,15 @@ static bool FixupInvocation(CompilerInvocation 
&Invocation,
     LangOpts.NewAlignOverride = 0;
   }
 
-  // The -f[no-]raw-string-literals option is only valid in C.
+  // The -f[no-]raw-string-literals option is only valid in C and C++ standards
+  // before C++11.
   if ((Args.hasArg(OPT_fraw_string_literals) ||
        Args.hasArg(OPT_fno_raw_string_literals)) &&
-      LangOpts.CPlusPlus) {
-    Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx)
+      LangOpts.CPlusPlus11) {
+    Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
         << bool(LangOpts.RawStringLiterals);
-    LangOpts.RawStringLiterals = LangOpts.CPlusPlus11;
+    // Do not allow disabling raw string literals in C++11 or later.
+    LangOpts.RawStringLiterals = true;
   }
 
   // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host.
diff --git a/clang/test/Driver/fraw-string-literals-cxx.cpp 
b/clang/test/Driver/fraw-string-literals-cxx.cpp
index cb1133711a030..20692e77839de 100644
--- a/clang/test/Driver/fraw-string-literals-cxx.cpp
+++ b/clang/test/Driver/fraw-string-literals-cxx.cpp
@@ -1,11 +1,17 @@
-// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
-// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
-// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
-// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
 // RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
 // RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++11 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
 // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
 // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++11 %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++20   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++20 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++20   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++20 %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s
 
-// CHECK-POS: ignoring '-fraw-string-literals', which is only valid for C
-// CHECK-NEG: ignoring '-fno-raw-string-literals', which is only valid for C
+// CHECK-PRE-CXX11-NOT: ignoring '-fraw-string-literals'
+// CHECK-PRE-CXX11-NOT: ignoring '-fno-raw-string-literals'
+// CHECK-POS: ignoring '-fraw-string-literals', which is only valid for C and 
C++ standards before C++11
+// CHECK-NEG: ignoring '-fno-raw-string-literals', which is only valid for C 
and C++ standards before C++11
diff --git a/clang/test/Lexer/raw-string-ext.c 
b/clang/test/Lexer/raw-string-ext.c
index feac8d0c4beaf..f6ab1144c2b7a 100644
--- a/clang/test/Lexer/raw-string-ext.c
+++ b/clang/test/Lexer/raw-string-ext.c
@@ -6,8 +6,8 @@
 
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-verify=unsupported,cxx-unsupported %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-verify=unsupported,cxx-unsupported %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-fraw-string-literals -verify=unsupported,cxx-unsupported,yes %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-fraw-string-literals -verify=unsupported,cxx-unsupported,yes %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-fraw-string-literals -verify=supported %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-fraw-string-literals -verify=supported %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-verify=supported,cxx %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 
-verify=supported,cxx %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-fno-raw-string-literals -verify=supported,no %s

>From 83065acfdb04be60ae1dff3ab74574b7a8ea0074 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Mon, 20 May 2024 19:09:59 +0200
Subject: [PATCH 4/6] [Driver] WIP: Allow fraw-string-literals in C++<11

---
 clang/lib/Frontend/CompilerInvocation.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index fa3038a9271f2..3d89a54305076 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -610,13 +610,13 @@ static bool FixupInvocation(CompilerInvocation 
&Invocation,
     LangOpts.NewAlignOverride = 0;
   }
 
-  // The -f[no-]raw-string-literals option is only valid in C and C++ standards
-  // before C++11.
-  if ((Args.hasArg(OPT_fraw_string_literals) ||
-       Args.hasArg(OPT_fno_raw_string_literals)) &&
-      LangOpts.CPlusPlus11) {
+  // The -f[no-]raw-string-literals option is only valid in C and C++
+  // standards before C++11.
+  if (LangOpts.CPlusPlus11) {
+    Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
     Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
         << bool(LangOpts.RawStringLiterals);
+
     // Do not allow disabling raw string literals in C++11 or later.
     LangOpts.RawStringLiterals = true;
   }

>From 21f41bcea0536f33d9f6bb5ebb95bd9950c35b06 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Wed, 19 Jun 2024 16:50:41 +0200
Subject: [PATCH 5/6] Fix spurious diagnostic

---
 clang/lib/Frontend/CompilerInvocation.cpp | 10 +++++----
 clang/test/Lexer/raw-string-ext.c         | 27 ++++++++++++++---------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 62640da8a4fb7..d4a682e71b0a7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -610,12 +610,14 @@ static bool FixupInvocation(CompilerInvocation 
&Invocation,
     LangOpts.NewAlignOverride = 0;
   }
 
-  // The -f[no-]raw-string-literals option is only valid in C and C++
+  // The -f[no-]raw-string-literals option is only valid in C and in C++
   // standards before C++11.
   if (LangOpts.CPlusPlus11) {
-    Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
-    Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
-        << bool(LangOpts.RawStringLiterals);
+    if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) {
+      Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
+      Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
+          << bool(LangOpts.RawStringLiterals);
+    }
 
     // Do not allow disabling raw string literals in C++11 or later.
     LangOpts.RawStringLiterals = true;
diff --git a/clang/test/Lexer/raw-string-ext.c 
b/clang/test/Lexer/raw-string-ext.c
index f6ab1144c2b7a..de318b616df70 100644
--- a/clang/test/Lexer/raw-string-ext.c
+++ b/clang/test/Lexer/raw-string-ext.c
@@ -1,35 +1,40 @@
 // RUN: %clang_cc1 -fsyntax-only -std=gnu11 -verify=supported %s
-// RUN: %clang_cc1 -fsyntax-only -std=c11 -fraw-string-literals 
-verify=supported %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -DUNICODE -fraw-string-literals 
-verify=supported %s
 // RUN: %clang_cc1 -fsyntax-only -std=gnu89 -verify=unsupported %s
-// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify=unsupported %s
-// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -fno-raw-string-literals 
-verify=unsupported %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -DUNICODE -verify=unsupported %s
+// RUN: %clang_cc1 -fsyntax-only -std=gnu11 -DUNICODE -fno-raw-string-literals 
-verify=unsupported %s
 
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-verify=unsupported,cxx-unsupported %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-verify=unsupported,cxx-unsupported %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 
-fraw-string-literals -verify=supported %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 
-fraw-string-literals -verify=supported %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-verify=supported,cxx %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 
-verify=supported,cxx %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 
-fno-raw-string-literals -verify=supported,no %s
-// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 
-fno-raw-string-literals -verify=supported,no %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE 
-verify=supported,cxx %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE 
-verify=supported,cxx %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE 
-fraw-string-literals -verify=supported,yes %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE 
-fraw-string-literals -verify=supported,yes %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE 
-fno-raw-string-literals -verify=supported,no %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE 
-fno-raw-string-literals -verify=supported,no %s
 
 // GCC supports raw string literals in C99 and later in '-std=gnuXY' mode; we
 // additionally provide '-f[no-]raw-string-literals' to enable/disable them
 // explicitly in C.
 //
-// We do not allow disabling or enabling raw string literals in C++ mode if
-// they’re not already enabled by the language standard.
+// We do not allow disabling raw string literals in C++ mode if they’re enabled
+// by the language standard, i.e. in C++11 or later.
 
 // Driver warnings.
-// yes-warning@* {{ignoring '-fraw-string-literals', which is only valid for 
C}}
-// no-warning@* {{ignoring '-fno-raw-string-literals', which is only valid for 
C}}
+// yes-warning@* {{ignoring '-fraw-string-literals'}}
+// no-warning@* {{ignoring '-fno-raw-string-literals'}}
 
 void f() {
   (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 
'R'}} cxx-unsupported-error {{expected ';' after expression}}
   (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'LR'}} cxx-unsupported-error {{expected ';' after expression}}
+
+#ifdef UNICODE
   (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'uR'}} cxx-unsupported-error {{expected ';' after expression}}
   (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 
'u8R'}} cxx-unsupported-error {{expected ';' after expression}}
   (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 
'UR'}} cxx-unsupported-error {{expected ';' after expression}}
+#endif
 }
 
 // supported-error@* {{missing terminating delimiter}}

>From 3ccbd018564cec324ce994f4471b333d18614e74 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Wed, 19 Jun 2024 17:42:02 +0200
Subject: [PATCH 6/6] Fix driver test

---
 clang/test/Driver/fraw-string-literals-cxx.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Driver/fraw-string-literals-cxx.cpp 
b/clang/test/Driver/fraw-string-literals-cxx.cpp
index 20692e77839de..f831bf5344e63 100644
--- a/clang/test/Driver/fraw-string-literals-cxx.cpp
+++ b/clang/test/Driver/fraw-string-literals-cxx.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
-// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
-// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
-// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s
+// RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03   %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s
+// RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | 
FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s
 // RUN: %clang -fraw-string-literals    -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
 // RUN: %clang -fraw-string-literals    -fsyntax-only -std=gnu++11 %s 2>&1 | 
FileCheck --check-prefix=CHECK-POS %s
 // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++11   %s 2>&1 | 
FileCheck --check-prefix=CHECK-NEG %s

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to