Index: lib/Frontend/ASTConsumers.cpp =================================================================== --- lib/Frontend/ASTConsumers.cpp +++ lib/Frontend/ASTConsumers.cpp @@ -370,6 +370,26 @@ break; } + case Decl::ClassTemplateSpecialization: { + const auto *CTSD = cast(DC); + if (CTSD->isCompleteDefinition()) + Out << "[class template specialization] "; + else + Out << " "; + Out << *CTSD; + break; + } + + case Decl::ClassTemplatePartialSpecialization: { + const auto *CTPSD = cast(DC); + if (CTPSD->isCompleteDefinition()) + Out << "[class template partial specialization] "; + else + Out << " "; + Out << *CTPSD; + break; + } + default: llvm_unreachable("a decl that inherits DeclContext isn't handled"); } @@ -400,7 +420,8 @@ case Decl::CXXConstructor: case Decl::CXXDestructor: case Decl::CXXConversion: - { + case Decl::ClassTemplateSpecialization: + case Decl::ClassTemplatePartialSpecialization: { DeclContext* DC = cast(I); PrintDeclContext(DC, Indentation+2); break; @@ -478,6 +499,37 @@ Out << " " << '"' << I << "\"\n"; break; } + case Decl::Friend: { + Out << ""; + if (const NamedDecl *ND = cast(I)->getFriendDecl()) + Out << ' ' << *ND; + Out << "\n"; + break; + } + case Decl::Using: { + Out << " " << *cast(I) << "\n"; + break; + } + case Decl::UsingShadow: { + Out << " " << *cast(I) << "\n"; + break; + } + case Decl::Empty: { + Out << "\n"; + break; + } + case Decl::AccessSpec: { + Out << "\n"; + break; + } + case Decl::VarTemplate: { + Out << " " << *cast(I) << "\n"; + break; + } + case Decl::StaticAssert: { + Out << "\n"; + break; + } default: Out << "DeclKind: " << DK << '"' << I << "\"\n"; llvm_unreachable("decl unhandled"); Index: test/Coverage/ast-printing.cpp =================================================================== --- test/Coverage/ast-printing.cpp +++ test/Coverage/ast-printing.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only %s -// RUN: %clang_cc1 -ast-print %s -o %t.1.cpp -// RUN: %clang_cc1 -ast-print %t.1.cpp -o %t.2.cpp +// RUN: %clang_cc1 -std=c++14 -fsyntax-only %s +// RUN: %clang_cc1 -std=c++14 -ast-print %s -o %t.1.cpp +// RUN: %clang_cc1 -std=c++14 -ast-print %t.1.cpp -o %t.2.cpp // RUN: diff %t.1.cpp %t.2.cpp -// RUN: %clang_cc1 -ast-dump %s -// RUN: %clang_cc1 -print-decl-contexts %s -// RUN: %clang_cc1 -fdump-record-layouts %s +// RUN: %clang_cc1 -std=c++14 -ast-dump %s +// RUN: %clang_cc1 -std=c++14 -print-decl-contexts %s +// RUN: %clang_cc1 -std=c++14 -fdump-record-layouts %s #include "cxx-language-features.inc" Index: test/Coverage/cxx-language-features.inc =================================================================== --- test/Coverage/cxx-language-features.inc +++ test/Coverage/cxx-language-features.inc @@ -25,3 +25,43 @@ template class C1 {}; template C1 f1() { return C1(); } void f2() { f1(); } + +// Friend declarations +struct FriendlyStruct { + friend bool operator==(FriendlyStruct, FriendlyStruct) { return true; } + friend struct FriendedStruct; +}; + +struct FriendedStruct { }; + +// Using declaration +namespace provider { + void foo(); +} +namespace user { + using provider::foo; +} + +// Empty declaration +; + +// Template specialization declarations +template class ClassTemplateSpecialization; + +template<> +class ClassTemplateSpecialization { }; + +template struct ClassTemplatePartialSpecialization; + +template +struct ClassTemplatePartialSpecialization { }; + +// Access specifier +struct AccessSpec { +private: +}; + +// Variable template +template T varTemplate = 0; + +static_assert(true, "");