From 7fd9da9badd629c0a67441fe6696e0c7e850a491 Mon Sep 17 00:00:00 2001
From: Alex Lorenz <arphaman@gmail.com>
Date: Tue, 3 Jan 2017 12:11:17 +0000
Subject: [PATCH] Handle ClassTemplateSpecializationDecl in DeclContextPrinter

This commit fixes a crash that occurs when -print-decl-contexts AST consumer
tries to print an unhandled declaration.

rdar://19467234

Differential Revision: https://reviews.llvm.org/D26964


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290884 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/ASTConsumers.cpp           | 23 ++++++++++++++++++++++-
 test/Coverage/cxx-language-features.inc | 11 +++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index d30d486b6e..f5cca139bc 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -370,6 +370,26 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
     break;
   }
 
+  case Decl::ClassTemplateSpecialization: {
+    const auto *CTSD = cast<ClassTemplateSpecializationDecl>(DC);
+    if (CTSD->isCompleteDefinition())
+      Out << "[class template specialization] ";
+    else
+      Out << "<class template specialization> ";
+    Out << *CTSD;
+    break;
+  }
+
+  case Decl::ClassTemplatePartialSpecialization: {
+    const auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl>(DC);
+    if (CTPSD->isCompleteDefinition())
+      Out << "[class template partial specialization] ";
+    else
+      Out << "<class template partial specialization> ";
+    Out << *CTPSD;
+    break;
+  }
+
   default:
     llvm_unreachable("a decl that inherits DeclContext isn't handled");
   }
@@ -400,7 +420,8 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
     case Decl::CXXConstructor:
     case Decl::CXXDestructor:
     case Decl::CXXConversion:
-    {
+    case Decl::ClassTemplateSpecialization:
+    case Decl::ClassTemplatePartialSpecialization: {
       DeclContext* DC = cast<DeclContext>(I);
       PrintDeclContext(DC, Indentation+2);
       break;
diff --git a/test/Coverage/cxx-language-features.inc b/test/Coverage/cxx-language-features.inc
index 5a2cc2374e..1df4db7d35 100644
--- a/test/Coverage/cxx-language-features.inc
+++ b/test/Coverage/cxx-language-features.inc
@@ -44,3 +44,14 @@ namespace user {
 
 // Empty declaration
 ;
+
+// Template specialization declarations
+template<typename T> class ClassTemplateSpecialization;
+
+template<>
+class ClassTemplateSpecialization<bool> { };
+
+template<typename T, bool> struct ClassTemplatePartialSpecialization;
+
+template<typename T>
+struct ClassTemplatePartialSpecialization<T, true> { };
-- 
2.40.0