llvm.org GIT mirror llvm / e87b2ab
Change raw_ostream so that it doesn't call llvm_report_error immediately on every output error. Instead, add a flag to raw_ostream, and set the flag whenever an error is detected. The flag can be queried and cleared from the public API. This gives applications more flexibility to handling errors in application-specific ways. If the flag is not cleared when the raw_ostream is destructed, llvm_report_error is called from the destructor. This ensures that errors are not implicitly silenced, and provides convenient default behavior for tools like llc and opt. Clients wishing to avoid llvm_report_error calls from raw_ostream should check for errors and clear the error flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75857 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
2 changed file(s) with 45 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
4343 char *OutBufStart, *OutBufEnd, *OutBufCur;
4444 bool Unbuffered;
4545
46 /// Error This flag is true if an error of any kind has been detected.
47 ///
48 bool Error;
49
4650 public:
4751 // color order matches ANSI escape sequence, don't change
4852 enum Colors {
5761 SAVEDCOLOR
5862 };
5963
60 explicit raw_ostream(bool unbuffered=false) : Unbuffered(unbuffered) {
64 explicit raw_ostream(bool unbuffered=false)
65 : Unbuffered(unbuffered), Error(false) {
6166 // Start out ready to flush.
6267 OutBufStart = OutBufEnd = OutBufCur = 0;
6368 }
6469
65 virtual ~raw_ostream() {
66 delete [] OutBufStart;
67 }
70 virtual ~raw_ostream();
6871
6972 /// tell - Return the current offset with the file.
7073 uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); }
74
75 /// has_error - Return the value of the flag in this raw_ostream indicating
76 /// whether an output error has been encountered.
77 bool has_error() const {
78 return Error;
79 };
80
81 /// clear_error - Set the flag read by has_error() to false. If the error
82 /// flag is set at the time when this raw_ostream's destructor is called,
83 /// llvm_report_error is called to report the error. Use clear_error()
84 /// after handling the error to avoid this behavior.
85 void clear_error() {
86 Error = false;
87 };
7188
7289 //===--------------------------------------------------------------------===//
7390 // Configuration Interface
211228 /// current_pos - Return the current position within the stream, not
212229 /// counting the bytes currently in the buffer.
213230 virtual uint64_t current_pos() = 0;
231
232 protected:
233 /// error_detected - Set the flag indicating that an output error has
234 /// been encountered.
235 void error_detected() { Error = true; }
214236
215237 //===--------------------------------------------------------------------===//
216238 // Private Interface
310332 //===----------------------------------------------------------------------===//
311333
312334 /// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
313 /// simple adaptor class. It does not check for I/O errors; clients should use
314 /// the underlying stream to detect errors.
335 /// simple adaptor class. It does not check for output errors; clients should
336 /// use the underlying stream to detect errors.
315337 class raw_os_ostream : public raw_ostream {
316338 std::ostream &OS;
317339
331353 };
332354
333355 /// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
334 /// simple adaptor class.
356 /// simple adaptor class. This class does not encounter output errors.
335357 class raw_string_ostream : public raw_ostream {
336358 std::string &OS;
337359
357379 };
358380
359381 /// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
360 /// SmallString. This is a simple adaptor class.
382 /// SmallString. This is a simple adaptor class. This class does not
383 /// encounter output errors.
361384 class raw_svector_ostream : public raw_ostream {
362385 SmallVectorImpl &OS;
363386
4343
4444 using namespace llvm;
4545
46 raw_ostream::~raw_ostream() {
47 delete [] OutBufStart;
48
49 // If there are any pending errors, report them now. Clients wishing
50 // to avoid llvm_report_error calls should check for errors with
51 // has_error() and clear the error flag with clear_error() before
52 // destructing raw_ostream objects which may have errors.
53 if (Error)
54 llvm_report_error("IO failure on output stream.");
55 }
4656
4757 // An out of line virtual method to provide a home for the class vtable.
4858 void raw_ostream::handle() {}
281291 flush();
282292 if (ShouldClose)
283293 if (::close(FD) != 0)
284 llvm_report_error("IO failure closing output stream.");
294 error_detected();
285295 }
286296 }
287297
289299 assert (FD >= 0 && "File already closed.");
290300 pos += Size;
291301 if (::write(FD, Ptr, Size) != (ssize_t) Size)
292 llvm_report_error("IO failure writing to output stream.");
302 error_detected();
293303 }
294304
295305 void raw_fd_ostream::close() {
297307 ShouldClose = false;
298308 flush();
299309 if (::close(FD) != 0)
300 llvm_report_error("IO failure closing output stream.");
310 error_detected();
301311 FD = -1;
302312 }
303313
305315 flush();
306316 pos = ::lseek(FD, off, SEEK_SET);
307317 if (pos != off)
308 llvm_report_error("IO failure seeking on output stream.");
318 error_detected();
309319 return pos;
310320 }
311321