Fixes infinite loop in PR15220

http://llvm-reviews.chandlerc.com/D388

Files:
  lib/AST/ASTDumper.cpp
  test/Misc/ast-dump-decl.cpp

Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -947,7 +947,10 @@
     case TSK_ImplicitInstantiation:
     case TSK_ExplicitInstantiationDeclaration:
     case TSK_ExplicitInstantiationDefinition:
-      dumpDecl(*I);
+      if (D == D->getCanonicalDecl())
+        dumpDecl(*I);
+      else
+        dumpDeclRef(*I);
       break;
     case TSK_ExplicitSpecialization:
       dumpDeclRef(*I);
@@ -975,7 +978,10 @@
     switch (I->getTemplateSpecializationKind()) {
     case TSK_Undeclared:
     case TSK_ImplicitInstantiation:
-      dumpDecl(*I);
+      if (D == D->getCanonicalDecl())
+        dumpDecl(*I);
+      else
+        dumpDeclRef(*I);
       break;
     case TSK_ExplicitSpecialization:
     case TSK_ExplicitInstantiationDeclaration:
Index: test/Misc/ast-dump-decl.cpp
===================================================================
--- test/Misc/ast-dump-decl.cpp
+++ test/Misc/ast-dump-decl.cpp
@@ -251,6 +251,45 @@
 // CHECK-NEXT:   CXXRecordDecl{{.*}} class TestClassTemplatePartial
 // CHECK-NEXT:   FieldDecl{{.*}} j
 
+// PR15220 dump instantiation only once
+namespace testCanonicalTemplate {
+  class A {};
+
+  template<typename T> void TestFunctionTemplate(T);
+  template<typename T> void TestFunctionTemplate(T);
+  void bar(A a) { TestFunctionTemplate(a); }
+  // CHECK:      FunctionTemplateDecl{{.*}} TestFunctionTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+  // CHECK-NEXT:     ParmVarDecl{{.*}} 'T'
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
+  // CHECK-NEXT:     TemplateArgument
+  // CHECK-NEXT:     ParmVarDecl
+  // CHECK:      FunctionTemplateDecl{{.*}} TestFunctionTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+  // CHECK-NEXT:     ParmVarDecl{{.*}} 'T'
+  // CHECK-NEXT:   Function{{.*}} 'TestFunctionTemplate'
+  // CHECK-NEXT-NOT: TemplateArgument
+
+  template<typename T1> class TestClassTemplate {
+    template<typename T2> friend class TestClassTemplate;
+  };
+  TestClassTemplate<A> a;
+  // CHECK:      ClassTemplateDecl{{.*}} TestClassTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:     CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:     FriendDecl
+  // CHECK-NEXT:       ClassTemplateDecl{{.*}} TestClassTemplate
+  // CHECK-NEXT:         TemplateTypeParmDecl
+  // CHECK-NEXT:         CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:         ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
+  // CHECK-NEXT:   ClassTemplateSpecializationDecl{{.*}} class 
TestClassTemplate
+  // CHECK-NEXT:     TemplateArgument{{.*}}A
+  // CHECK-NEXT:     CXXRecordDecl{{.*}} class TestClassTemplate
+}
+
 template <class T>
 class TestClassScopeFunctionSpecialization {
   template<class U> void foo(U a) { }
Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -947,7 +947,10 @@
     case TSK_ImplicitInstantiation:
     case TSK_ExplicitInstantiationDeclaration:
     case TSK_ExplicitInstantiationDefinition:
-      dumpDecl(*I);
+      if (D == D->getCanonicalDecl())
+        dumpDecl(*I);
+      else
+        dumpDeclRef(*I);
       break;
     case TSK_ExplicitSpecialization:
       dumpDeclRef(*I);
@@ -975,7 +978,10 @@
     switch (I->getTemplateSpecializationKind()) {
     case TSK_Undeclared:
     case TSK_ImplicitInstantiation:
-      dumpDecl(*I);
+      if (D == D->getCanonicalDecl())
+        dumpDecl(*I);
+      else
+        dumpDeclRef(*I);
       break;
     case TSK_ExplicitSpecialization:
     case TSK_ExplicitInstantiationDeclaration:
Index: test/Misc/ast-dump-decl.cpp
===================================================================
--- test/Misc/ast-dump-decl.cpp
+++ test/Misc/ast-dump-decl.cpp
@@ -251,6 +251,45 @@
 // CHECK-NEXT:   CXXRecordDecl{{.*}} class TestClassTemplatePartial
 // CHECK-NEXT:   FieldDecl{{.*}} j
 
+// PR15220 dump instantiation only once
+namespace testCanonicalTemplate {
+  class A {};
+
+  template<typename T> void TestFunctionTemplate(T);
+  template<typename T> void TestFunctionTemplate(T);
+  void bar(A a) { TestFunctionTemplate(a); }
+  // CHECK:      FunctionTemplateDecl{{.*}} TestFunctionTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+  // CHECK-NEXT:     ParmVarDecl{{.*}} 'T'
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
+  // CHECK-NEXT:     TemplateArgument
+  // CHECK-NEXT:     ParmVarDecl
+  // CHECK:      FunctionTemplateDecl{{.*}} TestFunctionTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+  // CHECK-NEXT:     ParmVarDecl{{.*}} 'T'
+  // CHECK-NEXT:   Function{{.*}} 'TestFunctionTemplate'
+  // CHECK-NEXT-NOT: TemplateArgument
+
+  template<typename T1> class TestClassTemplate {
+    template<typename T2> friend class TestClassTemplate;
+  };
+  TestClassTemplate<A> a;
+  // CHECK:      ClassTemplateDecl{{.*}} TestClassTemplate
+  // CHECK-NEXT:   TemplateTypeParmDecl
+  // CHECK-NEXT:   CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:     CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:     FriendDecl
+  // CHECK-NEXT:       ClassTemplateDecl{{.*}} TestClassTemplate
+  // CHECK-NEXT:         TemplateTypeParmDecl
+  // CHECK-NEXT:         CXXRecordDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:         ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
+  // CHECK-NEXT:   ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+  // CHECK-NEXT:     TemplateArgument{{.*}}A
+  // CHECK-NEXT:     CXXRecordDecl{{.*}} class TestClassTemplate
+}
+
 template <class T>
 class TestClassScopeFunctionSpecialization {
   template<class U> void foo(U a) { }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to