Author: Piotr Zegar Date: 2024-03-31T14:58:27Z New Revision: b6f6be4b500ff64c23a5103ac3311cb74519542f
URL: https://github.com/llvm/llvm-project/commit/b6f6be4b500ff64c23a5103ac3311cb74519542f DIFF: https://github.com/llvm/llvm-project/commit/b6f6be4b500ff64c23a5103ac3311cb74519542f.diff LOG: [clang-tidy][NFC] Remove duplicated code Remove duplicated matchers by moving some of them to utils/Matchers.h. Add some anonymous namespaces and renamed some code to avoid ODR issues. Added: clang-tools-extra/clang-tidy/objc/ObjcMatcher.h Modified: clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp clang-tools-extra/clang-tidy/utils/LexerUtils.cpp clang-tools-extra/clang-tidy/utils/LexerUtils.h clang-tools-extra/clang-tidy/utils/Matchers.h clang-tools-extra/clang-tidy/utils/NamespaceAliaser.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h index 1eef86ddc00b95..b20d1b1fa7e32f 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 <algorithm> @@ -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 6cb687de4dc86e..448bb4b7e1f941 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<CallExpr>("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 28b2f81fdc8c84..687171e4c782d9 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<std::string> makeRewriteRule(ArrayRef<StringRef> 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 a2171aad32b739..ecf9a2293c9a8c 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<BinaryOperator>("binop"); std::string InverseName = Result.Nodes.getNodeAs<FunctionDecl>("func_decl")->getNameAsString(); - if (insideMacroDefinition(Result, BinOp->getSourceRange())) + if (tidy::utils::lexer::insideMacroDefinition(BinOp->getSourceRange(), + *Result.SourceManager, + Result.Context->getLangOpts())) return; std::optional<DurationScale> Scale = getScaleForTimeInverse(InverseName); @@ -139,7 +133,9 @@ void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) { const auto *OuterCall = Result.Nodes.getNodeAs<CallExpr>("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 8e27e8e3e0c2be..323d966711ddcf 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<Stmt> 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 8c13ce5a90e9b5..939c311b56b351 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<unsigned> { + [this](Preprocessor::macro_iterator It) -> std::optional<unsigned> { 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 f21b8c09eb0c6d..17580e744be9dc 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<unsigned> 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 93f35cb2c1a3d7..2c56a39bbeb104 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 84e99c7fafc74b..6e7c017aca893d 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 ff5b885aa95f81..3c64479249a970 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 9b3b01eb026833..d6645a0e91c172 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 e329588290cd4b..b91c585489c78a 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<Stmt> -loopEndingStmt(internal::Matcher<Stmt> Internal) { - internal::Matcher<QualType> isNoReturnFunType = +static ast_matchers::internal::Matcher<Stmt> +loopEndingStmt(ast_matchers::internal::Matcher<Stmt> Internal) { + ast_matchers::internal::Matcher<QualType> isNoReturnFunType = ignoringParens(functionType(typeHasNoReturnAttr())); - internal::Matcher<Decl> isNoReturnDecl = + ast_matchers::internal::Matcher<Decl> 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 41191a3cfed23a..becfdc5ee6e977 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<QualType>, 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<FunctionProtoType>()->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 de05cc0e4f7fb5..5746a1f3b358d2 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<SourceRange>; /// \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 902490f4d33c13..93412c213bbdf0 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 a1cffbc6661992..77cc9f39d302e3 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<Expr>, 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<DependentSizedArrayType>(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 8ae4351ac2830a..11d105e23fca4a 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<StringRef> @@ -36,8 +32,6 @@ removeNamespaces(const std::vector<StringRef> &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 b160e7259905ba..155dced4a136c5 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<QualType>, 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<FunctionProtoType>()->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 bebdce525e2887..bd73a7cac3781c 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 3923df312791db..d933c043da64fa 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<Stmt, VAArgExpr> VAArgExpr; +const clang::ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt, + VAArgExpr> + 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 aa70b3896f16dd..a93b603099b88c 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<CXXRecordDecl> 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 805dcaf3ce4025..c7590b51523245 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 <typename NodeType> static bool isInTemplate(const NodeType &Node, const MatchFinder::MatchResult &Result) { - internal::Matcher<NodeType> IsInsideTemplate = + ast_matchers::internal::Matcher<NodeType> 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 7d4120085b8667..77d4bd0a254141 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 89790ea70cf229..517288930fa88e 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<clang::Type>, - 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 3229e302eb4322..9b05c3a7425c50 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<Expr> LimitExpr) { +arrayConditionMatcher(ast_matchers::internal::Matcher<Expr> 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<VarDecl> TestDerefReturnsByValue = + ast_matchers::internal::Matcher<VarDecl> 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 aec67808846b12..dc8a87b8ae0fdf 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<NamedDecl> 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 430455a38f395e..c477e566c78782 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 5134eb51a03226..406be8c66be764 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<const Type *> 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<Expr> accessToFieldInVar(const FieldDecl *Field, - const ValueDecl *Var) { +ast_matchers::internal::Matcher<Expr> 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 9561cc71183d97..9fdd60ead04042 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<CXXMethodDecl>(SpecialFunction)) { + Result.Nodes.getNodeAs<CXXMethodDecl>("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<CXXMethodDecl>(DeletedNotPublic)) { + Result.Nodes.getNodeAs<CXXMethodDecl>("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 2223a1999f736b..225a1e7bedea43 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 <typename T> static T getInnerTypeLocAs(TypeLoc Loc) { T Result; @@ -79,7 +79,7 @@ void UseTransparentFunctorsCheck::check( Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("FunctorClass"); if (const auto *FuncInst = Result.Nodes.getNodeAs<CXXConstructExpr>("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 42f383edc67eda..103268caf32c8e 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<ObjCInterfaceDecl>, Base) { - const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface(); - return Base.matches(*InterfaceDecl, Finder, Builder); -} - AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod, ast_matchers::internal::Matcher<ObjCMethodDecl>, 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 00000000000000..f272b5b0f8a648 --- /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<ObjCInterfaceDecl>, 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 951cbc52c9a994..572a1463e5c02d 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<ObjCInterfaceDecl>, 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 9beb185cba929d..8c38bad593a376 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<Expr> &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 1284df6bd99cfd..5b1bf0108cbb79 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<CXXMethodDecl>, InnerMatcher) { - return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); -} - AST_MATCHER(CXXMethodDecl, usesThis) { class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { 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 759cdd44fd6581..261c02ea2d53c9 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<FunctionASTVisitor> { - using Base = RecursiveASTVisitor<FunctionASTVisitor>; +class CognitiveComplexityFunctionASTVisitor final + : public RecursiveASTVisitor<CognitiveComplexityFunctionASTVisitor> { + using Base = RecursiveASTVisitor<CognitiveComplexityFunctionASTVisitor>; // If set to true, macros are ignored during analysis. const bool IgnoreMacros; @@ -219,7 +219,7 @@ class FunctionASTVisitor final std::stack<OBO, SmallVector<OBO, 4>> 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 diff erentiate 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<FunctionDecl>("func"); diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index d42fcba70e81b4..c828ef3bc78b4d 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<CXXMethodDecl>, InnerMatcher) { - return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); -} - enum UsageKind { Unused, Const, NonConst }; class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { @@ -205,6 +176,7 @@ class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { } }; +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 7850a6f29995f6..bfd4dca11e947a 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 8837ac16e88281..86d3c7e860c9d4 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<Expr> callToGet(const internal::Matcher<Decl> &OnClass) { +clang::ast_matchers::internal::Matcher<Expr> +callToGet(const clang::ast_matchers::internal::Matcher<Decl> &OnClass) { return expr( anyOf(cxxMemberCallExpr( on(expr(anyOf(hasType(OnClass), @@ -43,7 +44,7 @@ internal::Matcher<Expr> callToGet(const internal::Matcher<Decl> &OnClass) { .bind("redundant_get"); } -internal::Matcher<Decl> knownSmartptr() { +clang::ast_matchers::internal::Matcher<Decl> 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 587ae8ea305802..9abe0f0e155ace 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<ValueDecl>(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 65356cc3929c54..77b8f5e5ac2169 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<ElaboratedType>()) { 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 df2b0bef576ca3..8ee148a5bb3922 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 ea9bd512b68b8f..a697e7ee8adf11 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 045e3ffbb6a8b4..dc47bb515e0ef1 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<bool> 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<CXXMethodDecl>, 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<FunctionProtoType>()) + return !FuncType->isNothrow(); + return false; +} + +AST_MATCHER_P(CXXTryStmt, hasHandlerFor, + ast_matchers::internal::Matcher<QualType>, 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 4703ce12698190..214f0fd43a621b 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 <optional> + 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<NamespaceDecl>, innerMatcher) { return innerMatcher.matches(*Node.getNamespace(), Finder, Builder); } +} // namespace + +NamespaceAliaser::NamespaceAliaser(const SourceManager &SourceMgr) + : SourceMgr(SourceMgr) {} + std::optional<FixItHint> NamespaceAliaser::createAlias(ASTContext &Context, const Stmt &Statement, StringRef Namespace, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits