//===--- 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("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("decl"); if (TypeDecl != nullptr) diag(TypeDecl->getLocStart(), "type defined here", DiagnosticIDs::Note); } } // namespace hicpp } // namespace tidy } // namespace clang