]> granicus.if.org Git - clang/commitdiff
Add template instantiations to the output of -ast-dump.
authorRichard Trieu <rtrieu@google.com>
Thu, 28 Jul 2011 00:19:05 +0000 (00:19 +0000)
committerRichard Trieu <rtrieu@google.com>
Thu, 28 Jul 2011 00:19:05 +0000 (00:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136306 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclBase.h
lib/AST/DeclPrinter.cpp
lib/Frontend/ASTConsumers.cpp
test/Misc/ast-dump-templates.cpp [new file with mode: 0644]

index 8ba94525ccabe44bd9e9e4976c18f04688e52883..8355e36c750d40117ef211e6b7ac836af9e03571 100644 (file)
@@ -734,9 +734,10 @@ public:
   static DeclContext *castToDeclContext(const Decl *);
   static Decl *castFromDeclContext(const DeclContext *);
 
-  void print(raw_ostream &Out, unsigned Indentation = 0) const;
+  void print(raw_ostream &Out, unsigned Indentation = 0,
+             bool PrintInstantiation = false) const;
   void print(raw_ostream &Out, const PrintingPolicy &Policy,
-             unsigned Indentation = 0) const;
+             unsigned Indentation = 0, bool PrintInstantiation = false) const;
   static void printGroup(Decl** Begin, unsigned NumDecls,
                          raw_ostream &Out, const PrintingPolicy &Policy,
                          unsigned Indentation = 0);
index 08112cb7f8e0bf160af0ac2c738f8ad5026f1fd0..64b31ec1859d834f9fc19c0c9afa1e47dbb44fd3 100644 (file)
@@ -28,6 +28,7 @@ namespace {
     ASTContext &Context;
     PrintingPolicy Policy;
     unsigned Indentation;
+    bool PrintInstantiation;
 
     raw_ostream& Indent() { return Indent(Indentation); }
     raw_ostream& Indent(unsigned Indentation);
@@ -38,8 +39,10 @@ namespace {
   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 @@ namespace {
     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 @@ namespace {
     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 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
     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 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
 
       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 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
         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 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
   }
 
   Out << "> ";
+}
+
+void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
+  PrintTemplateParameters(D->getTemplateParameters());
 
   if (const TemplateTemplateParmDecl *TTP =
         dyn_cast<TemplateTemplateParmDecl>(D)) {
@@ -757,6 +779,33 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
   }
 }
 
+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
 //----------------------------------------------------------------------------
index b0746b290cf4e58b17625c86ef9db9efb0a36f04..6412727cd74bd7afe45b07232290bf259199ca1d 100644 (file)
@@ -41,7 +41,8 @@ namespace {
     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
diff --git a/test/Misc/ast-dump-templates.cpp b/test/Misc/ast-dump-templates.cpp
new file mode 100644 (file)
index 0000000..6be36ec
--- /dev/null
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+template <int X, typename Y, int Z = 5>
+struct foo {
+  int constant;
+  foo() {}
+  Y getSum() { return Y(X + Z); }
+};
+
+template <int A, typename B>
+B bar() {
+  return B(A);
+}
+
+void baz() {
+  int x = bar<5, int>();
+  int y = foo<5, int>().getSum();
+  double z = foo<2, double, 3>().getSum();
+}
+
+// Template instantiation - foo
+// CHECK: template <int X = 5, typename Y = int, int Z = 5> struct foo {
+// CHECK: template <int X = 2, typename Y = double, int Z = 3> struct foo {
+
+// Template definition - foo
+// CHECK: template <int X, typename Y, int Z = (IntegerLiteral {{.*}} 'int' 5)
+
+// Template instantiation - bar
+// CHECK: template <int A = 5, typename B = int> int bar()
+
+// Template definition - bar
+// CHECK: template <int A, typename B> B bar()