arphaman created this revision. arphaman added reviewers: rsmith, mehdi_amini. arphaman added a subscriber: cfe-commits. arphaman set the repository for this revision to rL LLVM.
This patch handles more declarations in DeclContextPrinter to avoid crashes when clang is given the `-print-decl-contexts` option. I would like to get an opinion on the testing in this patch - the current `-print-decl-contexts` test doesn't check the output, so this patch follows the same testing protocol. Do you think I should also check the output of `-print-decl-contexts`? This patch contains 7 commits that I squashed just for review to make it easier: - DeclContextPrinter: Handle StaticAssertDecl - DeclContextPrinter: Handle variable template declaration - DeclContextPrinter: Handle Access specifier declaration - DeclContextPrinter: Handle ClassTemplateSpecialization and ClassTemplatePartialSpecialization declarations - DeclContextPrinter: Handle EmptyDecl - DeclContextPrinter: Handle UsingDecl - DeclContextPrinter: Handle FriendDecl Thanks Repository: rL LLVM https://reviews.llvm.org/D26964 Files: lib/Frontend/ASTConsumers.cpp test/Coverage/ast-printing.cpp test/Coverage/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 <E1 v> class C1 {}; template <E1 v> C1<v> f1() { return C1<v>(); } void f2() { f1<EC1>(); } + +// 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<typename T> class ClassTemplateSpecialization; + +template<> +class ClassTemplateSpecialization<bool> { }; + +template<typename T, bool> struct ClassTemplatePartialSpecialization; + +template<typename T> +struct ClassTemplatePartialSpecialization<T, true> { }; + +// Access specifier +struct AccessSpec { +private: +}; + +// Variable template +template <typename T> T varTemplate = 0; + +static_assert(true, ""); 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: lib/Frontend/ASTConsumers.cpp =================================================================== --- lib/Frontend/ASTConsumers.cpp +++ lib/Frontend/ASTConsumers.cpp @@ -370,6 +370,26 @@ 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 @@ 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; @@ -478,6 +499,37 @@ Out << "<omp threadprivate> " << '"' << I << "\"\n"; break; } + case Decl::Friend: { + Out << "<friend>"; + if (const NamedDecl *ND = cast<FriendDecl>(I)->getFriendDecl()) + Out << ' ' << *ND; + Out << "\n"; + break; + } + case Decl::Using: { + Out << "<using> " << *cast<UsingDecl>(I) << "\n"; + break; + } + case Decl::UsingShadow: { + Out << "<using shadow> " << *cast<UsingShadowDecl>(I) << "\n"; + break; + } + case Decl::Empty: { + Out << "<empty>\n"; + break; + } + case Decl::AccessSpec: { + Out << "<access specifier>\n"; + break; + } + case Decl::VarTemplate: { + Out << "<var template> " << *cast<VarTemplateDecl>(I) << "\n"; + break; + } + case Decl::StaticAssert: { + Out << "<static assert>\n"; + break; + } default: Out << "DeclKind: " << DK << '"' << I << "\"\n"; llvm_unreachable("decl unhandled");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits