[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);