Add line tracking support to FormattedStream

- previously formatted_raw_ostream tracked columns, now it tracks lines too
- used by (upcoming) DebugIR pass to know the line number to connect to each IR
  instruction



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181463 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Malea 2013-05-08 20:29:10 +00:00
parent b637b9f89e
commit f28e3c501e
2 changed files with 42 additions and 29 deletions

View File

@ -16,11 +16,13 @@
#define LLVM_SUPPORT_FORMATTEDSTREAM_H #define LLVM_SUPPORT_FORMATTEDSTREAM_H
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <utility>
namespace llvm { namespace llvm {
/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
/// of column position, allowing padding out to specific column boundaries. /// of line and column position, allowing padding out to specific column
/// boundaries and querying the number of lines written to the stream.
/// ///
class formatted_raw_ostream : public raw_ostream { class formatted_raw_ostream : public raw_ostream {
public: public:
@ -44,11 +46,11 @@ private:
/// ///
bool DeleteStream; bool DeleteStream;
/// ColumnScanned - The current output column of the data that's /// Position - The current output column and line of the data that's
/// been flushed and the portion of the buffer that's been /// been flushed and the portion of the buffer that's been
/// scanned. The column scheme is zero-based. /// scanned. The line and column scheme is zero-based.
/// ///
unsigned ColumnScanned; std::pair<unsigned, unsigned> Position;
/// Scanned - This points to one past the last character in the /// Scanned - This points to one past the last character in the
/// buffer we've scanned. /// buffer we've scanned.
@ -66,10 +68,10 @@ private:
return TheStream->tell(); return TheStream->tell();
} }
/// ComputeColumn - Examine the given output buffer and figure out which /// ComputePosition - Examine the given output buffer and figure out the new
/// column we end up in after output. /// position after output.
/// ///
void ComputeColumn(const char *Ptr, size_t size); void ComputePosition(const char *Ptr, size_t size);
public: public:
/// formatted_raw_ostream - Open the specified file for /// formatted_raw_ostream - Open the specified file for
@ -83,11 +85,11 @@ public:
/// underneath it. /// underneath it.
/// ///
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
setStream(Stream, Delete); setStream(Stream, Delete);
} }
explicit formatted_raw_ostream() explicit formatted_raw_ostream()
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
Scanned = 0; Scanned = 0;
} }
@ -122,6 +124,12 @@ public:
/// \param NewCol - The column to move to. /// \param NewCol - The column to move to.
formatted_raw_ostream &PadToColumn(unsigned NewCol); formatted_raw_ostream &PadToColumn(unsigned NewCol);
/// getColumn - Return the column number
unsigned getColumn() { return Position.first; }
/// getLine - Return the line number
unsigned getLine() { return Position.second; }
private: private:
void releaseStream() { void releaseStream() {
// Delete the stream if needed. Otherwise, transfer the buffer // Delete the stream if needed. Otherwise, transfer the buffer

View File

@ -17,38 +17,43 @@
using namespace llvm; using namespace llvm;
/// CountColumns - Examine the given char sequence and figure out which /// UpdatePosition - Examine the given char sequence and figure out which
/// column we end up in after output. /// column we end up in after output, and how many line breaks are contained.
/// ///
static unsigned CountColumns(unsigned Column, const char *Ptr, size_t Size) { static void UpdatePosition(std::pair<unsigned, unsigned> &Position, const char *Ptr, size_t Size) {
// Keep track of the current column by scanning the string for unsigned &Column = Position.first;
// special characters unsigned &Line = Position.second;
// Keep track of the current column and line by scanning the string for
// special characters
for (const char *End = Ptr + Size; Ptr != End; ++Ptr) { for (const char *End = Ptr + Size; Ptr != End; ++Ptr) {
++Column; ++Column;
if (*Ptr == '\n' || *Ptr == '\r') switch (*Ptr) {
case '\n':
Line += 1;
case '\r':
Column = 0; Column = 0;
else if (*Ptr == '\t') break;
case '\t':
// Assumes tab stop = 8 characters. // Assumes tab stop = 8 characters.
Column += (8 - (Column & 0x7)) & 0x7; Column += (8 - (Column & 0x7)) & 0x7;
break;
}
} }
return Column;
} }
/// ComputeColumn - Examine the current output and figure out which /// ComputePosition - Examine the current output and update line and column
/// column we end up in after output. /// counts.
void formatted_raw_ostream::ComputeColumn(const char *Ptr, size_t Size) { void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) {
// If our previous scan pointer is inside the buffer, assume we already // If our previous scan pointer is inside the buffer, assume we already
// scanned those bytes. This depends on raw_ostream to not change our buffer // scanned those bytes. This depends on raw_ostream to not change our buffer
// in unexpected ways. // in unexpected ways.
if (Ptr <= Scanned && Scanned <= Ptr + Size) { if (Ptr <= Scanned && Scanned <= Ptr + Size)
// Scan all characters added since our last scan to determine the new // Scan all characters added since our last scan to determine the new
// column. // column.
ColumnScanned = CountColumns(ColumnScanned, Scanned, UpdatePosition(Position, Scanned, Size - (Scanned - Ptr));
Size - (Scanned - Ptr)); else
} else UpdatePosition(Position, Ptr, Size);
ColumnScanned = CountColumns(ColumnScanned, Ptr, Size);
// Update the scanning pointer. // Update the scanning pointer.
Scanned = Ptr + Size; Scanned = Ptr + Size;
@ -60,16 +65,16 @@ void formatted_raw_ostream::ComputeColumn(const char *Ptr, size_t Size) {
/// ///
formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) { formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
// Figure out what's in the buffer and add it to the column count. // Figure out what's in the buffer and add it to the column count.
ComputeColumn(getBufferStart(), GetNumBytesInBuffer()); ComputePosition(getBufferStart(), GetNumBytesInBuffer());
// Output spaces until we reach the desired column. // Output spaces until we reach the desired column.
indent(std::max(int(NewCol - ColumnScanned), 1)); indent(std::max(int(NewCol - getColumn()), 1));
return *this; return *this;
} }
void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) { void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
// Figure out what's in the buffer and add it to the column count. // Figure out what's in the buffer and add it to the column count.
ComputeColumn(Ptr, Size); ComputePosition(Ptr, Size);
// Write the data to the underlying stream (which is unbuffered, so // Write the data to the underlying stream (which is unbuffered, so
// the data will be immediately written out). // the data will be immediately written out).