[clang-tidy] Improve hicpp-exception-baseclass to handle generic code better

Summary:
This patch is a followup to the first revision D36583, that had problems with 
generic code and its diagnostic messages, which were found by @lebedev.ri

Reviewers: alexfh, aaron.ballman, lebedev.ri, hokein

Reviewed By: aaron.ballman, lebedev.ri

Subscribers: klimek, sbenza, cfe-commits, JDevlieghere, lebedev.ri, xazax.hun

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

llvm-svn: 312134
diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
index e528ae9..298759f 100644
--- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
@@ -11,8 +11,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 
-#include <iostream>
-
 using namespace clang::ast_matchers;
 
 namespace clang {
@@ -24,20 +22,23 @@
     return;
 
   Finder->addMatcher(
-      cxxThrowExpr(
-          allOf(
-              has(expr(unless(hasType(cxxRecordDecl(
-                  isSameOrDerivedFrom(hasName("std::exception"))))))),
-              eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything())))
+      cxxThrowExpr(allOf(has(expr(unless(hasType(qualType(hasCanonicalType(
+                             hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom(
+                                 hasName("std::exception")))))))))),
+                         has(expr(unless(cxxUnresolvedConstructExpr()))),
+                         eachOf(has(expr(hasType(namedDecl().bind("decl")))),
+                                anything())))
           .bind("bad_throw"),
       this);
 }
 
 void ExceptionBaseclassCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("bad_throw");
-  diag(BadThrow->getLocStart(),
-       "throwing an exception whose type is not derived from 'std::exception'")
-      << BadThrow->getSourceRange();
+
+  diag(BadThrow->getSubExpr()->getLocStart(), "throwing an exception whose "
+                                              "type %0 is not derived from "
+                                              "'std::exception'")
+      << BadThrow->getSubExpr()->getType() << BadThrow->getSourceRange();
 
   const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl");
   if (TypeDecl != nullptr)