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

Reply via email to