Revert r367649: Improve raw_ostream so that you can "write" colors using operator<<

This reverts commit r367649 in an attempt to unbreak Windows bots.

llvm-svn: 367658
diff --git a/clang/include/clang/AST/ASTDumperUtils.h b/clang/include/clang/AST/ASTDumperUtils.h
index 3dd4f9c..55a0854 100644
--- a/clang/include/clang/AST/ASTDumperUtils.h
+++ b/clang/include/clang/AST/ASTDumperUtils.h
@@ -27,7 +27,7 @@
 // Do not use bold yellow for any text.  It is hard to read on white screens.
 
 struct TerminalColor {
-  llvm::raw_ostream::Color Color;
+  llvm::raw_ostream::Colors Color;
   bool Bold;
 };
 
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 5db1507..0ed1e98 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -5509,7 +5509,7 @@
   if (print_edges) {
     // Print the predecessors of this block.
     if (!B.pred_empty()) {
-      const raw_ostream::Color Color = raw_ostream::BLUE;
+      const raw_ostream::Colors Color = raw_ostream::BLUE;
       if (ShowColors)
         OS.changeColor(Color);
       OS << "   Preds " ;
@@ -5546,7 +5546,7 @@
 
     // Print the successors of this block.
     if (!B.succ_empty()) {
-      const raw_ostream::Color Color = raw_ostream::MAGENTA;
+      const raw_ostream::Colors Color = raw_ostream::MAGENTA;
       if (ShowColors)
         OS.changeColor(Color);
       OS << "   Succs ";
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index d9bbe25..6bf4fbc 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1491,10 +1491,6 @@
                    OPT_fno_diagnostics_show_option, DefaultShowOpt);
 
   llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes));
-  if (Opts.ShowColors) {
-    llvm::outs().enable_colors();
-    llvm::errs().enable_colors();
-  }
 
   // Default behavior is to not to show note include stacks.
   Opts.ShowNoteIncludeStack = false;
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index d066ce0..d6e75a9 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -23,16 +23,23 @@
 
 using namespace clang;
 
-static const raw_ostream::Color noteColor = raw_ostream::BLACK;
-static const raw_ostream::Color remarkColor = raw_ostream::BLUE;
-static const raw_ostream::Color fixitColor = raw_ostream::GREEN;
-static const raw_ostream::Color caretColor = raw_ostream::GREEN;
-static const raw_ostream::Color warningColor = raw_ostream::MAGENTA;
-static const raw_ostream::Color templateColor = raw_ostream::CYAN;
-static const raw_ostream::Color errorColor = raw_ostream::RED;
-static const raw_ostream::Color fatalColor = raw_ostream::RED;
+static const enum raw_ostream::Colors noteColor =
+  raw_ostream::BLACK;
+static const enum raw_ostream::Colors remarkColor =
+  raw_ostream::BLUE;
+static const enum raw_ostream::Colors fixitColor =
+  raw_ostream::GREEN;
+static const enum raw_ostream::Colors caretColor =
+  raw_ostream::GREEN;
+static const enum raw_ostream::Colors warningColor =
+  raw_ostream::MAGENTA;
+static const enum raw_ostream::Colors templateColor =
+  raw_ostream::CYAN;
+static const enum raw_ostream::Colors errorColor = raw_ostream::RED;
+static const enum raw_ostream::Colors fatalColor = raw_ostream::RED;
 // Used for changing only the bold attribute.
-static const raw_ostream::Color savedColor = raw_ostream::SAVEDCOLOR;
+static const enum raw_ostream::Colors savedColor =
+  raw_ostream::SAVEDCOLOR;
 
 /// Add highlights to differences in template strings.
 static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str,
diff --git a/clang/tools/diagtool/TreeView.cpp b/clang/tools/diagtool/TreeView.cpp
index 9bb7107..154c52a 100644
--- a/clang/tools/diagtool/TreeView.cpp
+++ b/clang/tools/diagtool/TreeView.cpp
@@ -20,16 +20,29 @@
 using namespace clang;
 using namespace diagtool;
 
