void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  Finder->addMatcher(
      cxxThrowExpr(has(ignoringParenImpCasts(
          cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
                               isCopyConstructor(), unless(isNoThrow()))))
              .bind("expr")))),
      this);
}
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
  const auto ControlFlowInterruptorMatcher =
      stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),
                 breakStmt().bind("break"), cxxThrowExpr().bind("throw")));
  Finder->addMatcher(
      stmt(forEach(
          ifStmt(hasThen(stmt(
                     anyOf(ControlFlowInterruptorMatcher,
                           compoundStmt(has(ControlFlowInterruptorMatcher))))),
                 hasElse(stmt().bind("else")))
              .bind("if"))),
      this);
}
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);
}