uint64_t current_pos() const override { return Count; }
public:
- raw_counting_ostream() : Count(0) {}
+ raw_counting_ostream() : raw_ostream(SK_COUNTING), Count(0) {}
~raw_counting_ostream() { flush(); }
+
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_COUNTING;
+ }
};
raw_counting_ostream OutStream;
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
- formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
+ : raw_ostream(SK_FORMATTED), TheStream(nullptr), DeleteStream(false),
+ Position(0, 0) {
setStream(Stream, Delete);
}
explicit formatted_raw_ostream()
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ : raw_ostream(SK_FORMATTED), TheStream(nullptr), DeleteStream(false),
+ Position(0, 0) {
Scanned = nullptr;
}
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_FORMATTED;
+ }
+
~formatted_raw_ostream() {
flush();
releaseStream();
/// management of it, etc.
///
circular_raw_ostream(raw_ostream &Stream, const char *Header,
- size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
- : raw_ostream(/*unbuffered*/true),
- TheStream(nullptr),
- OwnsStream(Owns),
- BufferSize(BuffSize),
- BufferArray(nullptr),
- Filled(false),
- Banner(Header) {
+ size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
+ : raw_ostream(SK_CIRCULAR, /*unbuffered*/ true), TheStream(nullptr),
+ OwnsStream(Owns), BufferSize(BuffSize), BufferArray(nullptr),
+ Filled(false), Banner(Header) {
if (BufferSize != 0)
BufferArray = new char[BufferSize];
Cur = BufferArray;
///
void flushBufferWithBanner();
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_CIRCULAR;
+ }
+
private:
/// releaseStream - Delete the held stream if needed. Otherwise,
/// transfer the buffer settings from this circular_raw_ostream
uint64_t current_pos() const override;
public:
- raw_os_ostream(std::ostream &O) : OS(O) {}
+ raw_os_ostream(std::ostream &O) : raw_ostream(SK_STD_OS), OS(O) {}
~raw_os_ostream();
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_STD_OS;
+ }
};
} // end llvm namespace
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <system_error>
} BufferMode;
public:
+ enum StreamKind {
+ SK_FD,
+ SK_STRING,
+ SK_SVECTOR,
+ SK_NULL,
+ SK_STD_OS,
+ SK_CIRCULAR,
+ SK_FORMATTED,
+ SK_COUNTING
+ };
+
// color order matches ANSI escape sequence, don't change
enum Colors {
BLACK=0,
SAVEDCOLOR
};
- explicit raw_ostream(bool unbuffered=false)
- : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
+ explicit raw_ostream(StreamKind Kind, bool unbuffered = false)
+ : BufferMode(unbuffered ? Unbuffered : InternalBuffer), Kind(Kind) {
// Start out ready to flush.
OutBufStart = OutBufEnd = OutBufCur = nullptr;
}
// Subclass Interface
//===--------------------------------------------------------------------===//
+ StreamKind getKind() const { return Kind; }
+
private:
+ StreamKind Kind;
/// The is the piece of the class that is implemented by subclasses. This
/// writes the \p Size bytes starting at
/// \p Ptr to the underlying stream.
/// this closes the file when the stream is destroyed.
raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
+ static bool classof(const raw_ostream *OS) { return OS->getKind() == SK_FD; }
+
~raw_fd_ostream();
/// Manually flush the stream and close the file. Note that this does not call
/// currently in the buffer.
uint64_t current_pos() const override { return OS.size(); }
public:
- explicit raw_string_ostream(std::string &O) : OS(O) {}
+ explicit raw_string_ostream(std::string &O) : raw_ostream(SK_STRING), OS(O) {}
~raw_string_ostream();
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_STRING;
+ }
+
/// Flushes the stream contents to the target string and returns the string's
/// reference.
std::string& str() {
explicit raw_svector_ostream(SmallVectorImpl<char> &O);
~raw_svector_ostream();
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_SVECTOR;
+ }
+
/// This is called when the SmallVector we're appending to is changed outside
/// of the raw_svector_ostream's control. It is only safe to do this if the
/// raw_svector_ostream has previously been flushed.
uint64_t current_pos() const override;
public:
- explicit raw_null_ostream() {}
+ explicit raw_null_ostream() : raw_ostream(SK_NULL) {}
~raw_null_ostream();
+ static bool classof(const raw_ostream *OS) {
+ return OS->getKind() == SK_NULL;
+ }
};
} // end llvm namespace
// know that debug mode is enabled and dbgs() really is a
// circular_raw_ostream. If NDEBUG is defined, then dbgs() ==
// errs() but this will never be invoked.
- llvm::circular_raw_ostream *dbgout =
- static_cast<llvm::circular_raw_ostream *>(&llvm::dbgs());
- dbgout->flushBufferWithBanner();
+ llvm::circular_raw_ostream &dbgout = cast<circular_raw_ostream>(llvm::dbgs());
+ dbgout.flushBufferWithBanner();
}
/// dbgs - Return a circular-buffered debug stream.
raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
sys::fs::OpenFlags Flags)
- : Error(false), UseAtomicWrites(false), pos(0) {
+ : raw_ostream(SK_FD), Error(false), UseAtomicWrites(false), pos(0) {
EC = std::error_code();
// Handle "-" as stdout. Note that when we do this, we consider ourself
// the owner of stdout. This means that we can do things like close the
/// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
/// ShouldClose is true, this closes the file when the stream is destroyed.
raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
- : raw_ostream(unbuffered), FD(fd),
- ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) {
+ : raw_ostream(SK_FD, unbuffered), FD(fd), ShouldClose(shouldClose),
+ Error(false), UseAtomicWrites(false) {
#ifdef O_BINARY
// Setting STDOUT to binary mode is necessary in Win32
// to avoid undesirable linefeed conversion.
// capacity. This allows raw_ostream to write directly into the correct place,
// and we only need to set the vector size when the data is flushed.
-raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {
+raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O)
+ : raw_ostream(SK_SVECTOR), OS(O) {
// Set up the initial external buffer. We make sure that the buffer has at
// least 128 bytes free; raw_ostream itself only requires 64, but we want to
// make sure that we don't grow the buffer unnecessarily on destruction (when