10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) {
22 unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))),
25 hasType(qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
26 isSameOrDerivedFrom(hasName(
"::std::exception")))))))))),
30 hasType(substTemplateTypeParmType().bind(
"templ_type")))),
36 eachOf(has(expr(hasType(namedDecl().bind(
"decl")))), anything()))
41 void ExceptionBaseclassCheck::check(
const MatchFinder::MatchResult &Result) {
42 const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>(
"bad_throw");
43 assert(BadThrow &&
"Did not match the throw expression");
45 diag(BadThrow->getSubExpr()->getBeginLoc(),
"throwing an exception whose "
46 "type %0 is not derived from "
48 << BadThrow->getSubExpr()->getType() << BadThrow->getSourceRange();
50 if (
const auto *Template =
51 Result.Nodes.getNodeAs<SubstTemplateTypeParmType>(
"templ_type"))
52 diag(BadThrow->getSubExpr()->getBeginLoc(),
53 "type %0 is a template instantiation of %1", DiagnosticIDs::Note)
54 << BadThrow->getSubExpr()->getType()
55 << Template->getReplacedParameter()->getDecl();
57 if (
const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>(
"decl"))
58 diag(TypeDecl->getBeginLoc(),
"type defined here", DiagnosticIDs::Note);