MyDeveloperDay created this revision. MyDeveloperDay added reviewers: HazardyKnusperkeks, curdeius, owenpan, njames93. MyDeveloperDay added projects: clang, clang-format. MyDeveloperDay requested review of this revision.
https://bugs.llvm.org/show_bug.cgi?id=49298 clang-format does not respect raw string literals when sorting includes const char *RawStr = R"( #include "headerB.h" #include "headerA.h" )"; Running clang-format over with SortIncludes enabled transforms this code to: const char *RawStr = R"( #include "headerA.h" #include "headerB.h" )"; The following code tries to minimize this impact during IncludeSorting, by treating R"( and )" as equivalent of // clang-format off/on Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D115168 Files: clang/lib/Format/Format.cpp clang/unittests/Format/SortIncludesTest.cpp Index: clang/unittests/Format/SortIncludesTest.cpp =================================================================== --- clang/unittests/Format/SortIncludesTest.cpp +++ clang/unittests/Format/SortIncludesTest.cpp @@ -1045,6 +1045,37 @@ EXPECT_EQ(Unsorted, sort(Unsorted, "input.cpp", 0)); } +TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) { + + EXPECT_EQ("const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";", + sort("const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";", + "test.cxx", 0)); + + EXPECT_EQ("#include <a.h>\n" + "#include <b.h>\n" + "const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";\n" + "#include <c.h>\n" + "#include <d.h>", + sort("#include <b.h>\n" + "#include <a.h>\n" + "const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";\n" + "#include <d.h>\n" + "#include <c.h>", + "test.cc", 2)); +} + } // end namespace } // end namespace format } // end namespace clang Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -2590,8 +2590,18 @@ 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 we the rawstring literal close. + if (Trimmed.contains("R\"(")) { + FormattingOff = true; + } + if (Trimmed.contains(")\"")) { + 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,37 @@ EXPECT_EQ(Unsorted, sort(Unsorted, "input.cpp", 0)); } +TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) { + + EXPECT_EQ("const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";", + sort("const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";", + "test.cxx", 0)); + + EXPECT_EQ("#include <a.h>\n" + "#include <b.h>\n" + "const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";\n" + "#include <c.h>\n" + "#include <d.h>", + sort("#include <b.h>\n" + "#include <a.h>\n" + "const char *t = R\"(\n" + "#include <b.h>\n" + "#include <a.h>\n" + ")\";\n" + "#include <d.h>\n" + "#include <c.h>", + "test.cc", 2)); +} + } // end namespace } // end namespace format } // end namespace clang Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -2590,8 +2590,18 @@ 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 we the rawstring literal close. + if (Trimmed.contains("R\"(")) { + FormattingOff = true; + } + if (Trimmed.contains(")\"")) { + FormattingOff = false; + } + if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */") FormattingOff = true; else if (Trimmed == "// clang-format on" ||
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits