From 271631a0afecebfb806e8d4d67407c919c4e1c0d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 9 Apr 2015 02:10:28 +0000 Subject: [PATCH] Add classof implementations to the raw_ostream classes. More uses to follow in a another patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234460 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCLinkerOptimizationHint.h | 6 +++- include/llvm/Support/FormattedStream.h | 12 +++++-- include/llvm/Support/circular_raw_ostream.h | 16 ++++----- include/llvm/Support/raw_os_ostream.h | 5 ++- include/llvm/Support/raw_ostream.h | 36 ++++++++++++++++++--- lib/Support/Debug.cpp | 5 ++- lib/Support/raw_ostream.cpp | 9 +++--- 7 files changed, 65 insertions(+), 24 deletions(-) diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index 890d6385aac..8c0813b6b0a 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -140,8 +140,12 @@ public: 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; diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index 8137daaff1f..71120370a02 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -84,15 +84,21 @@ public: /// 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(); diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h index 3d0f6e83cd3..0d1f378846f 100644 --- a/include/llvm/Support/circular_raw_ostream.h +++ b/include/llvm/Support/circular_raw_ostream.h @@ -107,14 +107,10 @@ namespace llvm /// 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; @@ -144,6 +140,10 @@ namespace llvm /// 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 diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h index 04cf3b6202c..e41cc71026f 100644 --- a/include/llvm/Support/raw_os_ostream.h +++ b/include/llvm/Support/raw_os_ostream.h @@ -33,8 +33,11 @@ class raw_os_ostream : public 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 diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index dfe25978faf..982271397e4 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -16,6 +16,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include @@ -67,6 +68,17 @@ private: } 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, @@ -80,8 +92,8 @@ public: 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; } @@ -259,7 +271,10 @@ public: // 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. @@ -364,6 +379,8 @@ public: /// 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 @@ -443,9 +460,13 @@ class raw_string_ostream : public raw_ostream { /// 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() { @@ -473,6 +494,10 @@ public: explicit raw_svector_ostream(SmallVectorImpl &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. @@ -493,8 +518,11 @@ class raw_null_ostream : public raw_ostream { 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 diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp index a88b18e6c06..896898c185c 100644 --- a/lib/Support/Debug.cpp +++ b/lib/Support/Debug.cpp @@ -114,9 +114,8 @@ static void debug_user_sig_handler(void *Cookie) { // 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::dbgs()); - dbgout->flushBufferWithBanner(); + llvm::circular_raw_ostream &dbgout = cast(llvm::dbgs()); + dbgout.flushBufferWithBanner(); } /// dbgs - Return a circular-buffered debug stream. diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 051e2dd252f..a312126fffe 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -489,7 +489,7 @@ void format_object_base::home() { 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 @@ -519,8 +519,8 @@ raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC, /// 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. @@ -749,7 +749,8 @@ void raw_string_ostream::write_impl(const char *Ptr, size_t Size) { // 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 &O) : OS(O) { +raw_svector_ostream::raw_svector_ostream(SmallVectorImpl &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