diff --git a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp --- a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -281,27 +281,28 @@ StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom); + // count lines manually, it's faster than getPresumedLoc() + Line += TextToWrite.count(LocalEOL); if (MainEOL == LocalEOL) { OS << TextToWrite; - // count lines manually, it's faster than getPresumedLoc() - Line += TextToWrite.count(LocalEOL); - if (EnsureNewline && !TextToWrite.endswith(LocalEOL)) - OS << MainEOL; } else { // Output the file one line at a time, rewriting the line endings as we go. StringRef Rest = TextToWrite; while (!Rest.empty()) { - StringRef LineText; - std::tie(LineText, Rest) = Rest.split(LocalEOL); + size_t Idx = Rest.find(LocalEOL); + StringRef LineText = Rest.substr(0, Idx); OS << LineText; - Line++; - if (!Rest.empty()) + if (Idx != StringRef::npos) { OS << MainEOL; + Idx += LocalEOL.size(); + } + Rest = Rest.substr(Idx); } - if (TextToWrite.endswith(LocalEOL) || EnsureNewline) - OS << MainEOL; } + if (EnsureNewline && !TextToWrite.endswith(LocalEOL)) + OS << MainEOL; + WriteFrom = WriteTo; } diff --git a/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.h b/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.h new file mode 100644 --- /dev/null +++ b/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.h @@ -0,0 +1,11 @@ +// Note: This header file has CRLF line endings. +// The indentation in some of the conditional inclusion directives below is +// intentional and is required for this test to function as a regression test +// for GH59736. +_Static_assert(__LINE__ == 5, ""); +#if 1 +_Static_assert(__LINE__ == 7, ""); + #if 1 + _Static_assert(__LINE__ == 9, ""); + #endif +#endif diff --git a/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.c b/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.c new file mode 100644 --- /dev/null +++ b/clang/test/Frontend/rewrite-includes-mixed-eol-crlf.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -E -frewrite-includes %s | %clang_cc1 - +// expected-no-diagnostics +// Note: This source file has CRLF line endings. +// This test validates that -frewrite-includes translates the end of line (EOL) +// form used in header files to the EOL form used in the the primary source +// file when the files use different EOL forms. +#include "rewrite-includes-mixed-eol-crlf.h" +#include "rewrite-includes-mixed-eol-lf.h" diff --git a/clang/test/Frontend/rewrite-includes-mixed-eol-lf.h b/clang/test/Frontend/rewrite-includes-mixed-eol-lf.h new file mode 100644 --- /dev/null +++ b/clang/test/Frontend/rewrite-includes-mixed-eol-lf.h @@ -0,0 +1,11 @@ +// Note: This header file has LF line endings. +// The indentation in some of the conditional inclusion directives below is +// intentional and is required for this test to function as a regression test +// for GH59736. +_Static_assert(__LINE__ == 5, ""); +#if 1 +_Static_assert(__LINE__ == 7, ""); + #if 1 + _Static_assert(__LINE__ == 9, ""); + #endif +#endif diff --git a/clang/test/Frontend/rewrite-includes-mixed-eol-lf.c b/clang/test/Frontend/rewrite-includes-mixed-eol-lf.c new file mode 100644 --- /dev/null +++ b/clang/test/Frontend/rewrite-includes-mixed-eol-lf.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -E -frewrite-includes %s | %clang_cc1 - +// expected-no-diagnostics +// Note: This source file has LF line endings. +// This test validates that -frewrite-includes translates the end of line (EOL) +// form used in header files to the EOL form used in the the primary source +// file when the files use different EOL forms. +#include "rewrite-includes-mixed-eol-crlf.h" +#include "rewrite-includes-mixed-eol-lf.h"