diff --git a/llvm/include/llvm/Support/FormattedStream.h b/llvm/include/llvm/Support/FormattedStream.h index 5f937cfa79840..850a18dbb9412 100644 --- a/llvm/include/llvm/Support/FormattedStream.h +++ b/llvm/include/llvm/Support/FormattedStream.h @@ -52,6 +52,10 @@ class formatted_raw_ostream : public raw_ostream { /// have the rest of it. SmallString<4> PartialUTF8Char; + /// DisableScan - Temporarily disable scanning of output. Used to ignore color + /// codes. + bool DisableScan; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, @@ -89,9 +93,33 @@ class formatted_raw_ostream : public raw_ostream { SetUnbuffered(); TheStream->SetUnbuffered(); + enable_colors(TheStream->colors_enabled()); + Scanned = nullptr; } + void PreDisableScan() { + assert(!DisableScan); + ComputePosition(getBufferStart(), GetNumBytesInBuffer()); + assert(PartialUTF8Char.empty()); + DisableScan = true; + } + + void PostDisableScan() { + assert(DisableScan); + DisableScan = false; + Scanned = getBufferStart() + GetNumBytesInBuffer(); + } + + struct DisableScanScope { + formatted_raw_ostream *S; + + DisableScanScope(formatted_raw_ostream *FRO) : S(FRO) { + S->PreDisableScan(); + } + ~DisableScanScope() { S->PostDisableScan(); } + }; + public: /// formatted_raw_ostream - Open the specified file for /// writing. If an error occurs, information about the error is @@ -104,12 +132,12 @@ class formatted_raw_ostream : public raw_ostream { /// underneath it. /// formatted_raw_ostream(raw_ostream &Stream) - : TheStream(nullptr), Position(0, 0) { + : TheStream(nullptr), Position(0, 0), DisableScan(false) { setStream(Stream); } - explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) { - Scanned = nullptr; - } + explicit formatted_raw_ostream() + : TheStream(nullptr), Position(0, 0), Scanned(nullptr), + DisableScan(false) {} ~formatted_raw_ostream() override { flush(); @@ -136,17 +164,26 @@ class formatted_raw_ostream : public raw_ostream { } raw_ostream &resetColor() override { - TheStream->resetColor(); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::resetColor(); + } return *this; } raw_ostream &reverseColor() override { - TheStream->reverseColor(); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::reverseColor(); + } return *this; } raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override { - TheStream->changeColor(Color, Bold, BG); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::changeColor(Color, Bold, BG); + } return *this; } diff --git a/llvm/lib/Support/FormattedStream.cpp b/llvm/lib/Support/FormattedStream.cpp index c0d2843509957..c50530e76efc0 100644 --- a/llvm/lib/Support/FormattedStream.cpp +++ b/llvm/lib/Support/FormattedStream.cpp @@ -94,6 +94,9 @@ void formatted_raw_ostream::UpdatePosition(const char *Ptr, size_t Size) { /// ComputePosition - Examine the current output and update line and column /// counts. void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) { + if (DisableScan) + return; + // If our previous scan pointer is inside the buffer, assume we already // scanned those bytes. This depends on raw_ostream to not change our buffer // in unexpected ways. diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index 8eb53e4404598..807071a7b9a16 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -541,11 +541,6 @@ int main(int argc, char **argv) { std::unique_ptr MAB( TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); auto FOut = std::make_unique(*OS); - // FIXME: Workaround for bug in formatted_raw_ostream. Color escape codes - // are (incorrectly) written directly to the unbuffered raw_ostream wrapped - // by the formatted_raw_ostream. - if (Action == AC_CDisassemble) - FOut->SetUnbuffered(); Str.reset( TheTarget->createAsmStreamer(Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 78cf67b1e630b..9b65ea5a99e4d 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2115,13 +2115,6 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj, formatted_raw_ostream FOS(outs()); - // FIXME: Workaround for bug in formatted_raw_ostream. Color escape codes - // are (incorrectly) written directly to the unbuffered raw_ostream - // wrapped by the formatted_raw_ostream. - if (DisassemblyColor == ColorOutput::Enable || - DisassemblyColor == ColorOutput::Auto) - FOS.SetUnbuffered(); - std::unordered_map AllLabels; std::unordered_map> BBAddrMapLabels; if (SymbolizeOperands) {