Add machine-parseable Fix-It output as part of diagnostics, under the
flag -fdiagnostics-parseable-fixits, from Eelis van der Weegen!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111557 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index bc1b504..c971ca3 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -537,6 +537,48 @@
     if (DiagOpts->ShowColors)
       OS.resetColor();
   }
+
+  if (DiagOpts->ShowParseableFixits) {
+
+    // We follow FixItRewriter's example in not (yet) handling
+    // fix-its in macros.
+    bool BadApples = false;
+    for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) {
+      if (Hint->RemoveRange.isInvalid() ||
+          Hint->RemoveRange.getBegin().isMacroID() ||
+          Hint->RemoveRange.getEnd().isMacroID()) {
+        BadApples = true;
+        break;
+      }
+    }
+
+    if (!BadApples) {
+      for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) {
+
+        SourceLocation B = Hint->RemoveRange.getBegin();
+        SourceLocation E = Hint->RemoveRange.getEnd();
+
+        std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+        std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+        // Adjust for token ranges.
+        if (Hint->RemoveRange.isTokenRange())
+          EInfo.second += Lexer::MeasureTokenLength(E, SM, *LangOpts);
+
+        // We specifically do not do word-wrapping or tab-expansion here,
+        // because this is supposed to be easy to parse.
+        OS << " fix-it: \"";
+        OS.write_escaped(SM.getPresumedLoc(B).getFilename());
+        OS << "\":{" << SM.getLineNumber(BInfo.first, BInfo.second)
+          << ':' << SM.getColumnNumber(BInfo.first, BInfo.second)
+          << '-' << SM.getLineNumber(EInfo.first, EInfo.second)
+          << ':' << SM.getColumnNumber(EInfo.first, EInfo.second)
+          << "}: \"";
+        OS.write_escaped(Hint->CodeToInsert);
+        OS << "\"\n";
+      }
+    }
+  }
 }
 
 /// \brief Skip over whitespace in the string, starting at the given