Index: clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.h =================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.h +++ clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.h @@ -32,9 +32,10 @@ private: void replaceWithRawStringLiteral( const ast_matchers::MatchFinder::MatchResult &Result, - const StringLiteral *Literal); + const StringLiteral *Literal, StringRef Replacement); std::string DelimiterStem; + const bool ReplaceShorterLiterals; }; } // namespace modernize Index: clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.cpp @@ -101,10 +101,13 @@ RawStringLiteralCheck::RawStringLiteralCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - DelimiterStem(Options.get("DelimiterStem", "lit")) {} + DelimiterStem(Options.get("DelimiterStem", "lit")), + ReplaceShorterLiterals(Options.get("ReplaceShorterLiterals", false)) {} void RawStringLiteralCheck::storeOptions(ClangTidyOptions::OptionMap &Options) { ClangTidyCheck::storeOptions(Options); + this->Options.store(Options, "ReplaceShorterLiterals", + ReplaceShorterLiterals); } void RawStringLiteralCheck::registerMatchers(MatchFinder *Finder) { @@ -121,19 +124,25 @@ if (Literal->getLocStart().isMacroID()) return; - if (containsEscapedCharacters(Result, Literal)) - replaceWithRawStringLiteral(Result, Literal); + if (containsEscapedCharacters(Result, Literal)) { + std::string Replacement = asRawStringLiteral(Literal, DelimiterStem); + if (ReplaceShorterLiterals || + Replacement.length() <= + Lexer::MeasureTokenLength(Literal->getLocStart(), + *Result.SourceManager, getLangOpts())) + replaceWithRawStringLiteral(Result, Literal, Replacement); + } } void RawStringLiteralCheck::replaceWithRawStringLiteral( - const MatchFinder::MatchResult &Result, const StringLiteral *Literal) { + const MatchFinder::MatchResult &Result, const StringLiteral *Literal, + StringRef Replacement) { CharSourceRange CharRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Literal->getSourceRange()), *Result.SourceManager, getLangOpts()); diag(Literal->getLocStart(), "escaped string literal can be written as a raw string literal") - << FixItHint::CreateReplacement( - CharRange, asRawStringLiteral(Literal, DelimiterStem)); + << FixItHint::CreateReplacement(CharRange, Replacement); } } // namespace modernize Index: clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-delimiter.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config='{CheckOptions: [{key: "modernize-raw-string-literal.DelimiterStem", value: "str"}]}' -- -std=c++11 +// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config='{CheckOptions: [{key: "modernize-raw-string-literal.DelimiterStem", value: "str"}, {key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}' -- -std=c++11 char const *const ContainsSentinel{"who\\ops)\""}; // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal Index: clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal-replace-shorter.cpp @@ -0,0 +1,13 @@ +// RUN: %check_clang_tidy %s modernize-raw-string-literal %t + +// Don't replace these, because the raw literal would be longer. +char const *const JustAQuote("quote:\'"); +char const *const NeedDelimiter("\":)\""); + +char const *const ManyQuotes("quotes:\'\'\'\'"); +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: {{.*}} can be written as a raw string literal +// CHECK-FIXES: {{^}}char const *const ManyQuotes(R"(quotes:'''')");{{$}} + +char const *const LongOctal("\042\072\051\042"); +// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} can be written as a raw string literal +// CHECK-FIXES: {{^}}char const *const LongOctal(R"lit(":)")lit");{{$}} Index: clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-raw-string-literal.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s modernize-raw-string-literal %t +// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config="{CheckOptions: [{key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}" -- -std=c++11 char const *const BackSlash("goink\\frob"); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: escaped string literal can be written as a raw string literal [modernize-raw-string-literal]