diff options
| -rw-r--r-- | llvm/include/llvm/Support/raw_ostream.h | 39 | ||||
| -rw-r--r-- | llvm/lib/Support/raw_ostream.cpp | 18 | 
2 files changed, 45 insertions, 12 deletions
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index 2cf9d22903b..367c35ca120 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -44,6 +44,10 @@ private:    char *OutBufStart, *OutBufEnd, *OutBufCur;    bool Unbuffered; +  /// Error This flag is true if an error of any kind has been detected. +  /// +  bool Error; +  public:    // color order matches ANSI escape sequence, don't change    enum Colors { @@ -58,18 +62,31 @@ public:      SAVEDCOLOR    }; -  explicit raw_ostream(bool unbuffered=false) : Unbuffered(unbuffered) { +  explicit raw_ostream(bool unbuffered=false) +    : Unbuffered(unbuffered), Error(false) {      // Start out ready to flush.      OutBufStart = OutBufEnd = OutBufCur = 0;    } -  virtual ~raw_ostream() { -    delete [] OutBufStart; -  } +  virtual ~raw_ostream();    /// tell - Return the current offset with the file.    uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); } +  /// has_error - Return the value of the flag in this raw_ostream indicating +  /// whether an output error has been encountered. +  bool has_error() const { +    return Error; +  }; + +  /// clear_error - Set the flag read by has_error() to false. If the error +  /// flag is set at the time when this raw_ostream's destructor is called, +  /// llvm_report_error is called to report the error. Use clear_error() +  /// after handling the error to avoid this behavior. +  void clear_error() { +    Error = false; +  }; +    //===--------------------------------------------------------------------===//    // Configuration Interface    //===--------------------------------------------------------------------===// @@ -213,6 +230,11 @@ private:    /// counting the bytes currently in the buffer.    virtual uint64_t current_pos() = 0; +protected: +  /// error_detected - Set the flag indicating that an output error has +  /// been encountered. +  void error_detected() { Error = true; } +    //===--------------------------------------------------------------------===//    // Private Interface    //===--------------------------------------------------------------------===// @@ -311,8 +333,8 @@ raw_ostream &errs();  //===----------------------------------------------------------------------===//  /// raw_os_ostream - A raw_ostream that writes to an std::ostream.  This is a -/// simple adaptor class.  It does not check for I/O errors; clients should use -/// the underlying stream to detect errors. +/// simple adaptor class.  It does not check for output errors; clients should +/// use the underlying stream to detect errors.  class raw_os_ostream : public raw_ostream {    std::ostream &OS; @@ -332,7 +354,7 @@ public:  };  /// raw_string_ostream - A raw_ostream that writes to an std::string.  This is a -/// simple adaptor class. +/// simple adaptor class. This class does not encounter output errors.  class raw_string_ostream : public raw_ostream {    std::string &OS; @@ -358,7 +380,8 @@ public:  };  /// raw_svector_ostream - A raw_ostream that writes to an SmallVector or -/// SmallString.  This is a simple adaptor class. +/// SmallString.  This is a simple adaptor class. This class does not +/// encounter output errors.  class raw_svector_ostream : public raw_ostream {    SmallVectorImpl<char> &OS; diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index b13d922b217..8724801818c 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -44,6 +44,16 @@  using namespace llvm; +raw_ostream::~raw_ostream() { +  delete [] OutBufStart; + +  // If there are any pending errors, report them now. Clients wishing +  // to avoid llvm_report_error calls should check for errors with +  // has_error() and clear the error flag with clear_error() before +  // destructing raw_ostream objects which may have errors. +  if (Error) +    llvm_report_error("IO failure on output stream."); +}  // An out of line virtual method to provide a home for the class vtable.  void raw_ostream::handle() {} @@ -282,7 +292,7 @@ raw_fd_ostream::~raw_fd_ostream() {      flush();      if (ShouldClose)        if (::close(FD) != 0) -        llvm_report_error("IO failure closing output stream."); +        error_detected();    }  } @@ -290,7 +300,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, unsigned Size) {    assert (FD >= 0 && "File already closed.");    pos += Size;    if (::write(FD, Ptr, Size) != (ssize_t) Size) -    llvm_report_error("IO failure writing to output stream."); +    error_detected();  }  void raw_fd_ostream::close() { @@ -298,7 +308,7 @@ void raw_fd_ostream::close() {    ShouldClose = false;    flush();    if (::close(FD) != 0) -    llvm_report_error("IO failure closing output stream."); +    error_detected();    FD = -1;  } @@ -306,7 +316,7 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {    flush();    pos = ::lseek(FD, off, SEEK_SET);    if (pos != off) -    llvm_report_error("IO failure seeking on output stream."); +    error_detected();    return pos;    }  | 

