Dump macro expansion information as needed when outputting the AST to JSON.

llvm-svn: 361172
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index ce003ad..37040ea 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -146,9 +146,9 @@
   attributeOnlyIfTrue("selected", A.isSelected());
 }
 
-llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) {
-  SourceLocation Spelling = SM.getSpellingLoc(Loc);
-  PresumedLoc Presumed = SM.getPresumedLoc(Spelling);
+llvm::json::Object
+JSONNodeDumper::createBareSourceLocation(SourceLocation Loc) {
+  PresumedLoc Presumed = SM.getPresumedLoc(Loc);
 
   if (Presumed.isInvalid())
     return llvm::json::Object{};
@@ -158,6 +158,28 @@
                             {"col", Presumed.getColumn()}};
 }
 
+llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) {
+  SourceLocation Spelling = SM.getSpellingLoc(Loc);
+  SourceLocation Expansion = SM.getExpansionLoc(Loc);
+
+  llvm::json::Object SLoc = createBareSourceLocation(Spelling);
+  if (Expansion != Spelling) {
+    // If the expansion and the spelling are different, output subobjects
+    // describing both locations.
+    llvm::json::Object ELoc = createBareSourceLocation(Expansion);
+
+    // If there is a macro expansion, add extra information if the interesting
+    // bit is the macro arg expansion.
+    if (SM.isMacroArgExpansion(Loc))
+      ELoc["isMacroArgExpansion"] = true;
+
+    return llvm::json::Object{{"spellingLoc", std::move(SLoc)},
+                              {"expansionLoc", std::move(ELoc)}};
+  }
+
+  return SLoc;
+}
+
 llvm::json::Object JSONNodeDumper::createSourceRange(SourceRange R) {
   return llvm::json::Object{{"begin", createSourceLocation(R.getBegin())},
                             {"end", createSourceLocation(R.getEnd())}};