| //===--- ExceptionBaseclassCheck.cpp - clang-tidy--------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ExceptionBaseclassCheck.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/ASTMatchers/ASTMatchFinder.h" |
| |
| using namespace clang::ast_matchers; |
| |
| namespace clang { |
| namespace tidy { |
| namespace hicpp { |
| |
| void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) { |
| if (!getLangOpts().CPlusPlus) |
| return; |
| |
| Finder->addMatcher( |
| 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->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) |
| diag(TypeDecl->getLocStart(), "type defined here", DiagnosticIDs::Note); |
| } |
| |
| } // namespace hicpp |
| } // namespace tidy |
| } // namespace clang |