Index: Driver/TextDiagnosticPrinter.cpp
===================================================================
--- Driver/TextDiagnosticPrinter.cpp	(revision 45317)
+++ Driver/TextDiagnosticPrinter.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "clang/Lex/Lexer.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Process.h"
 #include <iostream>
 #include <string>
 using namespace clang;
@@ -109,6 +110,21 @@
   unsigned LineNo = 0, ColNo = 0;
   const char *LineStart = 0, *LineEnd = 0;
   
+  // FIXME set colors based on env var?  allow clopt instead of env var?
+  bool ColorDiagnostics = getenv("CLANG_COLOR_DIAGNOSTICS") &&
+                          llvm::sys::Process::StandardErrIsDisplayed();
+  
+  if (ColorDiagnostics) {
+    switch (Level) {
+    default: assert(0 && "Unknown diagnostic type!");
+    case Diagnostic::Note:    break;
+    case Diagnostic::Warning: std::cerr << "\033[33m"; break;
+    case Diagnostic::Error:   std::cerr << "\033[31m"; break;
+    case Diagnostic::Fatal:   std::cerr << "\033[1m\033[31m"; break;
+      break;
+    }
+  }
+  
   if (Pos.isValid()) {
     FullSourceLoc LPos = Pos.getLogicalLoc();
     LineNo = LPos.getLineNumber();
@@ -148,11 +164,14 @@
   case Diagnostic::Warning: std::cerr << "warning: "; break;
   case Diagnostic::Error:   std::cerr << "error: "; break;
   case Diagnostic::Fatal:   std::cerr << "fatal error: "; break;
-    break;
   }
   
   std::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";
   
+  if (ColorDiagnostics) {
+    std::cerr << "\033[0m";
+  }
+  
   if (!NoCaretDiagnostics && Pos.isValid()) {
     // Get the line of the source file.
     std::string SourceLine(LineStart, LineEnd);
@@ -190,6 +209,27 @@
       CaratLine.insert(i+1, NumSpaces, CaratLine[i] == '~' ? '~' : ' ');
     }
     
+    // FIXME this is pretty nasty, but lots of the prior code depends on 1-1
+    // correspondence between source & caret line character indices
+    if (ColorDiagnostics) {
+      unsigned j = 0;
+      bool InRange = false;
+      for (unsigned i = 0; i != CaratLine.size(); ++i, ++j) {
+        if (!InRange && CaratLine[i] == '~') {
+          SourceLine.insert(j, "\033[34m");
+          j += 5;
+          InRange = true;
+        } else if (InRange && CaratLine[i] != '~') {
+          SourceLine.insert(j, "\033[0m");
+          j += 4;
+        }
+      }
+      
+      SourceLine += "\033[0m";
+      CaratLine.insert(0, "\033[34m");
+      CaratLine += "\033[0m";
+    }
+    
     // Finally, remove any blank spaces from the end of CaratLine.
     while (CaratLine[CaratLine.size()-1] == ' ')
       CaratLine.erase(CaratLine.end()-1);
