Index: lib/DebugInfo/CMakeLists.txt =================================================================== --- lib/DebugInfo/CMakeLists.txt +++ lib/DebugInfo/CMakeLists.txt @@ -15,4 +15,5 @@ DWARFFormValue.cpp DWARFTypeUnit.cpp DWARFUnit.cpp + SyntaxHighlighting.cpp ) Index: lib/DebugInfo/DWARFDebugInfoEntry.cpp =================================================================== --- lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "SyntaxHighlighting.h" #include "llvm/DebugInfo/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARFContext.h" @@ -19,6 +20,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace dwarf; +using namespace syntax; // Small helper to extract a DIE pointed by a reference // attribute. It looks up the Unit containing the DIE and calls @@ -39,15 +41,22 @@ if (debug_info_data.isValidOffset(offset)) { uint32_t abbrCode = debug_info_data.getULEB128(&offset); + { + WithColor C(OS, syntax::Address); + OS << format("\n0x%8.8x: ", Offset); + } - OS << format("\n0x%8.8x: ", Offset); if (abbrCode) { if (AbbrevDecl) { - const char *tagString = TagString(getTag()); - if (tagString) - OS.indent(indent) << tagString; - else - OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); + { + WithColor C(OS, syntax::Tag); + const char *tagString = TagString(getTag()); + if (tagString) + OS.indent(indent) << tagString; + else + OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); + } + OS << format(" [%u] %c\n", abbrCode, AbbrevDecl->hasChildren() ? '*' : ' '); @@ -112,11 +121,15 @@ const char BaseIndent[] = " "; OS << BaseIndent; OS.indent(indent+2); - const char *attrString = AttributeString(attr); - if (attrString) - OS << attrString; - else - OS << format("DW_AT_Unknown_%x", attr); + { + WithColor C(OS, syntax::Attribute); + const char *attrString = AttributeString(attr); + if (attrString) + OS << attrString; + else + OS << format("DW_AT_Unknown_%x", attr); + } + const char *formString = FormEncodingString(form); if (formString) OS << " [" << formString << ']'; @@ -145,7 +158,13 @@ Name = AttributeValueString(attr, *Val); if (Name) { - OS << Name; + if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { + WithColor C(OS, syntax::String); + OS << Name; + } else { + WithColor C(OS, syntax::Enumerator); + OS << Name; + } } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) { OS << *formValue.getAsUnsignedConstant(); } else { Index: lib/DebugInfo/DWARFFormValue.cpp =================================================================== --- lib/DebugInfo/DWARFFormValue.cpp +++ lib/DebugInfo/DWARFFormValue.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "SyntaxHighlighting.h" #include "llvm/DebugInfo/DWARFFormValue.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -19,6 +20,7 @@ #include using namespace llvm; using namespace dwarf; +using namespace syntax; namespace { uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { @@ -423,6 +425,7 @@ OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); Optional DbgStr = getAsCString(cu); if (DbgStr.hasValue()) { + WithColor C(OS, syntax::String); OS << '"'; OS.write_escaped(DbgStr.getValue()); OS << '"'; @@ -433,6 +436,7 @@ OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); Optional DbgStr = getAsCString(cu); if (DbgStr.hasValue()) { + WithColor C(OS, syntax::String); OS << '"'; OS.write_escaped(DbgStr.getValue()); OS << '"'; @@ -479,8 +483,14 @@ break; } - if (cu_relative_offset) - OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0)); + if (cu_relative_offset) { + OS << " => {"; + { + WithColor C(OS, syntax::Address); + OS << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0)); + } + OS << "}"; + } } Optional DWARFFormValue::getAsCString(const DWARFUnit *U) const { Index: lib/DebugInfo/SyntaxHighlighting.h =================================================================== --- /dev/null +++ lib/DebugInfo/SyntaxHighlighting.h @@ -0,0 +1,35 @@ +//===-- SyntaxHighlighting.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_DEBUGINFO_SYNTAXHIGHLIGHTING_H +#define LLVM_LIB_DEBUGINFO_SYNTAXHIGHLIGHTING_H + +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace dwarf { +namespace syntax { + +// Symbolic names for various syntax elements. +enum HighlightColor { Address, String, Tag, Attribute, Enumerator }; + +/// An RAII object that temporarily switches an output stream to a +/// specific color. +class WithColor { + llvm::raw_ostream &OS; + +public: + WithColor(llvm::raw_ostream &OS, enum HighlightColor Type); + ~WithColor(); +}; +} +} +} + +#endif Index: lib/DebugInfo/SyntaxHighlighting.cpp =================================================================== --- /dev/null +++ lib/DebugInfo/SyntaxHighlighting.cpp @@ -0,0 +1,37 @@ +//===-- SyntaxHighlighting.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SyntaxHighlighting.h" +#include "llvm/Support/CommandLine.h" +using namespace llvm; +using namespace dwarf; +using namespace syntax; + +static cl::opt + UseColor("color", + cl::desc("use colored syntax highlighting (default=autodetect)"), + cl::init(cl::BOU_UNSET)); + +WithColor::WithColor(llvm::raw_ostream &OS, enum HighlightColor Type) : OS(OS) { + // Detect color from terminal type unless the user passed the --color option. + if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) { + switch (Type) { + case Address: OS.changeColor(llvm::raw_ostream::YELLOW); break; + case String: OS.changeColor(llvm::raw_ostream::GREEN); break; + case Tag: OS.changeColor(llvm::raw_ostream::BLUE); break; + case Attribute: OS.changeColor(llvm::raw_ostream::CYAN); break; + case Enumerator: OS.changeColor(llvm::raw_ostream::MAGENTA); break; + } + } +} + +WithColor::~WithColor() { + if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) + OS.resetColor(); +}