-class TreePrinter {
-  using Color = llvm::raw_ostream::Color;
+static bool hasColors(const llvm::raw_ostream &out) {
+  if (&out != &llvm::errs() && &out != &llvm::outs())
+    return false;
+  return llvm::errs().is_displayed() && llvm::outs().is_displayed();
+}
 
+class TreePrinter {
 public:
   llvm::raw_ostream &out;
+  const bool ShowColors;
   bool Internal;
 
-  TreePrinter(llvm::raw_ostream &out) : out(out), Internal(false) {
-    if (&out != &llvm::errs() && &out != &llvm::outs())
-      out.disable_colors();
+  TreePrinter(llvm::raw_ostream &out)
+      : out(out), ShowColors(hasColors(out)), Internal(false) {}
+
+  void setColor(llvm::raw_ostream::Colors Color) {
+    if (ShowColors)
+      out << llvm::sys::Process::OutputColor(Color, false, false);
+  }
+
+  void resetColor() {
+    if (ShowColors)
+      out << llvm::sys::Process::ResetColor();
   }
 
   static bool isIgnored(unsigned DiagID) {
@@ -57,11 +70,12 @@
     out.indent(Indent * 2);
 
     if (enabledByDefault(Group))
-      out << Color::GREEN;
+      setColor(llvm::raw_ostream::GREEN);
     else
-      out << Color::YELLOW;
+      setColor(llvm::raw_ostream::YELLOW);
 
-    out << "-W" << Group.getName() << "\n" << Color::RESET;
+    out << "-W" << Group.getName() << "\n";
+    resetColor();
 
     ++Indent;
     for (const GroupRecord &GR : Group.subgroups()) {
@@ -70,10 +84,12 @@
 
     if (Internal) {
       for (const DiagnosticRecord &DR : Group.diagnostics()) {
-        if (!isIgnored(DR.DiagID))
-          out << Color::GREEN;
+        if (ShowColors && !isIgnored(DR.DiagID))
+          setColor(llvm::raw_ostream::GREEN);
         out.indent(Indent * 2);
-        out << DR.getName() << Color::RESET << "\n";
+        out << DR.getName();
+        resetColor();
+        out << "\n";
       }
     }
   }
@@ -119,9 +135,13 @@
   }
 
   void showKey() {
-    out << '\n'
-        << Color::GREEN << "GREEN" << Color::RESET
-        << " = enabled by default\n\n";
+    if (ShowColors) {
+      out << '\n';
+      setColor(llvm::raw_ostream::GREEN);
+      out << "GREEN";
+      resetColor();
+      out << " = enabled by default\n\n";
+    }
   }
 };
 
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e54a5f1..9fb2c51 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -62,6 +62,7 @@
 bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &diag) {
   errorHandler().logName = args::getFilenameWithoutExe(args[0]);
   errorHandler().errorOS = &diag;
+  errorHandler().colorDiagnostics = diag.has_colors();
   errorHandler().errorLimitExceededMsg =
       "too many errors emitted, stopping now"
       " (use /errorlimit:0 to see all errors)";
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 6726621..4360ac2 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -756,17 +756,16 @@
                               OPT_no_color_diagnostics);
   if (!arg)
     return;
-
   if (arg->getOption().getID() == OPT_color_diagnostics) {
-    errorHandler().errorOS->enable_colors();
+    errorHandler().colorDiagnostics = true;
   } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
-    errorHandler().errorOS->disable_colors();
+    errorHandler().colorDiagnostics = false;
   } else {
     StringRef s = arg->getValue();
     if (s == "always")
-      errorHandler().errorOS->enable_colors();
+      errorHandler().colorDiagnostics = true;
     else if (s == "never")
-      errorHandler().errorOS->disable_colors();
+      errorHandler().colorDiagnostics = false;
     else if (s != "auto")
       error("unknown option: --color-diagnostics=" + s);
   }
diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp
index a012afc..4c6a5b3 100644
--- a/lld/Common/ErrorHandler.cpp
+++ b/lld/Common/ErrorHandler.cpp
@@ -106,42 +106,54 @@
 //
 // This function returns an error location string. An error location is
 // extracted from an error message using regexps.
