10#include "../utils/Matchers.h"
11#include "../utils/OptionsUtils.h"
12#include "clang/AST/ASTContext.h"
13#include "clang/ASTMatchers/ASTMatchFinder.h"
14#include "clang/Lex/Lexer.h"
18using ::clang::ast_matchers::internal::Matcher;
24 return Node.getBeginLoc().isMacroID() ||
Node.getEndLoc().isMacroID() ||
25 Node.getCatchLoc().isMacroID();
28AST_MATCHER_P(CXXCatchStmt, hasHandler, Matcher<Stmt>, InnerMatcher) {
29 Stmt *Handler =
Node.getHandlerBlock();
32 return InnerMatcher.matches(*Handler, Finder,
Builder);
35AST_MATCHER_P(CXXCatchStmt, hasCaughtType, Matcher<QualType>, InnerMatcher) {
36 return InnerMatcher.matches(
Node.getCaughtType(), Finder,
Builder);
39AST_MATCHER_P(CompoundStmt, hasAnyTextFromList, std::vector<llvm::StringRef>,
44 ASTContext &Context = Finder->getASTContext();
45 SourceManager &SM = Context.getSourceManager();
46 StringRef
Text = Lexer::getSourceText(
47 CharSourceRange::getTokenRange(
Node.getSourceRange()), SM,
48 Context.getLangOpts());
49 return llvm::any_of(List, [&](
const StringRef &Str) {
50 return Text.contains_insensitive(Str);
58 IgnoreCatchWithKeywords(utils::options::parseStringList(
59 Options.get(
"IgnoreCatchWithKeywords",
"@TODO;@FIXME"))),
60 AllowEmptyCatchForExceptions(utils::options::parseStringList(
61 Options.get(
"AllowEmptyCatchForExceptions",
""))) {}
67 Opts,
"AllowEmptyCatchForExceptions",
72 const LangOptions &LangOpts)
const {
73 return LangOpts.CPlusPlus;
77 return TK_IgnoreUnlessSpelledInSource;
81 auto AllowedNamedExceptionDecl =
83 auto AllowedNamedExceptionTypes =
84 qualType(anyOf(hasDeclaration(AllowedNamedExceptionDecl),
85 references(AllowedNamedExceptionDecl),
86 pointsTo(AllowedNamedExceptionDecl)));
87 auto IgnoredExceptionType =
88 qualType(anyOf(AllowedNamedExceptionTypes,
89 hasCanonicalType(AllowedNamedExceptionTypes)));
92 cxxCatchStmt(unless(isExpansionInSystemHeader()), unless(isInMacro()),
93 unless(hasCaughtType(IgnoredExceptionType)),
94 hasHandler(compoundStmt(
96 unless(hasAnyTextFromList(IgnoreCatchWithKeywords)))))
102 const auto *MatchedCatchStmt = Result.Nodes.getNodeAs<CXXCatchStmt>(
"catch");
105 MatchedCatchStmt->getCatchLoc(),
106 "empty catch statements hide issues; to handle exceptions appropriately, "
107 "consider re-throwing, handling, or avoiding catch altogether");
llvm::SmallString< 256U > Name
CodeCompletionBuilder Builder
::clang::DynTypedNode Node
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Base class for all clang-tidy checks.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
EmptyCatchCheck(StringRef Name, ClangTidyContext *Context)
std::optional< TraversalKind > getCheckTraversalKind() const override
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override
Override this to disable registering matchers and PP callbacks if an invalid language version is bein...
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
AST_MATCHER_P(FunctionDecl, parameterCountGE, unsigned, N)
Matches functions that have at least the specified amount of parameters.
AST_MATCHER(clang::VarDecl, hasConstantDeclaration)
inline ::clang::ast_matchers::internal::Matcher< NamedDecl > matchesAnyListedName(llvm::ArrayRef< StringRef > NameList)
std::string serializeStringList(ArrayRef< StringRef > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
llvm::StringMap< ClangTidyValue > OptionMap