Index: lib/Support/LineIterator.cpp =================================================================== --- lib/Support/LineIterator.cpp +++ lib/Support/LineIterator.cpp @@ -12,6 +12,25 @@ using namespace llvm; +static bool isAtLineEnd(const char *P) { + if (*P == '\n') + return true; + if (*P == '\r' && *(P + 1) == '\n') + return true; + return false; +} + +static void skipLineEnd(const char *&P) { + if (*P == '\n') { + ++P; + return; + } + if (*P == '\r' && *(P + 1) == '\n') { + P += 2; + return; + } +} + line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks, char CommentMarker) : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), @@ -23,7 +42,7 @@ if (Buffer.getBufferSize()) { assert(Buffer.getBufferEnd()[0] == '\0'); // Make sure we don't skip a leading newline if we're keeping blanks - if (SkipBlanks || *Buffer.getBufferStart() != '\n') + if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart())) advance(); } } @@ -32,33 +51,32 @@ assert(Buffer && "Cannot advance past the end!"); const char *Pos = CurrentLine.end(); - assert(Pos == Buffer->getBufferStart() || *Pos == '\n' || *Pos == '\0'); + assert(Pos == Buffer->getBufferStart() || isAtLineEnd(Pos) || *Pos == '\0'); - if (*Pos == '\n') { - ++Pos; + if (isAtLineEnd(Pos)) { + skipLineEnd(Pos); ++LineNumber; } - if (!SkipBlanks && *Pos == '\n') { + if (!SkipBlanks && isAtLineEnd(Pos)) { // Nothing to do for a blank line. } else if (CommentMarker == '\0') { // If we're not stripping comments, this is simpler. - size_t Blanks = 0; - while (Pos[Blanks] == '\n') - ++Blanks; - Pos += Blanks; - LineNumber += Blanks; + while (isAtLineEnd(Pos)) { + skipLineEnd(Pos); + ++LineNumber; + } } else { // Skip comments and count line numbers, which is a bit more complex. for (;;) { - if (*Pos == '\n' && !SkipBlanks) + if (isAtLineEnd(Pos) && !SkipBlanks) break; if (*Pos == CommentMarker) do { ++Pos; - } while (*Pos != '\0' && *Pos != '\n'); - if (*Pos != '\n') + } while (*Pos != '\0' && !isAtLineEnd(Pos)); + if (!isAtLineEnd(Pos)) break; - ++Pos; + skipLineEnd(Pos); ++LineNumber; } } @@ -72,7 +90,7 @@ // Measure the line. size_t Length = 0; - while (Pos[Length] != '\0' && Pos[Length] != '\n') { + while (Pos[Length] != '\0' && !isAtLineEnd(&Pos[Length])) { ++Length; } Index: test/Object/Inputs/mri-crlf.mri =================================================================== --- /dev/null +++ test/Object/Inputs/mri-crlf.mri @@ -0,0 +1,2 @@ +; this file intentionally has crlf line endings +end Index: test/Object/mri-crlf.test =================================================================== --- /dev/null +++ test/Object/mri-crlf.test @@ -0,0 +1 @@ +; RUN: llvm-ar -M < %S/Inputs/mri-crlf.mri