[llvm] r225269 - Implement a very basic colored syntax highlighting for llvm-dwarfdump.
David Blaikie
dblaikie at gmail.com
Tue Jan 6 10:00:58 PST 2015
On Tue, Jan 6, 2015 at 9:11 AM, Adrian Prantl <aprantl at apple.com> wrote:
>
> On Jan 6, 2015, at 9:05 AM, David Blaikie <dblaikie at gmail.com> wrote:
>
>
>
> On Tue, Jan 6, 2015 at 8:50 AM, Adrian Prantl <aprantl at apple.com> wrote:
>
>> Author: adrian
>> Date: Tue Jan 6 10:50:25 2015
>> New Revision: 225269
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=225269&view=rev
>> Log:
>> 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
>>
>> Added:
>> llvm/trunk/lib/DebugInfo/SyntaxHighlighting.cpp
>> llvm/trunk/lib/DebugInfo/SyntaxHighlighting.h
>> Modified:
>> llvm/trunk/lib/DebugInfo/CMakeLists.txt
>> llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
>> llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp
>>
>> Modified: llvm/trunk/lib/DebugInfo/CMakeLists.txt
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CMakeLists.txt?rev=225269&r1=225268&r2=225269&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/DebugInfo/CMakeLists.txt Tue Jan 6 10:50:25 2015
>> @@ -15,4 +15,5 @@ add_llvm_library(LLVMDebugInfo
>> DWARFFormValue.cpp
>> DWARFTypeUnit.cpp
>> DWARFUnit.cpp
>> + SyntaxHighlighting.cpp
>> )
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp?rev=225269&r1=225268&r2=225269&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp Tue Jan 6 10:50:25
>> 2015
>> @@ -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(ra
>>
>> 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());
>>
>
> Perhaps we could/should introduce a non-member form of indent something
> like:
>
> stream << indent(2) << ...
>
>
> I think that would be nice. Thinking of it, it might be even better to
> have something like
>
> OS << indent(2) << color(syntax::Attribute) << text << color_reset;
>
> where color and color_reset are the identity if color support is not
> enabled.
>
I rather like the scoped solution that ensures we don't have to remember to
'reset' all the time - though that could still be done with the syntax
you're suggesting. It'd be a bit tricky.
color(syntax::Attribute) would be (or return) an object that, when passed
to the relevant op<<, would apply the color and store a reference to the
stream in a mutable member. In color's dtor, it would then undo the color
application.
>
>
> ?
>
>
>> +
>> OS << format(" [%u] %c\n", abbrCode,
>> AbbrevDecl->hasChildren() ? '*' : ' ');
>>
>> @@ -114,9 +118,10 @@ void DWARFDebugInfoEntryMinimal::dumpAtt
>> 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);
>>
>
> Why do some calls have get, and some not?
>
>
> The C++ type system cannot infer that we want the llvm::ostream
> &operator() if the format template is involved.
>
Ah. I believe this is the problem I alluded to in the review. The way the
format() is implemented is that it returns a format_object<...> (a subclass
of format_object_base) and raw_ostream has an op<< overload for const
format_object_base&. The problem is that this op<< is implemented as a
member function which means you don't get the free implicit conversions on
the LHS of the << usage. If this (and related) op<< are moved out to be
non-members, I believe this should work.
> Maybe having both forms is even worse compared to having calls to get()
> everywhere?
>
> -- adrian
>
>
>
>> +
>> const char *formString = FormEncodingString(form);
>> if (formString)
>> OS << " [" << formString << ']';
>> @@ -132,7 +137,9 @@ void DWARFDebugInfoEntryMinimal::dumpAtt
>>
>> 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::dumpAtt
>> } 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
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp?rev=225269&r1=225268&r2=225269&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp Tue Jan 6 10:50:25 2015
>> @@ -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, co
>> 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, co
>> 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, co
>> 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 {
>>
>> Added: llvm/trunk/lib/DebugInfo/SyntaxHighlighting.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/SyntaxHighlighting.cpp?rev=225269&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/SyntaxHighlighting.cpp (added)
>> +++ llvm/trunk/lib/DebugInfo/SyntaxHighlighting.cpp Tue Jan 6 10:50:25
>> 2015
>> @@ -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();
>> +}
>>
>> Added: llvm/trunk/lib/DebugInfo/SyntaxHighlighting.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/SyntaxHighlighting.h?rev=225269&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/SyntaxHighlighting.h (added)
>> +++ llvm/trunk/lib/DebugInfo/SyntaxHighlighting.h Tue Jan 6 10:50:25 2015
>> @@ -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
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150106/e3c2531e/attachment.html>
More information about the llvm-commits
mailing list