[analyzer] exploded-graph-rewriter: Improve source location dumps.

- Correctly display macro expansion and spelling locations.
- Use the same procedure to display location context call site locations.
- Display statement IDs for program points.

llvm-svn: 365861
diff --git a/clang/lib/Analysis/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp
index 0398251..97e9096 100644
--- a/clang/lib/Analysis/ProgramPoint.cpp
+++ b/clang/lib/Analysis/ProgramPoint.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/JsonSupport.h"
 
 using namespace clang;
 
@@ -46,19 +47,6 @@
   return printJson(llvm::errs());
 }
 
-static void printLocJson(raw_ostream &Out, SourceLocation Loc,
-                         const SourceManager &SM) {
-  Out << "\"location\": ";
-  if (!Loc.isFileID()) {
-    Out << "null";
-    return;
-  }
-
-  Out << "{ \"line\": " << SM.getExpansionLineNumber(Loc)
-      << ", \"column\": " << SM.getExpansionColumnNumber(Loc)
-      << ", \"file\": \"" << SM.getFilename(Loc) << "\" }";
-}
-
 void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const {
   const ASTContext &Context =
       getLocationContext()->getAnalysisDeclContext()->getASTContext();
@@ -112,16 +100,18 @@
   case ProgramPoint::PreImplicitCallKind: {
     ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
     Out << "PreCall\", \"decl\": \""
-        << PC.getDecl()->getAsFunction()->getQualifiedNameAsString() << "\", ";
-    printLocJson(Out, PC.getLocation(), SM);
+        << PC.getDecl()->getAsFunction()->getQualifiedNameAsString()
+        << "\", \"location\": ";
+    printSourceLocationAsJson(Out, PC.getLocation(), SM);
     break;
   }
 
   case ProgramPoint::PostImplicitCallKind: {
     ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
     Out << "PostCall\", \"decl\": \""
-        << PC.getDecl()->getAsFunction()->getQualifiedNameAsString() << "\", ";
-    printLocJson(Out, PC.getLocation(), SM);
+        << PC.getDecl()->getAsFunction()->getQualifiedNameAsString()
+        << "\", \"location\": ";
+    printSourceLocationAsJson(Out, PC.getLocation(), SM);
     break;
   }
 
@@ -153,8 +143,8 @@
 
     E.getSrc()->printTerminatorJson(Out, Context.getLangOpts(),
                                     /*AddQuotes=*/true);
-    Out << ", ";
-    printLocJson(Out, T->getBeginLoc(), SM);
+    Out << ", \"location\": ";
+    printSourceLocationAsJson(Out, T->getBeginLoc(), SM);
 
     Out << ", \"term_kind\": \"";
     if (isa<SwitchStmt>(T)) {
@@ -202,8 +192,8 @@
 
     S->printJson(Out, nullptr, PP, AddQuotes);
 
-    Out << ", ";
-    printLocJson(Out, S->getBeginLoc(), SM);
+    Out << ", \"location\": ";
+    printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
 
     Out << ", \"stmt_point_kind\": \"";
     if (getAs<PreLoad>())