[clang-tools-extra] Fix RawStringLiteral being available to C and C++ versions prior to C++11 (PR #69775)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 20 13:34:18 PDT 2023


https://github.com/robozati created https://github.com/llvm/llvm-project/pull/69775

The `RawStringLiteral` code action runs both on C and C++ versions prior to C++11, where this feature is unavailable.

This patch adds a condition to check if the context is running a version equal or greater than C++11 and adds tests for failing in the wrong versions.

Fixes https://github.com/clangd/clangd/issues/1795.

>From c644be1d123769395bed6ea069a45c051e3fc66d Mon Sep 17 00:00:00 2001
From: robozati <139823421+robozati at users.noreply.github.com>
Date: Fri, 20 Oct 2023 17:23:21 -0300
Subject: [PATCH] Fix RawStringLiteral being available to C and C++ versions
 prior to C++11

---
 .../refactor/tweaks/RawStringLiteral.cpp       |  8 +++++++-
 .../unittests/tweaks/RawStringLiteralTests.cpp | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp b/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp
index f5021b820f38d7f..82c908b494790cb 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp
@@ -43,6 +43,12 @@ class RawStringLiteral : public Tweak {
 
 REGISTER_TWEAK(RawStringLiteral)
 
+static bool isFeatureAvailable(const Tweak::Selection &Inputs) {
+  // Raw strings are available only for C++11 or later versions, and they are
+  // not available for C.
+  return Inputs.AST->getASTContext().getLangOpts().CPlusPlus11;
+}
+
 static bool isNormalString(const StringLiteral &Str, SourceLocation Cursor,
                           SourceManager &SM) {
   // All chunks must be normal ASCII strings, not u8"..." etc.
@@ -76,7 +82,7 @@ bool RawStringLiteral::prepare(const Selection &Inputs) {
   if (!N)
     return false;
   Str = dyn_cast_or_null<StringLiteral>(N->ASTNode.get<Stmt>());
-  return Str &&
+  return Str && isFeatureAvailable(Inputs) &&
          isNormalString(*Str, Inputs.Cursor, Inputs.AST->getSourceManager()) &&
          needsRaw(Str->getBytes()) && canBeRaw(Str->getBytes());
 }
diff --git a/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
index 4bc304559705031..0e96dfbe2e376bc 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
@@ -36,6 +36,24 @@ literal)")cpp";
   EXPECT_EQ(apply(Input), Output);
 }
 
+TEST_F(RawStringLiteralTest, TestC) {
+  Context = File;
+  FileName = "TestTU.c";
+  ExtraArgs = {"-xc"}; // raw strings are unavailable in C
+  EXPECT_UNAVAILABLE(R"c(
+    const char* a = "^f^o^o^\^n^";
+  )c");
+}
+
+TEST_F(RawStringLiteralTest, TestCpp98) {
+  Context = File;
+  ExtraArgs = {"-std=c++98"}; // raw strings are unavailable
+                              // in versions prior to C++11
+  EXPECT_UNAVAILABLE(R"cpp(
+    const char* a = "^f^o^o^\^n^";
+  )cpp");
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang



More information about the cfe-commits mailing list