[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang-tools-extra / clang-tidy / hicpp / ExceptionBaseclassCheck.cpp
blob2b2acfdf5b08e9b26978ad6edc4b897196b243a2
1 //===--- ExceptionBaseclassCheck.cpp - clang-tidy--------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "ExceptionBaseclassCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 using namespace clang::ast_matchers;
15 namespace clang::tidy::hicpp {
17 void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) {
18 Finder->addMatcher(
19 cxxThrowExpr(
20 unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))),
21 // The thrown value is not derived from 'std::exception'.
22 has(expr(unless(
23 hasType(qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
24 isSameOrDerivedFrom(hasName("::std::exception")))))))))),
25 // This condition is always true, but will bind to the
26 // template value if the thrown type is templated.
27 anyOf(has(expr(
28 hasType(substTemplateTypeParmType().bind("templ_type")))),
29 anything()),
30 // Bind to the declaration of the type of the value that
31 // is thrown. 'anything()' is necessary to always succeed
32 // in the 'eachOf' because builtin types are not
33 // 'namedDecl'.
34 eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything()))
35 .bind("bad_throw"),
36 this);
39 void ExceptionBaseclassCheck::check(const MatchFinder::MatchResult &Result) {
40 const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("bad_throw");
41 assert(BadThrow && "Did not match the throw expression");
43 diag(BadThrow->getSubExpr()->getBeginLoc(), "throwing an exception whose "
44 "type %0 is not derived from "
45 "'std::exception'")
46 << BadThrow->getSubExpr()->getType() << BadThrow->getSourceRange();
48 if (const auto *Template =
49 Result.Nodes.getNodeAs<SubstTemplateTypeParmType>("templ_type"))
50 diag(BadThrow->getSubExpr()->getBeginLoc(),
51 "type %0 is a template instantiation of %1", DiagnosticIDs::Note)
52 << BadThrow->getSubExpr()->getType()
53 << Template->getReplacedParameter();
55 if (const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl"))
56 diag(TypeDecl->getBeginLoc(), "type defined here", DiagnosticIDs::Note);
59 } // namespace clang::tidy::hicpp