Commit af6b8d51 authored by peter klausler's avatar peter klausler
Browse files

[flang] Refine CR handling

We need to retain carriage return characters in source files
that are not parts of multi-byte line endings; they are
significant in CHARACTER literal constants.

Reviewed By: tskeith

Differential Revision: https://reviews.llvm.org/D83808
parent c1e2f73c
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -58,9 +58,6 @@ public:

  std::string Marshal() const;

  // Removes carriage returns ('\r') and ensures a final line feed ('\n').
  std::string MarshalNormalized() const;

private:
  struct Block {
    static constexpr std::size_t capacity{1 << 20};
+0 −22
Original line number Diff line number Diff line
@@ -65,26 +65,4 @@ std::string CharBuffer::Marshal() const {
  CHECK(result.size() == bytes_);
  return result;
}

std::string CharBuffer::MarshalNormalized() const {
  std::string result;
  std::size_t bytes{bytes_};
  result.reserve(bytes + 1 /* for terminal line feed */);
  char ch{'\0'};
  for (const Block &block : blocks_) {
    std::size_t chunk{std::min(bytes, Block::capacity)};
    for (std::size_t j{0}; j < chunk; ++j) {
      ch = block.data[j];
      if (ch != '\r') {
        result += ch;
      }
    }
    bytes -= chunk;
  }
  if (ch != '\n') {
    result += '\n';
  }
  result.shrink_to_fit();
  return result;
}
} // namespace Fortran::parser
+11 −2
Original line number Diff line number Diff line
@@ -85,10 +85,19 @@ std::size_t RemoveCarriageReturns(llvm::MutableArrayRef<char> buf) {
      break;
    }
    std::size_t chunk = crcp - p;
    auto advance{chunk + 1};
    if (chunk + 1 >= bytes || crcp[1] == '\n') {
      // CR followed by LF or EOF: omit
    } else if ((chunk == 0 && p == buf.data()) || crcp[-1] == '\n') {
      // CR preceded by LF or BOF: omit
    } else {
      // CR in line: retain
      ++chunk;
    }
    std::memmove(buffer + wrote, p, chunk);
    wrote += chunk;
    p += chunk + 1;
    bytes -= chunk + 1;
    p += advance;
    bytes -= advance;
  }
  return wrote;
}