Introduce the -fdiagnostics-format=xxx option to control how Clang
prints the file, line, and column of a diagnostic. We currently
support Clang's normal format, MSVC, and Vi formats.

Note that we no longer change the diagnostic format based on
-fms-extensions.

Patch by Andrew Fish!



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131794 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 924e5ed..d1de31b 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -277,6 +277,14 @@
     Res.push_back("-fdiagnostics-show-category=id");
   else if (Opts.ShowCategories == 2)
     Res.push_back("-fdiagnostics-show-category=name");
+  switch (Opts.Format) {
+  case DiagnosticOptions::Clang: 
+    Res.push_back("-fdiagnostics-format=clang"); break;
+  case DiagnosticOptions::Msvc:  
+    Res.push_back("-fdiagnostics-format=msvc");  break;
+  case DiagnosticOptions::Vi:    
+    Res.push_back("-fdiagnostics-format=vi");    break;
+  }
   if (Opts.ErrorLimit) {
     Res.push_back("-ferror-limit");
     Res.push_back(llvm::utostr(Opts.ErrorLimit));
@@ -1011,7 +1019,9 @@
   Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
   Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
   Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics);
-  Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column);
+  Opts.ShowColumn = Args.hasFlag(OPT_fshow_column,
+                                 OPT_fno_show_column,
+                                 /*Default=*/true);
   Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
   Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
   Opts.ShowNames = Args.hasArg(OPT_fdiagnostics_show_name);
@@ -1048,6 +1058,19 @@
       << Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
       << ShowCategory;
 
+  llvm::StringRef Format =
+    Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
+  if (Format == "clang")
+    Opts.Format = DiagnosticOptions::Clang;
+  else if (Format == "msvc") 
+    Opts.Format = DiagnosticOptions::Msvc;
+  else if (Format == "vi") 
+    Opts.Format = DiagnosticOptions::Vi;
+  else 
+    Diags.Report(diag::err_drv_invalid_value)
+      << Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
+      << Format;
+  
   Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
   Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
   Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 47c942c..46ebd18 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -819,16 +819,28 @@
         if (DiagOpts->ShowColors)
           OS.changeColor(savedColor, true);
 
-        // Emit a Visual Studio compatible line number syntax.
-        if (LangOpts && LangOpts->Microsoft) {
-          OS << PLoc.getFilename() << '(' << LineNo << ')';
-          OS << " : ";
-        } else {
-          OS << PLoc.getFilename() << ':' << LineNo << ':';
-          if (DiagOpts->ShowColumn)
-            if (unsigned ColNo = PLoc.getColumn())
-              OS << ColNo << ':';
+        OS << PLoc.getFilename();
+        switch (DiagOpts->Format) {
+        case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
+        case DiagnosticOptions::Msvc:  OS << '('  << LineNo; break;
+        case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
         }
+        if (DiagOpts->ShowColumn)
+          if (unsigned ColNo = PLoc.getColumn()) {
+            if (DiagOpts->Format == DiagnosticOptions::Msvc) {
+              OS << ',';
+              ColNo--;
+            } else 
+              OS << ':';
+            OS << ColNo;
+          }
+        switch (DiagOpts->Format) {
+        case DiagnosticOptions::Clang: 
+        case DiagnosticOptions::Vi:    OS << ':';    break;
+        case DiagnosticOptions::Msvc:  OS << ") : "; break;
+        }
+
+                
         if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
           FileID CaretFileID =
             SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));