summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2015-01-06 16:50:25 +0000
committerAdrian Prantl <aprantl@apple.com>2015-01-06 16:50:25 +0000
commitaea3b23b9b9fb32ec506be32af7d514dd794efed (patch)
tree11cd285c291d5876524303272557b218fd867fdc
parent15914b5c2244bdbda439bf2a4cab2191cc7617dc (diff)
Implement a very basic colored syntax highlighting for llvm-dwarfdump.
The color scheme is the same as the one used by the colorize dwarfdump script on Darwin. A new --color option can be used to forcibly turn color on or off. http://reviews.llvm.org/D6852 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225269 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/DebugInfo/CMakeLists.txt1
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp32
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp24
-rw-r--r--lib/DebugInfo/SyntaxHighlighting.cpp37
-rw-r--r--lib/DebugInfo/SyntaxHighlighting.h39
5 files changed, 112 insertions, 21 deletions
diff --git a/lib/DebugInfo/CMakeLists.txt b/lib/DebugInfo/CMakeLists.txt
index 81fc84d4a80..4cce35b5ca1 100644
--- a/lib/DebugInfo/CMakeLists.txt
+++ b/lib/DebugInfo/CMakeLists.txt
@@ -15,4 +15,5 @@ add_llvm_library(LLVMDebugInfo
DWARFFormValue.cpp
DWARFTypeUnit.cpp
DWARFUnit.cpp
+ SyntaxHighlighting.cpp
)
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index 22c27c72dab..a91262f5d3e 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/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,17 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u,
if (debug_info_data.isValidOffset(offset)) {
uint32_t abbrCode = debug_info_data.getULEB128(&offset);
+ WithColor(OS, syntax::Address).get() << 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());
+ const char *tagString = TagString(getTag());
+ if (tagString)
+ WithColor(OS, syntax::Tag).get().indent(indent) << tagString;
+ else
+ WithColor(OS, syntax::Tag).get().indent(indent) <<
+ format("DW_TAG_Unknown_%x", getTag());
+
OS << format(" [%u] %c\n", abbrCode,
AbbrevDecl->hasChildren() ? '*' : ' ');
@@ -114,9 +118,10 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
OS.indent(indent+2);
const char *attrString = AttributeString(attr);
if (attrString)
- OS << attrString;
+ WithColor(OS, syntax::Attribute) << attrString;
else
- OS << format("DW_AT_Unknown_%x", attr);
+ WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", attr);
+
const char *formString = FormEncodingString(form);
if (formString)
OS << " [" << formString << ']';
@@ -132,7 +137,9 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
const char *Name = nullptr;
std::string File;
+ auto Color = syntax::Enumerator;
if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
+ Color = syntax::String;
if (const auto *LT = u->getContext().getLineTableForUnit(u))
if (LT->getFileNameByIndex(
formValue.getAsUnsignedConstant().getValue(),
@@ -144,13 +151,12 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
} else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
Name = AttributeValueString(attr, *Val);
- if (Name) {
- OS << Name;
- } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) {
+ if (Name)
+ WithColor(OS, Color) << Name;
+ else if (attr == DW_AT_decl_line || attr == DW_AT_call_line)
OS << *formValue.getAsUnsignedConstant();
- } else {
+ else
formValue.dump(OS, u);
- }
// We have dumped the attribute raw value. For some attributes
// having both the raw value and the pretty-printed value is
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index 0ff8f2c58cb..31b1ce7237d 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/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 <cassert>
using namespace llvm;
using namespace dwarf;
+using namespace syntax;
namespace {
uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
@@ -423,9 +425,10 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
Optional<const char *> DbgStr = getAsCString(cu);
if (DbgStr.hasValue()) {
- OS << '"';
- OS.write_escaped(DbgStr.getValue());
- OS << '"';
+ raw_ostream &COS = WithColor(OS, syntax::String);
+ COS << '"';
+ COS.write_escaped(DbgStr.getValue());
+ COS << '"';
}
break;
}
@@ -433,9 +436,10 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
Optional<const char *> DbgStr = getAsCString(cu);
if (DbgStr.hasValue()) {
- OS << '"';
- OS.write_escaped(DbgStr.getValue());
- OS << '"';
+ raw_ostream &COS = WithColor(OS, syntax::String);
+ COS << '"';
+ COS.write_escaped(DbgStr.getValue());
+ COS << '"';
}
break;
}
@@ -479,8 +483,12 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
break;
}
- if (cu_relative_offset)
- OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
+ if (cu_relative_offset) {
+ OS << " => {";
+ WithColor(OS, syntax::Address).get()
+ << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0));
+ OS << "}";
+ }
}
Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
diff --git a/lib/DebugInfo/SyntaxHighlighting.cpp b/lib/DebugInfo/SyntaxHighlighting.cpp
new file mode 100644
index 00000000000..a6b4c6549ca
--- /dev/null
+++ b/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<cl::boolOrDefault>
+ 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();
+}
diff --git a/lib/DebugInfo/SyntaxHighlighting.h b/lib/DebugInfo/SyntaxHighlighting.h
new file mode 100644
index 00000000000..946a31308aa
--- /dev/null
+++ b/lib/DebugInfo/SyntaxHighlighting.h
@@ -0,0 +1,39 @@
+//===-- 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:
+ /// To be used like this: WithColor(OS, syntax::String) << "text";
+ WithColor(llvm::raw_ostream &OS, enum HighlightColor Type);
+ ~WithColor();
+
+ llvm::raw_ostream& get() { return OS; }
+ operator llvm::raw_ostream& () { return OS; }
+};
+}
+}
+}
+
+#endif