Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Support/raw_ostream.cpp @ 77:54457678186b
LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Sep 2014 22:06:00 +0900 |
parents | 95c75e76d11b |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
20 #include "llvm/Support/ErrorHandling.h" | 20 #include "llvm/Support/ErrorHandling.h" |
21 #include "llvm/Support/FileSystem.h" | 21 #include "llvm/Support/FileSystem.h" |
22 #include "llvm/Support/Format.h" | 22 #include "llvm/Support/Format.h" |
23 #include "llvm/Support/Process.h" | 23 #include "llvm/Support/Process.h" |
24 #include "llvm/Support/Program.h" | 24 #include "llvm/Support/Program.h" |
25 #include "llvm/Support/system_error.h" | |
26 #include <cctype> | 25 #include <cctype> |
27 #include <cerrno> | 26 #include <cerrno> |
28 #include <sys/stat.h> | 27 #include <sys/stat.h> |
28 #include <system_error> | |
29 | 29 |
30 // <fcntl.h> may provide O_BINARY. | 30 // <fcntl.h> may provide O_BINARY. |
31 #if defined(HAVE_FCNTL_H) | 31 #if defined(HAVE_FCNTL_H) |
32 # include <fcntl.h> | 32 # include <fcntl.h> |
33 #endif | 33 #endif |
85 SetUnbuffered(); | 85 SetUnbuffered(); |
86 } | 86 } |
87 | 87 |
88 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, | 88 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, |
89 BufferKind Mode) { | 89 BufferKind Mode) { |
90 assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || | 90 assert(((Mode == Unbuffered && !BufferStart && Size == 0) || |
91 (Mode != Unbuffered && BufferStart && Size)) && | 91 (Mode != Unbuffered && BufferStart && Size != 0)) && |
92 "stream must be unbuffered or have at least one byte"); | 92 "stream must be unbuffered or have at least one byte"); |
93 // Make sure the current buffer is free of content (we can't flush here; the | 93 // Make sure the current buffer is free of content (we can't flush here; the |
94 // child buffer management logic will be in write_impl). | 94 // child buffer management logic will be in write_impl). |
95 assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!"); | 95 assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!"); |
96 | 96 |
225 raw_ostream &raw_ostream::operator<<(double N) { | 225 raw_ostream &raw_ostream::operator<<(double N) { |
226 #ifdef _WIN32 | 226 #ifdef _WIN32 |
227 // On MSVCRT and compatible, output of %e is incompatible to Posix | 227 // On MSVCRT and compatible, output of %e is incompatible to Posix |
228 // by default. Number of exponent digits should be at least 2. "%+03d" | 228 // by default. Number of exponent digits should be at least 2. "%+03d" |
229 // FIXME: Implement our formatter to here or Support/Format.h! | 229 // FIXME: Implement our formatter to here or Support/Format.h! |
230 #if __cplusplus >= 201103L && defined(__MINGW32__) | |
231 // FIXME: It should be generic to C++11. | |
232 if (N == 0.0 && std::signbit(N)) | |
233 return *this << "-0.000000e+00"; | |
234 #else | |
230 int fpcl = _fpclass(N); | 235 int fpcl = _fpclass(N); |
231 | 236 |
232 // negative zero | 237 // negative zero |
233 if (fpcl == _FPCLASS_NZ) | 238 if (fpcl == _FPCLASS_NZ) |
234 return *this << "-0.000000e+00"; | 239 return *this << "-0.000000e+00"; |
240 #endif | |
235 | 241 |
236 char buf[16]; | 242 char buf[16]; |
237 unsigned len; | 243 unsigned len; |
238 len = snprintf(buf, sizeof(buf), "%e", N); | 244 len = snprintf(buf, sizeof(buf), "%e", N); |
239 if (len <= sizeof(buf) - 2) { | 245 if (len <= sizeof(buf) - 2) { |
418 | 424 |
419 //===----------------------------------------------------------------------===// | 425 //===----------------------------------------------------------------------===// |
420 // raw_fd_ostream | 426 // raw_fd_ostream |
421 //===----------------------------------------------------------------------===// | 427 //===----------------------------------------------------------------------===// |
422 | 428 |
423 /// raw_fd_ostream - Open the specified file for writing. If an error | 429 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC, |
424 /// occurs, information about the error is put into ErrorInfo, and the | |
425 /// stream should be immediately destroyed; the string will be empty | |
426 /// if no error occurred. | |
427 raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, | |
428 sys::fs::OpenFlags Flags) | 430 sys::fs::OpenFlags Flags) |
429 : Error(false), UseAtomicWrites(false), pos(0) { | 431 : Error(false), UseAtomicWrites(false), pos(0) { |
430 assert(Filename != 0 && "Filename is null"); | 432 EC = std::error_code(); |
431 ErrorInfo.clear(); | |
432 | |
433 // Handle "-" as stdout. Note that when we do this, we consider ourself | 433 // Handle "-" as stdout. Note that when we do this, we consider ourself |
434 // the owner of stdout. This means that we can do things like close the | 434 // the owner of stdout. This means that we can do things like close the |
435 // file descriptor when we're done and set the "binary" flag globally. | 435 // file descriptor when we're done and set the "binary" flag globally. |
436 if (Filename[0] == '-' && Filename[1] == 0) { | 436 if (Filename == "-") { |
437 FD = STDOUT_FILENO; | 437 FD = STDOUT_FILENO; |
438 // If user requested binary then put stdout into binary mode if | 438 // If user requested binary then put stdout into binary mode if |
439 // possible. | 439 // possible. |
440 if (Flags & sys::fs::F_Binary) | 440 if (!(Flags & sys::fs::F_Text)) |
441 sys::ChangeStdoutToBinary(); | 441 sys::ChangeStdoutToBinary(); |
442 // Close stdout when we're done, to detect any output errors. | 442 // Close stdout when we're done, to detect any output errors. |
443 ShouldClose = true; | 443 ShouldClose = true; |
444 return; | 444 return; |
445 } | 445 } |
446 | 446 |
447 error_code EC = sys::fs::openFileForWrite(Filename, FD, Flags); | 447 EC = sys::fs::openFileForWrite(Filename, FD, Flags); |
448 | 448 |
449 if (EC) { | 449 if (EC) { |
450 ErrorInfo = "Error opening output file '" + std::string(Filename) + "': " + | |
451 EC.message(); | |
452 ShouldClose = false; | 450 ShouldClose = false; |
453 return; | 451 return; |
454 } | 452 } |
455 | 453 |
456 // Ok, we successfully opened the file, so it'll need to be closed. | 454 // Ok, we successfully opened the file, so it'll need to be closed. |
461 /// ShouldClose is true, this closes the file when the stream is destroyed. | 459 /// ShouldClose is true, this closes the file when the stream is destroyed. |
462 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) | 460 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) |
463 : raw_ostream(unbuffered), FD(fd), | 461 : raw_ostream(unbuffered), FD(fd), |
464 ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) { | 462 ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) { |
465 #ifdef O_BINARY | 463 #ifdef O_BINARY |
466 // Setting STDOUT and STDERR to binary mode is necessary in Win32 | 464 // Setting STDOUT to binary mode is necessary in Win32 |
467 // to avoid undesirable linefeed conversion. | 465 // to avoid undesirable linefeed conversion. |
468 if (fd == STDOUT_FILENO || fd == STDERR_FILENO) | 466 // Don't touch STDERR, or w*printf() (in assert()) would barf wide chars. |
467 if (fd == STDOUT_FILENO) | |
469 setmode(fd, O_BINARY); | 468 setmode(fd, O_BINARY); |
470 #endif | 469 #endif |
471 | 470 |
472 // Get the starting position. | 471 // Get the starting position. |
473 off_t loc = ::lseek(FD, 0, SEEK_CUR); | 472 off_t loc = ::lseek(FD, 0, SEEK_CUR); |
651 | 650 |
652 /// outs() - This returns a reference to a raw_ostream for standard output. | 651 /// outs() - This returns a reference to a raw_ostream for standard output. |
653 /// Use it like: outs() << "foo" << "bar"; | 652 /// Use it like: outs() << "foo" << "bar"; |
654 raw_ostream &llvm::outs() { | 653 raw_ostream &llvm::outs() { |
655 // Set buffer settings to model stdout behavior. | 654 // Set buffer settings to model stdout behavior. |
656 // Delete the file descriptor when the program exists, forcing error | 655 // Delete the file descriptor when the program exits, forcing error |
657 // detection. If you don't want this behavior, don't use outs(). | 656 // detection. If you don't want this behavior, don't use outs(). |
658 static raw_fd_ostream S(STDOUT_FILENO, true); | 657 static raw_fd_ostream S(STDOUT_FILENO, true); |
659 return S; | 658 return S; |
660 } | 659 } |
661 | 660 |
720 OS.reserve(OS.capacity() * 2); | 719 OS.reserve(OS.capacity() * 2); |
721 SetBuffer(OS.end(), OS.capacity() - OS.size()); | 720 SetBuffer(OS.end(), OS.capacity() - OS.size()); |
722 } | 721 } |
723 | 722 |
724 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { | 723 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { |
725 // If we're writing bytes from the end of the buffer into the smallvector, we | |
726 // don't need to copy the bytes, just commit the bytes because they are | |
727 // already in the right place. | |
728 if (Ptr == OS.end()) { | 724 if (Ptr == OS.end()) { |
729 assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!"); | 725 // Grow the buffer to include the scratch area without copying. |
730 OS.set_size(OS.size() + Size); | 726 size_t NewSize = OS.size() + Size; |
727 assert(NewSize <= OS.capacity() && "Invalid write_impl() call!"); | |
728 OS.set_size(NewSize); | |
731 } else { | 729 } else { |
732 assert(GetNumBytesInBuffer() == 0 && | 730 assert(!GetNumBytesInBuffer()); |
733 "Should be writing from buffer if some bytes in it"); | 731 OS.append(Ptr, Ptr + Size); |
734 // Otherwise, do copy the bytes. | 732 } |
735 OS.append(Ptr, Ptr+Size); | 733 |
736 } | 734 OS.reserve(OS.size() + 64); |
737 | |
738 // Grow the vector if necessary. | |
739 if (OS.capacity() - OS.size() < 64) | |
740 OS.reserve(OS.capacity() * 2); | |
741 | |
742 // Update the buffer position. | |
743 SetBuffer(OS.end(), OS.capacity() - OS.size()); | 735 SetBuffer(OS.end(), OS.capacity() - OS.size()); |
744 } | 736 } |
745 | 737 |
746 uint64_t raw_svector_ostream::current_pos() const { | 738 uint64_t raw_svector_ostream::current_pos() const { |
747 return OS.size(); | 739 return OS.size(); |