Add template instantiations to the output of -ast-dump.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136306 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 08112cb..64b31ec 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -28,6 +28,7 @@
     ASTContext &Context;
     PrintingPolicy Policy;
     unsigned Indentation;
+    bool PrintInstantiation;
 
     raw_ostream& Indent() { return Indent(Indentation); }
     raw_ostream& Indent(unsigned Indentation);
@@ -38,8 +39,10 @@
   public:
     DeclPrinter(raw_ostream &Out, ASTContext &Context,
                 const PrintingPolicy &Policy,
-                unsigned Indentation = 0)
-      : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation) { }
+                unsigned Indentation = 0,
+                bool PrintInstantiation = false)
+      : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation),
+        PrintInstantiation(PrintInstantiation) { }
 
     void VisitDeclContext(DeclContext *DC, bool Indent = true);
 
@@ -62,6 +65,8 @@
     void VisitCXXRecordDecl(CXXRecordDecl *D);
     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
     void VisitTemplateDecl(const TemplateDecl *D);
+    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    void VisitClassTemplateDecl(ClassTemplateDecl *D);
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
     void VisitObjCClassDecl(ObjCClassDecl *D);
     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
@@ -77,16 +82,20 @@
     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
     void VisitUsingDecl(UsingDecl *D);
     void VisitUsingShadowDecl(UsingShadowDecl *D);
+
+    void PrintTemplateParameters(const TemplateParameterList *Params,
+                                 const TemplateArgumentList *Args);
   };
 }
 
-void Decl::print(raw_ostream &Out, unsigned Indentation) const {
-  print(Out, getASTContext().PrintingPolicy, Indentation);
+void Decl::print(raw_ostream &Out, unsigned Indentation,
+                 bool PrintInstantiation) const {
+  print(Out, getASTContext().PrintingPolicy, Indentation, PrintInstantiation);
 }
 
 void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
-                 unsigned Indentation) const {
-  DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
+                 unsigned Indentation, bool PrintInstantiation) const {
+  DeclPrinter Printer(Out, getASTContext(), Policy, Indentation, PrintInstantiation);
   Printer.Visit(const_cast<Decl*>(this));
 }
 
@@ -694,10 +703,13 @@
     Visit(*D->decls_begin());
 }
 
-void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
+void DeclPrinter::PrintTemplateParameters(
+    const TemplateParameterList *Params, const TemplateArgumentList *Args = 0) {
+  assert(Params);
+  assert(!Args || Params->size() == Args->size());
+
   Out << "template <";
 
-  TemplateParameterList *Params = D->getTemplateParameters();
   for (unsigned i = 0, e = Params->size(); i != e; ++i) {
     if (i != 0)
       Out << ", ";
@@ -716,7 +728,10 @@
 
       Out << TTP->getNameAsString();
 
-      if (TTP->hasDefaultArgument()) {
+      if (Args) {
+        Out << " = ";
+        Args->get(i).print(Policy, Out);
+      } else if (TTP->hasDefaultArgument()) {
         Out << " = ";
         Out << TTP->getDefaultArgument().getAsString(Policy);
       };
@@ -732,7 +747,10 @@
         Out << Name->getName();
       }
 
-      if (NTTP->hasDefaultArgument()) {
+      if (Args) {
+        Out << " = ";
+        Args->get(i).print(Policy, Out);
+      } else if (NTTP->hasDefaultArgument()) {
         Out << " = ";
         NTTP->getDefaultArgument()->printPretty(Out, Context, 0, Policy,
                                                 Indentation);
@@ -745,6 +763,10 @@
   }
 
   Out << "> ";
+}
+
+void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
+  PrintTemplateParameters(D->getTemplateParameters());
 
   if (const TemplateTemplateParmDecl *TTP =
         dyn_cast<TemplateTemplateParmDecl>(D)) {
@@ -757,6 +779,33 @@
   }
 }
 
+void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  if (PrintInstantiation) {
+    TemplateParameterList *Params = D->getTemplateParameters();
+    for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
+         I != E; ++I) {
+      PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs());
+      Visit(*I);
+    }
+  }
+
+  return VisitRedeclarableTemplateDecl(D);
+}
+
+void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  if (PrintInstantiation) {
+    TemplateParameterList *Params = D->getTemplateParameters();
+    for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
+         I != E; ++I) {
+      PrintTemplateParameters(Params, &(*I)->getTemplateArgs());
+      Visit(*I);
+      Out << '\n';
+    }
+  }
+
+  return VisitRedeclarableTemplateDecl(D);
+}
+
 //----------------------------------------------------------------------------
 // Objective-C declarations
 //----------------------------------------------------------------------------
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index b0746b2..6412727 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -41,7 +41,8 @@
     virtual void HandleTranslationUnit(ASTContext &Context) {
       PrintingPolicy Policy = Context.PrintingPolicy;
       Policy.Dump = Dump;
-      Context.getTranslationUnitDecl()->print(Out, Policy);
+      Context.getTranslationUnitDecl()->print(Out, Policy, /*Indentation=*/0,
+                                              /*PrintInstantiation=*/true);
     }
   };
 } // end anonymous namespace