[llvm] r225269 - Implement a very basic colored syntax highlighting for llvm-dwarfdump.

Adrian Prantl aprantl at apple.com
Tue Jan 6 09:11:28 PST 2015


> 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 <mailto: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 <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 <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 <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 <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.

> 
> ?
>  
> +
>          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. 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 <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 <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 <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 <mailto:llvm-commits at cs.uiuc.edu>
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <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/49047f99/attachment.html>


More information about the llvm-commits mailing list