[WIP][Sema] Improve static_assert diagnostics for type traits.

Summary:
In our codebase, `static_assert(std::some_type_trait<Ts...>::value, "msg")`
(where `some_type_trait` is an std type_trait and `Ts...` is the
appropriate template parameters) account for 11.2% of the `static_assert`s.

In these cases, the `Ts` are typically not spelled out explicitly, e.g.
`static_assert(std::is_same<SomeT::TypeT, typename SomeDependentT::value_type>::value, "message");`

The diagnostic when the assert fails is typically not very useful, e.g.
`static_assert failed due to requirement 'std::is_same<SomeT::TypeT, typename SomeDependentT::value_type>::value' "message"`

This change makes the diagnostic spell out the types explicitly , e.g.
`static_assert failed due to requirement 'std::is_same<int, float>::value' "message"`

See tests for more examples.

After this is submitted, I intend to handle
`static_assert(!std::some_type_trait<Ts...>::value, "msg")`,
which is another 6.6% of static_asserts.

Subscribers: cfe-commits

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

llvm-svn: 348239
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index 097c3ae..548f2f8 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
@@ -270,9 +271,8 @@
 
 /// Print this nested name specifier to the given output
 /// stream.
-void
-NestedNameSpecifier::print(raw_ostream &OS,
-                           const PrintingPolicy &Policy) const {
+void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
+                                bool ResolveTemplateArguments) const {
   if (getPrefix())
     getPrefix()->print(OS, Policy);
 
@@ -305,6 +305,15 @@
     LLVM_FALLTHROUGH;
 
   case TypeSpec: {
+    const auto *Record =
+            dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
+    if (ResolveTemplateArguments && Record) {
+        // Print the type trait with resolved template parameters.
+        Record->printName(OS);
+        printTemplateArgumentList(OS, Record->getTemplateArgs().asArray(),
+                                  Policy);
+        break;
+    }
     const Type *T = getAsType();
 
     PrintingPolicy InnerPolicy(Policy);