When dumping the AST to JSON, dump the type information from a typeid expression with a type operand.

llvm-svn: 361769
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index dfad90b..9408a2e 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -121,6 +121,7 @@
   friend class JSONDumper;
 
   const SourceManager &SM;
+  ASTContext& Ctx;
   PrintingPolicy PrintPolicy;
   const comments::CommandTraits *Traits;
 
@@ -172,11 +173,11 @@
   StringRef getCommentCommandName(unsigned CommandID) const;
 
 public:
-  JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr,
+  JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
                  const PrintingPolicy &PrintPolicy,
                  const comments::CommandTraits *Traits)
-      : NodeStreamer(OS), SM(SrcMgr), PrintPolicy(PrintPolicy), Traits(Traits) {
-  }
+      : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy),
+        Traits(Traits) {}
 
   void Visit(const Attr *A);
   void Visit(const Stmt *Node);
@@ -247,6 +248,7 @@
   void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE);
   void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE);
   void VisitAddrLabelExpr(const AddrLabelExpr *ALE);
+  void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE);
 
   void VisitIntegerLiteral(const IntegerLiteral *IL);
   void VisitCharacterLiteral(const CharacterLiteral *CL);
@@ -360,10 +362,10 @@
   }
 
 public:
-  JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr,
+  JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
              const PrintingPolicy &PrintPolicy,
              const comments::CommandTraits *Traits)
-      : NodeDumper(OS, SrcMgr, PrintPolicy, Traits) {}
+      : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {}
 
   JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; }
 
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 0e0ddcd..22196a1 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -180,11 +180,11 @@
 
 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
                                  ASTDumpOutputFormat Format) const {
-  const ASTContext &Ctx = getASTContext();
+  ASTContext &Ctx = getASTContext();
   const SourceManager &SM = Ctx.getSourceManager();
 
   if (ADOF_JSON == Format) {
-    JSONDumper P(OS, SM, Ctx.getPrintingPolicy(),
+    JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
                  &Ctx.getCommentCommandTraits());
     (void)Deserialize; // FIXME?
     P.Visit(this);
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 08f63fb..43cad2b 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -917,6 +917,16 @@
   JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
 }
 
+void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
+  if (CTE->isTypeOperand()) {
+    QualType Adjusted = CTE->getTypeOperand(Ctx);
+    QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();
+    JOS.attribute("typeArg", createQualType(Unadjusted));
+    if (Adjusted != Unadjusted)
+      JOS.attribute("adjustedTypeArg", createQualType(Adjusted));
+  }
+}
+
 void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
   JOS.attribute("value",
                 IL->getValue().toString(
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index c6ccc95..fa6d6ed 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -3447,7 +3447,10 @@
 // CHECK-NEXT:      "type": {
 // CHECK-NEXT:       "qualType": "const std::type_info"
 // CHECK-NEXT:      },
-// CHECK-NEXT:      "valueCategory": "lvalue"
+// CHECK-NEXT:      "valueCategory": "lvalue",
+// CHECK-NEXT:      "typeArg": {
+// CHECK-NEXT:       "qualType": "S"
+// CHECK-NEXT:      }
 // CHECK-NEXT:     },
 // CHECK-NEXT:     {
 // CHECK-NEXT:      "id": "0x{{.*}}",
@@ -3467,7 +3470,13 @@
 // CHECK-NEXT:      "type": {
 // CHECK-NEXT:       "qualType": "const std::type_info"
 // CHECK-NEXT:      },
-// CHECK-NEXT:      "valueCategory": "lvalue"
+// CHECK-NEXT:      "valueCategory": "lvalue",
+// CHECK-NEXT:      "typeArg": {
+// CHECK-NEXT:       "qualType": "const volatile S"
+// CHECK-NEXT:      },
+// CHECK-NEXT:      "adjustedTypeArg": {
+// CHECK-NEXT:       "qualType": "S"
+// CHECK-NEXT:      }
 // CHECK-NEXT:     }
 // CHECK-NEXT:    ]
 // CHECK-NEXT:   }