Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -2586,12 +2586,32 @@ bool MainIncludeFound = false; bool FormattingOff = false; + llvm::Regex RawStringRegex("R\"([A-Za-z]*)\\("); + SmallVector RawStringMatches; + std::string RawStringTermination = ")\""; + for (;;) { auto Pos = Code.find('\n', SearchFrom); StringRef Line = Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); StringRef Trimmed = Line.trim(); + + // #includes inside raw string literals need to be ignored. + // or we will sort the contents of the string. + // Skip past until we think we are at the rawstring literal close. + if (RawStringRegex.match(Trimmed, &RawStringMatches)) { + std::string CharSequence = RawStringMatches[1].str(); + if (!CharSequence.empty()) { + RawStringTermination = ")" + CharSequence + "\""; + } + FormattingOff = true; + } + + if (Trimmed.contains(RawStringTermination)) { + FormattingOff = false; + } + if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */") FormattingOff = true; else if (Trimmed == "// clang-format on" || Index: clang/unittests/Format/SortIncludesTest.cpp =================================================================== --- clang/unittests/Format/SortIncludesTest.cpp +++ clang/unittests/Format/SortIncludesTest.cpp @@ -1045,6 +1045,79 @@ EXPECT_EQ(Unsorted, sort(Unsorted, "input.cpp", 0)); } +TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) { + + EXPECT_EQ("const char *t = R\"(\n" + "#include \n" + "#include \n" + ")\";", + sort("const char *t = R\"(\n" + "#include \n" + "#include \n" + ")\";", + "test.cxx", 0)); + EXPECT_EQ("const char *t = R\"x(\n" + "#include \n" + "#include \n" + ")x\";", + sort("const char *t = R\"x(\n" + "#include \n" + "#include \n" + ")x\";", + "test.cxx", 0)); + EXPECT_EQ("const char *t = R\"xyz(\n" + "#include \n" + "#include \n" + ")xyz\";", + sort("const char *t = R\"xyz(\n" + "#include \n" + "#include \n" + ")xyz\";", + "test.cxx", 0)); + + EXPECT_EQ("#include \n" + "#include \n" + "const char *t = R\"(\n" + "#include \n" + "#include \n" + ")\";\n" + "#include \n" + "#include \n" + "const char *t = R\"x(\n" + "#include \n" + "#include \n" + ")x\";\n" + "#include \n" + "#include \n" + "const char *t = R\"xyz(\n" + "#include \n" + "#include \n" + ")xyz\";\n" + "#include \n" + "#include ", + sort("#include \n" + "#include \n" + "const char *t = R\"(\n" + "#include \n" + "#include \n" + ")\";\n" + "#include \n" + "#include \n" + "const char *t = R\"x(\n" + "#include \n" + "#include \n" + ")x\";\n" + "#include \n" + "#include \n" + "const char *t = R\"xyz(\n" + "#include \n" + "#include \n" + ")xyz\";\n" + "#include \n" + "#include ", + "test.cc", 4)); +} + } // end namespace } // end namespace format } // end namespace clang