diff --git a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h index 1eef86ddc00b9..b20d1b1fa7e32 100644 --- a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h +++ b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_ABSEILMATCHER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_ABSEILMATCHER_H + #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include @@ -57,3 +60,5 @@ AST_POLYMORPHIC_MATCHER( } } // namespace clang::ast_matchers + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_ABSEILMATCHER_H diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index 6cb687de4dc86..448bb4b7e1f94 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "DurationFactoryFloatCheck.h" +#include "../utils/LexerUtils.h" #include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -18,15 +19,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::abseil { -// Returns `true` if `Range` is inside a macro definition. -static bool insideMacroDefinition(const MatchFinder::MatchResult &Result, - SourceRange Range) { - return !clang::Lexer::makeFileCharRange( - clang::CharSourceRange::getCharRange(Range), - *Result.SourceManager, Result.Context->getLangOpts()) - .isValid(); -} - void DurationFactoryFloatCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr(callee(functionDecl(DurationFactoryFunction())), @@ -45,7 +37,9 @@ void DurationFactoryFloatCheck::check(const MatchFinder::MatchResult &Result) { const auto *MatchedCall = Result.Nodes.getNodeAs("call"); // Don't try and replace things inside of macro definitions. - if (insideMacroDefinition(Result, MatchedCall->getSourceRange())) + if (tidy::utils::lexer::insideMacroDefinition(MatchedCall->getSourceRange(), + *Result.SourceManager, + Result.Context->getLangOpts())) return; const Expr *Arg = MatchedCall->getArg(0)->IgnoreImpCasts(); diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index 28b2f81fdc8c8..687171e4c782d 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -30,12 +30,15 @@ using ::clang::transformer::makeRule; using ::clang::transformer::node; using ::clang::transformer::RewriteRuleWith; +namespace { + AST_MATCHER(Type, isCharType) { return Node.isCharType(); } +} // namespace -static const char DefaultStringLikeClasses[] = "::std::basic_string;" +static const char StringLikeClassesDefault[] = "::std::basic_string;" "::std::basic_string_view;" "::absl::string_view"; -static const char DefaultAbseilStringsMatchHeader[] = "absl/strings/match.h"; +static const char AbseilStringsMatchHeaderDefault[] = "absl/strings/match.h"; static transformer::RewriteRuleWith makeRewriteRule(ArrayRef StringLikeClassNames, @@ -84,9 +87,9 @@ StringFindStrContainsCheck::StringFindStrContainsCheck( StringRef Name, ClangTidyContext *Context) : TransformerClangTidyCheck(Name, Context), StringLikeClassesOption(utils::options::parseStringList( - Options.get("StringLikeClasses", DefaultStringLikeClasses))), + Options.get("StringLikeClasses", StringLikeClassesDefault))), AbseilStringsMatchHeaderOption(Options.get( - "AbseilStringsMatchHeader", DefaultAbseilStringsMatchHeader)) { + "AbseilStringsMatchHeader", AbseilStringsMatchHeaderDefault)) { setRule( makeRewriteRule(StringLikeClassesOption, AbseilStringsMatchHeaderOption)); } diff --git a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp index a2171aad32b73..ecf9a2293c9a8 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "TimeSubtractionCheck.h" +#include "../utils/LexerUtils.h" #include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -18,15 +19,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::abseil { -// Returns `true` if `Range` is inside a macro definition. -static bool insideMacroDefinition(const MatchFinder::MatchResult &Result, - SourceRange Range) { - return !clang::Lexer::makeFileCharRange( - clang::CharSourceRange::getCharRange(Range), - *Result.SourceManager, Result.Context->getLangOpts()) - .isValid(); -} - static bool isConstructorAssignment(const MatchFinder::MatchResult &Result, const Expr *Node) { // For C++14 and earlier there are elidable constructors that must be matched @@ -130,7 +122,9 @@ void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) { const auto *BinOp = Result.Nodes.getNodeAs("binop"); std::string InverseName = Result.Nodes.getNodeAs("func_decl")->getNameAsString(); - if (insideMacroDefinition(Result, BinOp->getSourceRange())) + if (tidy::utils::lexer::insideMacroDefinition(BinOp->getSourceRange(), + *Result.SourceManager, + Result.Context->getLangOpts())) return; std::optional Scale = getScaleForTimeInverse(InverseName); @@ -139,7 +133,9 @@ void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) { const auto *OuterCall = Result.Nodes.getNodeAs("outer_call"); if (OuterCall) { - if (insideMacroDefinition(Result, OuterCall->getSourceRange())) + if (tidy::utils::lexer::insideMacroDefinition( + OuterCall->getSourceRange(), *Result.SourceManager, + Result.Context->getLangOpts())) return; // We're working with the first case of matcher, and need to replace the @@ -165,7 +161,9 @@ void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) { .bind("arg"))), *BinOp, *Result.Context)); if (MaybeCallArg && MaybeCallArg->getArg(0)->IgnoreImpCasts() == BinOp && - !insideMacroDefinition(Result, MaybeCallArg->getSourceRange())) { + !tidy::utils::lexer::insideMacroDefinition( + MaybeCallArg->getSourceRange(), *Result.SourceManager, + Result.Context->getLangOpts())) { // Handle the case where the matched expression is inside a call which // converts it from the inverse to a Duration. In this case, we replace // the outer with just the subtraction expression, which gives the right diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index 8e27e8e3e0c2b..323d966711ddc 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -139,8 +139,8 @@ void UpgradeDurationConversionsCheck::check( // We gather source locations from template matches not in template // instantiations for future matches. - internal::Matcher IsInsideTemplate = - hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl()))); + auto IsInsideTemplate = stmt( + hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())))); if (!match(IsInsideTemplate, *ArgExpr, *Result.Context).empty()) MatchedTemplateLocations.insert(Loc); diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp index 8c13ce5a90e9b..939c311b56b35 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp @@ -25,15 +25,13 @@ void BadSignalToKillThreadCheck::registerMatchers(MatchFinder *Finder) { this); } -static Preprocessor *PP; - void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { const auto IsSigterm = [](const auto &KeyValue) -> bool { return KeyValue.first->getName() == "SIGTERM" && KeyValue.first->hasMacroDefinition(); }; const auto TryExpandAsInteger = - [](Preprocessor::macro_iterator It) -> std::optional { + [this](Preprocessor::macro_iterator It) -> std::optional { if (It == PP->macro_end()) return std::nullopt; const MacroInfo *MI = PP->getMacroInfo(It->first); @@ -64,8 +62,8 @@ void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { } void BadSignalToKillThreadCheck::registerPPCallbacks( - const SourceManager &SM, Preprocessor *Pp, Preprocessor *ModuleExpanderPP) { - PP = Pp; + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + this->PP = PP; } } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h index f21b8c09eb0c6..17580e744be9d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h @@ -26,7 +26,10 @@ class BadSignalToKillThreadCheck : public ClangTidyCheck { void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; + +private: std::optional SigtermValue; + Preprocessor *PP = nullptr; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp index 93f35cb2c1a3d..2c56a39bbeb10 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp @@ -15,6 +15,8 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { +namespace { + AST_MATCHER(clang::VarDecl, hasConstantDeclaration) { const Expr *Init = Node.getInit(); if (Init && !Init->isValueDependent()) { @@ -25,6 +27,8 @@ AST_MATCHER(clang::VarDecl, hasConstantDeclaration) { return false; } +} // namespace + DynamicStaticInitializersCheck::DynamicStaticInitializersCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp index 84e99c7fafc74..6e7c017aca893 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp @@ -1881,6 +1881,8 @@ static bool prefixSuffixCoverUnderThreshold(std::size_t Threshold, } // namespace filter +namespace { + /// Matches functions that have at least the specified amount of parameters. AST_MATCHER_P(FunctionDecl, parameterCountGE, unsigned, N) { return Node.getNumParams() >= N; @@ -1903,6 +1905,8 @@ AST_MATCHER(FunctionDecl, isOverloadedUnaryOrBinaryOperator) { } } +} // namespace + /// Returns the DefaultMinimumLength if the Value of requested minimum length /// is less than 2. Minimum lengths of 0 or 1 are not accepted. static inline unsigned clampMinimumLength(const unsigned Value) { diff --git a/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp index ff5b885aa95f8..3c64479249a97 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp @@ -20,7 +20,7 @@ using ::clang::ast_matchers::internal::Matcher; namespace clang::tidy::bugprone { namespace { -AST_MATCHER(CXXCatchStmt, isInMacro) { +AST_MATCHER(CXXCatchStmt, isCatchInMacro) { return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID() || Node.getCatchLoc().isMacroID(); } @@ -89,7 +89,8 @@ void EmptyCatchCheck::registerMatchers(MatchFinder *Finder) { hasCanonicalType(AllowedNamedExceptionTypes))); Finder->addMatcher( - cxxCatchStmt(unless(isExpansionInSystemHeader()), unless(isInMacro()), + cxxCatchStmt(unless(isExpansionInSystemHeader()), + unless(isCatchInMacro()), unless(hasCaughtType(IgnoredExceptionType)), hasHandler(compoundStmt( statementCountIs(0), diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp index 9b3b01eb02683..d6645a0e91c17 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp @@ -15,6 +15,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { +namespace { AST_MATCHER(BinaryOperator, isLogicalOperator) { return Node.isLogicalOp(); } AST_MATCHER(UnaryOperator, isUnaryPrePostOperator) { @@ -26,6 +27,8 @@ AST_MATCHER(CXXOperatorCallExpr, isPrePostOperator) { Node.getOperator() == OO_MinusMinus; } +} // namespace + void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { auto OperatorMatcher = expr( anyOf(binaryOperator(anyOf(isComparisonOperator(), isLogicalOperator())), diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index e329588290cd4..b91c585489c78 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -33,11 +33,11 @@ AST_MATCHER(FunctionType, typeHasNoReturnAttr) { } // namespace ast_matchers namespace tidy::bugprone { -static internal::Matcher -loopEndingStmt(internal::Matcher Internal) { - internal::Matcher isNoReturnFunType = +static ast_matchers::internal::Matcher +loopEndingStmt(ast_matchers::internal::Matcher Internal) { + ast_matchers::internal::Matcher isNoReturnFunType = ignoringParens(functionType(typeHasNoReturnAttr())); - internal::Matcher isNoReturnDecl = + ast_matchers::internal::Matcher isNoReturnDecl = anyOf(declHasNoReturnAttr(), functionDecl(hasType(isNoReturnFunType)), varDecl(hasType(blockPointerType(pointee(isNoReturnFunType))))); diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp index 41191a3cfed23..becfdc5ee6e97 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "MultipleNewInOneExpressionCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" @@ -51,29 +52,6 @@ bool isExprValueStored(const Expr *E, ASTContext &C) { } // namespace -AST_MATCHER_P(CXXTryStmt, hasHandlerFor, - ast_matchers::internal::Matcher, InnerMatcher) { - for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { - const CXXCatchStmt *CatchS = Node.getHandler(I); - // Check for generic catch handler (match anything). - if (CatchS->getCaughtType().isNull()) - return true; - ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); - if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) { - *Builder = std::move(Result); - return true; - } - } - return false; -} - -AST_MATCHER(CXXNewExpr, mayThrow) { - FunctionDecl *OperatorNew = Node.getOperatorNew(); - if (!OperatorNew) - return false; - return !OperatorNew->getType()->castAs()->isNothrow(); -} - void MultipleNewInOneExpressionCheck::registerMatchers(MatchFinder *Finder) { auto BadAllocType = recordType(hasDeclaration(cxxRecordDecl(hasName("::std::bad_alloc")))); @@ -85,9 +63,10 @@ void MultipleNewInOneExpressionCheck::registerMatchers(MatchFinder *Finder) { auto CatchBadAllocType = qualType(hasCanonicalType(anyOf(BadAllocType, BadAllocReferenceType, ExceptionType, ExceptionReferenceType))); - auto BadAllocCatchingTryBlock = cxxTryStmt(hasHandlerFor(CatchBadAllocType)); + auto BadAllocCatchingTryBlock = + cxxTryStmt(matchers::hasHandlerFor(CatchBadAllocType)); - auto NewExprMayThrow = cxxNewExpr(mayThrow()); + auto NewExprMayThrow = cxxNewExpr(matchers::mayThrow()); auto HasNewExpr1 = expr(anyOf(NewExprMayThrow.bind("new1"), hasDescendant(NewExprMayThrow.bind("new1")))); auto HasNewExpr2 = expr(anyOf(NewExprMayThrow.bind("new2"), @@ -115,7 +94,7 @@ void MultipleNewInOneExpressionCheck::registerMatchers(MatchFinder *Finder) { hasAncestor(BadAllocCatchingTryBlock)), this); Finder->addMatcher( - cxxNewExpr(mayThrow(), + cxxNewExpr(matchers::mayThrow(), hasDescendant(NewExprMayThrow.bind("new2_in_new1")), hasAncestor(BadAllocCatchingTryBlock)) .bind("new1"), diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp index de05cc0e4f7fb..5746a1f3b358d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp @@ -16,10 +16,13 @@ namespace clang::tidy::bugprone { namespace { -AST_MATCHER(Expr, isInMacro) { return Node.getBeginLoc().isMacroID(); } +AST_MATCHER(Expr, isExprInMacro) { return Node.getBeginLoc().isMacroID(); } + +} // namespace /// Find the next statement after `S`. -const Stmt *nextStmt(const MatchFinder::MatchResult &Result, const Stmt *S) { +static const Stmt *nextStmt(const MatchFinder::MatchResult &Result, + const Stmt *S) { auto Parents = Result.Context->getParents(*S); if (Parents.empty()) return nullptr; @@ -40,8 +43,8 @@ using ExpansionRanges = std::vector; /// \brief Get all the macro expansion ranges related to `Loc`. /// /// The result is ordered from most inner to most outer. -ExpansionRanges getExpansionRanges(SourceLocation Loc, - const MatchFinder::MatchResult &Result) { +static ExpansionRanges +getExpansionRanges(SourceLocation Loc, const MatchFinder::MatchResult &Result) { ExpansionRanges Locs; while (Loc.isMacroID()) { Locs.push_back( @@ -51,10 +54,9 @@ ExpansionRanges getExpansionRanges(SourceLocation Loc, return Locs; } -} // namespace - void MultipleStatementMacroCheck::registerMatchers(MatchFinder *Finder) { - const auto Inner = expr(isInMacro(), unless(compoundStmt())).bind("inner"); + const auto Inner = + expr(isExprInMacro(), unless(compoundStmt())).bind("inner"); Finder->addMatcher( stmt(anyOf(ifStmt(hasThen(Inner)), ifStmt(hasElse(Inner)).bind("else"), whileStmt(hasBody(Inner)), forStmt(hasBody(Inner)))) diff --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp index 902490f4d33c1..93412c213bbdf 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp @@ -322,12 +322,12 @@ SourceRange getSourceRangeOfStmt(const Stmt *S, ASTContext &Ctx) { return P.getSourceRange(); } -} // namespace - AST_MATCHER(FunctionDecl, isStandardFunction) { return isStandardFunction(&Node); } +} // namespace + SignalHandlerCheck::SignalHandlerCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index a1cffbc666199..77cc9f39d302e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -17,10 +17,6 @@ namespace clang::tidy::bugprone { namespace { -AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) { - return Node.getValue().ugt(N); -} - AST_MATCHER_P2(Expr, hasSizeOfDescendant, int, Depth, ast_matchers::internal::Matcher, InnerMatcher) { if (Depth < 0) @@ -48,15 +44,15 @@ AST_MATCHER_P2(Expr, hasSizeOfDescendant, int, Depth, return false; } -CharUnits getSizeOfType(const ASTContext &Ctx, const Type *Ty) { +} // namespace + +static CharUnits getSizeOfType(const ASTContext &Ctx, const Type *Ty) { if (!Ty || Ty->isIncompleteType() || Ty->isDependentType() || isa(Ty) || !Ty->isConstantSizeType()) return CharUnits::Zero(); return Ctx.getTypeSizeInChars(Ty); } -} // namespace - SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -183,10 +179,11 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { // Detect expression like: sizeof(expr) <= k for a suspicious constant 'k'. if (WarnOnSizeOfCompareToConstant) { Finder->addMatcher( - binaryOperator(matchers::isRelationalOperator(), - hasOperands(ignoringParenImpCasts(SizeOfExpr), - ignoringParenImpCasts(integerLiteral(anyOf( - equals(0), isBiggerThan(0x80000)))))) + binaryOperator( + matchers::isRelationalOperator(), + hasOperands(ignoringParenImpCasts(SizeOfExpr), + ignoringParenImpCasts(integerLiteral(anyOf( + equals(0), matchers::isBiggerThan(0x80000)))))) .bind("sizeof-compare-constant"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830..11d105e23fca4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "StringConstructorCheck.h" +#include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -16,12 +17,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { -namespace { -AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) { - return Node.getValue().getZExtValue() > N; -} - -const char DefaultStringNames[] = +static const char DefaultStringNames[] = "::std::basic_string;::std::basic_string_view"; static std::vector @@ -36,8 +32,6 @@ removeNamespaces(const std::vector &Names) { return Result; } -} // namespace - StringConstructorCheck::StringConstructorCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -61,7 +55,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { unaryOperator(hasOperatorName("-"), hasUnaryOperand(integerLiteral(unless(equals(0))))))); const auto LargeLengthExpr = expr(ignoringParenImpCasts( - integerLiteral(isBiggerThan(LargeLengthThreshold)))); + integerLiteral(matchers::isBiggerThan(LargeLengthThreshold)))); const auto CharPtrType = type(anyOf(pointerType(), arrayType())); // Match a string-literal; even through a declaration with initializer. diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp index b160e7259905b..155dced4a136c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "UnhandledExceptionAtNewCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -14,29 +15,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { -AST_MATCHER_P(CXXTryStmt, hasHandlerFor, - ast_matchers::internal::Matcher, InnerMatcher) { - for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { - const CXXCatchStmt *CatchS = Node.getHandler(I); - // Check for generic catch handler (match anything). - if (CatchS->getCaughtType().isNull()) - return true; - ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); - if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) { - *Builder = std::move(Result); - return true; - } - } - return false; -} - -AST_MATCHER(CXXNewExpr, mayThrow) { - FunctionDecl *OperatorNew = Node.getOperatorNew(); - if (!OperatorNew) - return false; - return !OperatorNew->getType()->castAs()->isNothrow(); -} - UnhandledExceptionAtNewCheck::UnhandledExceptionAtNewCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} @@ -52,11 +30,12 @@ void UnhandledExceptionAtNewCheck::registerMatchers(MatchFinder *Finder) { auto CatchBadAllocType = qualType(hasCanonicalType(anyOf(BadAllocType, BadAllocReferenceType, ExceptionType, ExceptionReferenceType))); - auto BadAllocCatchingTryBlock = cxxTryStmt(hasHandlerFor(CatchBadAllocType)); + auto BadAllocCatchingTryBlock = + cxxTryStmt(matchers::hasHandlerFor(CatchBadAllocType)); auto FunctionMayNotThrow = functionDecl(isNoThrow()); - Finder->addMatcher(cxxNewExpr(mayThrow(), + Finder->addMatcher(cxxNewExpr(matchers::mayThrow(), unless(hasAncestor(BadAllocCatchingTryBlock)), hasAncestor(FunctionMayNotThrow)) .bind("new-expr"), diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp index bebdce525e288..bd73a7cac3781 100644 --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "VirtualNearMissCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -17,8 +18,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { namespace { -AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } - AST_MATCHER(CXXMethodDecl, isOverloadedOperator) { return Node.isOverloadedOperator(); } @@ -216,8 +215,8 @@ void VirtualNearMissCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxMethodDecl( unless(anyOf(isOverride(), isImplicit(), cxxConstructorDecl(), - cxxDestructorDecl(), cxxConversionDecl(), isStatic(), - isOverloadedOperator()))) + cxxDestructorDecl(), cxxConversionDecl(), + matchers::isStaticMethod(), isOverloadedOperator()))) .bind("method"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp index 3923df312791d..d933c043da64f 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp @@ -20,7 +20,9 @@ using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { -const internal::VariadicDynCastAllOfMatcher VAArgExpr; +const clang::ast_matchers::internal::VariadicDynCastAllOfMatcher + VAArgExpr; static constexpr StringRef AllowedVariadics[] = { // clang-format off diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp index aa70b3896f16d..a93b603099b88 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp @@ -18,6 +18,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { +namespace { AST_MATCHER(CXXRecordDecl, hasPublicVirtualOrProtectedNonVirtualDestructor) { // We need to call Node.getDestructor() instead of matching a // CXXDestructorDecl. Otherwise, tests will fail for class templates, since @@ -33,6 +34,7 @@ AST_MATCHER(CXXRecordDecl, hasPublicVirtualOrProtectedNonVirtualDestructor) { !Destructor->isVirtual())); } +} // namespace void VirtualClassDestructorCheck::registerMatchers(MatchFinder *Finder) { ast_matchers::internal::Matcher InheritsVirtualMethod = hasAnyBase(hasType(cxxRecordDecl(has(cxxMethodDecl(isVirtual()))))); diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp index 805dcaf3ce402..c7590b5152324 100644 --- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp @@ -234,7 +234,7 @@ static bool isInInstantiation(const NodeType &Node, template static bool isInTemplate(const NodeType &Node, const MatchFinder::MatchResult &Result) { - internal::Matcher IsInsideTemplate = + ast_matchers::internal::Matcher IsInsideTemplate = hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl()))); return !match(IsInsideTemplate, Node, *Result.Context).empty(); } diff --git a/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h b/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h index 7d4120085b866..77d4bd0a25414 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h +++ b/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_NAMESPACE_CONSTANTS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_NAMESPACE_CONSTANTS_H + #include "llvm/ADT/StringRef.h" namespace clang::tidy::llvm_libc { @@ -14,3 +17,5 @@ const static llvm::StringRef RequiredNamespaceStart = "__llvm_libc"; const static llvm::StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE"; } // namespace clang::tidy::llvm_libc + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_NAMESPACE_CONSTANTS_H diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index 89790ea70cf22..517288930fa88 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -20,14 +20,6 @@ AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) { return Node.getBeginLoc().isValid(); } -AST_MATCHER_P(clang::TypeLoc, hasType, - clang::ast_matchers::internal::Matcher, - InnerMatcher) { - const clang::Type *TypeNode = Node.getTypePtr(); - return TypeNode != nullptr && - InnerMatcher.matches(*TypeNode, Finder, Builder); -} - AST_MATCHER(clang::RecordDecl, isExternCContext) { return Node.isExternCContext(); } @@ -59,7 +51,7 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { unless(parmVarDecl()))))); Finder->addMatcher( - typeLoc(hasValidBeginLoc(), hasType(arrayType()), + typeLoc(hasValidBeginLoc(), loc(arrayType()), unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())), hasParent(varDecl(isExternC())), hasParent(fieldDecl( diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index 3229e302eb432..9b05c3a7425c5 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -94,7 +94,7 @@ static StatementMatcher incrementVarMatcher() { } static StatementMatcher -arrayConditionMatcher(internal::Matcher LimitExpr) { +arrayConditionMatcher(ast_matchers::internal::Matcher LimitExpr) { return binaryOperator( anyOf(allOf(hasOperatorName("<"), hasLHS(integerComparisonMatcher()), hasRHS(LimitExpr)), @@ -209,7 +209,7 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { // This matcher tests that a declaration is a CXXRecordDecl that has an // overloaded operator*(). If the operator*() returns by value instead of by // reference then the return type is tagged with DerefByValueResultName. - internal::Matcher TestDerefReturnsByValue = + ast_matchers::internal::Matcher TestDerefReturnsByValue = hasType(hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(hasMethod(cxxMethodDecl( hasOverloadedOperatorName("*"), diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index aec67808846b1..dc8a87b8ae0fd 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "UseAutoCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/AST/TypeLoc.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -20,6 +21,7 @@ using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; namespace clang::tidy::modernize { + namespace { const char IteratorDeclStmtId[] = "iterator_decl"; @@ -155,14 +157,6 @@ Matcher hasStdContainerName() { return hasAnyName(ContainerNames); } -/// Matches declaration reference or member expressions with explicit template -/// arguments. -AST_POLYMORPHIC_MATCHER(hasExplicitTemplateArgs, - AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, - MemberExpr)) { - return Node.hasExplicitTemplateArgs(); -} - /// Returns a DeclarationMatcher that matches standard iterators nested /// inside records with a standard container name. DeclarationMatcher standardIterator() { @@ -238,9 +232,9 @@ StatementMatcher makeDeclWithTemplateCastMatcher() { auto ST = substTemplateTypeParmType(hasReplacementType(equalsBoundNode("arg"))); - auto ExplicitCall = - anyOf(has(memberExpr(hasExplicitTemplateArgs())), - has(ignoringImpCasts(declRefExpr(hasExplicitTemplateArgs())))); + auto ExplicitCall = anyOf( + has(memberExpr(matchers::hasExplicitTemplateArgs())), + has(ignoringImpCasts(declRefExpr(matchers::hasExplicitTemplateArgs())))); auto TemplateArg = hasTemplateArgument(0, refersToType(qualType().bind("arg"))); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 430455a38f395..c477e566c7878 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "UseEmplaceCheck.h" +#include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" + using namespace clang::ast_matchers; namespace clang::tidy::modernize { @@ -78,10 +80,6 @@ AST_MATCHER(CXXMemberCallExpr, hasSameNumArgsAsDeclNumParams) { return Node.getNumArgs() == Node.getMethodDecl()->getNumParams(); } -AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) { - return Node.hasExplicitTemplateArgs(); -} - // Helper Matcher which applies the given QualType Matcher either directly or by // resolving a pointer type to its pointee. Used to match v.push_back() as well // as p->push_back(). @@ -221,7 +219,7 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { auto MakeTuple = ignoringImplicit( callExpr(callee(expr(ignoringImplicit(declRefExpr( - unless(hasExplicitTemplateArgs()), + unless(matchers::hasExplicitTemplateArgs()), to(functionDecl(hasAnyName(TupleMakeFunctions)))))))) .bind("make")); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index 5134eb51a0322..406be8c66be76 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -48,8 +48,8 @@ static std::set getAllDirectBases(const CXXRecordDecl *Record) { /// Returns a matcher that matches member expressions where the base is /// the variable declared as \p Var and the accessed member is the one declared /// as \p Field. -internal::Matcher accessToFieldInVar(const FieldDecl *Field, - const ValueDecl *Var) { +ast_matchers::internal::Matcher accessToFieldInVar(const FieldDecl *Field, + const ValueDecl *Var) { return ignoringImpCasts( memberExpr(hasObjectExpression(declRefExpr(to(varDecl(equalsNode(Var))))), member(fieldDecl(equalsNode(Field))))); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp index 9561cc71183d9..9fdd60ead0404 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp @@ -16,6 +16,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::modernize { namespace { + AST_MATCHER(FunctionDecl, hasAnyDefinition) { if (Node.hasBody() || Node.isPureVirtual() || Node.isDefaulted() || Node.isDeleted()) @@ -41,9 +42,6 @@ AST_MATCHER(CXXMethodDecl, isSpecialFunction) { } } // namespace -static const char SpecialFunction[] = "SpecialFunction"; -static const char DeletedNotPublic[] = "DeletedNotPublic"; - UseEqualsDeleteCheck::UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -63,17 +61,17 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { // defined. unless(ofClass(hasMethod(cxxMethodDecl(unless(PrivateSpecialFn), unless(hasAnyDefinition())))))) - .bind(SpecialFunction), + .bind("SpecialFunction"), this); Finder->addMatcher( - cxxMethodDecl(isDeleted(), unless(isPublic())).bind(DeletedNotPublic), + cxxMethodDecl(isDeleted(), unless(isPublic())).bind("DeletedNotPublic"), this); } void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Func = - Result.Nodes.getNodeAs(SpecialFunction)) { + Result.Nodes.getNodeAs("SpecialFunction")) { SourceLocation EndLoc = Lexer::getLocForEndOfToken( Func->getEndLoc(), 0, *Result.SourceManager, getLangOpts()); @@ -84,7 +82,7 @@ void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) { "use '= delete' to prohibit calling of a special member function") << FixItHint::CreateInsertion(EndLoc, " = delete"); } else if (const auto *Func = - Result.Nodes.getNodeAs(DeletedNotPublic)) { + Result.Nodes.getNodeAs("DeletedNotPublic")) { // Ignore this warning in macros, since it's extremely noisy in code using // DISALLOW_COPY_AND_ASSIGN-style macros and there's no easy way to // automatically fix the warning when macros are in play. diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp index 2223a1999f736..225a1e7bedea4 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp @@ -62,7 +62,7 @@ void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) { this); } -static const StringRef Message = "prefer transparent functors '%0<>'"; +static const StringRef MessageDiag = "prefer transparent functors '%0<>'"; template static T getInnerTypeLocAs(TypeLoc Loc) { T Result; @@ -79,7 +79,7 @@ void UseTransparentFunctorsCheck::check( Result.Nodes.getNodeAs("FunctorClass"); if (const auto *FuncInst = Result.Nodes.getNodeAs("FuncInst")) { - diag(FuncInst->getBeginLoc(), Message) << FuncClass->getName(); + diag(FuncInst->getBeginLoc(), MessageDiag) << FuncClass->getName(); return; } @@ -117,9 +117,9 @@ void UseTransparentFunctorsCheck::check( SourceLocation ReportLoc = FunctorLoc.getLocation(); if (ReportLoc.isInvalid()) return; - diag(ReportLoc, Message) << FuncClass->getName() - << FixItHint::CreateRemoval( - FunctorTypeLoc.getArgLoc(0).getSourceRange()); + diag(ReportLoc, MessageDiag) + << FuncClass->getName() + << FixItHint::CreateRemoval(FunctorTypeLoc.getArgLoc(0).getSourceRange()); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp index 42f383edc67ed..103268caf32c8 100644 --- a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "MissingHashCheck.h" +#include "ObjcMatcher.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -16,12 +17,6 @@ namespace clang::tidy::objc { namespace { -AST_MATCHER_P(ObjCImplementationDecl, hasInterface, - ast_matchers::internal::Matcher, Base) { - const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface(); - return Base.matches(*InterfaceDecl, Finder, Builder); -} - AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod, ast_matchers::internal::Matcher, Base) { // Check each instance method against the provided matcher. diff --git a/clang-tools-extra/clang-tidy/objc/ObjcMatcher.h b/clang-tools-extra/clang-tidy/objc/ObjcMatcher.h new file mode 100644 index 0000000000000..f272b5b0f8a64 --- /dev/null +++ b/clang-tools-extra/clang-tidy/objc/ObjcMatcher.h @@ -0,0 +1,40 @@ +//===- AbseilMatcher.h - clang-tidy ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_OBJCMATCHER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_OBJCMATCHER_H + +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +namespace clang::ast_matchers { + +/// Matches Objective-C implementations with interfaces that match +/// \c Base. +/// +/// Example matches implementation declarations for X. +/// (matcher = objcImplementationDecl(hasInterface(hasName("X")))) +/// \code +/// @interface X +/// @end +/// @implementation X +/// @end +/// @interface Y +// @end +/// @implementation Y +/// @end +/// \endcode +AST_MATCHER_P(ObjCImplementationDecl, hasInterface, + ast_matchers::internal::Matcher, Base) { + const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface(); + return Base.matches(*InterfaceDecl, Finder, Builder); +} + +} // namespace clang::ast_matchers + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_OBJCMATCHER_H diff --git a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp index 951cbc52c9a99..572a1463e5c02 100644 --- a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "SuperSelfCheck.h" +#include "ObjcMatcher.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -32,27 +33,6 @@ AST_MATCHER(ObjCMethodDecl, isInitializer) { return Node.getMethodFamily() == OMF_init; } -/// Matches Objective-C implementations with interfaces that match -/// \c Base. -/// -/// Example matches implementation declarations for X. -/// (matcher = objcImplementationDecl(hasInterface(hasName("X")))) -/// \code -/// @interface X -/// @end -/// @implementation X -/// @end -/// @interface Y -// @end -/// @implementation Y -/// @end -/// \endcode -AST_MATCHER_P(ObjCImplementationDecl, hasInterface, - ast_matchers::internal::Matcher, Base) { - const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface(); - return Base.matches(*InterfaceDecl, Finder, Builder); -} - /// Matches Objective-C message expressions where the receiver is the /// super instance. /// diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp index 9beb185cba929..8c38bad593a37 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -232,7 +232,7 @@ UnnecessaryCopyInitialization::UnnecessaryCopyInitialization( Options.get("ExcludedContainerTypes", ""))) {} void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { - auto LocalVarCopiedFrom = [this](const internal::Matcher &CopyCtorArg) { + auto LocalVarCopiedFrom = [this](const auto &CopyCtorArg) { return compoundStmt( forEachDescendant( declStmt( diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp index 1284df6bd99cf..5b1bf0108cbb7 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ConvertMemberFunctionsToStatic.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -18,40 +19,12 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { -AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } - -AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } +namespace { AST_MATCHER(CXXMethodDecl, isOverloadedOperator) { return Node.isOverloadedOperator(); } -AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) { - return Node.hasAnyDependentBases(); -} - -AST_MATCHER(CXXMethodDecl, isTemplate) { - return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate; -} - -AST_MATCHER(CXXMethodDecl, isDependentContext) { - return Node.isDependentContext(); -} - -AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) { - const ASTContext &Ctxt = Finder->getASTContext(); - return clang::Lexer::makeFileCharRange( - clang::CharSourceRange::getCharRange( - Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()), - Ctxt.getSourceManager(), Ctxt.getLangOpts()) - .isInvalid(); -} - -AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, - ast_matchers::internal::Matcher, InnerMatcher) { - return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); -} - AST_MATCHER(CXXMethodDecl, usesThis) { class FindUsageOfThis : public RecursiveASTVisitor { public: @@ -74,22 +47,27 @@ AST_MATCHER(CXXMethodDecl, usesThis) { return UsageOfThis.Used; } +} // namespace + void ConvertMemberFunctionsToStatic::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxMethodDecl( isDefinition(), isUserProvided(), unless(anyOf( - isExpansionInSystemHeader(), isVirtual(), isStatic(), - hasTrivialBody(), isOverloadedOperator(), cxxConstructorDecl(), - cxxDestructorDecl(), cxxConversionDecl(), isTemplate(), - isDependentContext(), + isExpansionInSystemHeader(), isVirtual(), + matchers::isStaticMethod(), matchers::hasTrivialBody(), + isOverloadedOperator(), cxxConstructorDecl(), cxxDestructorDecl(), + cxxConversionDecl(), matchers::isTemplate(), + matchers::isDependentContext(), ofClass(anyOf( isLambda(), - hasAnyDependentBases()) // Method might become virtual - // depending on template base class. + matchers::hasAnyDependentBases()) // Method might become + // virtual depending on + // template base class. ), - isInsideMacroDefinition(), - hasCanonicalDecl(isInsideMacroDefinition()), usesThis()))) + matchers::isInsideMacroDefinition(), + matchers::hasCanonicalDecl(matchers::isInsideMacroDefinition()), + usesThis()))) .bind("x"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp index 759cdd44fd658..261c02ea2d53c 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp @@ -202,9 +202,9 @@ void CognitiveComplexity::account(SourceLocation Loc, unsigned short Nesting, Total += Increase; } -class FunctionASTVisitor final - : public RecursiveASTVisitor { - using Base = RecursiveASTVisitor; +class CognitiveComplexityFunctionASTVisitor final + : public RecursiveASTVisitor { + using Base = RecursiveASTVisitor; // If set to true, macros are ignored during analysis. const bool IgnoreMacros; @@ -219,7 +219,7 @@ class FunctionASTVisitor final std::stack> BinaryOperatorsStack; public: - explicit FunctionASTVisitor(const bool IgnoreMacros) + explicit CognitiveComplexityFunctionASTVisitor(const bool IgnoreMacros) : IgnoreMacros(IgnoreMacros) {} bool traverseStmtWithIncreasedNestingLevel(Stmt *Node) { @@ -453,12 +453,13 @@ class FunctionASTVisitor final // The parameter MainAnalyzedFunction is needed to differentiate between the // cases where TraverseDecl() is the entry point from // FunctionCognitiveComplexityCheck::check() and the cases where it was called - // from the FunctionASTVisitor itself. Explanation: if we get a function - // definition (e.g. constructor, destructor, method), the Cognitive Complexity - // specification states that the Nesting level shall be increased. But if this - // function is the entry point, then the Nesting level should not be - // increased. Thus that parameter is there and is used to fall-through - // directly to traversing if this is the main function that is being analyzed. + // from the CognitiveComplexityFunctionASTVisitor itself. Explanation: if we + // get a function definition (e.g. constructor, destructor, method), the + // Cognitive Complexity specification states that the Nesting level shall be + // increased. But if this function is the entry point, then the Nesting level + // should not be increased. Thus that parameter is there and is used to + // fall-through directly to traversing if this is the main function that is + // being analyzed. bool TraverseDecl(Decl *Node, bool MainAnalyzedFunction = false) { if (!Node || MainAnalyzedFunction) return Base::TraverseDecl(Node); @@ -515,7 +516,7 @@ void FunctionCognitiveComplexityCheck::registerMatchers(MatchFinder *Finder) { void FunctionCognitiveComplexityCheck::check( const MatchFinder::MatchResult &Result) { - FunctionASTVisitor Visitor(IgnoreMacros); + CognitiveComplexityFunctionASTVisitor Visitor(IgnoreMacros); SourceLocation Loc; const auto *TheDecl = Result.Nodes.getNodeAs("func"); diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index d42fcba70e81b..c828ef3bc78b4 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "MakeMemberFunctionConstCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -17,36 +18,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { -AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } - -AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } - -AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) { - return Node.hasAnyDependentBases(); -} - -AST_MATCHER(CXXMethodDecl, isTemplate) { - return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate; -} - -AST_MATCHER(CXXMethodDecl, isDependentContext) { - return Node.isDependentContext(); -} - -AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) { - const ASTContext &Ctxt = Finder->getASTContext(); - return clang::Lexer::makeFileCharRange( - clang::CharSourceRange::getCharRange( - Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()), - Ctxt.getSourceManager(), Ctxt.getLangOpts()) - .isInvalid(); -} - -AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, - ast_matchers::internal::Matcher, InnerMatcher) { - return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); -} - enum UsageKind { Unused, Const, NonConst }; class FindUsageOfThis : public RecursiveASTVisitor { @@ -205,6 +176,7 @@ class FindUsageOfThis : public RecursiveASTVisitor { } }; +namespace { AST_MATCHER(CXXMethodDecl, usesThisAsConst) { FindUsageOfThis UsageOfThis(Finder->getASTContext()); @@ -214,6 +186,8 @@ AST_MATCHER(CXXMethodDecl, usesThisAsConst) { return UsageOfThis.Usage == Const; } +} // namespace + void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( traverse( @@ -222,15 +196,18 @@ void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) { isDefinition(), isUserProvided(), unless(anyOf( isExpansionInSystemHeader(), isVirtual(), isConst(), - isStatic(), hasTrivialBody(), cxxConstructorDecl(), - cxxDestructorDecl(), isTemplate(), isDependentContext(), - ofClass(anyOf(isLambda(), - hasAnyDependentBases()) // Method might become + matchers::isStaticMethod(), matchers::hasTrivialBody(), + cxxConstructorDecl(), cxxDestructorDecl(), + matchers::isTemplate(), matchers::isDependentContext(), + ofClass(anyOf( + isLambda(), + matchers::hasAnyDependentBases()) // Method might become // virtual depending on // template base class. ), - isInsideMacroDefinition(), - hasCanonicalDecl(isInsideMacroDefinition()))), + matchers::isInsideMacroDefinition(), + matchers::hasCanonicalDecl( + matchers::isInsideMacroDefinition()))), usesThisAsConst()) .bind("x")), this); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp index 7850a6f29995f..bfd4dca11e947 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -15,10 +15,13 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { +namespace { AST_MATCHER(FunctionDecl, doesDeclarationForceExternallyVisibleDefinition) { return Node.doesDeclarationForceExternallyVisibleDefinition(); } +} // namespace + RedundantDeclarationCheck::RedundantDeclarationCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), diff --git a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp index 8837ac16e8828..86d3c7e860c9d 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp @@ -15,7 +15,8 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { namespace { -internal::Matcher callToGet(const internal::Matcher &OnClass) { +clang::ast_matchers::internal::Matcher +callToGet(const clang::ast_matchers::internal::Matcher &OnClass) { return expr( anyOf(cxxMemberCallExpr( on(expr(anyOf(hasType(OnClass), @@ -43,7 +44,7 @@ internal::Matcher callToGet(const internal::Matcher &OnClass) { .bind("redundant_get"); } -internal::Matcher knownSmartptr() { +clang::ast_matchers::internal::Matcher knownSmartptr() { return recordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr")); } diff --git a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp index 587ae8ea30580..9abe0f0e155ac 100644 --- a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp @@ -20,7 +20,8 @@ namespace { // Predicate structure to check if lifetime of temporary is not extended by // ValueDecl pointed out by ID struct NotExtendedByDeclBoundToPredicate { - bool operator()(const internal::BoundNodesMap &Nodes) const { + bool + operator()(const clang::ast_matchers::internal::BoundNodesMap &Nodes) const { const auto *Other = Nodes.getNodeAs(ID); if (!Other) return true; diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp index 65356cc3929c5..77b8f5e5ac216 100644 --- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "StaticAccessedThroughInstanceCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "llvm/ADT/StringRef.h" @@ -15,10 +16,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { -namespace { -AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } -} // namespace - static unsigned getNameSpecifierNestingLevel(const QualType &QType) { if (const auto *ElType = QType->getAs()) { if (const NestedNameSpecifier *NestedSpecifiers = ElType->getQualifier()) { @@ -42,7 +39,7 @@ void StaticAccessedThroughInstanceCheck::storeOptions( void StaticAccessedThroughInstanceCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStatic()), + memberExpr(hasDeclaration(anyOf(cxxMethodDecl(matchers::isStaticMethod()), varDecl(hasStaticStorageDuration()), enumConstantDecl()))) .bind("memberExpression"), diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp index df2b0bef576ca..8ee148a5bb392 100644 --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp @@ -285,4 +285,11 @@ SourceLocation getLocationForNoexceptSpecifier(const FunctionDecl *FuncDecl, return {}; } +bool insideMacroDefinition(SourceRange Range, const SourceManager &SM, + const LangOptions &LangOpts) { + return clang::Lexer::makeFileCharRange( + clang::CharSourceRange::getCharRange(Range), SM, LangOpts) + .isInvalid(); +} + } // namespace clang::tidy::utils::lexer diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.h b/clang-tools-extra/clang-tidy/utils/LexerUtils.h index ea9bd512b68b8..a697e7ee8adf1 100644 --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.h +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.h @@ -125,6 +125,11 @@ SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, SourceLocation getLocationForNoexceptSpecifier(const FunctionDecl *FuncDecl, const SourceManager &SM); +// Returns true if a part of the range resides inside a macro expansion or the +// range does not reside on the same FileID. +bool insideMacroDefinition(SourceRange Range, const SourceManager &SM, + const LangOptions &LangOpts); + } // namespace tidy::utils::lexer } // namespace clang diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h b/clang-tools-extra/clang-tidy/utils/Matchers.h index 045e3ffbb6a8b..dc47bb515e0ef 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.h +++ b/clang-tools-extra/clang-tidy/utils/Matchers.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H +#include "LexerUtils.h" #include "TypeTraits.h" #include "clang/AST/ExprConcepts.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -22,6 +23,10 @@ AST_MATCHER(BinaryOperator, isRelationalOperator) { AST_MATCHER(BinaryOperator, isEqualityOperator) { return Node.isEqualityOp(); } +AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) { + return Node.getValue().getZExtValue() > N; +} + AST_MATCHER(QualType, isExpensiveToCopy) { std::optional IsExpensive = utils::type_traits::isExpensiveToCopy(Node, Finder->getASTContext()); @@ -37,6 +42,67 @@ AST_MATCHER(QualType, isTriviallyDestructible) { return utils::type_traits::isTriviallyDestructible(Node); } +AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) { + return Node.hasAnyDependentBases(); +} + +AST_MATCHER(CXXMethodDecl, isStaticMethod) { return Node.isStatic(); } + +AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } + +AST_MATCHER(CXXMethodDecl, isTemplate) { + return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate; +} + +AST_MATCHER(CXXMethodDecl, isDependentContext) { + return Node.isDependentContext(); +} + +AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) { + const ASTContext &Ctxt = Finder->getASTContext(); + return utils::lexer::insideMacroDefinition( + Node.getTypeSourceInfo()->getTypeLoc().getSourceRange(), + Ctxt.getSourceManager(), Ctxt.getLangOpts()); +} + +AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, + ast_matchers::internal::Matcher, InnerMatcher) { + return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); +} + +AST_MATCHER(CXXNewExpr, mayThrow) { + FunctionDecl *OperatorNew = Node.getOperatorNew(); + if (!OperatorNew) + return false; + if (auto *FuncType = OperatorNew->getType()->getAs()) + return !FuncType->isNothrow(); + return false; +} + +AST_MATCHER_P(CXXTryStmt, hasHandlerFor, + ast_matchers::internal::Matcher, InnerMatcher) { + for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { + const CXXCatchStmt *CatchS = Node.getHandler(I); + // Check for generic catch handler (match anything). + if (CatchS->getCaughtType().isNull()) + return true; + ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); + if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) { + *Builder = std::move(Result); + return true; + } + } + return false; +} + +// Matches declaration reference or member expressions with explicit template +// arguments. +AST_POLYMORPHIC_MATCHER(hasExplicitTemplateArgs, + AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, + MemberExpr)) { + return Node.hasExplicitTemplateArgs(); +} + // Returns QualType matcher for references to const. AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isReferenceToConst) { using namespace ast_matchers; diff --git a/clang-tools-extra/clang-tidy/utils/NamespaceAliaser.cpp b/clang-tools-extra/clang-tidy/utils/NamespaceAliaser.cpp index 4703ce1269819..214f0fd43a621 100644 --- a/clang-tools-extra/clang-tidy/utils/NamespaceAliaser.cpp +++ b/clang-tools-extra/clang-tidy/utils/NamespaceAliaser.cpp @@ -13,18 +13,23 @@ #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Lex/Lexer.h" #include + namespace clang::tidy::utils { using namespace ast_matchers; -NamespaceAliaser::NamespaceAliaser(const SourceManager &SourceMgr) - : SourceMgr(SourceMgr) {} +namespace { AST_MATCHER_P(NamespaceAliasDecl, hasTargetNamespace, ast_matchers::internal::Matcher, innerMatcher) { return innerMatcher.matches(*Node.getNamespace(), Finder, Builder); } +} // namespace + +NamespaceAliaser::NamespaceAliaser(const SourceManager &SourceMgr) + : SourceMgr(SourceMgr) {} + std::optional NamespaceAliaser::createAlias(ASTContext &Context, const Stmt &Statement, StringRef Namespace,