diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/include/llvm/DebugInfo/DIContext.h @@ -191,6 +191,7 @@ bool SummarizeTypes = false; bool Verbose = false; bool DisplayRawContents = false; + llvm::ColorMode ColorMode = llvm::ColorMode::Auto; /// Return default option set for printing a single DIE without children. static DIDumpOptions getForSingleDIE() { diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -150,7 +150,7 @@ const dwarf::FormParams FormParams); private: - void dumpString(raw_ostream &OS) const; + void dumpString(raw_ostream &OS, const DIDumpOptions &DumpOpts) const; }; namespace dwarf { diff --git a/llvm/include/llvm/Support/WithColor.h b/llvm/include/llvm/Support/WithColor.h --- a/llvm/include/llvm/Support/WithColor.h +++ b/llvm/include/llvm/Support/WithColor.h @@ -132,6 +132,10 @@ /// Implement default handling for Warning. /// Print "warning: " to stderr. static void defaultWarningHandler(Error Warning); + + /// Return ColorMode::Enable or ColorMode::Disable instead of ColorMode::Auto. + /// Cache that value for later calls of WithColor constructor. + static ColorMode GetModeForOS(raw_ostream &OS); }; } // end namespace llvm diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -239,7 +239,8 @@ const char BaseIndent[] = " "; OS << BaseIndent; OS.indent(Indent + 2); - WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr); + WithColor(OS, HighlightColor::Attribute, DumpOpts.ColorMode) + << formatv("{0}", Attr); if (DumpOpts.Verbose || DumpOpts.ShowForm) OS << formatv(" [{0}]", Form); @@ -266,7 +267,7 @@ Name = AttributeValueString(Attr, *Val); if (!Name.empty()) - WithColor(OS, Color) << Name; + WithColor(OS, Color, DumpOpts.ColorMode) << Name; else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) OS << *FormValue.getAsUnsignedConstant(); else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && @@ -596,13 +597,15 @@ if (debug_info_data.isValidOffset(offset)) { uint32_t abbrCode = debug_info_data.getULEB128(&offset); if (DumpOpts.ShowAddresses) - WithColor(OS, HighlightColor::Address).get() + WithColor(OS, HighlightColor::Address, DumpOpts.ColorMode).get() << format("\n0x%8.8" PRIx64 ": ", Offset); if (abbrCode) { auto AbbrevDecl = getAbbreviationDeclarationPtr(); if (AbbrevDecl) { - WithColor(OS, HighlightColor::Tag).get().indent(Indent) + WithColor(OS, HighlightColor::Tag, DumpOpts.ColorMode) + .get() + .indent(Indent) << formatv("{0}", getTag()); if (DumpOpts.Verbose) OS << format(" [%u] %c", abbrCode, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -384,9 +384,10 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { uint64_t UValue = Value.uval; bool CURelativeOffset = false; - raw_ostream &AddrOS = DumpOpts.ShowAddresses - ? WithColor(OS, HighlightColor::Address).get() - : nulls(); + raw_ostream &AddrOS = + DumpOpts.ShowAddresses + ? WithColor(OS, HighlightColor::Address, DumpOpts.ColorMode).get() + : nulls(); int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); switch (Form) { case DW_FORM_addr: @@ -484,13 +485,13 @@ case DW_FORM_strp: if (DumpOpts.Verbose) OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue); - dumpString(OS); + dumpString(OS, DumpOpts); break; case DW_FORM_line_strp: if (DumpOpts.Verbose) OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue); - dumpString(OS); + dumpString(OS, DumpOpts); break; case DW_FORM_strx: case DW_FORM_strx1: @@ -500,12 +501,12 @@ case DW_FORM_GNU_str_index: if (DumpOpts.Verbose) OS << format("indexed (%8.8x) string = ", (uint32_t)UValue); - dumpString(OS); + dumpString(OS, DumpOpts); break; case DW_FORM_GNU_strp_alt: if (DumpOpts.Verbose) OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue); - dumpString(OS); + dumpString(OS, DumpOpts); break; case DW_FORM_ref_addr: AddrOS << format("0x%016" PRIx64, UValue); @@ -566,17 +567,18 @@ if (DumpOpts.Verbose) OS << " => {"; if (DumpOpts.ShowAddresses) - WithColor(OS, HighlightColor::Address).get() + WithColor(OS, HighlightColor::Address, DumpOpts.ColorMode).get() << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0)); if (DumpOpts.Verbose) OS << "}"; } } -void DWARFFormValue::dumpString(raw_ostream &OS) const { +void DWARFFormValue::dumpString(raw_ostream &OS, + const DIDumpOptions &DumpOpts) const { Optional DbgStr = getAsCString(); if (DbgStr.hasValue()) { - auto COS = WithColor(OS, HighlightColor::String); + auto COS = WithColor(OS, HighlightColor::String, DumpOpts.ColorMode); COS.get() << '"'; COS.get().write_escaped(DbgStr.getValue()); COS.get() << '"'; diff --git a/llvm/lib/Support/WithColor.cpp b/llvm/lib/Support/WithColor.cpp --- a/llvm/lib/Support/WithColor.cpp +++ b/llvm/lib/Support/WithColor.cpp @@ -105,6 +105,13 @@ << "remark: "; } +ColorMode WithColor::GetModeForOS(raw_ostream &OS) { + return (UseColor == cl::BOU_UNSET ? OS.has_colors() + : UseColor == cl::BOU_TRUE) + ? ColorMode::Enable + : ColorMode::Disable; +} + bool WithColor::colorsEnabled() { switch (Mode) { case ColorMode::Enable: @@ -112,8 +119,8 @@ case ColorMode::Disable: return false; case ColorMode::Auto: - return UseColor == cl::BOU_UNSET ? OS.has_colors() - : UseColor == cl::BOU_TRUE; + Mode = GetModeForOS(OS); + return colorsEnabled(); } llvm_unreachable("All cases handled above."); } diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -264,7 +264,7 @@ exit(1); } -static DIDumpOptions getDumpOpts(DWARFContext &C) { +static DIDumpOptions getDumpOpts(DWARFContext &C, raw_ostream &OS) { DIDumpOptions DumpOpts; DumpOpts.DumpType = DumpType; DumpOpts.ChildRecurseDepth = ChildRecurseDepth; @@ -275,6 +275,7 @@ DumpOpts.ShowForm = ShowForm; DumpOpts.SummarizeTypes = SummarizeTypes; DumpOpts.Verbose = Verbose; + DumpOpts.ColorMode = llvm::WithColor::GetModeForOS(OS); DumpOpts.RecoverableErrorHandler = C.getRecoverableErrorHandler(); // In -verify mode, print DIEs without children in error messages. if (Verify) @@ -316,7 +317,7 @@ /// Print only DIEs that have a certain name. static bool filterByName(const StringSet<> &Names, DWARFDie Die, StringRef NameRef, raw_ostream &OS) { - DIDumpOptions DumpOpts = getDumpOpts(Die.getDwarfUnit()->getContext()); + DIDumpOptions DumpOpts = getDumpOpts(Die.getDwarfUnit()->getContext(), OS); std::string Name = (IgnoreCase && !UseRegex) ? NameRef.lower() : NameRef.str(); if (UseRegex) { @@ -408,7 +409,7 @@ llvm::sort(Dies); Dies.erase(std::unique(Dies.begin(), Dies.end()), Dies.end()); - DIDumpOptions DumpOpts = getDumpOpts(DICtx); + DIDumpOptions DumpOpts = getDumpOpts(DICtx, OS); for (DWARFDie Die : Dies) Die.dump(OS, 0, DumpOpts); } @@ -426,7 +427,7 @@ if (!DIEsForAddr) return false; - DIDumpOptions DumpOpts = getDumpOpts(DICtx); + DIDumpOptions DumpOpts = getDumpOpts(DICtx, OS); DumpOpts.ChildRecurseDepth = 0; DIEsForAddr.CompileUnit->dump(OS, DumpOpts); if (DIEsForAddr.FunctionDIE) { @@ -474,7 +475,7 @@ } // Dump the complete DWARF structure. - DICtx.dump(OS, getDumpOpts(DICtx), DumpOffsets); + DICtx.dump(OS, getDumpOpts(DICtx, OS), DumpOffsets); return true; } @@ -485,7 +486,7 @@ raw_ostream &stream = Quiet ? nulls() : OS; stream << "Verifying " << Filename.str() << ":\tfile format " << Obj.getFileFormatName() << "\n"; - bool Result = DICtx.verify(stream, getDumpOpts(DICtx)); + bool Result = DICtx.verify(stream, getDumpOpts(DICtx, OS)); if (Result) stream << "No errors.\n"; else