-std::string ErrorHandler::getLocation(const Twine &msg) {
-  if (!vsDiagnostics)
-    return logName;
-
-  static std::regex regexes[] = {
-      std::regex(
-          R"(^undefined (?:\S+ )?symbol:.*\n>>> referenced by (\S+):(\d+)\n.*)"),
+static std::string getLocation(std::string msg, std::string defaultMsg) {
+  static std::vector<std::regex> Regexes{
+      std::regex(R"(^undefined (?:\S+ )?symbol:.*\n>>> referenced by (\S+):(\d+)\n.*)"),
       std::regex(R"(^undefined symbol:.*\n>>> referenced by (.*):)"),
       std::regex(
           R"(^duplicate symbol: .*\n>>> defined in (\S+)\n>>> defined in.*)"),
-      std::regex(R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+).*)"),
-      std::regex(R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"),
+      std::regex(
+          R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+).*)"),
+      std::regex(
+          R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"),
       std::regex(R"((\S+):(\d+): unclosed quote)"),
   };
 
-  std::string str = msg.str();
+  std::smatch Match;
+  for (std::regex &Re : Regexes) {
+    if (std::regex_search(msg, Match, Re)) {
+      return Match.size() > 2 ? Match.str(1) + "(" + Match.str(2) + ")"
+                              : Match.str(1);
+    }
+  }
+  return defaultMsg;
+}
 
-  for (std::regex &re : regexes) {
-    std::smatch m;
-    if (!std::regex_search(str, m, re))
-      continue;
-    assert(m.size() == 2 || m.size() == 3);
+void ErrorHandler::printHeader(StringRef s, raw_ostream::Colors c,
+                               const Twine &msg) {
 
-    if (m.size() == 2)
-      return m.str(1);
-    return m.str(1) + "(" + m.str(2) + ")";
+  if (vsDiagnostics) {
+    // A Visual Studio-style error message starts with an error location.
+    // If a location cannot be extracted then we default to LogName.
+    *errorOS << getLocation(msg.str(), logName) << ": ";
+  } else {
+    *errorOS << logName << ": ";
   }
 
-  return logName;
+  if (colorDiagnostics) {
+    errorOS->changeColor(c, true);
+    *errorOS << s;
+    errorOS->resetColor();
+  } else {
+    *errorOS << s;
+  }
 }
 
 void ErrorHandler::log(const Twine &msg) {
-  if (!verbose)
-    return;
-  std::lock_guard<std::mutex> lock(mu);
-  *errorOS << logName << ": " << msg << "\n";
+  if (verbose) {
+    std::lock_guard<std::mutex> lock(mu);
+    *errorOS << logName << ": " << msg << "\n";
+  }
 }
 
 void ErrorHandler::message(const Twine &msg) {
@@ -158,37 +170,42 @@
 
   std::lock_guard<std::mutex> lock(mu);
   newline(errorOS, msg);
-  *errorOS << getLocation(msg) << ": " << Color::MAGENTA
-           << "warning: " << Color::RESET << msg << "\n";
+  printHeader("warning: ", raw_ostream::MAGENTA, msg);
+  *errorOS << msg << "\n";
 }
 
-void ErrorHandler::error(const Twine &msg) {
-  // If Microsoft Visual Studio-style error message mode is enabled,
-  // this particular error is printed out as two errors.
-  if (vsDiagnostics) {
-    static std::regex re(R"(^(duplicate symbol: .*))"
-                         R"((\n>>> defined at \S+:\d+\n>>>.*))"
-                         R"((\n>>> defined at \S+:\d+\n>>>.*))");
-    std::string str = msg.str();
-    std::smatch m;
+void ErrorHandler::printErrorMsg(const Twine &msg) {
+  newline(errorOS, msg);
+  printHeader("error: ", raw_ostream::RED, msg);
+  *errorOS << msg << "\n";
+}
 
-    if (std::regex_match(str, m, re)) {
-      error(m.str(1) + m.str(2));
-      error(m.str(1) + m.str(3));
+void ErrorHandler::printError(const Twine &msg) {
+  if (vsDiagnostics) {
+    static std::regex reDuplicateSymbol(
+        R"(^(duplicate symbol: .*))"
+        R"((\n>>> defined at \S+:\d+\n>>>.*))"
+        R"((\n>>> defined at \S+:\d+\n>>>.*))");
+    std::string msgStr = msg.str();
+    std::smatch match;
+    if (std::regex_match(msgStr, match, reDuplicateSymbol)) {
+      printErrorMsg(match.str(1) + match.str(2));
+      printErrorMsg(match.str(1) + match.str(3));
       return;
     }
   }
+  printErrorMsg(msg);
+}
 
+void ErrorHandler::error(const Twine &msg) {
   std::lock_guard<std::mutex> lock(mu);
 
   if (errorLimit == 0 || errorCount < errorLimit) {
-    newline(errorOS, msg);
-    *errorOS << getLocation(msg) << ": " << Color::RED
-             << "error: " << Color::RESET << msg << "\n";
+    printError(msg);
   } else if (errorCount == errorLimit) {
     newline(errorOS, msg);
-    *errorOS << getLocation(msg) << ": " << Color::RED
-             << "error: " << Color::RESET << errorLimitExceededMsg << "\n";
+    printHeader("error: ", raw_ostream::RED, msg);
+    *errorOS << errorLimitExceededMsg << "\n";
     if (exitEarly)
       exitLld(1);
   }
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a48bbea..7ee7575 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -82,6 +82,7 @@
       "-error-limit=0 to see all errors)";
   errorHandler().errorOS = &error;
   errorHandler().exitEarly = canExitEarly;
+  errorHandler().colorDiagnostics = error.has_colors();
 
   inputSections.clear();
   outputSections.clear();
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 2f35c12..87f0aa2 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -58,17 +58,16 @@
                               OPT_no_color_diagnostics);
   if (!arg)
     return;
-
   if (arg->getOption().getID() == OPT_color_diagnostics) {
-    errorHandler().errorOS->enable_colors();
+    errorHandler().colorDiagnostics = true;
   } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
-    errorHandler().errorOS->disable_colors();
+    errorHandler().colorDiagnostics = false;
   } else {
     StringRef s = arg->getValue();
     if (s == "always")
-      errorHandler().errorOS->enable_colors();
+      errorHandler().colorDiagnostics = true;
     else if (s == "never")
-      errorHandler().errorOS->disable_colors();
+      errorHandler().colorDiagnostics = false;
     else if (s != "auto")
       error("unknown option: --color-diagnostics=" + s);
   }
diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h
index 3c6ea973..52e2200 100644
--- a/lld/include/lld/Common/ErrorHandler.h
+++ b/lld/include/lld/Common/ErrorHandler.h
@@ -87,6 +87,7 @@
   StringRef errorLimitExceededMsg = "too many errors emitted, stopping now";
   StringRef logName = "lld";
   llvm::raw_ostream *errorOS = &llvm::errs();
+  bool colorDiagnostics = llvm::errs().has_colors();
   bool exitEarly = true;
   bool fatalWarnings = false;
   bool verbose = false;
@@ -101,9 +102,9 @@
   std::unique_ptr<llvm::FileOutputBuffer> outputBuffer;
 
 private:
-  using Color = raw_ostream::Color;
-
-  std::string getLocation(const Twine &msg);
+  void printHeader(StringRef s, raw_ostream::Colors c, const Twine &msg);
+  void printErrorMsg(const Twine &msg);
+  void printError(const Twine &msg);
 };
 
 /// Returns the default error handler.
diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp
index 2d54d6a..8646d86 100644
--- a/lld/lib/Driver/DarwinLdDriver.cpp
+++ b/lld/lib/Driver/DarwinLdDriver.cpp
@@ -1151,6 +1151,7 @@
       "'-error-limit 0' to see all errors)";
   errorHandler().errorOS = &Error;
   errorHandler().exitEarly = CanExitEarly;
+  errorHandler().colorDiagnostics = Error.has_colors();
 
   MachOLinkingContext ctx;
   if (!parse(args, ctx))
diff --git a/lld/test/COFF/color-diagnostics.test b/lld/test/COFF/color-diagnostics.test
index 210965d..11cf8af 100644
--- a/lld/test/COFF/color-diagnostics.test
+++ b/lld/test/COFF/color-diagnostics.test
@@ -6,8 +6,8 @@
 # RUN: not lld-link -xyz --color-diagnostics=always /nosuchfile 2>&1 \
 # RUN:   | FileCheck -check-prefix=COLOR %s
 
-# COLOR: {{lld-link: .\[0;35mwarning: .\[0mignoring unknown argument '-xyz'}}
-# COLOR: {{lld-link: .\[0;31merror: .\[0mcould not open '/nosuchfile'}}
+# COLOR: {{lld-link: .\[0;1;35mwarning: .\[0mignoring unknown argument '-xyz'}}
+# COLOR: {{lld-link: .\[0;1;31merror: .\[0mcould not open '/nosuchfile'}}
 
 # RUN: not lld-link /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
 # RUN: not lld-link -color-diagnostics=never /nosuchfile 2>&1 \
diff --git a/lld/test/ELF/color-diagnostics.test b/lld/test/ELF/color-diagnostics.test
index 7f1e46c..8613074 100644
--- a/lld/test/ELF/color-diagnostics.test
+++ b/lld/test/ELF/color-diagnostics.test
@@ -6,8 +6,8 @@
 # RUN: not ld.lld -xyz -color-diagnostics=always /nosuchfile 2>&1 \
 # RUN:   | FileCheck -check-prefix=COLOR %s
 
-# COLOR: {{ld.lld: .\[0;31merror: .\[0munknown argument '-xyz'}}
-# COLOR: {{ld.lld: .\[0;31merror: .\[0mcannot open /nosuchfile}}
+# COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument '-xyz'}}
+# COLOR: {{ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}}
 
 # RUN: not ld.lld -color-diagnostics=foobar 2>&1 | FileCheck -check-prefix=ERR %s
 # ERR: unknown option: --color-diagnostics=foobar
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 89e7f59..a1d22bf 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -83,6 +83,7 @@
                      raw_ostream &error) {
   errorHandler().logName = args::getFilenameWithoutExe(args[0]);
   errorHandler().errorOS = &error;
+  errorHandler().colorDiagnostics = error.has_colors();
   errorHandler().errorLimitExceededMsg =
       "too many errors emitted, stopping now (use "
       "-error-limit=0 to see all errors)";
@@ -132,17 +133,16 @@
                               OPT_no_color_diagnostics);
   if (!arg)
     return;
-
   if (arg->getOption().getID() == OPT_color_diagnostics) {
-    errorHandler().errorOS->enable_colors();
+    errorHandler().colorDiagnostics = true;
   } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
-    errorHandler().errorOS->disable_colors();
+    errorHandler().colorDiagnostics = false;
   } else {
     StringRef s = arg->getValue();
     if (s == "always")
-      errorHandler().errorOS->enable_colors();
+      errorHandler().colorDiagnostics = true;
     else if (s == "never")
-      errorHandler().errorOS->disable_colors();
+      errorHandler().colorDiagnostics = false;
     else if (s != "auto")
       error("unknown option: --color-diagnostics=" + s);
   }
diff --git a/llvm/include/llvm/Support/FormattedStream.h b/llvm/include/llvm/Support/FormattedStream.h
index a029925..b49c8d8 100644
--- a/llvm/include/llvm/Support/FormattedStream.h
+++ b/llvm/include/llvm/Support/FormattedStream.h
@@ -121,8 +121,8 @@
     return *this;
   }
 
-  raw_ostream &changeColor(Color C, bool Bold, bool BG) override {
-    TheStream->changeColor(C, Bold, BG);
+  raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
+    TheStream->changeColor(Color, Bold, BG);
     return *this;
   }
 
diff --git a/llvm/include/llvm/Support/WithColor.h b/llvm/include/llvm/Support/WithColor.h
index ab9f524..f4e1075 100644
--- a/llvm/include/llvm/Support/WithColor.h
+++ b/llvm/include/llvm/Support/WithColor.h
@@ -53,7 +53,8 @@
   /// @param BG If true, change the background, default: change foreground
   /// @param DisableColors Whether to ignore color changes regardless of -color
   /// and support in OS
-  WithColor(raw_ostream &OS, raw_ostream::Color Color = raw_ostream::SAVEDCOLOR,
+  WithColor(raw_ostream &OS,
+            raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR,
             bool Bold = false, bool BG = false, bool DisableColors = false)
       : OS(OS), DisableColors(DisableColors) {
     changeColor(Color, Bold, BG);
@@ -101,7 +102,7 @@
   /// change only the bold attribute, and keep colors untouched
   /// @param Bold Bold/brighter text, default false
   /// @param BG If true, change the background, default: change foreground
-  WithColor &changeColor(raw_ostream::Color Color, bool Bold = false,
+  WithColor &changeColor(raw_ostream::Colors Color, bool Bold = false,
                          bool BG = false);
 
   /// Reset the colors to terminal defaults. Call this when you are done
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index f4321b0..48bb623 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -72,7 +72,7 @@
 
 public:
   // color order matches ANSI escape sequence, don't change
-  enum class Color {
+  enum Colors {
     BLACK = 0,
     RED,
     GREEN,
@@ -81,21 +81,9 @@
     MAGENTA,
     CYAN,
     WHITE,
-    SAVEDCOLOR,
-    RESET,
+    SAVEDCOLOR
   };
 
-  static const Color BLACK = Color::BLACK;
-  static const Color RED = Color::RED;
-  static const Color GREEN = Color::GREEN;
-  static const Color YELLOW = Color::YELLOW;
-  static const Color BLUE = Color::BLUE;
-  static const Color MAGENTA = Color::MAGENTA;
-  static const Color CYAN = Color::CYAN;
-  static const Color WHITE = Color::WHITE;
-  static const Color SAVEDCOLOR = Color::SAVEDCOLOR;
-  static const Color RESET = Color::RESET;
-
   explicit raw_ostream(bool unbuffered = false)
       : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
     // Start out ready to flush.
@@ -226,9 +214,6 @@
   /// Output \p N in hexadecimal, without any prefix or padding.
   raw_ostream &write_hex(unsigned long long N);
 
-  // Change the foreground color of text.
-  raw_ostream &operator<<(Color C);
-
   /// Output a formatted UUID with dash separators.
   using uuid_t = uint8_t[16];
   raw_ostream &write_uuid(const uuid_t UUID);
@@ -263,14 +248,15 @@
 
   /// Changes the foreground color of text that will be output from this point
   /// forward.
-  /// @param C ANSI color to use, the special SAVEDCOLOR can be used to
+  /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
   /// change only the bold attribute, and keep colors untouched
   /// @param Bold bold/brighter text, default false
   /// @param BG if true change the background, default: change foreground
   /// @returns itself so it can be used within << invocations
-  virtual raw_ostream &changeColor(Color C, bool Bold = false,
+  virtual raw_ostream &changeColor(enum Colors Color,
+                                   bool Bold = false,
                                    bool BG = false) {
-    (void)C;
+    (void)Color;
     (void)Bold;
     (void)BG;
     return *this;
@@ -291,11 +277,6 @@
   /// This function determines if this stream is displayed and supports colors.
   virtual bool has_colors() const { return is_displayed(); }
 
-  // Enable or disable colors. Once disable_colors() is called,
-  // changeColor() has no effect until enable_colors() is called.
-  virtual void enable_colors() {}
-  virtual void disable_colors() {}
-
   //===--------------------------------------------------------------------===//
   // Subclass Interface
   //===--------------------------------------------------------------------===//
@@ -387,8 +368,6 @@
 
   bool SupportsSeeking;
 
-  bool ColorEnabled;
-
 #ifdef _WIN32
   /// True if this fd refers to a Windows console device. Mintty and other
   /// terminal emulators are TTYs, but they are not consoles.
@@ -453,8 +432,8 @@
   /// to the offset specified from the beginning of the file.
   uint64_t seek(uint64_t off);
 
-  raw_ostream &changeColor(Color C, bool bold = false,
-                           bool bg = false) override;
+  raw_ostream &changeColor(enum Colors colors, bool bold=false,
+                           bool bg=false) override;
   raw_ostream &resetColor() override;
 
   raw_ostream &reverseColor() override;
@@ -463,10 +442,6 @@
 
   bool has_colors() const override;
 
-  void enable_colors() override { ColorEnabled = true; }
-
-  void disable_colors() override { ColorEnabled = false; }
-
   std::error_code error() const { return EC; }
 
   /// Return the value of the flag in this raw_fd_ostream indicating whether an
diff --git a/llvm/lib/Support/WithColor.cpp b/llvm/lib/Support/WithColor.cpp
index 1c380c6..345dd9c 100644
--- a/llvm/lib/Support/WithColor.cpp
+++ b/llvm/lib/Support/WithColor.cpp
@@ -22,8 +22,6 @@
     : OS(OS), DisableColors(DisableColors) {
   // Detect color from terminal type unless the user passed the --color option.
   if (colorsEnabled()) {
-    OS.enable_colors();
-
     switch (Color) {
     case HighlightColor::Address:
       OS.changeColor(raw_ostream::YELLOW);
@@ -106,9 +104,10 @@
   return UseColor == cl::BOU_TRUE;
 }
 
-WithColor &WithColor::changeColor(raw_ostream::Color C, bool Bold, bool BG) {
+WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold,
+                                  bool BG) {
   if (colorsEnabled())
-    OS.changeColor(C, Bold, BG);
+    OS.changeColor(Color, Bold, BG);
   return *this;
 }
 
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index da24fe2..2baccaa 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -65,17 +65,6 @@
 
 using namespace llvm;
 
-const raw_ostream::Color raw_ostream::BLACK;
-const raw_ostream::Color raw_ostream::RED;
-const raw_ostream::Color raw_ostream::GREEN;
-const raw_ostream::Color raw_ostream::YELLOW;
-const raw_ostream::Color raw_ostream::BLUE;
-const raw_ostream::Color raw_ostream::MAGENTA;
-const raw_ostream::Color raw_ostream::CYAN;
-const raw_ostream::Color raw_ostream::WHITE;
-const raw_ostream::Color raw_ostream::SAVEDCOLOR;
-const raw_ostream::Color raw_ostream::RESET;
-
 raw_ostream::~raw_ostream() {
   // raw_ostream's subclasses should take care to flush the buffer
   // in their destructors.
@@ -144,14 +133,6 @@
   return *this;
 }
 
-raw_ostream &raw_ostream::operator<<(Color C) {
-  if (C == Color::RESET)
-    resetColor();
-  else
-    changeColor(C);
-  return *this;
-}
-
 raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
   for (int Idx = 0; Idx < 16; ++Idx) {
     *this << format("%02" PRIX32, UUID[Idx]);
@@ -571,9 +552,8 @@
 /// FD is the file descriptor that this writes to.  If ShouldClose is true, this
 /// closes the file when the stream is destroyed.
 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
-    : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose),
-      ColorEnabled(sys::Process::FileDescriptorHasColors(fd)) {
-  if (FD < 0) {
+    : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose) {
+  if (FD < 0 ) {
     ShouldClose = false;
     return;
   }
@@ -802,16 +782,13 @@
 #endif
 }
 
-raw_ostream &raw_fd_ostream::changeColor(Color color, bool bold, bool bg) {
-  if (!ColorEnabled)
-    return *this;
-
+raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold,
+                                         bool bg) {
   if (sys::Process::ColorNeedsFlush())
     flush();
   const char *colorcode =
-      (color == Color::SAVEDCOLOR)
-          ? sys::Process::OutputBold(bg)
-          : sys::Process::OutputColor(static_cast<char>(color), bold, bg);
+    (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg)
+    : sys::Process::OutputColor(colors, bold, bg);
   if (colorcode) {
     size_t len = strlen(colorcode);
     write(colorcode, len);
@@ -822,9 +799,6 @@
 }
 
 raw_ostream &raw_fd_ostream::resetColor() {
-  if (!ColorEnabled)
-    return *this;
-
   if (sys::Process::ColorNeedsFlush())
     flush();
   const char *colorcode = sys::Process::ResetColor();
@@ -838,9 +812,6 @@
 }
 
 raw_ostream &raw_fd_ostream::reverseColor() {
-  if (!ColorEnabled)
-    return *this;
-
   if (sys::Process::ColorNeedsFlush())
     flush();
   const char *colorcode = sys::Process::OutputReverse();
diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp
index 1750d18..8225954 100644
--- a/llvm/tools/llvm-cov/CoverageReport.cpp
+++ b/llvm/tools/llvm-cov/CoverageReport.cpp
@@ -111,7 +111,7 @@
 /// Return the color which correponds to the coverage percentage of a
 /// certain metric.
 template <typename T>
-raw_ostream::Color determineCoveragePercentageColor(const T &Info) {
+raw_ostream::Colors determineCoveragePercentageColor(const T &Info) {
   if (Info.isFullyCovered())
     return raw_ostream::GREEN;
   return Info.getPercentCovered() >= 80.0 ? raw_ostream::YELLOW
diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h
index 3dbb013..dde0c69 100644
--- a/llvm/tools/llvm-cov/CoverageViewOptions.h
+++ b/llvm/tools/llvm-cov/CoverageViewOptions.h
@@ -46,7 +46,7 @@
 
   /// Change the output's stream color if the colors are enabled.
   ColoredRawOstream colored_ostream(raw_ostream &OS,
-                                    raw_ostream::Color Color) const {
+                                    raw_ostream::Colors Color) const {
     return llvm::colored_ostream(OS, Color, Colors);
   }
 
diff --git a/llvm/tools/llvm-cov/RenderingSupport.h b/llvm/tools/llvm-cov/RenderingSupport.h
index b25792e..0674fba 100644
--- a/llvm/tools/llvm-cov/RenderingSupport.h
+++ b/llvm/tools/llvm-cov/RenderingSupport.h
@@ -47,7 +47,7 @@
 /// Change the color of the output stream if the `IsColorUsed` flag
 /// is true. Returns an object that resets the color when destroyed.
 inline ColoredRawOstream colored_ostream(raw_ostream &OS,
-                                         raw_ostream::Color Color,
+                                         raw_ostream::Colors Color,
                                          bool IsColorUsed = true,
                                          bool Bold = false, bool BG = false) {
   if (IsColorUsed)
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
index f73b91a..fcabee2 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
@@ -101,7 +101,7 @@
   auto *WrappedSegment = LCS.getWrappedSegment();
   CoverageSegmentArray Segments = LCS.getLineSegments();
 
-  Optional<raw_ostream::Color> Highlight;
+  Optional<raw_ostream::Colors> Highlight;
   SmallVector<std::pair<unsigned, unsigned>, 2> HighlightedRanges;
 
   // The first segment overlaps from a previous line, so we treat it specially.
diff --git a/llvm/tools/llvm-cov/llvm-cov.cpp b/llvm/tools/llvm-cov/llvm-cov.cpp
index dabb8afe..172ec9f 100644
--- a/llvm/tools/llvm-cov/llvm-cov.cpp
+++ b/llvm/tools/llvm-cov/llvm-cov.cpp
@@ -83,10 +83,13 @@
     }
   }
 
-  if (argc > 1)
-    errs() << raw_ostream::RED << "Unrecognized command: " << argv[1] << ".\n\n"
-           << raw_ostream::RESET;
-
+  if (argc > 1) {
+    if (sys::Process::StandardErrHasColors())
+      errs().changeColor(raw_ostream::RED);
+    errs() << "Unrecognized command: " << argv[1] << ".\n\n";
+    if (sys::Process::StandardErrHasColors())
+      errs().resetColor();
+  }
   helpMain(argc, argv);
   return 1;
 }
diff --git a/llvm/tools/llvm-mca/Views/TimelineView.cpp b/llvm/tools/llvm-mca/Views/TimelineView.cpp
index 09b6b2a..fe3f16b 100644
--- a/llvm/tools/llvm-mca/Views/TimelineView.cpp
+++ b/llvm/tools/llvm-mca/Views/TimelineView.cpp
@@ -103,8 +103,8 @@
     LastCycle = std::max(LastCycle, CurrentCycle);
 }
 
-static raw_ostream::Color chooseColor(unsigned CumulativeCycles,
-                                      unsigned Executions, int BufferSize) {
+static raw_ostream::Colors chooseColor(unsigned CumulativeCycles,
+                                       unsigned Executions, int BufferSize) {
   if (CumulativeCycles && BufferSize < 0)
     return raw_ostream::MAGENTA;
   unsigned Size = static_cast<unsigned>(BufferSize);
@@ -120,7 +120,7 @@
   if (!OS.has_colors())
     return;
 
-  raw_ostream::Color Color = chooseColor(Cycles, Executions, BufferSize);
+  raw_ostream::Colors Color = chooseColor(Cycles, Executions, BufferSize);
   if (Color == raw_ostream::SAVEDCOLOR) {
     OS.resetColor();
     return;
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index b63447f..d9cad13 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -138,11 +138,12 @@
   /// The starting char (before tildes) for marking the line.
   char Lead;
   /// What color to use for this annotation.
-  raw_ostream::Color Color;
+  raw_ostream::Colors Color;
   /// A note to follow the marker, or empty string if none.
   std::string Note;
   MarkerStyle() {}
-  MarkerStyle(char Lead, raw_ostream::Color Color, const std::string &Note = "")
+  MarkerStyle(char Lead, raw_ostream::Colors Color,
+              const std::string &Note = "")
       : Lead(Lead), Color(Color), Note(Note) {}
 };