1 //===--- ExceptionBaseclassCheck.cpp - clang-tidy--------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "ExceptionBaseclassCheck.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 14 #include <iostream> 15 16 using namespace clang::ast_matchers; 17 18 namespace clang { 19 namespace tidy { 20 namespace hicpp { 21 22 void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) { 23 if (!getLangOpts().CPlusPlus) 24 return; 25 26 Finder->addMatcher( 27 cxxThrowExpr( 28 allOf( 29 has(expr(unless(hasType(cxxRecordDecl( 30 isSameOrDerivedFrom(hasName("std::exception"))))))), 31 eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything()))) 32 .bind("bad_throw"), 33 this); 34 } 35 36 void ExceptionBaseclassCheck::check(const MatchFinder::MatchResult &Result) { 37 const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("bad_throw"); 38 diag(BadThrow->getLocStart(), 39 "throwing an exception whose type is not derived from 'std::exception'") 40 << BadThrow->getSourceRange(); 41 42 const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl"); 43 if (TypeDecl != nullptr) 44 diag(TypeDecl->getLocStart(), "type defined here", DiagnosticIDs::Note); 45 } 46 47 } // namespace hicpp 48 } // namespace tidy 49 } // namespace clang 50