[lld] r287949 - Support -color-diagnostics={auto,always,never}.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 25 12:27:32 PST 2016


Author: ruiu
Date: Fri Nov 25 14:27:32 2016
New Revision: 287949

URL: http://llvm.org/viewvc/llvm-project?rev=287949&view=rev
Log:
Support -color-diagnostics={auto,always,never}.

-color-diagnostics=auto is default because that's the same as
Clang's default. When color is enabled, error or warning messages
are colored like this.

  error:
  <bold>ld.lld</bold> <red>error:</red> foo.o: no such file

  warning:
  <bold>ld.lld</bold> <magenta>warning:</magenta> foo.o: no such file

Differential Revision: https://reviews.llvm.org/D27117

Added:
    lld/trunk/test/ELF/color-diagnostics.test
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Error.cpp
    lld/trunk/ELF/Options.td

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=287949&r1=287948&r2=287949&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Fri Nov 25 14:27:32 2016
@@ -34,6 +34,9 @@ enum ELFKind {
 // For --build-id.
 enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
 
+// For --color-diagnostics.
+enum class ColorPolicy { Auto, Always, Never };
+
 // For --discard-{all,locals,none}.
 enum class DiscardPolicy { Default, All, Locals, None };
 
@@ -135,6 +138,7 @@ struct Configuration {
   bool ZRelro;
   bool ExitEarly;
   bool ZWxneeded;
+  ColorPolicy ColorDiagnostics = ColorPolicy::Auto;
   DiscardPolicy Discard;
   SortSectionPolicy SortSection;
   StripPolicy Strip = StripPolicy::None;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=287949&r1=287948&r2=287949&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Nov 25 14:27:32 2016
@@ -392,6 +392,24 @@ static bool getArg(opt::InputArgList &Ar
   return Default;
 }
 
+// Parse -color-diagnostics={auto,always,never} or -no-color-diagnostics.
+static ColorPolicy getColorDiagnostics(opt::InputArgList &Args) {
+  auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_no_color_diagnostics);
+  if (!Arg)
+    return ColorPolicy::Auto;
+  if (Arg->getOption().getID() == OPT_no_color_diagnostics)
+    return ColorPolicy::Never;
+
+  StringRef S = Arg->getValue();
+  if (S == "auto")
+    return ColorPolicy::Auto;
+  if (S == "always")
+    return ColorPolicy::Always;
+  if (S != "never")
+    error("unknown -color-diagnostics value: " + S);
+  return ColorPolicy::Never;
+}
+
 static DiscardPolicy getDiscardOption(opt::InputArgList &Args) {
   auto *Arg =
       Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
@@ -486,6 +504,7 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
+  Config->ColorDiagnostics = getColorDiagnostics(Args);
   Config->Demangle = getArg(Args, OPT_demangle, OPT_no_demangle, true);
   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
   Config->Discard = getDiscardOption(Args);

Modified: lld/trunk/ELF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.cpp?rev=287949&r1=287948&r2=287949&view=diff
==============================================================================
--- lld/trunk/ELF/Error.cpp (original)
+++ lld/trunk/ELF/Error.cpp Fri Nov 25 14:27:32 2016
@@ -13,6 +13,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/raw_ostream.h"
 #include <mutex>
 
@@ -20,6 +21,7 @@
 #include <unistd.h>
 #endif
 
+using namespace lld::elf;
 using namespace llvm;
 
 namespace lld {
@@ -32,6 +34,26 @@ StringRef elf::Argv0;
 // but outs() or errs() are not thread-safe. We protect them using a mutex.
 static std::mutex Mu;
 
+static bool useColor() {
+  if (Config->ColorDiagnostics == ColorPolicy::Always)
+    return true;
+  if (Config->ColorDiagnostics == ColorPolicy::Never)
+    return false;
+  return ErrorOS == &errs() && sys::Process::StandardErrHasColors();
+}
+
+static void print(StringRef S, raw_ostream::Colors C) {
+  if (useColor()) {
+    ErrorOS->changeColor(raw_ostream::WHITE, /*Bold=*/true);
+    *ErrorOS << Argv0 + ": ";
+    ErrorOS->changeColor(C, true);
+    *ErrorOS << S;
+    ErrorOS->resetColor();
+  } else {
+    *ErrorOS << Argv0 + ": " << S;
+  }
+}
+
 void elf::log(const Twine &Msg) {
   std::lock_guard<std::mutex> Lock(Mu);
   if (Config->Verbose)
@@ -44,16 +66,19 @@ void elf::warn(const Twine &Msg) {
     return;
   }
   std::lock_guard<std::mutex> Lock(Mu);
-  *ErrorOS << Argv0 << ": warning: " << Msg << "\n";
+  print("warning: ", raw_ostream::MAGENTA);
+  *ErrorOS << Msg << "\n";
 }
 
 void elf::error(const Twine &Msg) {
   std::lock_guard<std::mutex> Lock(Mu);
 
   if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
-    *ErrorOS << Argv0 << ": error: " << Msg << "\n";
+    print("error: ", raw_ostream::RED);
+    *ErrorOS << Msg << "\n";
   } else if (ErrorCount == Config->ErrorLimit) {
-    *ErrorOS << Argv0 << ": error: too many errors emitted, stopping now"
+    print("error: ", raw_ostream::RED);
+    *ErrorOS << "too many errors emitted, stopping now"
              << " (use -error-limit=0 to see all errors)\n";
     if (Config->ExitEarly)
       exitLld(1);
@@ -79,7 +104,8 @@ void elf::exitLld(int Val) {
 
 void elf::fatal(const Twine &Msg) {
   std::lock_guard<std::mutex> Lock(Mu);
-  *ErrorOS << Argv0 << ": error: " << Msg << "\n";
+  print("error: ", raw_ostream::RED);
+  *ErrorOS << Msg << "\n";
   exitLld(1);
 }
 

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=287949&r1=287948&r2=287949&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Fri Nov 25 14:27:32 2016
@@ -39,6 +39,9 @@ def allow_multiple_definition: F<"allow-
 def as_needed: F<"as-needed">,
   HelpText<"Only set DT_NEEDED for shared libraries if used">;
 
+def color_diagnostics: S<"color-diagnostics">,
+  HelpText<"Use colors in diagnostics">;
+
 def disable_new_dtags: F<"disable-new-dtags">,
   HelpText<"Disable new dynamic tags">;
 
@@ -121,6 +124,9 @@ def nostdlib: F<"nostdlib">,
 def no_as_needed: F<"no-as-needed">,
   HelpText<"Always DT_NEEDED for shared libraries">;
 
+def no_color_diagnostics: F<"no-color-diagnostics">,
+  HelpText<"Do not use colors in diagnostics">;
+
 def no_demangle: F<"no-demangle">,
   HelpText<"Do not demangle symbol names">;
 
@@ -238,6 +244,7 @@ def alias_Bstatic_dn: F<"dn">, Alias<Bst
 def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>;
 def alias_Bstatic_static: F<"static">, Alias<Bstatic>;
 def alias_L__library_path: J<"library-path=">, Alias<L>;
+def alias_color_diagnostics: J<"color-diagnostics=">, Alias<color_diagnostics>;
 def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
 def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
 def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;

Added: lld/trunk/test/ELF/color-diagnostics.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/color-diagnostics.test?rev=287949&view=auto
==============================================================================
--- lld/trunk/test/ELF/color-diagnostics.test (added)
+++ lld/trunk/test/ELF/color-diagnostics.test Fri Nov 25 14:27:32 2016
@@ -0,0 +1,12 @@
+# Windows command prompt doesn't support ANSI escape sequences.
+# REQUIRES: shell
+
+# RUN: not ld.lld -color-diagnostics=always /nosuchfile 2>&1 \
+# RUN:   | FileCheck -check-prefix=COLOR %s
+
+# COLOR: {{^.\[0;1;37m.*/ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}}
+
+# RUN: not ld.lld -color-diagnostics=always -no-color-diagnostics /nosuchfile 2>&1 \
+# RUN:   | FileCheck -check-prefix=NOCOLOR %s
+
+# NOCOLOR: ld.lld: error: cannot open /nosuchfile




More information about the llvm-commits mailing list