diff --git a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp index 869a0ec44556c8..03c69f1f92dbbc 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -20,7 +20,7 @@ namespace clang::tidy::abseil { void DurationConversionCastCheck::registerMatchers(MatchFinder *Finder) { auto CallMatcher = ignoringImpCasts(callExpr( callee(functionDecl(DurationConversionFunction()).bind("func_decl")), - hasArgument(0, expr().bind("arg")))); + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))))); Finder->addMatcher( expr(anyOf( diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp index 50e2d0366c768d..a0b1ffb6cd8660 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp @@ -22,9 +22,10 @@ void DurationDivisionCheck::registerMatchers(MatchFinder *Finder) { traverse(TK_AsIs, implicitCastExpr( hasSourceExpression(ignoringParenCasts( - cxxOperatorCallExpr(hasOverloadedOperatorName("/"), - hasArgument(0, DurationExpr), - hasArgument(1, DurationExpr)) + cxxOperatorCallExpr( + hasOverloadedOperatorName("/"), + hasArgument(0, ignoringParenImpCasts(DurationExpr)), + hasArgument(1, ignoringParenImpCasts(DurationExpr))) .bind("OpCall"))), hasImplicitDestinationType(qualType(unless(isInteger()))), unless(hasParent(cxxStaticCastExpr())), diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index 6cb687de4dc86e..7a28bf569363fe 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -30,13 +30,14 @@ static bool insideMacroDefinition(const MatchFinder::MatchResult &Result, void DurationFactoryFloatCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr(callee(functionDecl(DurationFactoryFunction())), - hasArgument(0, anyOf(cxxStaticCastExpr(hasDestinationType( - realFloatingPointType())), - cStyleCastExpr(hasDestinationType( - realFloatingPointType())), - cxxFunctionalCastExpr(hasDestinationType( - realFloatingPointType())), - floatLiteral()))) + hasArgument(0, ignoringParenImpCasts(anyOf( + cxxStaticCastExpr(hasDestinationType( + realFloatingPointType())), + cStyleCastExpr(hasDestinationType( + realFloatingPointType())), + cxxFunctionalCastExpr(hasDestinationType( + realFloatingPointType())), + floatLiteral())))) .bind("call"), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp index 3d807c1d0f7aa2..8ab953acfec977 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp @@ -75,10 +75,11 @@ rewriteInverseDurationCall(const MatchFinder::MatchResult &Result, getDurationInverseForScale(Scale); if (const auto *MaybeCallArg = selectFirst( "e", - match(callExpr(callee(functionDecl(hasAnyName( - InverseFunctions.first, InverseFunctions.second))), - hasArgument(0, expr().bind("e"))), - Node, *Result.Context))) { + match( + callExpr(callee(functionDecl(hasAnyName( + InverseFunctions.first, InverseFunctions.second))), + hasArgument(0, ignoringParenImpCasts(expr().bind("e")))), + Node, *Result.Context))) { return tooling::fixit::getText(*MaybeCallArg, *Result.Context).str(); } @@ -93,7 +94,8 @@ rewriteInverseTimeCall(const MatchFinder::MatchResult &Result, llvm::StringRef InverseFunction = getTimeInverseForScale(Scale); if (const auto *MaybeCallArg = selectFirst( "e", match(callExpr(callee(functionDecl(hasName(InverseFunction))), - hasArgument(0, expr().bind("e"))), + hasArgument( + 0, ignoringParenImpCasts(expr().bind("e")))), Node, *Result.Context))) { return tooling::fixit::getText(*MaybeCallArg, *Result.Context).str(); } diff --git a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp index 48600298a20ca3..61d4a23c317cee 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp @@ -21,9 +21,10 @@ void DurationSubtractionCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( binaryOperator( hasOperatorName("-"), - hasLHS(callExpr(callee(functionDecl(DurationConversionFunction()) - .bind("function_decl")), - hasArgument(0, expr().bind("lhs_arg"))))) + hasLHS(callExpr( + callee(functionDecl(DurationConversionFunction()) + .bind("function_decl")), + hasArgument(0, ignoringParenImpCasts(expr().bind("lhs_arg")))))) .bind("binop"), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp index 9bb1fd57a44010..8dbcd88e0977f5 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp @@ -36,19 +36,21 @@ void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) { // e.g. `absl::ToDoubleSeconds(dur)`. auto InverseFunctionMatcher = callExpr( callee(functionDecl(hasAnyName(FloatConversion, IntegerConversion))), - hasArgument(0, expr().bind("arg"))); + hasArgument(0, ignoringParenImpCasts(expr().bind("arg")))); // Matcher which matches a duration divided by the factory_matcher above, // e.g. `dur / absl::Seconds(1)`. auto DivisionOperatorMatcher = cxxOperatorCallExpr( - hasOverloadedOperatorName("/"), hasArgument(0, expr().bind("arg")), - hasArgument(1, FactoryMatcher)); + hasOverloadedOperatorName("/"), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))), + hasArgument(1, ignoringParenImpCasts(FactoryMatcher))); // Matcher which matches a duration argument to `FDivDuration`, // e.g. `absl::FDivDuration(dur, absl::Seconds(1))` - auto FdivMatcher = callExpr( - callee(functionDecl(hasName("::absl::FDivDuration"))), - hasArgument(0, expr().bind("arg")), hasArgument(1, FactoryMatcher)); + auto FdivMatcher = + callExpr(callee(functionDecl(hasName("::absl::FDivDuration"))), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))), + hasArgument(1, ignoringParenImpCasts(FactoryMatcher))); // Matcher which matches a duration argument being scaled, // e.g. `absl::ToDoubleSeconds(dur) * 2` @@ -57,15 +59,17 @@ void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) { hasEitherOperand(expr(ignoringParenImpCasts( callExpr(callee(functionDecl(hasAnyName( FloatConversion, IntegerConversion))), - hasArgument(0, expr().bind("arg"))) + hasArgument(0, ignoringParenImpCasts( + expr().bind("arg")))) .bind("inner_call"))))) .bind("binop")); Finder->addMatcher( - callExpr(callee(functionDecl(hasName(DurationFactory))), - hasArgument(0, anyOf(InverseFunctionMatcher, - DivisionOperatorMatcher, FdivMatcher, - ScalarMatcher))) + callExpr( + callee(functionDecl(hasName(DurationFactory))), + hasArgument(0, ignoringParenImpCasts(anyOf( + InverseFunctionMatcher, DivisionOperatorMatcher, + FdivMatcher, ScalarMatcher)))) .bind("call"), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp index 4a6f17ed5f8689..69912e6a06e531 100644 --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp @@ -72,7 +72,7 @@ void FasterStrsplitDelimiterCheck::registerMatchers(MatchFinder *Finder) { expr(has(ignoringElidableConstructorCall( ignoringParenCasts(cxxBindTemporaryExpr(has(cxxConstructExpr( hasType(recordDecl(hasName("::absl::ByAnyChar"))), - hasArgument(0, StringViewArg)))))))) + hasArgument(0, ignoringParenImpCasts(StringViewArg))))))))) .bind("ByAnyChar"); // Find uses of absl::StrSplit(..., "x") and absl::StrSplit(..., @@ -80,7 +80,8 @@ void FasterStrsplitDelimiterCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( traverse(TK_AsIs, callExpr(callee(functionDecl(hasName("::absl::StrSplit"))), - hasArgument(1, anyOf(ByAnyCharArg, SingleChar)), + hasArgument(1, ignoringParenImpCasts( + anyOf(ByAnyCharArg, SingleChar))), unless(isInTemplateInstantiation())) .bind("StrSplit")), this); @@ -91,8 +92,9 @@ void FasterStrsplitDelimiterCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( traverse(TK_AsIs, callExpr(callee(functionDecl(hasName("::absl::MaxSplits"))), - hasArgument(0, anyOf(ByAnyCharArg, - ignoringParenCasts(SingleChar))), + hasArgument(0, ignoringParenImpCasts(anyOf( + ByAnyCharArg, + ignoringParenCasts(SingleChar)))), unless(isInTemplateInstantiation()))), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp index fafb029e7de1b4..1e1100dc0bdb5e 100644 --- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp @@ -22,7 +22,7 @@ namespace clang::tidy::abseil { // - Make it work in macros if the outer and inner StrCats are both in the // argument. -void RedundantStrcatCallsCheck::registerMatchers(MatchFinder* Finder) { +void RedundantStrcatCallsCheck::registerMatchers(MatchFinder *Finder) { const auto CallToStrcat = callExpr(callee(functionDecl(hasName("::absl::StrCat")))); const auto CallToStrappend = @@ -61,15 +61,17 @@ const clang::CallExpr *processArgument(const Expr *Arg, const MatchFinder::MatchResult &Result, StrCatCheckResult *CheckResult) { const auto IsAlphanum = hasDeclaration(cxxMethodDecl(hasName("AlphaNum"))); - static const auto* const Strcat = new auto(hasName("::absl::StrCat")); + static const auto *const Strcat = new auto(hasName("::absl::StrCat")); const auto IsStrcat = cxxBindTemporaryExpr( has(callExpr(callee(functionDecl(*Strcat))).bind("StrCat"))); if (const auto *SubStrcatCall = selectFirst( "StrCat", - match(stmt(traverse(TK_AsIs, - anyOf(cxxConstructExpr(IsAlphanum, - hasArgument(0, IsStrcat)), - IsStrcat))), + match(stmt(traverse( + TK_AsIs, + anyOf(cxxConstructExpr( + IsAlphanum, + hasArgument(0, ignoringParenImpCasts(IsStrcat))), + IsStrcat))), *Arg->IgnoreParenImpCasts(), *Result.Context))) { removeCallLeaveArgs(SubStrcatCall, CheckResult); return SubStrcatCall; @@ -80,18 +82,18 @@ const clang::CallExpr *processArgument(const Expr *Arg, StrCatCheckResult processCall(const CallExpr *RootCall, bool IsAppend, const MatchFinder::MatchResult &Result) { StrCatCheckResult CheckResult; - std::deque CallsToProcess = {RootCall}; + std::deque CallsToProcess = {RootCall}; while (!CallsToProcess.empty()) { ++CheckResult.NumCalls; - const CallExpr* CallExpr = CallsToProcess.front(); + const CallExpr *CallExpr = CallsToProcess.front(); CallsToProcess.pop_front(); int StartArg = CallExpr == RootCall && IsAppend; for (const auto *Arg : CallExpr->arguments()) { - if (StartArg-- > 0) - continue; + if (StartArg-- > 0) + continue; if (const clang::CallExpr *Sub = processArgument(Arg, Result, &CheckResult)) { CallsToProcess.push_back(Sub); @@ -100,18 +102,18 @@ StrCatCheckResult processCall(const CallExpr *RootCall, bool IsAppend, } return CheckResult; } -} // namespace +} // namespace -void RedundantStrcatCallsCheck::check(const MatchFinder::MatchResult& Result) { +void RedundantStrcatCallsCheck::check(const MatchFinder::MatchResult &Result) { bool IsAppend = false; const CallExpr *RootCall = nullptr; - if ((RootCall = Result.Nodes.getNodeAs("StrCat"))) - IsAppend = false; - else if ((RootCall = Result.Nodes.getNodeAs("StrAppend"))) - IsAppend = true; - else - return; + if ((RootCall = Result.Nodes.getNodeAs("StrCat"))) + IsAppend = false; + else if ((RootCall = Result.Nodes.getNodeAs("StrAppend"))) + IsAppend = true; + else + return; if (RootCall->getBeginLoc().isMacroID()) { // Ignore calls within macros. @@ -127,8 +129,8 @@ void RedundantStrcatCallsCheck::check(const MatchFinder::MatchResult& Result) { return; } - diag(RootCall->getBeginLoc(), - "multiple calls to 'absl::StrCat' can be flattened into a single call") + diag(RootCall->getBeginLoc(), + "multiple calls to 'absl::StrCat' can be flattened into a single call") << CheckResult.Hints; } diff --git a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp index ab6ed701e59fee..765f61668a746a 100644 --- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp @@ -34,15 +34,15 @@ AST_MATCHER_P(Stmt, IgnoringTemporaries, ast_matchers::internal::Matcher, return InnerMatcher.matches(*E, Finder, Builder); } -} // namespace +} // namespace // TODO: str += StrCat(...) // str.append(StrCat(...)) void StrCatAppendCheck::registerMatchers(MatchFinder *Finder) { const auto StrCat = functionDecl(hasName("::absl::StrCat")); - // The arguments of absl::StrCat are implicitly converted to AlphaNum. This - // matches to the arguments because of that behavior. + // The arguments of absl::StrCat are implicitly converted to AlphaNum. This + // matches to the arguments because of that behavior. const auto AlphaNum = IgnoringTemporaries(cxxConstructExpr( argumentCountIs(1), hasType(cxxRecordDecl(hasName("::absl::AlphaNum"))), hasArgument(0, ignoringImpCasts(declRefExpr(to(equalsBoundNode("LHS")), @@ -56,24 +56,28 @@ void StrCatAppendCheck::registerMatchers(MatchFinder *Finder) { // StrCat on the RHS. The first argument of the StrCat call should be the same // as the LHS. Ignore calls from template instantiations. Finder->addMatcher( - traverse(TK_AsIs, - cxxOperatorCallExpr( - unless(isInTemplateInstantiation()), - hasOverloadedOperatorName("="), - hasArgument(0, declRefExpr(to(decl().bind("LHS")))), - hasArgument( - 1, IgnoringTemporaries( - callExpr(callee(StrCat), hasArgument(0, AlphaNum), - unless(HasAnotherReferenceToLhs)) - .bind("Call")))) - .bind("Op")), + traverse( + TK_AsIs, + cxxOperatorCallExpr( + unless(isInTemplateInstantiation()), + hasOverloadedOperatorName("="), + hasArgument(0, ignoringParenImpCasts( + declRefExpr(to(decl().bind("LHS"))))), + hasArgument(1, IgnoringTemporaries( + callExpr(callee(StrCat), + hasArgument(0, ignoringParenImpCasts( + AlphaNum)), + unless(HasAnotherReferenceToLhs)) + .bind("Call")))) + .bind("Op")), this); } void StrCatAppendCheck::check(const MatchFinder::MatchResult &Result) { const auto *Op = Result.Nodes.getNodeAs("Op"); const auto *Call = Result.Nodes.getNodeAs("Call"); - assert(Op != nullptr && Call != nullptr && "Matcher does not work as expected"); + assert(Op != nullptr && Call != nullptr && + "Matcher does not work as expected"); // Handles the case 'x = absl::StrCat(x)', which has no effect. if (Call->getNumArgs() == 1) { diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp index 221e924c10f621..ebf32d8f4f3ec8 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp @@ -44,9 +44,10 @@ void StringFindStartswithCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(hasName("find")).bind("findfun")), on(hasType(StringType)), // ... with some search expression ... - hasArgument(0, expr().bind("needle")), + hasArgument(0, expr().ignoringParenImpCasts().bind("needle")), // ... and either "0" as second argument or the default argument (also 0). - anyOf(hasArgument(1, ZeroLiteral), hasArgument(1, cxxDefaultArgExpr()))); + anyOf(hasArgument(1, ignoringParenImpCasts(ZeroLiteral)), + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr())))); Finder->addMatcher( // Match [=!]= with a zero on one side and a string.find on the other. @@ -62,9 +63,9 @@ void StringFindStartswithCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(hasName("rfind")).bind("findfun")), on(hasType(StringType)), // ... with some search expression ... - hasArgument(0, expr().bind("needle")), + hasArgument(0, expr().ignoringParenImpCasts().bind("needle")), // ... and "0" as second argument. - hasArgument(1, ZeroLiteral)); + hasArgument(1, ignoringParenImpCasts(ZeroLiteral))); Finder->addMatcher( // Match [=!]= with either a zero or npos on one side and a string.rfind diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index 28b2f81fdc8c84..bab6ff7bfedd53 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -54,9 +54,10 @@ makeRewriteRule(ArrayRef StringLikeClassNames, hasParameter( 0, parmVarDecl(anyOf(hasType(StringType), hasType(CharStarType), hasType(CharType)))))), - on(hasType(StringType)), hasArgument(0, expr().bind("parameter_to_find")), - anyOf(hasArgument(1, integerLiteral(equals(0))), - hasArgument(1, cxxDefaultArgExpr())), + on(hasType(StringType)), + hasArgument(0, ignoringParenImpCasts(expr().bind("parameter_to_find"))), + anyOf(hasArgument(1, ignoringParenImpCasts(integerLiteral(equals(0)))), + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr()))), onImplicitObjectArgument(expr().bind("string_being_searched"))); RewriteRuleWith Rule = applyFirst( diff --git a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp index a2171aad32b739..91041e174179da 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp @@ -110,8 +110,9 @@ void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) { auto CallMatcher = callExpr( callee(functionDecl(hasName(getDurationFactoryForScale(*Scale)))), - hasArgument(0, binaryOperator(hasOperatorName("-"), - hasLHS(TimeInverseMatcher)) + hasArgument(0, ignoringParenImpCasts( + binaryOperator(hasOperatorName("-"), + hasLHS(TimeInverseMatcher))) .bind("binop"))) .bind("outer_call"); Finder->addMatcher(CallMatcher, this); diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index 8e27e8e3e0c2be..26da027bef07aa 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -30,9 +30,9 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxOperatorCallExpr( argumentCountIs(2), - hasArgument( - 0, expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))))), - hasArgument(1, expr().bind("arg")), + hasArgument(0, ignoringParenImpCasts(expr(hasType( + cxxRecordDecl(hasName("::absl::Duration")))))), + hasArgument(1, ignoringParenImpCasts(expr().bind("arg"))), callee(functionDecl( hasParent(functionTemplateDecl()), unless(hasTemplateArgument(0, refersToType(builtinType()))), @@ -49,7 +49,8 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { hasParent(functionTemplateDecl()), unless(hasTemplateArgument(0, refersToType(builtinType()))), hasAnyName("operator*=", "operator/="))), - argumentCountIs(1), hasArgument(0, expr().bind("arg"))) + argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg")))) .bind("OuterExpr"), this); @@ -62,9 +63,9 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { unless(hasTemplateArgument(0, refersToType(builtinType()))), hasAnyName("::absl::operator*", "::absl::operator/"))), argumentCountIs(2), - hasArgument(0, expr(hasType( - cxxRecordDecl(hasName("::absl::Duration"))))), - hasArgument(1, expr().bind("arg"))) + hasArgument(0, ignoringParenImpCasts(expr(hasType(cxxRecordDecl( + hasName("::absl::Duration")))))), + hasArgument(1, ignoringParenImpCasts(expr().bind("arg")))) .bind("OuterExpr"), this); @@ -75,9 +76,10 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { hasParent(functionTemplateDecl()), unless(hasTemplateArgument(0, refersToType(builtinType()))), hasName("::absl::operator*"))), - argumentCountIs(2), hasArgument(0, expr().bind("arg")), - hasArgument(1, expr(hasType( - cxxRecordDecl(hasName("::absl::Duration")))))) + argumentCountIs(2), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))), + hasArgument(1, ignoringParenImpCasts(expr(hasType(cxxRecordDecl( + hasName("::absl::Duration"))))))) .bind("OuterExpr"), this); @@ -98,16 +100,18 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { // `absl::Hours(x)` // where `x` is not of a built-in type. Finder->addMatcher( - traverse(TK_AsIs, implicitCastExpr( - anyOf(hasCastKind(CK_UserDefinedConversion), - has(implicitCastExpr( - hasCastKind(CK_UserDefinedConversion)))), - hasParent(callExpr( - callee(functionDecl( - DurationFactoryFunction(), - unless(hasParent(functionTemplateDecl())))), - hasArgument(0, expr().bind("arg"))))) - .bind("OuterExpr")), + traverse( + TK_AsIs, + implicitCastExpr( + anyOf( + hasCastKind(CK_UserDefinedConversion), + has(implicitCastExpr(hasCastKind(CK_UserDefinedConversion)))), + hasParent(callExpr( + callee( + functionDecl(DurationFactoryFunction(), + unless(hasParent(functionTemplateDecl())))), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg")))))) + .bind("OuterExpr")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp index 8c13ce5a90e9b5..1d70e70c7772e1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp @@ -20,7 +20,8 @@ void BadSignalToKillThreadCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr(callee(functionDecl(hasName("::pthread_kill"))), argumentCountIs(2), - hasArgument(1, integerLiteral().bind("integer-literal"))) + hasArgument(1, ignoringParenImpCasts( + integerLiteral().bind("integer-literal")))) .bind("thread-kill"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp index d55df3a6d7b741..72517cbbcbd716 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -24,7 +24,7 @@ handleFrom(const ast_matchers::internal::Matcher &IsAHandle, const ast_matchers::internal::Matcher &Arg) { return expr( anyOf(cxxConstructExpr(hasDeclaration(cxxMethodDecl(ofClass(IsAHandle))), - hasArgument(0, Arg)), + hasArgument(0, ignoringParenImpCasts(Arg))), cxxMemberCallExpr(hasType(hasUnqualifiedDesugaredType(recordType( hasDeclaration(cxxRecordDecl(IsAHandle))))), callee(memberExpr(member(cxxConversionDecl()))), @@ -123,9 +123,10 @@ void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) { // Find 'foo = ReturnsAValue(); // foo is Handle' Finder->addMatcher( traverse(TK_AsIs, - cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(IsAHandle))), - hasOverloadedOperatorName("="), - hasArgument(1, ConvertedHandle)) + cxxOperatorCallExpr( + callee(cxxMethodDecl(ofClass(IsAHandle))), + hasOverloadedOperatorName("="), + hasArgument(1, ignoringParenImpCasts(ConvertedHandle))) .bind("bad_stmt")), this); diff --git a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp index 164de76d4fa467..29869101e8dc1d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp @@ -20,8 +20,9 @@ void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) { callExpr( callee(functionDecl(hasAnyName("remove", "remove_if", "unique"))), hasArgument( - 1, optionally(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("end")))) - .bind("end")))) + 1, ignoringParenImpCasts(optionally( + cxxMemberCallExpr(callee(cxxMethodDecl(hasName("end")))) + .bind("end"))))) .bind("alg"); const auto DeclInStd = type(hasUnqualifiedDesugaredType( @@ -30,16 +31,14 @@ void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) { cxxMemberCallExpr( on(anyOf(hasType(DeclInStd), hasType(pointsTo(DeclInStd)))), callee(cxxMethodDecl(hasName("erase"))), argumentCountIs(1), - hasArgument(0, EndCall)) + hasArgument(0, ignoringParenImpCasts(EndCall))) .bind("erase"), this); } void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) { - const auto *MemberCall = - Result.Nodes.getNodeAs("erase"); - const auto *EndExpr = - Result.Nodes.getNodeAs("end"); + const auto *MemberCall = Result.Nodes.getNodeAs("erase"); + const auto *EndExpr = Result.Nodes.getNodeAs("end"); const SourceLocation Loc = MemberCall->getBeginLoc(); FixItHint Hint; diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp index 40e4ab6c8b12af..fad3ae9db3f17f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp @@ -54,12 +54,12 @@ void MisplacedOperatorInStrlenInAllocCheck::registerMatchers( Finder->addMatcher( traverse(TK_AsIs, callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))), - hasArgument(0, BadArg)) + hasArgument(0, ignoringParenImpCasts(BadArg))) .bind("Alloc")), this); Finder->addMatcher( traverse(TK_AsIs, callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))), - hasArgument(1, BadArg)) + hasArgument(1, ignoringParenImpCasts(BadArg))) .bind("Alloc")), this); Finder->addMatcher( @@ -74,7 +74,7 @@ void MisplacedOperatorInStrlenInAllocCheck::check( if (!Alloc) Alloc = Result.Nodes.getNodeAs("Alloc"); assert(Alloc && "Matched node bound by 'Alloc' should be either 'CallExpr'" - " or 'CXXNewExpr'"); + " or 'CXXNewExpr'"); const auto *StrLen = Result.Nodes.getNodeAs("StrLen"); const auto *BinOp = Result.Nodes.getNodeAs("BinOp"); diff --git a/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp index 8023e32d53278a..0732ed38690d7e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp @@ -15,14 +15,16 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { void NoEscapeCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_async"))), - argumentCountIs(2), - hasArgument(1, blockExpr().bind("arg-block"))), - this); - Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_after"))), - argumentCountIs(3), - hasArgument(2, blockExpr().bind("arg-block"))), - this); + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::dispatch_async"))), argumentCountIs(2), + hasArgument(1, ignoringParenImpCasts(blockExpr().bind("arg-block")))), + this); + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::dispatch_after"))), argumentCountIs(3), + hasArgument(2, ignoringParenImpCasts(blockExpr().bind("arg-block")))), + this); } void NoEscapeCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp index 977241e91b9a93..71fb8e10f47703 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp @@ -687,21 +687,22 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) { }; auto MatchDestination = [=](CallContext CC) { - return hasArgument(*CC.DestinationPos, - allOf(AnyOfDestDecl, - unless(hasAncestor(compoundStmt( - hasDescendant(NullTerminatorExpr)))), - unless(Container))); + return hasArgument( + *CC.DestinationPos, + ignoringParenImpCasts(allOf(AnyOfDestDecl, + unless(hasAncestor(compoundStmt( + hasDescendant(NullTerminatorExpr)))), + unless(Container)))); }; auto MatchSource = [=](CallContext CC) { - return hasArgument(*CC.SourcePos, AnyOfSrcDecl); + return hasArgument(*CC.SourcePos, ignoringParenImpCasts(AnyOfSrcDecl)); }; auto MatchGivenLength = [=](CallContext CC) { return hasArgument( CC.LengthPos, - allOf( + ignoringParenImpCasts(allOf( anyOf( ignoringImpCasts(integerLiteral().bind(WrongLengthExprName)), allOf(unless(hasDefinition(SizeOfCharExpr)), @@ -713,7 +714,7 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) { UnknownLengthName)), hasDefinition(anything())))), AnyOfWrongLengthInit))), - expr().bind(LengthExprName))); + expr().bind(LengthExprName)))); }; auto MatchCall = [=](CallContext CC) { @@ -734,12 +735,14 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) { return allOf(MatchCall(CC), MatchDestination(CC), MatchSource(CC)); if (CC.DestinationPos && !CC.SourcePos) - return allOf(MatchCall(CC), MatchDestination(CC), - hasArgument(*CC.DestinationPos, anything())); + return allOf( + MatchCall(CC), MatchDestination(CC), + hasArgument(*CC.DestinationPos, ignoringParenImpCasts(anything()))); if (!CC.DestinationPos && CC.SourcePos) - return allOf(MatchCall(CC), MatchSource(CC), - hasArgument(*CC.SourcePos, anything())); + return allOf( + MatchCall(CC), MatchSource(CC), + hasArgument(*CC.SourcePos, ignoringParenImpCasts(anything()))); llvm_unreachable("Unhandled match"); }; diff --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp index 902490f4d33c13..0af886f6025419 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp @@ -22,200 +22,200 @@ constexpr llvm::StringLiteral MinimalConformingFunctions[] = { // mentioned POSIX specification was not updated after 'quick_exit' appeared // in the C11 standard. // Also, we want to keep the "minimal set" a subset of the "POSIX set". -// The list is repeated in bugprone-signal-handler.rst and should be kept up to date. -constexpr llvm::StringLiteral POSIXConformingFunctions[] = { - "_Exit", - "_exit", - "abort", - "accept", - "access", - "aio_error", - "aio_return", - "aio_suspend", - "alarm", - "bind", - "cfgetispeed", - "cfgetospeed", - "cfsetispeed", - "cfsetospeed", - "chdir", - "chmod", - "chown", - "clock_gettime", - "close", - "connect", - "creat", - "dup", - "dup2", - "execl", - "execle", - "execv", - "execve", - "faccessat", - "fchdir", - "fchmod", - "fchmodat", - "fchown", - "fchownat", - "fcntl", - "fdatasync", - "fexecve", - "ffs", - "fork", - "fstat", - "fstatat", - "fsync", - "ftruncate", - "futimens", - "getegid", - "geteuid", - "getgid", - "getgroups", - "getpeername", - "getpgrp", - "getpid", - "getppid", - "getsockname", - "getsockopt", - "getuid", - "htonl", - "htons", - "kill", - "link", - "linkat", - "listen", - "longjmp", - "lseek", - "lstat", - "memccpy", - "memchr", - "memcmp", - "memcpy", - "memmove", - "memset", - "mkdir", - "mkdirat", - "mkfifo", - "mkfifoat", - "mknod", - "mknodat", - "ntohl", - "ntohs", - "open", - "openat", - "pause", - "pipe", - "poll", - "posix_trace_event", - "pselect", - "pthread_kill", - "pthread_self", - "pthread_sigmask", - "quick_exit", - "raise", - "read", - "readlink", - "readlinkat", - "recv", - "recvfrom", - "recvmsg", - "rename", - "renameat", - "rmdir", - "select", - "sem_post", - "send", - "sendmsg", - "sendto", - "setgid", - "setpgid", - "setsid", - "setsockopt", - "setuid", - "shutdown", - "sigaction", - "sigaddset", - "sigdelset", - "sigemptyset", - "sigfillset", - "sigismember", - "siglongjmp", - "signal", - "sigpause", - "sigpending", - "sigprocmask", - "sigqueue", - "sigset", - "sigsuspend", - "sleep", - "sockatmark", - "socket", - "socketpair", - "stat", - "stpcpy", - "stpncpy", - "strcat", - "strchr", - "strcmp", - "strcpy", - "strcspn", - "strlen", - "strncat", - "strncmp", - "strncpy", - "strnlen", - "strpbrk", - "strrchr", - "strspn", - "strstr", - "strtok_r", - "symlink", - "symlinkat", - "tcdrain", - "tcflow", - "tcflush", - "tcgetattr", - "tcgetpgrp", - "tcsendbreak", - "tcsetattr", - "tcsetpgrp", - "time", - "timer_getoverrun", - "timer_gettime", - "timer_settime", - "times", - "umask", - "uname", - "unlink", - "unlinkat", - "utime", - "utimensat", - "utimes", - "wait", - "waitpid", - "wcpcpy", - "wcpncpy", - "wcscat", - "wcschr", - "wcscmp", - "wcscpy", - "wcscspn", - "wcslen", - "wcsncat", - "wcsncmp", - "wcsncpy", - "wcsnlen", - "wcspbrk", - "wcsrchr", - "wcsspn", - "wcsstr", - "wcstok", - "wmemchr", - "wmemcmp", - "wmemcpy", - "wmemmove", - "wmemset", - "write"}; +// The list is repeated in bugprone-signal-handler.rst and should be kept up to +// date. +constexpr llvm::StringLiteral POSIXConformingFunctions[] = {"_Exit", + "_exit", + "abort", + "accept", + "access", + "aio_error", + "aio_return", + "aio_suspend", + "alarm", + "bind", + "cfgetispeed", + "cfgetospeed", + "cfsetispeed", + "cfsetospeed", + "chdir", + "chmod", + "chown", + "clock_gettime", + "close", + "connect", + "creat", + "dup", + "dup2", + "execl", + "execle", + "execv", + "execve", + "faccessat", + "fchdir", + "fchmod", + "fchmodat", + "fchown", + "fchownat", + "fcntl", + "fdatasync", + "fexecve", + "ffs", + "fork", + "fstat", + "fstatat", + "fsync", + "ftruncate", + "futimens", + "getegid", + "geteuid", + "getgid", + "getgroups", + "getpeername", + "getpgrp", + "getpid", + "getppid", + "getsockname", + "getsockopt", + "getuid", + "htonl", + "htons", + "kill", + "link", + "linkat", + "listen", + "longjmp", + "lseek", + "lstat", + "memccpy", + "memchr", + "memcmp", + "memcpy", + "memmove", + "memset", + "mkdir", + "mkdirat", + "mkfifo", + "mkfifoat", + "mknod", + "mknodat", + "ntohl", + "ntohs", + "open", + "openat", + "pause", + "pipe", + "poll", + "posix_trace_event", + "pselect", + "pthread_kill", + "pthread_self", + "pthread_sigmask", + "quick_exit", + "raise", + "read", + "readlink", + "readlinkat", + "recv", + "recvfrom", + "recvmsg", + "rename", + "renameat", + "rmdir", + "select", + "sem_post", + "send", + "sendmsg", + "sendto", + "setgid", + "setpgid", + "setsid", + "setsockopt", + "setuid", + "shutdown", + "sigaction", + "sigaddset", + "sigdelset", + "sigemptyset", + "sigfillset", + "sigismember", + "siglongjmp", + "signal", + "sigpause", + "sigpending", + "sigprocmask", + "sigqueue", + "sigset", + "sigsuspend", + "sleep", + "sockatmark", + "socket", + "socketpair", + "stat", + "stpcpy", + "stpncpy", + "strcat", + "strchr", + "strcmp", + "strcpy", + "strcspn", + "strlen", + "strncat", + "strncmp", + "strncpy", + "strnlen", + "strpbrk", + "strrchr", + "strspn", + "strstr", + "strtok_r", + "symlink", + "symlinkat", + "tcdrain", + "tcflow", + "tcflush", + "tcgetattr", + "tcgetpgrp", + "tcsendbreak", + "tcsetattr", + "tcsetpgrp", + "time", + "timer_getoverrun", + "timer_gettime", + "timer_settime", + "times", + "umask", + "uname", + "unlink", + "unlinkat", + "utime", + "utimensat", + "utimes", + "wait", + "waitpid", + "wcpcpy", + "wcpncpy", + "wcscat", + "wcschr", + "wcscmp", + "wcscpy", + "wcscspn", + "wcslen", + "wcsncat", + "wcsncmp", + "wcsncpy", + "wcsnlen", + "wcspbrk", + "wcsrchr", + "wcsspn", + "wcsstr", + "wcstok", + "wmemchr", + "wmemcmp", + "wmemcpy", + "wmemmove", + "wmemset", + "write"}; using namespace clang::ast_matchers; @@ -361,10 +361,12 @@ void SignalHandlerCheck::registerMatchers(MatchFinder *Finder) { .bind("handler_expr"); auto HandlerLambda = cxxMemberCallExpr( on(expr(ignoringParenImpCasts(lambdaExpr().bind("handler_lambda"))))); - Finder->addMatcher(callExpr(callee(SignalFunction), - hasArgument(1, anyOf(HandlerExpr, HandlerLambda))) - .bind("register_call"), - this); + Finder->addMatcher( + callExpr(callee(SignalFunction), + hasArgument(1, anyOf(ignoringParenImpCasts(HandlerExpr), + ignoringParenImpCasts(HandlerLambda)))) + .bind("register_call"), + this); } void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp index ea3b8b8e9df4fe..33ee876a388e7a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -113,7 +113,7 @@ void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { cxxOperatorCallExpr( hasOverloadedOperatorName("[]"), hasArgument(0, hasType(cxxRecordDecl(hasName("::std::array")))), - hasArgument(1, SignedCharCastExpr)) + hasArgument(1, ignoringParenImpCasts(SignedCharCastExpr))) .bind("arraySubscript"); Finder->addMatcher(STDArraySubscript, this); diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp index fbdb676be68b09..ab7a03a1769495 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp @@ -65,11 +65,12 @@ void SmartPtrArrayMismatchCheck::registerMatchers(MatchFinder *Finder) { auto FindConstructExpr = cxxConstructExpr( hasDeclaration(FindConstructor), argumentCountIs(1), - hasArgument(0, - cxxNewExpr(isArray(), - hasType(hasCanonicalType(pointerType( - pointee(equalsBoundNode(PointerTypeN)))))) - .bind(NewExprN))) + hasArgument( + 0, ignoringParenImpCasts( + cxxNewExpr(isArray(), + hasType(hasCanonicalType(pointerType( + pointee(equalsBoundNode(PointerTypeN))))))) + .bind(NewExprN))) .bind(ConstructExprN); Finder->addMatcher(FindConstructExpr, this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..97c35b7672139d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,8 +82,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger()))), - hasArgument(1, hasType(qualType(isInteger()))), + hasArgument(0, ignoringParenImpCasts(hasType(qualType(isInteger())))), + hasArgument(1, ignoringParenImpCasts(hasType(qualType(isInteger())))), anyOf( // Detect the expression: string('x', 40); hasArgument(0, CharExpr.bind("swapped-parameter")), @@ -92,7 +92,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string(-4, ...); hasArgument(0, NegativeExpr.bind("negative-length")), // Detect the expression: string(0x1234567, ...); - hasArgument(0, LargeLengthExpr.bind("large-length")))) + hasArgument(0, ignoringParenImpCasts( + LargeLengthExpr.bind("large-length"))))) .bind("constructor"), this); @@ -102,8 +103,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))), - hasArgument(0, hasType(CharPtrType)), - hasArgument(1, hasType(isInteger())), + hasArgument(0, ignoringParenImpCasts(hasType(CharPtrType))), + hasArgument(1, ignoringParenImpCasts(hasType(isInteger()))), anyOf( // Detect the expression: string("...", 0); hasArgument(1, ZeroExpr.bind("empty-string")), @@ -112,7 +113,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 0x1234567); hasArgument(1, LargeLengthExpr.bind("large-length")), // Detect the expression: string("lit", 5) - allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), + allOf(hasArgument(0, ignoringParenImpCasts(ConstStrLiteral.bind( + "literal-with-length"))), hasArgument(1, ignoringParenImpCasts( integerLiteral().bind("int")))))) .bind("constructor"), @@ -128,11 +130,12 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxRecordDecl(hasName("basic_string_view")) .bind("basic_string_view_decl"), cxxRecordDecl(hasAnyName(removeNamespaces(StringNames))))))), - hasArgument(0, expr().bind("from-ptr")), + hasArgument(0, ignoringParenImpCasts(expr().bind("from-ptr"))), // do not match std::string(ptr, int) // match std::string(ptr, alloc) // match std::string(ptr) - anyOf(hasArgument(1, unless(hasType(isInteger()))), + anyOf(hasArgument( + 1, ignoringParenImpCasts(unless(hasType(isInteger())))), argumentCountIs(1))) .bind("constructor")), this); diff --git a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index 4f93b3ef779f5b..e379a4d4131f90 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -25,7 +25,7 @@ void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { qualType().bind("type")))))))), hasArgument( 1, - ignoringImpCasts( + ignoringParenImpCasts( expr(hasType(isInteger()), unless(hasType(isAnyCharacter())), // Ignore calls to tolower/toupper (see PR27723). unless(callExpr(callee(functionDecl( diff --git a/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp index 72e680d25cb846..7642491f1ff652 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp @@ -41,14 +41,17 @@ void StringLiteralWithEmbeddedNulCheck::registerMatchers(MatchFinder *Finder) { hasDeclaration(cxxMethodDecl(hasName("basic_string")))), // If present, the second argument is the alloc object which must not // be present explicitly. - cxxConstructExpr(argumentCountIs(2), - hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(1, cxxDefaultArgExpr())))); + cxxConstructExpr( + argumentCountIs(2), + hasDeclaration(cxxMethodDecl(hasName("basic_string"))), + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr()))))); // Detect passing a suspicious string literal to a string constructor. // example: std::string str = "abc\0def"; - Finder->addMatcher(traverse(TK_AsIs, - cxxConstructExpr(StringConstructorExpr, hasArgument(0, StrLitWithNul))), + Finder->addMatcher( + traverse(TK_AsIs, cxxConstructExpr(StringConstructorExpr, + hasArgument(0, ignoringParenImpCasts( + StrLitWithNul)))), this); // Detect passing a suspicious string literal through an overloaded operator. diff --git a/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp index ea50250f829f02..54d467ca08aaf5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp @@ -74,7 +74,7 @@ RewriteRuleWith StringviewNullptrCheckImpl() { auto BasicStringViewConstructingFromNullExpr = cxxConstructExpr( HasBasicStringViewType, argumentCountIs(1), - hasAnyArgument(/* `hasArgument` would skip over parens */ anyOf( + hasArgument(/* `hasArgument` would skip over parens */ anyOf( NullLiteral, NullInitList, EmptyInitList)), unless(cxxTemporaryObjectExpr(/* filters out type spellings */)), has(expr().bind("null_arg_expr"))) @@ -87,13 +87,13 @@ RewriteRuleWith StringviewNullptrCheckImpl() { remove(node("null_arg_expr")), construction_warning); // `std::string_view{null_arg_expr}` and `(std::string_view){null_arg_expr}` - auto HandleTemporaryCXXTemporaryObjectExprAndCompoundLiteralExpr = makeRule( - cxxTemporaryObjectExpr(cxxConstructExpr( - HasBasicStringViewType, argumentCountIs(1), - hasAnyArgument(/* `hasArgument` would skip over parens */ anyOf( - NullLiteral, NullInitList, EmptyInitList)), - has(expr().bind("null_arg_expr")))), - remove(node("null_arg_expr")), construction_warning); + auto HandleTemporaryCXXTemporaryObjectExprAndCompoundLiteralExpr = + makeRule(cxxTemporaryObjectExpr(cxxConstructExpr( + HasBasicStringViewType, argumentCountIs(1), + hasArgument(/* `hasArgument` would skip over parens */ anyOf( + NullLiteral, NullInitList, EmptyInitList)), + has(expr().bind("null_arg_expr")))), + remove(node("null_arg_expr")), construction_warning); // `(std::string_view) null_arg_expr` auto HandleTemporaryCStyleCastExpr = makeRule( @@ -262,9 +262,9 @@ RewriteRuleWith StringviewNullptrCheckImpl() { // `T(null_arg_expr)` auto HandleConstructorInvocation = makeRule(cxxConstructExpr( - hasAnyArgument(/* `hasArgument` would skip over parens */ - ignoringImpCasts( - BasicStringViewConstructingFromNullExpr)), + hasArgument(/* `hasArgument` would skip over parens */ + ignoringImpCasts( + BasicStringViewConstructingFromNullExpr)), unless(HasBasicStringViewType)), changeTo(node("construct_expr"), cat("\"\"")), argument_construction_warning); diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp index a488d35ca74485..dd1305daf2d9b3 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp @@ -21,8 +21,7 @@ void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) { // Match the standard memset: // void *memset(void *buffer, int fill_char, size_t byte_count); auto MemsetDecl = - functionDecl(hasName("::memset"), - parameterCountIs(3), + functionDecl(hasName("::memset"), parameterCountIs(3), hasParameter(0, hasType(pointerType(pointee(voidType())))), hasParameter(1, hasType(isInteger())), hasParameter(2, hasType(isInteger()))); @@ -31,26 +30,30 @@ void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr( callee(MemsetDecl), argumentCountIs(3), - hasArgument(1, characterLiteral(equals(static_cast('0'))) + hasArgument(1, ignoringParenImpCasts(characterLiteral(equals( + static_cast('0')))) .bind("char-zero-fill")), unless(hasArgument( - 0, anyOf(hasType(pointsTo(isAnyCharacter())), - hasType(arrayType(hasElementType(isAnyCharacter()))))))), + 0, ignoringParenImpCasts(anyOf( + hasType(pointsTo(isAnyCharacter())), + hasType(arrayType(hasElementType(isAnyCharacter())))))))), this); // Look for memset with an integer literal in its fill_char argument. // Will check if it gets truncated. Finder->addMatcher( callExpr(callee(MemsetDecl), argumentCountIs(3), - hasArgument(1, integerLiteral().bind("num-fill"))), + hasArgument(1, ignoringParenImpCasts( + integerLiteral().bind("num-fill")))), this); // Look for memset(x, y, 0) as that is most likely an argument swap. Finder->addMatcher( callExpr(callee(MemsetDecl), argumentCountIs(3), - unless(hasArgument(1, anyOf(characterLiteral(equals( - static_cast('0'))), - integerLiteral())))) + unless(hasArgument( + 1, ignoringParenImpCasts(anyOf( + characterLiteral(equals(static_cast('0'))), + integerLiteral()))))) .bind("call"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp index 8a6dcc3c059958..c80acdf06c0391 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp @@ -114,7 +114,8 @@ void SuspiciousReallocUsageCheck::registerMatchers(MatchFinder *Finder) { .bind("realloc"); auto ReallocCall = - callExpr(callee(ReallocDecl), hasArgument(0, expr().bind("ptr_input")), + callExpr(callee(ReallocDecl), + hasArgument(0, ignoringParenImpCasts(expr().bind("ptr_input"))), hasAncestor(functionDecl().bind("parent_function"))) .bind("call"); Finder->addMatcher(binaryOperator(hasOperatorName("="), diff --git a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp index 4f6bc18151789d..2f00c56f8aa173 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp @@ -33,17 +33,19 @@ void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) { // Check whether destination object is not TriviallyCopyable. // Applicable to all three memory manipulation functions. - Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName( - "::memset", "::memcpy", "::memmove"))), - hasArgument(0, NotTriviallyCopyableObject)) - .bind("dest"), - this); + Finder->addMatcher( + callExpr( + callee(functionDecl(hasAnyName("::memset", "::memcpy", "::memmove"))), + hasArgument(0, ignoringParenImpCasts(NotTriviallyCopyableObject))) + .bind("dest"), + this); // Check whether source object is not TriviallyCopyable. // Only applicable to memcpy() and memmove(). Finder->addMatcher( - callExpr(callee(functionDecl(hasAnyName("::memcpy", "::memmove"))), - hasArgument(1, NotTriviallyCopyableObject)) + callExpr( + callee(functionDecl(hasAnyName("::memcpy", "::memmove"))), + hasArgument(1, ignoringParenImpCasts(NotTriviallyCopyableObject))) .bind("src"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index b91ad0f1822955..7cc45ddb660289 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -265,11 +265,12 @@ void UseAfterMoveFinder::getDeclRefs( AddDeclRefs(match(traverse(TK_AsIs, findAll(DeclRefMatcher)), *S->getStmt(), *Context)); - AddDeclRefs(match(findAll(cxxOperatorCallExpr( - hasAnyOverloadedOperatorName("*", "->", "[]"), - hasArgument(0, DeclRefMatcher)) - .bind("operator")), - *S->getStmt(), *Context)); + AddDeclRefs( + match(findAll(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("*", "->", "[]"), + hasArgument(0, ignoringParenImpCasts(DeclRefMatcher))) + .bind("operator")), + *S->getStmt(), *Context)); } } @@ -414,7 +415,7 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { callExpr(argumentCountIs(1), callee(functionDecl(hasAnyName("::std::move", "::std::forward")) .bind("move-decl")), - hasArgument(0, declRefExpr().bind("arg")), + hasArgument(0, ignoringParenImpCasts(declRefExpr().bind("arg"))), unless(inDecltypeOrTemplateArg()), unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), anyOf(hasAncestor(compoundStmt( diff --git a/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp b/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp index 1c57a8fa8e5095..7f40c9f5ec9621 100644 --- a/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp @@ -22,9 +22,9 @@ void CommandProcessorCheck::registerMatchers(MatchFinder *Finder) { // Do not diagnose when the call expression passes a null pointer // constant to system(); that only checks for the presence of a // command processor, which is not a security risk by itself. - unless(callExpr(callee(functionDecl(hasName("::system"))), - argumentCountIs(1), - hasArgument(0, nullPointerConstant())))) + unless(callExpr( + callee(functionDecl(hasName("::system"))), argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(nullPointerConstant()))))) .bind("expr"), this); } diff --git a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp index 1e52884a806b25..51ed92d885e2e6 100644 --- a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp @@ -80,8 +80,10 @@ void NonTrivialTypesLibcMemoryCallsCheck::registerMatchers( auto ArgChecker = [&](Matcher RecordConstraint, BindableMatcher SecondArg = expr()) { return allOf(argumentCountIs(3), - hasArgument(0, IsStructPointer(RecordConstraint, true)), - hasArgument(1, SecondArg), hasArgument(2, IsRecordSizeOf)); + hasArgument(0, ignoringParenImpCasts( + IsStructPointer(RecordConstraint, true))), + hasArgument(1, ignoringParenImpCasts(SecondArg)), + hasArgument(2, ignoringParenImpCasts(IsRecordSizeOf))); }; Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/concurrency/ThreadCanceltypeAsynchronousCheck.cpp b/clang-tools-extra/clang-tidy/concurrency/ThreadCanceltypeAsynchronousCheck.cpp index 6ea9884a1a31ce..5308fe7a84cb15 100644 --- a/clang-tools-extra/clang-tidy/concurrency/ThreadCanceltypeAsynchronousCheck.cpp +++ b/clang-tools-extra/clang-tidy/concurrency/ThreadCanceltypeAsynchronousCheck.cpp @@ -17,10 +17,10 @@ namespace clang::tidy::concurrency { void ThreadCanceltypeAsynchronousCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - callExpr( - callee(functionDecl(hasName("::pthread_setcanceltype"))), - argumentCountIs(2), - hasArgument(0, isExpandedFromMacro("PTHREAD_CANCEL_ASYNCHRONOUS"))) + callExpr(callee(functionDecl(hasName("::pthread_setcanceltype"))), + argumentCountIs(2), + hasArgument(0, ignoringParenImpCasts(isExpandedFromMacro( + "PTHREAD_CANCEL_ASYNCHRONOUS")))) .bind("setcanceltype"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp index bbb35228ce47fb..4eb69c6293edf4 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp @@ -117,7 +117,8 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) { auto ForwardCallMatcher = callExpr( callExpr().bind("call"), argumentCountIs(1), - hasArgument(0, declRefExpr(to(varDecl().bind("var")))), + hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl().bind("var"))))), forCallable( anyOf(allOf(equalsBoundNode("func"), functionDecl(hasAnyParameter(parmVarDecl(allOf( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp index 20f9a2e549fe2f..d3fc91277e169e 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp @@ -50,7 +50,7 @@ void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) { hasOverloadedOperatorName("[]"), callee(cxxMethodDecl( ofClass(cxxRecordDecl(hasName("::std::array")).bind("type")))), - hasArgument(1, expr().bind("index"))) + hasArgument(1, ignoringParenImpCasts(expr().bind("index")))) .bind("expr"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp index 7db9e29e8fd0e6..e191cce1ad5dd9 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp @@ -46,9 +46,9 @@ void RvalueReferenceParamNotMovedCheck::registerMatchers(MatchFinder *Finder) { callee(unresolvedLookupExpr(hasAnyDeclaration( namedDecl(hasUnderlyingDecl(hasName("::std::move"))))))), hasArgument( - 0, argumentOf( + 0, ignoringParenImpCasts(argumentOf( AllowPartialMove, - declRefExpr(to(equalsBoundNode("param"))).bind("ref"))), + declRefExpr(to(equalsBoundNode("param"))).bind("ref")))), unless(hasAncestor( lambdaExpr(valueCapturesVar(equalsBoundNode("param"))))), unless(anyOf(hasAncestor(typeLoc()), diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp index 76754394de760c..9678455f7ae7dd 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp @@ -46,12 +46,12 @@ void SlicingCheck::registerMatchers(MatchFinder *Finder) { isBaseInitializer(), withInitializer(equalsBoundNode("Call")))))); // Assignment slicing: "a = b;" and "a = std::move(b);" variants. - const auto SlicesObjectInAssignment = - callExpr(expr().bind("Call"), - callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(), - isMoveAssignmentOperator()), - OfBaseClass)), - hasArgument(1, HasTypeDerivedFromBaseDecl)); + const auto SlicesObjectInAssignment = callExpr( + expr().bind("Call"), + callee(cxxMethodDecl( + anyOf(isCopyAssignmentOperator(), isMoveAssignmentOperator()), + OfBaseClass)), + hasArgument(1, ignoringParenImpCasts(HasTypeDerivedFromBaseDecl))); // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of // slicing the letter will create a temporary and therefore call a ctor. @@ -59,7 +59,7 @@ void SlicingCheck::registerMatchers(MatchFinder *Finder) { expr().bind("Call"), hasDeclaration(cxxConstructorDecl( anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)), - hasArgument(0, HasTypeDerivedFromBaseDecl), + hasArgument(0, ignoringParenImpCasts(HasTypeDerivedFromBaseDecl)), // We need to disable matching on the call to the base copy/move // constructor in DerivedDecl's constructors. unless(IsCallToBaseClass)); diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp index 93333377777054..12b391e8df22e9 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp @@ -44,7 +44,9 @@ void PreferIsaOrDynCastInConditionalsCheck::registerMatchers( callee(namedDecl(hasAnyName("isa", "cast", "cast_or_null", "dyn_cast", "dyn_cast_or_null")) .bind("func")), - hasArgument(0, mapAnyOf(declRefExpr, cxxMemberCallExpr).bind("arg"))) + hasArgument( + 0, ignoringParenImpCasts( + mapAnyOf(declRefExpr, cxxMemberCallExpr).bind("arg")))) .bind("rhs"); Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp index 35536b47700a65..1f59d17f49f7e4 100644 --- a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp @@ -64,7 +64,7 @@ void StaticAssertCheck::registerMatchers(MatchFinder *Finder) { auto Condition = anyOf(ignoringParenImpCasts(callExpr( hasDeclaration(functionDecl(hasName("__builtin_expect"))), - hasArgument(0, AssertCondition))), + hasArgument(0, ignoringParenImpCasts(AssertCondition)))), AssertCondition); Finder->addMatcher(conditionalOperator(hasCondition(Condition), diff --git a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp index 42c4b6edb6d209..b9bb1ee8cbb873 100644 --- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp @@ -52,14 +52,14 @@ void UnconventionalAssignOperatorCheck::registerMatchers( const auto IsBadReturnStatement = returnStmt(unless(has(ignoringParenImpCasts( anyOf(unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())), - cxxOperatorCallExpr(argumentCountIs(1), - callee(unresolvedLookupExpr()), - hasArgument(0, cxxThisExpr())), + cxxOperatorCallExpr( + argumentCountIs(1), callee(unresolvedLookupExpr()), + hasArgument(0, ignoringParenImpCasts(cxxThisExpr()))), cxxOperatorCallExpr( hasOverloadedOperatorName("="), - hasArgument( - 0, unaryOperator(hasOperatorName("*"), - hasUnaryOperand(cxxThisExpr()))))))))); + hasArgument(0, ignoringParenImpCasts(unaryOperator( + hasOperatorName("*"), + hasUnaryOperand(cxxThisExpr())))))))))); const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType); Finder->addMatcher(returnStmt(IsBadReturnStatement, forFunction(IsGoodAssign)) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp index 51ee35da623f20..8da568efce8829 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp @@ -647,9 +647,10 @@ void AvoidBindCheck::registerMatchers(MatchFinder *Finder) { callExpr( callee(namedDecl(hasAnyName("::boost::bind", "::std::bind"))), hasArgument( - 0, anyOf(expr(hasType(memberPointerType())).bind("ref"), - expr(hasParent(materializeTemporaryExpr().bind("ref"))), - expr().bind("ref")))) + 0, ignoringParenImpCasts(anyOf( + expr(hasType(memberPointerType())).bind("ref"), + expr(hasParent(materializeTemporaryExpr().bind("ref"))), + expr().bind("ref"))))) .bind("bind"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index 3229e302eb4322..cb4bb46375cb96 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -238,9 +238,9 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { to(varDecl(equalsBoundNode(InitVarName)))))), cxxOperatorCallExpr( hasOverloadedOperatorName("++"), - hasArgument(0, declRefExpr(to( + hasArgument(0, ignoringParenImpCasts(declRefExpr(to( varDecl(equalsBoundNode(InitVarName), - TestDerefReturnsByValue)))))))) + TestDerefReturnsByValue))))))))) .bind(IsReverse ? LoopNameReverseIterator : LoopNameIterator); } diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index d1d7e9dcfa9c0d..9ab6487865242b 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -87,10 +87,12 @@ void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { cxxConstructExpr( hasType(getSmartPointerTypeMatcher()), argumentCountIs(1), hasArgument( - 0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( - equalsBoundNode(PointerType))))), - CanCallCtor, unless(IsPlacement)) - .bind(NewExpression)), + 0, + ignoringParenImpCasts( + cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( + equalsBoundNode(PointerType))))), + CanCallCtor, unless(IsPlacement))) + .bind(NewExpression)), unless(isInTemplateInstantiation())) .bind(ConstructorCall))))), this); @@ -100,7 +102,8 @@ void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { TK_AsIs, cxxMemberCallExpr( unless(isInTemplateInstantiation()), - hasArgument(0, cxxNewExpr(CanCallCtor, unless(IsPlacement)) + hasArgument(0, ignoringParenImpCasts( + cxxNewExpr(CanCallCtor, unless(IsPlacement))) .bind(NewExpression)), callee(cxxMethodDecl(hasName("reset"))), anyOf(thisPointerType(getSmartPointerTypeMatcher()), @@ -361,8 +364,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, Diag << FixItHint::CreateRemoval( SourceRange(NewStart, InitRange.getBegin())); Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd)); - } - else { + } else { // New array expression with default/value initialization: // smart_ptr(new int[5]()); // smart_ptr(new Foo[5]()); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp index 4587b086707899..095056e73e273e 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -82,14 +82,16 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId); Finder->addMatcher( - cxxOperatorCallExpr(hasOverloadedOperatorName("="), - callee(cxxMethodDecl(ofClass(AutoPtrDecl))), - hasArgument(1, MovableArgumentMatcher)), + cxxOperatorCallExpr( + hasOverloadedOperatorName("="), + callee(cxxMethodDecl(ofClass(AutoPtrDecl))), + hasArgument(1, ignoringParenImpCasts(MovableArgumentMatcher))), this); Finder->addMatcher( traverse(TK_AsIs, cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1), - hasArgument(0, MovableArgumentMatcher))), + hasArgument(0, ignoringParenImpCasts( + MovableArgumentMatcher)))), this); } @@ -141,8 +143,7 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) { "auto_ptr") return; - SourceLocation EndLoc = - AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1); + SourceLocation EndLoc = AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1); diag(AutoPtrLoc, "auto_ptr is deprecated, use unique_ptr instead") << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc), "unique_ptr"); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index 6a295dbfd05820..0abc11e1712958 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -26,9 +26,10 @@ ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name, areDiagsSelfContained()) {} void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) { - const auto Begin = hasArgument(0, expr()); - const auto End = hasArgument(1, expr()); - const auto RandomFunc = hasArgument(2, expr().bind("randomFunc")); + const auto Begin = hasArgument(0, ignoringParenImpCasts(expr())); + const auto End = hasArgument(1, ignoringParenImpCasts(expr())); + const auto RandomFunc = + hasArgument(2, ignoringParenImpCasts(expr().bind("randomFunc"))); Finder->addMatcher( traverse( TK_AsIs, diff --git a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp index b971b825076448..e7cc6f9b3d7e09 100644 --- a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp @@ -29,14 +29,16 @@ void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) { cxxMemberCallExpr( callee(cxxMethodDecl(hasName("swap"))), hasArgument( - 0, anyOf(Shrinkable, unaryOperator(hasUnaryOperand(Shrinkable)))), + 0, ignoringParenImpCasts(anyOf( + Shrinkable, unaryOperator(hasUnaryOperand(Shrinkable))))), on(cxxConstructExpr(hasArgument( - 0, - expr(anyOf(BoundShrinkable, - unaryOperator(hasUnaryOperand(BoundShrinkable))), - hasType(hasCanonicalType(hasDeclaration(namedDecl(hasAnyName( - "std::basic_string", "std::deque", "std::vector")))))) - .bind("ContainerToShrink"))))) + 0, ignoringParenImpCasts( + expr(anyOf(BoundShrinkable, unaryOperator(hasUnaryOperand( + BoundShrinkable))), + hasType(hasCanonicalType(hasDeclaration(namedDecl( + hasAnyName("std::basic_string", "std::deque", + "std::vector")))))) + .bind("ContainerToShrink")))))) .bind("CopyAndSwapTrick"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index 93151024064b42..f502312d42cbe4 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -74,19 +74,20 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context, for (const auto *Base : BasesToInit) { // The initialization of a base class should be a call to a copy // constructor of the base. - if (match( - traverse(TK_AsIs, - cxxConstructorDecl( - forEachConstructorInitializer(cxxCtorInitializer( - isBaseInitializer(), - withInitializer(cxxConstructExpr( - hasType(equalsNode(Base)), - hasDeclaration( - cxxConstructorDecl(isCopyConstructor())), - argumentCountIs(1), - hasArgument(0, declRefExpr(to(varDecl( - equalsNode(Param))))))))))), - *Ctor, *Context) + if (match(traverse( + TK_AsIs, + cxxConstructorDecl( + forEachConstructorInitializer(cxxCtorInitializer( + isBaseInitializer(), + withInitializer(cxxConstructExpr( + hasType(equalsNode(Base)), + hasDeclaration( + cxxConstructorDecl(isCopyConstructor())), + argumentCountIs(1), + hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to( + varDecl(equalsNode(Param)))))))))))), + *Ctor, *Context) .empty()) return false; } @@ -107,7 +108,9 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context, hasDeclaration( cxxConstructorDecl(isCopyConstructor())), argumentCountIs(1), - hasArgument(0, AccessToFieldInParam)))))))), + hasArgument(0, + ignoringParenImpCasts( + AccessToFieldInParam))))))))), *Ctor, *Context) .empty()) return false; @@ -169,8 +172,8 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context, // - The argument is (an implicit cast to a Base of) // the argument taken by "Operator". argumentCountIs(1), - hasArgument( - 0, declRefExpr(to(varDecl(equalsNode(Param)))))))))), + hasArgument(0, ignoringParenImpCasts(declRefExpr( + to(varDecl(equalsNode(Param))))))))))), *Compound, *Context) .empty()) return false; diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp index 89ee45faecd7f3..a24c66fc1eca1e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp @@ -38,37 +38,42 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) { const auto FindExpr = cxxMemberCallExpr( // A method call with no second argument or the second argument is zero... - anyOf(argumentCountIs(1), hasArgument(1, ZeroLiteral)), + anyOf(argumentCountIs(1), + hasArgument(1, ignoringParenImpCasts(ZeroLiteral))), // ... named find... callee(cxxMethodDecl(hasName("find")).bind("find_fun")), // ... on a class with a starts_with function. on(hasType( hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction)))), // Bind search expression. - hasArgument(0, expr().bind("search_expr"))); + hasArgument(0, ignoringParenImpCasts(expr().bind("search_expr")))); const auto RFindExpr = cxxMemberCallExpr( // A method call with a second argument of zero... - hasArgument(1, ZeroLiteral), + hasArgument(1, ignoringParenImpCasts(ZeroLiteral)), // ... named rfind... callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")), // ... on a class with a starts_with function. on(hasType( hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction)))), // Bind search expression. - hasArgument(0, expr().bind("search_expr"))); + hasArgument(0, ignoringParenImpCasts(expr().bind("search_expr")))); // Match a string literal and an integer or strlen() call matching the length. const auto HasStringLiteralAndLengthArgs = [](const auto StringArgIndex, const auto LengthArgIndex) { return allOf( - hasArgument(StringArgIndex, stringLiteral().bind("string_literal_arg")), - hasArgument(LengthArgIndex, - anyOf(integerLiteral().bind("integer_literal_size_arg"), - callExpr(callee(functionDecl(parameterCountIs(1), - hasName("strlen"))), - hasArgument(0, stringLiteral().bind( - "strlen_arg")))))); + hasArgument(StringArgIndex, ignoringParenImpCasts(stringLiteral().bind( + "string_literal_arg"))), + hasArgument( + LengthArgIndex, + anyOf(ignoringParenImpCasts( + integerLiteral().bind("integer_literal_size_arg")), + ignoringParenImpCasts(callExpr( + callee( + functionDecl(parameterCountIs(1), hasName("strlen"))), + hasArgument(0, ignoringParenImpCasts(stringLiteral().bind( + "strlen_arg")))))))); }; // Match a string variable and a call to length() or size(). diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 1548fc454cfb37..3665f0fd52d8dd 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -94,7 +94,7 @@ struct MatchBuilder { return expr(ignoreParenAndFloatingCasting( callExpr(callee(functionDecl(hasName(FunctionName), hasParameter(0, hasType(isArithmetic())))), - hasArgument(0, ArgumentMatcher)))); + hasArgument(0, ignoringParenImpCasts(ArgumentMatcher))))); } auto matchSqrt(const Matcher ArgumentMatcher) const { diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp index 660996aba7b70d..cacd319868b4b0 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp @@ -99,7 +99,8 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( unusedReturnValue( callExpr(argumentCountAtLeast(1), - hasArgument(0, stringLiteral(isOrdinary())), + hasArgument( + 0, ignoringParenImpCasts(stringLiteral(isOrdinary()))), callee(functionDecl(unless(cxxMethodDecl()), matchers::matchesAnyListedName( PrintfLikeFunctions)) @@ -111,7 +112,8 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( unusedReturnValue( callExpr(argumentCountAtLeast(2), - hasArgument(1, stringLiteral(isOrdinary())), + hasArgument( + 1, ignoringParenImpCasts(stringLiteral(isOrdinary()))), callee(functionDecl(unless(cxxMethodDecl()), matchers::matchesAnyListedName( FprintfLikeFunctions)) diff --git a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp index bd9bdd1701975a..df4aedf7c50e0d 100644 --- a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp @@ -105,17 +105,18 @@ void NSInvocationArgumentLifetimeCheck::registerMatchers(MatchFinder *Finder) { hasSelector("getReturnValue:")), hasArgument( 0, - anyOf(hasDescendant(memberExpr(isObjCManagedLifetime())), - hasDescendant(objcIvarRefExpr(isObjCManagedLifetime())), - hasDescendant( - // Reference to variables, but when dereferencing - // to ivars/fields a more-descendent variable - // reference (e.g. self) may match with strong - // object lifetime, leading to an incorrect match. - // Exclude these conditions. - declRefExpr(to(varDecl().bind("var")), - unless(hasParent(implicitCastExpr())), - isObjCManagedLifetime()))))) + ignoringParenImpCasts(anyOf( + hasDescendant(memberExpr(isObjCManagedLifetime())), + hasDescendant(objcIvarRefExpr(isObjCManagedLifetime())), + hasDescendant( + // Reference to variables, but when dereferencing + // to ivars/fields a more-descendent variable + // reference (e.g. self) may match with strong + // object lifetime, leading to an incorrect match. + // Exclude these conditions. + declRefExpr(to(varDecl().bind("var")), + unless(hasParent(implicitCastExpr())), + isObjCManagedLifetime())))))) .bind("call")), this); } diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp index 40ea915a332990..b8fa4056632702 100644 --- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp @@ -74,7 +74,7 @@ void FasterStringFindCheck::registerMatchers(MatchFinder *Finder) { cxxMemberCallExpr( callee(functionDecl(StringFindFunctions).bind("func")), anyOf(argumentCountIs(1), argumentCountIs(2)), - hasArgument(0, SingleChar), + hasArgument(0, ignoringParenImpCasts(SingleChar)), on(expr(hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration( recordDecl(hasAnyName(StringLikeClasses)))))), unless(hasSubstitutedType())))), diff --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp index ad900fcec2dee1..59e141cb805706 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp @@ -37,19 +37,19 @@ void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) { callExpr( callee(functionDecl(Algorithms)), hasArgument( - 0, cxxMemberCallExpr( + 0, ignoringParenImpCasts(cxxMemberCallExpr( callee(cxxMethodDecl(hasName("begin"))), on(declRefExpr( hasDeclaration(decl().bind("IneffContObj")), anyOf(hasType(ContainerMatcher.bind("IneffCont")), hasType(pointsTo( ContainerMatcher.bind("IneffContPtr"))))) - .bind("IneffContExpr")))), - hasArgument( - 1, cxxMemberCallExpr(callee(cxxMethodDecl(hasName("end"))), - on(declRefExpr(hasDeclaration( - equalsBoundNode("IneffContObj")))))), - hasArgument(2, expr().bind("AlgParam"))) + .bind("IneffContExpr"))))), + hasArgument(1, ignoringParenImpCasts(cxxMemberCallExpr( + callee(cxxMethodDecl(hasName("end"))), + on(declRefExpr(hasDeclaration( + equalsBoundNode("IneffContObj"))))))), + hasArgument(2, ignoringParenImpCasts(expr().bind("AlgParam")))) .bind("IneffAlg"); Finder->addMatcher(Matcher, this); diff --git a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp index 9e4e3f63e19cfe..165f39a953d483 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp @@ -43,11 +43,12 @@ void InefficientStringConcatenationCheck::registerMatchers( const auto AssignOperator = cxxOperatorCallExpr( hasOverloadedOperatorName("="), - hasArgument(0, declRefExpr(BasicStringType, - hasDeclaration(decl().bind("lhsStrT"))) + hasArgument(0, ignoringParenImpCasts( + declRefExpr(BasicStringType, + hasDeclaration(decl().bind("lhsStrT")))) .bind("lhsStr")), - hasArgument(1, stmt(hasDescendant(declRefExpr( - hasDeclaration(decl(equalsBoundNode("lhsStrT"))))))), + hasArgument(1, ignoringParenImpCasts(stmt(hasDescendant(declRefExpr( + hasDeclaration(decl(equalsBoundNode("lhsStrT")))))))), hasDescendant(BasicStringPlusOperator)); if (StrictMode) { diff --git a/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp b/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp index 869830aaf9d66d..5f885736e5199f 100644 --- a/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp @@ -54,7 +54,8 @@ void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) { return hasParameter(Pos, hasType(isBuiltinType(Kind))); }; auto HasBuiltinTyArg = [](int Pos, BuiltinType::Kind Kind) { - return hasArgument(Pos, hasType(isBuiltinType(Kind))); + return hasArgument(Pos, + ignoringParenImpCasts(hasType(isBuiltinType(Kind)))); }; // Match calls to foo(double) with a float argument. diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp index 9beb185cba929d..3ce01305b5e0af 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -97,11 +97,12 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall, hasCanonicalType(recordType(hasDeclaration(namedDecl( unless(matchers::matchesAnyListedName(ExcludedContainerTypes)))))); - return expr( - anyOf(cxxMemberCallExpr(callee(MethodDecl), on(OnExpr), - thisPointerType(ReceiverType)), - cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, OnExpr), - hasArgument(0, hasType(ReceiverType))))); + return expr(anyOf( + cxxMemberCallExpr(callee(MethodDecl), on(OnExpr), + thisPointerType(ReceiverType)), + cxxOperatorCallExpr( + callee(MethodDecl), hasArgument(0, ignoringParenImpCasts(OnExpr)), + hasArgument(0, ignoringParenImpCasts(hasType(ReceiverType)))))); } AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) { @@ -252,7 +253,8 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl( isCopyConstructor())), - hasArgument(0, CopyCtorArg)) + hasArgument(0, ignoringParenImpCasts( + CopyCtorArg))) .bind("ctorCall")))) .bind("newVarDecl"))) .bind("declStmt"))) diff --git a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp index a05e228520c9ef..183743c61f16f7 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp @@ -76,13 +76,15 @@ void ContainerDataPointerCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( unaryOperator( unless(isExpansionInSystemHeader()), hasOperatorName("&"), - hasUnaryOperand(expr( - anyOf(cxxOperatorCallExpr(SubscriptOperator, argumentCountIs(2), - hasArgument(0, ContainerExpr), - hasArgument(1, Zero)), - cxxMemberCallExpr(SubscriptOperator, on(ContainerExpr), - argumentCountIs(1), hasArgument(0, Zero)), - arraySubscriptExpr(hasLHS(ContainerExpr), hasRHS(Zero)))))) + hasUnaryOperand(expr(anyOf( + cxxOperatorCallExpr( + SubscriptOperator, argumentCountIs(2), + hasArgument(0, ignoringParenImpCasts(ContainerExpr)), + hasArgument(1, ignoringParenImpCasts(Zero))), + cxxMemberCallExpr(SubscriptOperator, on(ContainerExpr), + argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(Zero))), + arraySubscriptExpr(hasLHS(ContainerExpr), hasRHS(Zero)))))) .bind(AddressOfName), this); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp index 57f13db078020a..d2bf41acf2e21c 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -57,7 +57,7 @@ void RedundantStringCStrCheck::registerMatchers( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), // If present, the second argument is the alloc object which must not // be present explicitly. - hasArgument(1, cxxDefaultArgExpr())))); + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr()))))); // Match string constructor. const auto StringViewConstructorExpr = cxxConstructExpr( @@ -80,7 +80,7 @@ void RedundantStringCStrCheck::registerMatchers( TK_AsIs, cxxConstructExpr( anyOf(StringConstructorExpr, StringViewConstructorExpr), - hasArgument(0, StringCStrCallExpr), + hasArgument(0, ignoringParenImpCasts(StringCStrCallExpr)), unless(anyOf(HasRValueTempParent, hasParent(cxxBindTemporaryExpr( HasRValueTempParent)))))), this); @@ -89,49 +89,57 @@ void RedundantStringCStrCheck::registerMatchers( Finder->addMatcher( cxxOperatorCallExpr( hasAnyOverloadedOperatorName("<", ">", ">=", "<=", "!=", "==", "+"), - anyOf(allOf(hasArgument(0, StringExpr), - hasArgument(1, StringCStrCallExpr)), - allOf(hasArgument(0, StringCStrCallExpr), - hasArgument(1, StringExpr)))), + anyOf( + allOf(hasArgument(0, ignoringParenImpCasts(StringExpr)), + hasArgument(1, ignoringParenImpCasts(StringCStrCallExpr))), + allOf(hasArgument(0, ignoringParenImpCasts(StringCStrCallExpr)), + hasArgument(1, ignoringParenImpCasts(StringExpr))))), this); // Detect: 'dst += str.c_str()' -> 'dst += str' // Detect: 's = str.c_str()' -> 's = str' Finder->addMatcher( - cxxOperatorCallExpr(hasAnyOverloadedOperatorName("=", "+="), - hasArgument(0, StringExpr), - hasArgument(1, StringCStrCallExpr)), + cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("=", "+="), + hasArgument(0, ignoringParenImpCasts(StringExpr)), + hasArgument(1, ignoringParenImpCasts(StringCStrCallExpr))), this); // Detect: 'dst.append(str.c_str())' -> 'dst.append(str)' Finder->addMatcher( - cxxMemberCallExpr(on(StringExpr), callee(decl(cxxMethodDecl(hasAnyName( - "append", "assign", "compare")))), - argumentCountIs(1), hasArgument(0, StringCStrCallExpr)), + cxxMemberCallExpr( + on(StringExpr), + callee( + decl(cxxMethodDecl(hasAnyName("append", "assign", "compare")))), + argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(StringCStrCallExpr))), this); // Detect: 'dst.compare(p, n, str.c_str())' -> 'dst.compare(p, n, str)' Finder->addMatcher( - cxxMemberCallExpr(on(StringExpr), - callee(decl(cxxMethodDecl(hasName("compare")))), - argumentCountIs(3), hasArgument(2, StringCStrCallExpr)), + cxxMemberCallExpr( + on(StringExpr), callee(decl(cxxMethodDecl(hasName("compare")))), + argumentCountIs(3), + hasArgument(2, ignoringParenImpCasts(StringCStrCallExpr))), this); // Detect: 'dst.find(str.c_str())' -> 'dst.find(str)' Finder->addMatcher( - cxxMemberCallExpr(on(StringExpr), - callee(decl(cxxMethodDecl(hasAnyName( - "find", "find_first_not_of", "find_first_of", - "find_last_not_of", "find_last_of", "rfind")))), - anyOf(argumentCountIs(1), argumentCountIs(2)), - hasArgument(0, StringCStrCallExpr)), + cxxMemberCallExpr( + on(StringExpr), + callee(decl(cxxMethodDecl( + hasAnyName("find", "find_first_not_of", "find_first_of", + "find_last_not_of", "find_last_of", "rfind")))), + anyOf(argumentCountIs(1), argumentCountIs(2)), + hasArgument(0, ignoringParenImpCasts(StringCStrCallExpr))), this); // Detect: 'dst.insert(pos, str.c_str())' -> 'dst.insert(pos, str)' Finder->addMatcher( - cxxMemberCallExpr(on(StringExpr), - callee(decl(cxxMethodDecl(hasName("insert")))), - argumentCountIs(2), hasArgument(1, StringCStrCallExpr)), + cxxMemberCallExpr( + on(StringExpr), callee(decl(cxxMethodDecl(hasName("insert")))), + argumentCountIs(2), + hasArgument(1, ignoringParenImpCasts(StringCStrCallExpr))), this); // Detect redundant 'c_str()' calls through a StringRef constructor. @@ -151,7 +159,7 @@ void RedundantStringCStrCheck::registerMatchers( // a constructor from string which is more efficient (avoids // strlen), so we can construct StringRef from the string // directly. - hasArgument(0, StringCStrCallExpr))), + hasArgument(0, ignoringParenImpCasts(StringCStrCallExpr)))), this); if (!StringParameterFunctions.empty()) { diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp index b579aafe8ea435..71614173166fb6 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -68,14 +68,14 @@ void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) { const auto HasStringCtorName = hasAnyName(removeNamespaces(StringNames)); // Match string constructor. - const auto StringConstructorExpr = expr( - anyOf(cxxConstructExpr(argumentCountIs(1), - hasDeclaration(cxxMethodDecl(HasStringCtorName))), - // If present, the second argument is the alloc object which must - // not be present explicitly. - cxxConstructExpr(argumentCountIs(2), - hasDeclaration(cxxMethodDecl(HasStringCtorName)), - hasArgument(1, cxxDefaultArgExpr())))); + const auto StringConstructorExpr = expr(anyOf( + cxxConstructExpr(argumentCountIs(1), + hasDeclaration(cxxMethodDecl(HasStringCtorName))), + // If present, the second argument is the alloc object which must + // not be present explicitly. + cxxConstructExpr( + argumentCountIs(2), hasDeclaration(cxxMethodDecl(HasStringCtorName)), + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr()))))); // Match a string constructor expression with an empty string literal. const auto EmptyStringCtorExpr = cxxConstructExpr( diff --git a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp index 3b5d89c8c64719..a9ee94b5b7b4dd 100644 --- a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp @@ -25,8 +25,8 @@ void StringCompareCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(hasName("compare"), ofClass(classTemplateSpecializationDecl( hasName("::std::basic_string"))))), - hasArgument(0, expr().bind("str2")), argumentCountIs(1), - callee(memberExpr().bind("str1"))); + hasArgument(0, ignoringParenImpCasts(expr().bind("str2"))), + argumentCountIs(1), callee(memberExpr().bind("str1"))); // First and second case: cast str.compare(str) to boolean. Finder->addMatcher( diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 8a2bbfff9e9e6b..b315f894f9b236 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -112,8 +112,7 @@ class BoundNodes { /// /// Returns NULL if there was no node bound to \c ID or if there is a node but /// it cannot be converted to the specified type. - template - const T *getNodeAs(StringRef ID) const { + template const T *getNodeAs(StringRef ID) const { return MyBoundNodes.getNodeAs(ID); } @@ -123,9 +122,7 @@ class BoundNodes { using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap; /// Retrieve mapping from binding identifiers to bound nodes. - const IDToNodeMap &getMap() const { - return MyBoundNodes.getMap(); - } + const IDToNodeMap &getMap() const { return MyBoundNodes.getMap(); } private: friend class internal::BoundNodesTreeBuilder; @@ -318,13 +315,15 @@ AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro, std::string, MacroName) { // Verifies that the statement' beginning and ending are both expanded from // the same instance of the given macro. - auto& Context = Finder->getASTContext(); + auto &Context = Finder->getASTContext(); std::optional B = internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context); - if (!B) return false; + if (!B) + return false; std::optional E = internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context); - if (!E) return false; + if (!E) + return false; return *B == *E; } @@ -690,9 +689,7 @@ AST_POLYMORPHIC_MATCHER(isPrivate, /// \endcode /// fieldDecl(isBitField()) /// matches 'int a;' but not 'int b;'. -AST_MATCHER(FieldDecl, isBitField) { - return Node.isBitField(); -} +AST_MATCHER(FieldDecl, isBitField) { return Node.isBitField(); } /// Matches non-static data members that are bit-fields of the specified /// bit width. @@ -735,9 +732,7 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher, /// Determines whether the function is "main", which is the entry point /// into an executable program. -AST_MATCHER(FunctionDecl, isMain) { - return Node.isMain(); -} +AST_MATCHER(FunctionDecl, isMain) { return Node.isMain(); } /// Matches the specialized template of a specialization declaration. /// @@ -751,9 +746,8 @@ AST_MATCHER(FunctionDecl, isMain) { /// declaration of 'A' at #1. AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate, internal::Matcher, InnerMatcher) { - const ClassTemplateDecl* Decl = Node.getSpecializedTemplate(); - return (Decl != nullptr && - InnerMatcher.matches(*Decl, Finder, Builder)); + const ClassTemplateDecl *Decl = Node.getSpecializedTemplate(); + return (Decl != nullptr && InnerMatcher.matches(*Decl, Finder, Builder)); } /// Matches an entity that has been implicitly added by the compiler (e.g. @@ -788,8 +782,7 @@ AST_POLYMORPHIC_MATCHER(isImplicit, AST_POLYMORPHIC_MATCHER_P( hasAnyTemplateArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, - TemplateSpecializationType, - FunctionDecl), + TemplateSpecializationType, FunctionDecl), internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -890,8 +883,7 @@ traverse(TraversalKind TK, const internal::MapAnyOfHelper &InnerMatcher) { /// varDecl(hasInitializer(cxxConstructExpr())) /// \endcode /// only match the declarations for b and c. -AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher, InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder); } @@ -920,8 +912,7 @@ AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher, /// varDecl(hasInitializer(declRefExpr())) /// \endcode /// only match the declarations for a. -AST_MATCHER_P(Expr, ignoringImpCasts, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(Expr, ignoringImpCasts, internal::Matcher, InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder); } @@ -967,8 +958,8 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) { /// varDecl(hasInitializer(integerLiteral())) /// varDecl(hasInitializer(declRefExpr())) /// would only match the declaration for a. -AST_MATCHER_P(Expr, ignoringParenImpCasts, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(Expr, ignoringParenImpCasts, internal::Matcher, + InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder); } @@ -1068,8 +1059,7 @@ AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); } AST_POLYMORPHIC_MATCHER_P2( hasTemplateArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, - TemplateSpecializationType, - FunctionDecl), + TemplateSpecializationType, FunctionDecl), unsigned, N, internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -1106,8 +1096,8 @@ AST_POLYMORPHIC_MATCHER_P( /// classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType( /// recordType(hasDeclaration(recordDecl(hasName("X"))))))) /// matches the specialization of \c struct A generated by \c A. -AST_MATCHER_P(TemplateArgument, refersToType, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(TemplateArgument, refersToType, internal::Matcher, + InnerMatcher) { if (Node.getKind() != TemplateArgument::Type) return false; return InnerMatcher.matches(Node.getAsType(), Finder, Builder); @@ -1144,8 +1134,8 @@ AST_MATCHER_P(TemplateArgument, refersToTemplate, /// refersToDeclaration(fieldDecl(hasName("next"))))) /// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching /// \c B::next -AST_MATCHER_P(TemplateArgument, refersToDeclaration, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(TemplateArgument, refersToDeclaration, internal::Matcher, + InnerMatcher) { if (Node.getKind() == TemplateArgument::Declaration) return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder); return false; @@ -1215,8 +1205,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType, /// classTemplateSpecializationDecl( /// hasAnyTemplateArgument(equalsIntegralValue("42"))) /// matches the implicit instantiation of C in C<42>. -AST_MATCHER_P(TemplateArgument, equalsIntegralValue, - std::string, Value) { +AST_MATCHER_P(TemplateArgument, equalsIntegralValue, std::string, Value) { if (Node.getKind() != TemplateArgument::Integral) return false; return toString(Node.getAsIntegral(), 10) == Value; @@ -1233,7 +1222,8 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue, /// autoreleasePoolStmt(stmt()) matches the declaration of "x" /// inside the autorelease pool. extern const internal::VariadicDynCastAllOfMatcher autoreleasePoolStmt; + ObjCAutoreleasePoolStmt> + autoreleasePoolStmt; /// Matches any value declaration. /// @@ -1611,8 +1601,7 @@ extern const internal::VariadicDynCastAllOfMatcher /// printf("%d", p); /// }) /// \endcode -extern const internal::VariadicDynCastAllOfMatcher - blockDecl; +extern const internal::VariadicDynCastAllOfMatcher blockDecl; /// Matches Objective-C instance variable declarations. /// @@ -1701,8 +1690,8 @@ extern const internal::VariadicDynCastAllOfMatcher /// Matches the syntactic form of init list expressions /// (if expression have it). -AST_MATCHER_P(InitListExpr, hasSyntacticForm, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(InitListExpr, hasSyntacticForm, internal::Matcher, + InnerMatcher) { const Expr *SyntForm = Node.getSyntacticForm(); return (SyntForm != nullptr && InnerMatcher.matches(*SyntForm, Finder, Builder)); @@ -1981,7 +1970,8 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher cxxNoexceptExpr; -/// Matches a loop initializing the elements of an array in a number of contexts: +/// Matches a loop initializing the elements of an array in a number of +/// contexts: /// * in the implicit copy/move constructor for a class with an array member /// * when a lambda-expression captures an array by value /// * when a decomposition declaration decomposes an array @@ -1995,16 +1985,16 @@ extern const internal::VariadicDynCastAllOfMatcher /// }; /// } /// \endcode -/// arrayInitLoopExpr() matches the implicit loop that initializes each element of -/// the implicit array field inside the lambda object, that represents the array `a` -/// captured by value. +/// arrayInitLoopExpr() matches the implicit loop that initializes each element +/// of the implicit array field inside the lambda object, that represents the +/// array `a` captured by value. extern const internal::VariadicDynCastAllOfMatcher arrayInitLoopExpr; /// The arrayInitIndexExpr consists of two subexpressions: a common expression -/// (the source array) that is evaluated once up-front, and a per-element initializer -/// that runs once for each array element. Within the per-element initializer, -/// the current index may be obtained via an ArrayInitIndexExpr. +/// (the source array) that is evaluated once up-front, and a per-element +/// initializer that runs once for each array element. Within the per-element +/// initializer, the current index may be obtained via an ArrayInitIndexExpr. /// /// Given /// \code @@ -2160,8 +2150,7 @@ extern const internal::VariadicDynCastAllOfMatcher forStmt; /// \code /// for (x; x < N; ++x) { } /// \endcode -AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher, InnerMatcher) { const Stmt *const Increment = Node.getInc(); return (Increment != nullptr && InnerMatcher.matches(*Increment, Finder, Builder)); @@ -2175,8 +2164,7 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher, /// \code /// for (int x = 0; x < N; ++x) { } /// \endcode -AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher, InnerMatcher) { const Stmt *const Init = Node.getInit(); return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder)); } @@ -2528,8 +2516,7 @@ extern const internal::VariadicDynCastAllOfMatcher cxxNullPtrLiteralExpr; /// Matches GNU __builtin_choose_expr. -extern const internal::VariadicDynCastAllOfMatcher - chooseExpr; +extern const internal::VariadicDynCastAllOfMatcher chooseExpr; /// Matches builtin function __builtin_convertvector. extern const internal::VariadicDynCastAllOfMatcher @@ -3045,8 +3032,8 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { /// Same as unaryExprOrTypeTraitExpr, but only matching /// alignof. -inline internal::BindableMatcher alignOfExpr( - const internal::Matcher &InnerMatcher) { +inline internal::BindableMatcher +alignOfExpr(const internal::Matcher &InnerMatcher) { return stmt(unaryExprOrTypeTraitExpr( allOf(anyOf(ofKind(UETT_AlignOf), ofKind(UETT_PreferredAlignOf)), InnerMatcher))); @@ -3054,10 +3041,10 @@ inline internal::BindableMatcher alignOfExpr( /// Same as unaryExprOrTypeTraitExpr, but only matching /// sizeof. -inline internal::BindableMatcher sizeOfExpr( - const internal::Matcher &InnerMatcher) { - return stmt(unaryExprOrTypeTraitExpr( - allOf(ofKind(UETT_SizeOf), InnerMatcher))); +inline internal::BindableMatcher +sizeOfExpr(const internal::Matcher &InnerMatcher) { + return stmt( + unaryExprOrTypeTraitExpr(allOf(ofKind(UETT_SizeOf), InnerMatcher))); } /// Matches NamedDecl nodes that have the specified name. @@ -3265,10 +3252,10 @@ AST_MATCHER_P(CXXDependentScopeMemberExpr, memberHasSameNameAsBoundNode, /// \endcode /// /// Usable as: Matcher, Matcher -AST_POLYMORPHIC_MATCHER_P( - isDerivedFrom, - AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl), - internal::Matcher, Base) { +AST_POLYMORPHIC_MATCHER_P(isDerivedFrom, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, + ObjCInterfaceDecl), + internal::Matcher, Base) { // Check if the node is a C++ struct/union/class. if (const auto *RD = dyn_cast(&Node)) return Finder->classIsDerivedFrom(RD, Base, Builder, /*Directly=*/false); @@ -3453,9 +3440,7 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher, /// /// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of /// \c decltype(x) -AST_MATCHER(CXXRecordDecl, isLambda) { - return Node.isLambda(); -} +AST_MATCHER(CXXRecordDecl, isLambda) { return Node.isLambda(); } /// Matches AST nodes that have child AST nodes that match the /// provided matcher. @@ -3693,15 +3678,13 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher, /// matches `(g()).m()`. /// /// FIXME: Overload to allow directly matching types? -AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher, - InnerMatcher) { - const Expr *ExprNode = Node.getImplicitObjectArgument() - ->IgnoreParenImpCasts(); +AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher, InnerMatcher) { + const Expr *ExprNode = + Node.getImplicitObjectArgument()->IgnoreParenImpCasts(); return (ExprNode != nullptr && InnerMatcher.matches(*ExprNode, Finder, Builder)); } - /// Matches on the receiver of an ObjectiveC Message expression. /// /// Example @@ -3730,9 +3713,7 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher, /// \code /// @interface I - (void)bar; @end /// \endcode -AST_MATCHER(ObjCMethodDecl, isClassMethod) { - return Node.isClassMethod(); -} +AST_MATCHER(ObjCMethodDecl, isClassMethod) { return Node.isClassMethod(); } /// Returns true when the Objective-C method declaration is an instance method. /// @@ -3763,9 +3744,7 @@ AST_MATCHER(ObjCMethodDecl, isInstanceMethod) { /// NSString *x = @"hello"; /// [x containsString:@"h"]; /// \endcode -AST_MATCHER(ObjCMessageExpr, isClassMessage) { - return Node.isClassMessage(); -} +AST_MATCHER(ObjCMessageExpr, isClassMessage) { return Node.isClassMessage(); } /// Returns true when the Objective-C message is sent to an instance. /// @@ -3825,9 +3804,8 @@ AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { /// [myObj methodB:argB]; /// \endcode extern const internal::VariadicFunction, - StringRef, - internal::hasAnySelectorFunc> - hasAnySelector; + StringRef, internal::hasAnySelectorFunc> + hasAnySelector; /// Matches ObjC selectors whose name contains /// a substring matched by the given RegExp. @@ -4021,8 +3999,8 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// \endcode /// /// Example matches class Derived -/// (matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) -/// \code +/// (matcher = +/// cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) \code /// class Base {}; /// class Derived : Base {}; /// \endcode @@ -4110,9 +4088,7 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { /// class Y { public: void x(); }; /// void z() { Y *y; y->x(); } /// \endcode -AST_MATCHER_P( - QualType, pointsTo, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(QualType, pointsTo, internal::Matcher, InnerMatcher) { return (!Node.isNull() && Node->isAnyPointerType() && InnerMatcher.matches(Node->getPointeeType(), Finder, Builder)); } @@ -4153,8 +4129,7 @@ AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher, /// } /// }; /// \endcode -AST_MATCHER_P(QualType, references, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(QualType, references, internal::Matcher, InnerMatcher) { return (!Node.isNull() && Node->isReferenceType() && InnerMatcher.matches(Node->getPointeeType(), Finder, Builder)); } @@ -4228,7 +4203,7 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher, InnerMatcher, 0) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) .matches(Node, Finder, Builder); } @@ -4236,7 +4211,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher, InnerMatcher, 1) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) .matches(Node, Finder, Builder); } @@ -4249,8 +4224,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, /// bool x; /// if (x) {} /// \endcode -AST_MATCHER_P(DeclRefExpr, to, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(DeclRefExpr, to, internal::Matcher, InnerMatcher) { const Decl *DeclNode = Node.getDecl(); return (DeclNode != nullptr && InnerMatcher.matches(*DeclNode, Finder, Builder)); @@ -4334,9 +4308,7 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher, InnerMatcher) { /// bool y() { return true; } /// bool x = y(); /// \endcode -AST_MATCHER_P( - VarDecl, hasInitializer, internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(VarDecl, hasInitializer, internal::Matcher, InnerMatcher) { const Expr *Initializer = Node.getAnyInitializer(); return (Initializer != nullptr && InnerMatcher.matches(*Initializer, Finder, Builder)); @@ -4391,9 +4363,7 @@ AST_MATCHER_P(LambdaExpr, forEachLambdaCapture, /// } /// static int z; /// \endcode -AST_MATCHER(VarDecl, isStaticLocal) { - return Node.isStaticLocal(); -} +AST_MATCHER(VarDecl, isStaticLocal) { return Node.isStaticLocal(); } /// Matches a variable declaration that has function scope and is a /// non-static local variable. @@ -4406,9 +4376,7 @@ AST_MATCHER(VarDecl, isStaticLocal) { /// } /// int z; /// \endcode -AST_MATCHER(VarDecl, hasLocalStorage) { - return Node.hasLocalStorage(); -} +AST_MATCHER(VarDecl, hasLocalStorage) { return Node.hasLocalStorage(); } /// Matches a variable declaration that does not have local storage. /// @@ -4420,9 +4388,7 @@ AST_MATCHER(VarDecl, hasLocalStorage) { /// } /// int z; /// \endcode -AST_MATCHER(VarDecl, hasGlobalStorage) { - return Node.hasGlobalStorage(); -} +AST_MATCHER(VarDecl, hasGlobalStorage) { return Node.hasGlobalStorage(); } /// Matches a variable declaration that has automatic storage duration. /// @@ -4487,9 +4453,7 @@ AST_MATCHER(VarDecl, hasThreadStorageDuration) { /// } /// } /// \endcode -AST_MATCHER(VarDecl, isExceptionVariable) { - return Node.isExceptionVariable(); -} +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } /// Checks that a call expression or a constructor call expression has /// a specific number of arguments (including absent default arguments). @@ -4560,7 +4524,7 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument, const Expr *Arg = Node.getArg(N); if (Finder->isTraversalIgnoringImplicitNodes() && isa(Arg)) return false; - return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder); + return InnerMatcher.matches(*Arg, Finder, Builder); } /// Matches the operand that does not contain the parameter pack. @@ -4686,7 +4650,7 @@ AST_MATCHER(CXXFoldExpr, isBinaryFold) { return Node.getInit() != nullptr; } AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N, internal::Matcher, InnerMatcher) { return N < Node.getNumInits() && - InnerMatcher.matches(*Node.getInit(N), Finder, Builder); + InnerMatcher.matches(*Node.getInit(N), Finder, Builder); } /// Matches declaration statements that contain a specific number of @@ -4785,11 +4749,11 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, /// forField(hasName("foo_")))))) /// matches Foo /// with forField matching foo_ -AST_MATCHER_P(CXXCtorInitializer, forField, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(CXXCtorInitializer, forField, internal::Matcher, + InnerMatcher) { const FieldDecl *NodeAsDecl = Node.getAnyMember(); return (NodeAsDecl != nullptr && - InnerMatcher.matches(*NodeAsDecl, Finder, Builder)); + InnerMatcher.matches(*NodeAsDecl, Finder, Builder)); } /// Matches the initializer expression of a constructor initializer. @@ -4805,11 +4769,11 @@ AST_MATCHER_P(CXXCtorInitializer, forField, /// withInitializer(integerLiteral(equals(1))))))) /// matches Foo /// with withInitializer matching (1) -AST_MATCHER_P(CXXCtorInitializer, withInitializer, - internal::Matcher, InnerMatcher) { - const Expr* NodeAsExpr = Node.getInit(); +AST_MATCHER_P(CXXCtorInitializer, withInitializer, internal::Matcher, + InnerMatcher) { + const Expr *NodeAsExpr = Node.getInit(); return (NodeAsExpr != nullptr && - InnerMatcher.matches(*NodeAsExpr, Finder, Builder)); + InnerMatcher.matches(*NodeAsExpr, Finder, Builder)); } /// Matches a constructor initializer if it is explicitly written in @@ -4825,9 +4789,7 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, /// \endcode /// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten())) /// will match Foo(int), but not Foo() -AST_MATCHER(CXXCtorInitializer, isWritten) { - return Node.isWritten(); -} +AST_MATCHER(CXXCtorInitializer, isWritten) { return Node.isWritten(); } /// Matches a constructor initializer if it is initializing a base, as /// opposed to a member. @@ -5024,14 +4986,12 @@ AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) { /// the matcher objcMethodDecl(hasParameter(0, hasName("y"))) /// matches the declaration of method f with hasParameter /// matching y. -AST_POLYMORPHIC_MATCHER_P2(hasParameter, - AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, - ObjCMethodDecl, - BlockDecl), - unsigned, N, internal::Matcher, - InnerMatcher) { - return (N < Node.parameters().size() - && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); +AST_POLYMORPHIC_MATCHER_P2( + hasParameter, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, ObjCMethodDecl, BlockDecl), + unsigned, N, internal::Matcher, InnerMatcher) { + return (N < Node.parameters().size() && + InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); } /// Matches if the given method declaration declares a member function with an @@ -5091,8 +5051,8 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, bool Matched = false; for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) { BoundNodesTreeBuilder ArgMatches(*Builder); - if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), - Finder, &ArgMatches)) { + if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder, + &ArgMatches)) { BoundNodesTreeBuilder ParamMatches(ArgMatches); if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl( hasParameter(ParamIndex, ParamMatcher)))), @@ -5273,8 +5233,7 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyParameter, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, ObjCMethodDecl, BlockDecl), - internal::Matcher, - InnerMatcher) { + internal::Matcher, InnerMatcher) { return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(), Node.param_end(), Finder, Builder) != Node.param_end(); @@ -5371,8 +5330,8 @@ AST_MATCHER(FunctionDecl, isNoReturn) { return Node.isNoReturn(); } /// \endcode /// cxxMethodDecl(returns(asString("int"))) /// matches int f() { return 1; } -AST_MATCHER_P(FunctionDecl, returns, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(FunctionDecl, returns, internal::Matcher, + InnerMatcher) { return InnerMatcher.matches(Node.getReturnType(), Finder, Builder); } @@ -5425,9 +5384,7 @@ AST_POLYMORPHIC_MATCHER(isStaticStorageClass, /// \endcode /// functionDecl(isDeleted()) /// matches the declaration of DeletedFunc, but not Func. -AST_MATCHER(FunctionDecl, isDeleted) { - return Node.isDeleted(); -} +AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } /// Matches defaulted function declarations. /// @@ -5438,9 +5395,7 @@ AST_MATCHER(FunctionDecl, isDeleted) { /// \endcode /// functionDecl(isDefaulted()) /// matches the declaration of ~B, but not ~A. -AST_MATCHER(FunctionDecl, isDefaulted) { - return Node.isDefaulted(); -} +AST_MATCHER(FunctionDecl, isDefaulted) { return Node.isDefaulted(); } /// Matches weak function declarations. /// @@ -5541,8 +5496,7 @@ AST_POLYMORPHIC_MATCHER(isConsteval, /// ifStmt(isConstexpr()) /// matches the if statement in baz. AST_POLYMORPHIC_MATCHER(isConstexpr, - AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl, - FunctionDecl, + AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl, FunctionDecl, IfStmt)) { return Node.isConstexpr(); } @@ -5681,8 +5635,8 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, /// matches 'A* a = GetAPointer()'. AST_MATCHER_P(IfStmt, hasConditionVariableStatement, internal::Matcher, InnerMatcher) { - const DeclStmt* const DeclarationStatement = - Node.getConditionVariableDeclStmt(); + const DeclStmt *const DeclarationStatement = + Node.getConditionVariableDeclStmt(); return DeclarationStatement != nullptr && InnerMatcher.matches(*DeclarationStatement, Finder, Builder); } @@ -5696,9 +5650,9 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement, /// \endcode /// arraySubscriptExpression(hasIndex(integerLiteral())) /// matches \c i[1] with the \c integerLiteral() matching \c 1 -AST_MATCHER_P(ArraySubscriptExpr, hasIndex, - internal::Matcher, InnerMatcher) { - if (const Expr* Expression = Node.getIdx()) +AST_MATCHER_P(ArraySubscriptExpr, hasIndex, internal::Matcher, + InnerMatcher) { + if (const Expr *Expression = Node.getIdx()) return InnerMatcher.matches(*Expression, Finder, Builder); return false; } @@ -5713,9 +5667,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasIndex, /// arraySubscriptExpression(hasBase(implicitCastExpr( /// hasSourceExpression(declRefExpr())))) /// matches \c i[1] with the \c declRefExpr() matching \c i -AST_MATCHER_P(ArraySubscriptExpr, hasBase, - internal::Matcher, InnerMatcher) { - if (const Expr* Expression = Node.getBase()) +AST_MATCHER_P(ArraySubscriptExpr, hasBase, internal::Matcher, + InnerMatcher) { + if (const Expr *Expression = Node.getBase()) return InnerMatcher.matches(*Expression, Finder, Builder); return false; } @@ -5772,14 +5726,12 @@ AST_POLYMORPHIC_MATCHER_P( /// with compoundStmt() /// matching '{}' /// but does not match 'void g();' -AST_MATCHER_P(FunctionDecl, hasAnyBody, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(FunctionDecl, hasAnyBody, internal::Matcher, InnerMatcher) { const Stmt *const Statement = Node.getBody(); return (Statement != nullptr && InnerMatcher.matches(*Statement, Finder, Builder)); } - /// Matches compound statements where at least one substatement matches /// a given matcher. Also matches StmtExprs that have CompoundStmt as children. /// @@ -5849,32 +5801,31 @@ equals(const ValueT &Value) { Value); } -AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals, - AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, - CXXBoolLiteralExpr, - IntegerLiteral), - bool, Value, 0) { - return internal::ValueEqualsMatcher(Value) - .matchesNode(Node); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + equals, + AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, CXXBoolLiteralExpr, + IntegerLiteral), + bool, Value, 0) { + return internal::ValueEqualsMatcher(Value).matchesNode( + Node); } -AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals, - AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, - CXXBoolLiteralExpr, - IntegerLiteral), - unsigned, Value, 1) { - return internal::ValueEqualsMatcher(Value) - .matchesNode(Node); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + equals, + AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, CXXBoolLiteralExpr, + IntegerLiteral), + unsigned, Value, 1) { + return internal::ValueEqualsMatcher(Value).matchesNode( + Node); } -AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals, - AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, - CXXBoolLiteralExpr, - FloatingLiteral, - IntegerLiteral), - double, Value, 2) { - return internal::ValueEqualsMatcher(Value) - .matchesNode(Node); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + equals, + AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral, CXXBoolLiteralExpr, + FloatingLiteral, IntegerLiteral), + double, Value, 2) { + return internal::ValueEqualsMatcher(Value).matchesNode( + Node); } /// Matches the operator Name of operator expressions and fold expressions @@ -6088,8 +6039,8 @@ AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { /// /// (Note: Clang's AST refers to other conversions as "casts" too, and calls /// actual casts "explicit" casts.) -AST_MATCHER_P(ExplicitCastExpr, hasDestinationType, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(ExplicitCastExpr, hasDestinationType, internal::Matcher, + InnerMatcher) { const QualType NodeType = Node.getTypeAsWritten(); return InnerMatcher.matches(NodeType, Finder, Builder); } @@ -6110,9 +6061,7 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, /// union U {}; /// enum E {}; /// \endcode -AST_MATCHER(TagDecl, isStruct) { - return Node.isStruct(); -} +AST_MATCHER(TagDecl, isStruct) { return Node.isStruct(); } /// Matches TagDecl object that are spelled with "union." /// @@ -6123,9 +6072,7 @@ AST_MATCHER(TagDecl, isStruct) { /// union U {}; /// enum E {}; /// \endcode -AST_MATCHER(TagDecl, isUnion) { - return Node.isUnion(); -} +AST_MATCHER(TagDecl, isUnion) { return Node.isUnion(); } /// Matches TagDecl object that are spelled with "class." /// @@ -6136,9 +6083,7 @@ AST_MATCHER(TagDecl, isUnion) { /// union U {}; /// enum E {}; /// \endcode -AST_MATCHER(TagDecl, isClass) { - return Node.isClass(); -} +AST_MATCHER(TagDecl, isClass) { return Node.isClass(); } /// Matches TagDecl object that are spelled with "enum." /// @@ -6149,9 +6094,7 @@ AST_MATCHER(TagDecl, isClass) { /// union U {}; /// enum E {}; /// \endcode -AST_MATCHER(TagDecl, isEnum) { - return Node.isEnum(); -} +AST_MATCHER(TagDecl, isEnum) { return Node.isEnum(); } /// Matches the true branch expression of a conditional operator. /// @@ -6223,9 +6166,7 @@ AST_POLYMORPHIC_MATCHER(isDefinition, /// template void h(Ts...); /// void i(); /// \endcode -AST_MATCHER(FunctionDecl, isVariadic) { - return Node.isVariadic(); -} +AST_MATCHER(FunctionDecl, isVariadic) { return Node.isVariadic(); } /// Matches the class declaration that the given method declaration /// belongs to. @@ -6244,14 +6185,13 @@ AST_MATCHER(FunctionDecl, isVariadic) { /// }; /// A a = A(); /// \endcode -AST_MATCHER_P(CXXMethodDecl, ofClass, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(CXXMethodDecl, ofClass, internal::Matcher, + InnerMatcher) { ASTChildrenNotSpelledInSourceScope RAII(Finder, false); const CXXRecordDecl *Parent = Node.getParent(); - return (Parent != nullptr && - InnerMatcher.matches(*Parent, Finder, Builder)); + return (Parent != nullptr && InnerMatcher.matches(*Parent, Finder, Builder)); } /// Matches each method overridden by the given method. This matcher may @@ -6386,9 +6326,7 @@ AST_MATCHER(CXXMethodDecl, isPure) { return Node.isPureVirtual(); } /// \endcode /// /// cxxMethodDecl(isConst()) matches A::foo() but not A::bar() -AST_MATCHER(CXXMethodDecl, isConst) { - return Node.isConst(); -} +AST_MATCHER(CXXMethodDecl, isConst) { return Node.isConst(); } /// Matches if the given method declaration declares a copy assignment /// operator. @@ -6453,9 +6391,7 @@ AST_MATCHER(CXXMethodDecl, isOverride) { /// }; /// \endcode /// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. -AST_MATCHER(CXXMethodDecl, isUserProvided) { - return Node.isUserProvided(); -} +AST_MATCHER(CXXMethodDecl, isUserProvided) { return Node.isUserProvided(); } /// Matches member expressions that are called with '->' as opposed /// to '.'. @@ -6497,9 +6433,7 @@ AST_POLYMORPHIC_MATCHER( /// \endcode /// functionDecl(hasAnyParameter(hasType(isInteger()))) /// matches "a(int)", "b(long)", but not "c(double)". -AST_MATCHER(QualType, isInteger) { - return Node->isIntegerType(); -} +AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); } /// Matches QualType nodes that are of unsigned integer type. /// @@ -6512,7 +6446,7 @@ AST_MATCHER(QualType, isInteger) { /// functionDecl(hasAnyParameter(hasType(isUnsignedInteger()))) /// matches "b(unsigned long)", but not "a(int)" and "c(double)". AST_MATCHER(QualType, isUnsignedInteger) { - return Node->isUnsignedIntegerType(); + return Node->isUnsignedIntegerType(); } /// Matches QualType nodes that are of signed integer type. @@ -6525,9 +6459,7 @@ AST_MATCHER(QualType, isUnsignedInteger) { /// \endcode /// functionDecl(hasAnyParameter(hasType(isSignedInteger()))) /// matches "a(int)", but not "b(unsigned long)" and "c(double)". -AST_MATCHER(QualType, isSignedInteger) { - return Node->isSignedIntegerType(); -} +AST_MATCHER(QualType, isSignedInteger) { return Node->isSignedIntegerType(); } /// Matches QualType nodes that are of character type. /// @@ -6539,9 +6471,7 @@ AST_MATCHER(QualType, isSignedInteger) { /// \endcode /// functionDecl(hasAnyParameter(hasType(isAnyCharacter()))) /// matches "a(char)", "b(wchar_t)", but not "c(double)". -AST_MATCHER(QualType, isAnyCharacter) { - return Node->isAnyCharacterType(); -} +AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } /// Matches QualType nodes that are of any pointer type; this includes /// the Objective-C object pointer type, which is different despite being @@ -6559,9 +6489,7 @@ AST_MATCHER(QualType, isAnyCharacter) { /// \endcode /// varDecl(hasType(isAnyPointer())) /// matches "int *i" and "Foo *f", but not "int j". -AST_MATCHER(QualType, isAnyPointer) { - return Node->isAnyPointerType(); -} +AST_MATCHER(QualType, isAnyPointer) { return Node->isAnyPointerType(); } /// Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. @@ -6578,9 +6506,7 @@ AST_MATCHER(QualType, isAnyPointer) { /// matches "void b(int const)", "void c(const int)" and /// "void e(int const) {}". It does not match d as there /// is no top-level const on the parameter type "const int *". -AST_MATCHER(QualType, isConstQualified) { - return Node.isConstQualified(); -} +AST_MATCHER(QualType, isConstQualified) { return Node.isConstQualified(); } /// Matches QualType nodes that are volatile-qualified, i.e., that /// include "top-level" volatile. @@ -6614,9 +6540,7 @@ AST_MATCHER(QualType, isVolatileQualified) { /// \endcode /// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k. /// \c i is const-qualified but the qualifier is not local. -AST_MATCHER(QualType, hasLocalQualifiers) { - return Node.hasLocalQualifiers(); -} +AST_MATCHER(QualType, hasLocalQualifiers) { return Node.hasLocalQualifiers(); } /// Matches a member expression where the member is matched by a /// given matcher. @@ -6630,8 +6554,7 @@ AST_MATCHER(QualType, hasLocalQualifiers) { /// memberExpr(member(hasName("first"))) /// matches second.first /// but not first.second (because the member name there is "second"). -AST_MATCHER_P(MemberExpr, member, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(MemberExpr, member, internal::Matcher, InnerMatcher) { return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); } @@ -6693,8 +6616,8 @@ AST_MATCHER_P(BaseUsingDecl, hasAnyUsingShadowDecl, /// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) /// matches \code using X::b \endcode /// but not \code using X::a \endcode -AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, internal::Matcher, + InnerMatcher) { return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder); } @@ -6987,9 +6910,7 @@ AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher, /// \endcode /// functionDecl(returns(booleanType())) /// matches "bool func();" -AST_MATCHER(Type, booleanType) { - return Node.isBooleanType(); -} +AST_MATCHER(Type, booleanType) { return Node.isBooleanType(); } /// Matches type \c void. /// @@ -6999,9 +6920,7 @@ AST_MATCHER(Type, booleanType) { /// \endcode /// functionDecl(returns(voidType())) /// matches "void func();" -AST_MATCHER(Type, voidType) { - return Node.isVoidType(); -} +AST_MATCHER(Type, voidType) { return Node.isVoidType(); } template using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher; @@ -7051,9 +6970,7 @@ extern const AstTypeMatcher complexType; /// \endcode /// realFloatingPointType() /// matches "float f" but not "int i" -AST_MATCHER(Type, realFloatingPointType) { - return Node.isRealFloatingType(); -} +AST_MATCHER(Type, realFloatingPointType) { return Node.isRealFloatingType(); } /// Matches arrays and C99 complex types that have a specific element /// type. @@ -7175,8 +7092,8 @@ extern const AstTypeMatcher variableArrayType; /// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to( /// varDecl(hasName("b"))))))) /// matches "int a[b]" -AST_MATCHER_P(VariableArrayType, hasSizeExpr, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(VariableArrayType, hasSizeExpr, internal::Matcher, + InnerMatcher) { return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder); } @@ -7664,7 +7581,8 @@ extern const AstTypeMatcher injectedClassNameType; /// Matches decayed type /// Example matches i[] in declaration of f. -/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) +/// (matcher = +/// valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) /// Example matches i[1]. /// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType()))))) /// \code @@ -7696,7 +7614,8 @@ AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher, /// declaration of \c class \c D. AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher, InnerMatcher) { const DeclContext *DC = Node.getDeclContext(); - if (!DC) return false; + if (!DC) + return false; return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder); } @@ -7742,8 +7661,8 @@ AST_MATCHER_FUNCTION_P_OVERLOAD( /// hasDeclaration(cxxRecordDecl(hasName("A"))) /// )) /// matches "A::" -AST_MATCHER_P(NestedNameSpecifier, specifiesType, - internal::Matcher, InnerMatcher) { +AST_MATCHER_P(NestedNameSpecifier, specifiesType, internal::Matcher, + InnerMatcher) { if (!Node.getAsType()) return false; return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder); @@ -7844,20 +7763,20 @@ extern const internal::VariadicAllOfMatcher attr; /// Matches if a node equals another node. /// /// \c Decl has pointer identity in the AST. -AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) { +AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl *, Other, 0) { return &Node == Other; } /// Matches if a node equals another node. /// /// \c Stmt has pointer identity in the AST. -AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) { +AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt *, Other, 1) { return &Node == Other; } /// Matches if a node equals another node. /// /// \c Type has pointer identity in the AST. -AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) { - return &Node == Other; +AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type *, Other, 2) { + return &Node == Other; } /// @} @@ -8029,9 +7948,11 @@ AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES( /// S(int) -> S // #5 /// explicit S(double) -> S // #6 /// \endcode -/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and #9, but not #1 or #2. -/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or #4. -/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 or #6. +/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 +/// and #9, but not #1 or #2. +/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or +/// #4. cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not +/// match #5 or #6. AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher, InnerMatcher) { ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node); @@ -8081,9 +8002,7 @@ AST_POLYMORPHIC_MATCHER(isInline, AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl, /// } /// \endcode /// namespaceDecl(isAnonymous()) will match #1 but not ::n. -AST_MATCHER(NamespaceDecl, isAnonymous) { - return Node.isAnonymousNamespace(); -} +AST_MATCHER(NamespaceDecl, isAnonymous) { return Node.isAnonymousNamespace(); } /// Matches declarations in the namespace `std`, but not in nested namespaces. /// @@ -8431,9 +8350,7 @@ AST_MATCHER(NamedDecl, hasExternalFormalLinkage) { /// A matcher such as /// parmVarDecl(hasInitializer(anything())) /// is equivalent to parmVarDecl(hasDefaultArgument()). -AST_MATCHER(ParmVarDecl, hasDefaultArgument) { - return Node.hasDefaultArg(); -} +AST_MATCHER(ParmVarDecl, hasDefaultArgument) { return Node.hasDefaultArg(); } /// Matches array new expressions. /// @@ -8443,9 +8360,7 @@ AST_MATCHER(ParmVarDecl, hasDefaultArgument) { /// \endcode /// cxxNewExpr(isArray()) /// matches the expression 'new MyClass[10]'. -AST_MATCHER(CXXNewExpr, isArray) { - return Node.isArray(); -} +AST_MATCHER(CXXNewExpr, isArray) { return Node.isArray(); } /// Matches placement new expression arguments. /// @@ -8496,9 +8411,7 @@ AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher, InnerMatcher) { /// class x {}; /// class y; /// \endcode -AST_MATCHER(CXXRecordDecl, hasDefinition) { - return Node.hasDefinition(); -} +AST_MATCHER(CXXRecordDecl, hasDefinition) { return Node.hasDefinition(); } /// Matches C++11 scoped enum declaration. /// @@ -8507,9 +8420,7 @@ AST_MATCHER(CXXRecordDecl, hasDefinition) { /// enum X {}; /// enum class Y {}; /// \endcode -AST_MATCHER(EnumDecl, isScoped) { - return Node.isScoped(); -} +AST_MATCHER(EnumDecl, isScoped) { return Node.isScoped(); } /// Matches a function declared with a trailing return type. /// diff --git a/clang/lib/ASTMatchers/GtestMatchers.cpp b/clang/lib/ASTMatchers/GtestMatchers.cpp index a556d8ef2da066..a2d5e921157a8e 100644 --- a/clang/lib/ASTMatchers/GtestMatchers.cpp +++ b/clang/lib/ASTMatchers/GtestMatchers.cpp @@ -122,8 +122,9 @@ static internal::BindableMatcher gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, StatementMatcher Right) { return callExpr(isExpandedFromMacro(getMacroName(Macro, Cmp)), - callee(getComparisonDecl(Cmp)), hasArgument(2, Left), - hasArgument(3, Right)); + callee(getComparisonDecl(Cmp)), + hasArgument(2, ignoringParenImpCasts(Left)), + hasArgument(3, ignoringParenImpCasts(Right))); } static internal::BindableMatcher @@ -131,15 +132,17 @@ gtestThatInternal(MacroType Macro, StatementMatcher Actual, StatementMatcher Matcher) { return cxxOperatorCallExpr( isExpandedFromMacro(getMacroName(Macro, "THAT")), - hasOverloadedOperatorName("()"), hasArgument(2, Actual), + hasOverloadedOperatorName("()"), + hasArgument(2, ignoringParenImpCasts(Actual)), hasArgument( - 0, expr(hasType(classTemplateSpecializationDecl(hasName( - "::testing::internal::PredicateFormatterFromMatcher"))), - ignoringImplicit( - callExpr(callee(functionDecl(hasName( - "::testing::internal::" - "MakePredicateFormatterFromMatcher"))), - hasArgument(0, ignoringImplicit(Matcher))))))); + 0, ignoringParenImpCasts(expr( + hasType(classTemplateSpecializationDecl(hasName( + "::testing::internal::PredicateFormatterFromMatcher"))), + ignoringImplicit( + callExpr(callee(functionDecl(hasName( + "::testing::internal::" + "MakePredicateFormatterFromMatcher"))), + hasArgument(0, ignoringImplicit(Matcher)))))))); } static internal::BindableMatcher diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 87774b00956a5a..9a4c178219e315 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -164,26 +164,32 @@ TEST_P(ASTMatchersTest, AllOf) { "void g(int x) { struct T t; f(x, &t, 3, 4); }"; EXPECT_TRUE(matches( Program, callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))))))); + hasArgument(0, ignoringParenImpCasts(declRefExpr( + to(varDecl())))))))); EXPECT_TRUE(matches( Program, - callExpr( - allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))))))); + callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, ignoringParenImpCasts(declRefExpr(to(varDecl())))), + hasArgument(1, ignoringParenImpCasts( + hasType(pointsTo(recordDecl(hasName("T")))))))))); EXPECT_TRUE(matches( - Program, callExpr(allOf( - callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))))))); + Program, + callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, ignoringParenImpCasts(declRefExpr(to(varDecl())))), + hasArgument(1, ignoringParenImpCasts( + hasType(pointsTo(recordDecl(hasName("T")))))), + hasArgument(2, ignoringParenImpCasts(integerLiteral(equals(3)))))))); EXPECT_TRUE(matches( - Program, callExpr(allOf( - callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))), - hasArgument(3, integerLiteral(equals(4))))))); + Program, + callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, ignoringParenImpCasts(declRefExpr(to(varDecl())))), + hasArgument(1, ignoringParenImpCasts( + hasType(pointsTo(recordDecl(hasName("T")))))), + hasArgument(2, ignoringParenImpCasts(integerLiteral(equals(3)))), + hasArgument(3, ignoringParenImpCasts(integerLiteral(equals(4)))))))); } TEST_P(ASTMatchersTest, Has) { @@ -512,18 +518,22 @@ void F() { S s(true); } )cpp"; - EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, - mapAnyOf(callExpr, cxxConstructExpr) - .with(hasArgument(0, trueExpr))))); - EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, - mapAnyOf(callExpr, cxxConstructExpr) - .with(hasArgument(0, falseExpr))))); + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + mapAnyOf(callExpr, cxxConstructExpr) + .with(hasArgument(0, ignoringParenImpCasts(trueExpr)))))); + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + mapAnyOf(callExpr, cxxConstructExpr) + .with(hasArgument(0, ignoringParenImpCasts(falseExpr)))))); - EXPECT_TRUE( - matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, - mapAnyOf(callExpr, cxxConstructExpr) - .with(hasArgument(0, expr()), - hasDeclaration(functionDecl()))))); + EXPECT_TRUE(matches( + Code, traverse(TK_IgnoreUnlessSpelledInSource, + mapAnyOf(callExpr, cxxConstructExpr) + .with(hasArgument(0, ignoringParenImpCasts(expr())), + hasDeclaration(functionDecl()))))); EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, mapAnyOf(callExpr, cxxConstructExpr)))); @@ -887,23 +897,26 @@ void doConstruct() )cpp"; EXPECT_TRUE(matches( - Code, traverse(TK_IgnoreUnlessSpelledInSource, - invocation(forFunction(functionDecl(hasName("doCall"))), - hasArgument(0, integerLiteral(equals(42))), - hasAnyArgument(integerLiteral(equals(42))), - forEachArgumentWithParam( - integerLiteral(equals(42)), - parmVarDecl(hasName("i"))))))); + Code, + traverse( + TK_IgnoreUnlessSpelledInSource, + invocation( + forFunction(functionDecl(hasName("doCall"))), + hasArgument(0, ignoringParenImpCasts(integerLiteral(equals(42)))), + hasAnyArgument(integerLiteral(equals(42))), + forEachArgumentWithParam(integerLiteral(equals(42)), + parmVarDecl(hasName("i"))))))); EXPECT_TRUE(matches( Code, traverse( TK_IgnoreUnlessSpelledInSource, - invocation(forFunction(functionDecl(hasName("doConstruct"))), - hasArgument(0, integerLiteral(equals(42))), - hasAnyArgument(integerLiteral(equals(42))), - forEachArgumentWithParam(integerLiteral(equals(42)), - parmVarDecl(hasName("i"))))))); + invocation( + forFunction(functionDecl(hasName("doConstruct"))), + hasArgument(0, ignoringParenImpCasts(integerLiteral(equals(42)))), + hasAnyArgument(integerLiteral(equals(42))), + forEachArgumentWithParam(integerLiteral(equals(42)), + parmVarDecl(hasName("i"))))))); } TEST_P(ASTMatchersTest, IsDerivedFrom) { @@ -1497,8 +1510,8 @@ TEST_P(ASTMatchersTest, IsInteger_MatchesIntegers) { EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger())))); EXPECT_TRUE( matches("long long i = 0; void f(long long) { }; void g() {f(i);}", - callExpr(hasArgument( - 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); + callExpr(hasArgument(0, ignoringParenImpCasts(declRefExpr(to( + varDecl(hasType(isInteger()))))))))); } TEST_P(ASTMatchersTest, IsInteger_ReportsNoFalsePositives) { @@ -1509,10 +1522,10 @@ TEST_P(ASTMatchersTest, IsInteger_ReportsNoFalsePositives) { } EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger())))); - EXPECT_TRUE( - notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}", - callExpr(hasArgument( - 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); + EXPECT_TRUE(notMatches( + "struct T {}; T t; void f(T *) { }; void g() {f(&t);}", + callExpr(hasArgument(0, ignoringParenImpCasts(declRefExpr( + to(varDecl(hasType(isInteger()))))))))); } TEST_P(ASTMatchersTest, IsSignedInteger_MatchesSignedIntegers) { @@ -2195,7 +2208,8 @@ TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) { auto Constructor = traverse( TK_AsIs, - cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))))); + cxxConstructExpr(hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))))); EXPECT_TRUE(matches( "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor)); @@ -2208,9 +2222,10 @@ TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) { EXPECT_TRUE(notMatches( "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor)); - StatementMatcher WrongIndex = - traverse(TK_AsIs, cxxConstructExpr(hasArgument( - 42, declRefExpr(to(varDecl(hasName("y"))))))); + StatementMatcher WrongIndex = traverse( + TK_AsIs, + cxxConstructExpr(hasArgument( + 42, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))))); EXPECT_TRUE(notMatches( "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex)); } @@ -2339,11 +2354,14 @@ TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) { const auto *Code = "template struct S{ S(int){} }; template void x() { int y; auto s = S(y); }"; - EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument( - 0, declRefExpr(to(varDecl(hasName("y")))))))); - EXPECT_TRUE( - notMatches(Code, cxxUnresolvedConstructExpr(hasArgument( - 0, declRefExpr(to(varDecl(hasName("x")))))))); + EXPECT_TRUE(matches( + Code, + cxxUnresolvedConstructExpr(hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))))))); + EXPECT_TRUE(notMatches( + Code, + cxxUnresolvedConstructExpr(hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("x"))))))))); } TEST_P(ASTMatchersTest, IsListInitialization) { diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index f198dc71eb8337..10242f7412f181 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -29,38 +29,37 @@ TEST(DeclarationMatcher, hasMethod) { } TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) { - EXPECT_TRUE(matches( - "template struct A {" - " template struct F {};" - "};" - "template struct B : A::template F {};" - "B b;", - cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl())))); + EXPECT_TRUE( + matches("template struct A {" + " template struct F {};" + "};" + "template struct B : A::template F {};" + "B b;", + cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl())))); } TEST(DeclarationMatcher, hasDeclContext) { - EXPECT_TRUE(matches( - "namespace N {" - " namespace M {" - " class D {};" - " }" - "}", - recordDecl(hasDeclContext(namespaceDecl(hasName("M")))))); - EXPECT_TRUE(notMatches( - "namespace N {" - " namespace M {" - " class D {};" - " }" - "}", - recordDecl(hasDeclContext(namespaceDecl(hasName("N")))))); + EXPECT_TRUE(matches("namespace N {" + " namespace M {" + " class D {};" + " }" + "}", + recordDecl(hasDeclContext(namespaceDecl(hasName("M")))))); + EXPECT_TRUE( + notMatches("namespace N {" + " namespace M {" + " class D {};" + " }" + "}", + recordDecl(hasDeclContext(namespaceDecl(hasName("N")))))); EXPECT_TRUE(matches("namespace {" - " namespace M {" - " class D {};" - " }" - "}", + " namespace M {" + " class D {};" + " }" + "}", recordDecl(hasDeclContext(namespaceDecl( - hasName("M"), hasDeclContext(namespaceDecl())))))); + hasName("M"), hasDeclContext(namespaceDecl())))))); EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl())))); } @@ -68,8 +67,8 @@ TEST(DeclarationMatcher, hasDeclContext) { TEST(HasDescendant, MatchesDescendantTypes) { EXPECT_TRUE(matches("void f() { int i = 3; }", decl(hasDescendant(loc(builtinType()))))); - EXPECT_TRUE(matches("void f() { int i = 3; }", - stmt(hasDescendant(builtinType())))); + EXPECT_TRUE( + matches("void f() { int i = 3; }", stmt(hasDescendant(builtinType())))); EXPECT_TRUE(matches("void f() { int i = 3; }", stmt(hasDescendant(loc(builtinType()))))); @@ -80,46 +79,41 @@ TEST(HasDescendant, MatchesDescendantTypes) { stmt(hasDescendant(isInteger())))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() { int a; float c; int d; int e; }", - functionDecl(forEachDescendant( - varDecl(hasDescendant(isInteger())).bind("x"))), - std::make_unique>("x", 3))); + "void f() { int a; float c; int d; int e; }", + functionDecl( + forEachDescendant(varDecl(hasDescendant(isInteger())).bind("x"))), + std::make_unique>("x", 3))); } TEST(HasDescendant, MatchesDescendantsOfTypes) { EXPECT_TRUE(matches("void f() { int*** i; }", qualType(hasDescendant(builtinType())))); - EXPECT_TRUE(matches("void f() { int*** i; }", - qualType(hasDescendant( - pointerType(pointee(builtinType())))))); + EXPECT_TRUE( + matches("void f() { int*** i; }", + qualType(hasDescendant(pointerType(pointee(builtinType())))))); EXPECT_TRUE(matches("void f() { int*** i; }", typeLoc(hasDescendant(loc(builtinType()))))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() { int*** i; }", - qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))), - std::make_unique>("x", 2))); + "void f() { int*** i; }", + qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))), + std::make_unique>("x", 2))); } - TEST(Has, MatchesChildrenOfTypes) { - EXPECT_TRUE(matches("int i;", - varDecl(hasName("i"), has(isInteger())))); - EXPECT_TRUE(notMatches("int** i;", - varDecl(hasName("i"), has(isInteger())))); + EXPECT_TRUE(matches("int i;", varDecl(hasName("i"), has(isInteger())))); + EXPECT_TRUE(notMatches("int** i;", varDecl(hasName("i"), has(isInteger())))); EXPECT_TRUE(matchAndVerifyResultTrue( - "int (*f)(float, int);", - qualType(functionType(), forEach(qualType(isInteger()).bind("x"))), - std::make_unique>("x", 2))); + "int (*f)(float, int);", + qualType(functionType(), forEach(qualType(isInteger()).bind("x"))), + std::make_unique>("x", 2))); } TEST(Has, MatchesChildTypes) { EXPECT_TRUE(matches( - "int* i;", - varDecl(hasName("i"), hasType(qualType(has(builtinType())))))); + "int* i;", varDecl(hasName("i"), hasType(qualType(has(builtinType())))))); EXPECT_TRUE(notMatches( - "int* i;", - varDecl(hasName("i"), hasType(qualType(has(pointerType())))))); + "int* i;", varDecl(hasName("i"), hasType(qualType(has(pointerType())))))); } TEST(StatementMatcher, Has) { @@ -127,23 +121,23 @@ TEST(StatementMatcher, Has) { expr(hasType(pointsTo(recordDecl(hasName("X")))), has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i"))))))); - EXPECT_TRUE(matches( - "class X; X *x(int); void c() { int i; x(i); }", HasVariableI)); - EXPECT_TRUE(notMatches( - "class X; X *x(int); void c() { int i; x(42); }", HasVariableI)); + EXPECT_TRUE( + matches("class X; X *x(int); void c() { int i; x(i); }", HasVariableI)); + EXPECT_TRUE(notMatches("class X; X *x(int); void c() { int i; x(42); }", + HasVariableI)); } TEST(StatementMatcher, HasDescendant) { StatementMatcher HasDescendantVariableI = - expr(hasType(pointsTo(recordDecl(hasName("X")))), - hasDescendant(declRefExpr(to(varDecl(hasName("i")))))); + expr(hasType(pointsTo(recordDecl(hasName("X")))), + hasDescendant(declRefExpr(to(varDecl(hasName("i")))))); - EXPECT_TRUE(matches( - "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }", - HasDescendantVariableI)); + EXPECT_TRUE( + matches("class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }", + HasDescendantVariableI)); EXPECT_TRUE(notMatches( - "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }", - HasDescendantVariableI)); + "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }", + HasDescendantVariableI)); } TEST(TypeMatcher, MatchesClassType) { @@ -153,17 +147,17 @@ TEST(TypeMatcher, MatchesClassType) { EXPECT_TRUE(notMatches("class A {};", TypeA)); TypeMatcher TypeDerivedFromA = - hasDeclaration(cxxRecordDecl(isDerivedFrom("A"))); + hasDeclaration(cxxRecordDecl(isDerivedFrom("A"))); EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };", TypeDerivedFromA)); EXPECT_TRUE(notMatches("class A {};", TypeA)); - TypeMatcher TypeAHasClassB = hasDeclaration( - recordDecl(hasName("A"), has(recordDecl(hasName("B"))))); + TypeMatcher TypeAHasClassB = + hasDeclaration(recordDecl(hasName("A"), has(recordDecl(hasName("B"))))); EXPECT_TRUE( - matches("class A { public: A *a; class B {}; };", TypeAHasClassB)); + matches("class A { public: A *a; class B {}; };", TypeAHasClassB)); EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }", varDecl(hasType(namedDecl(hasName("S")))))); @@ -178,8 +172,8 @@ TEST(TypeMatcher, MatchesDeclTypes) { parmVarDecl(hasType(objcObjectPointerType())))); // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl EXPECT_TRUE(matchesObjC( - "@interface Foo @end void f(Foo *f);", - parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo"))))))); + "@interface Foo @end void f(Foo *f);", + parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo"))))))); // TemplateTypeParmType EXPECT_TRUE(matches("template void f(T t);", parmVarDecl(hasType(templateTypeParmType())))); @@ -199,20 +193,20 @@ TEST(TypeMatcher, MatchesDeclTypes) { namesType(injectedClassNameType())))))); // InjectedClassNameType -> CXXRecordDecl EXPECT_TRUE(matches("template struct S {" - " void f(S s);" - "};", + " void f(S s);" + "};", parmVarDecl(hasType(namedDecl(hasName("S")))))); static const char Using[] = "template " - "struct Base {" - " typedef T Foo;" - "};" - "" - "template " - "struct S : private Base {" - " using typename Base::Foo;" - " void f(Foo);" - "};"; + "struct Base {" + " typedef T Foo;" + "};" + "" + "template " + "struct S : private Base {" + " using typename Base::Foo;" + " void f(Foo);" + "};"; // UnresolvedUsingTypenameDecl EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo")))); // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl @@ -222,7 +216,7 @@ TEST(TypeMatcher, MatchesDeclTypes) { TEST(HasDeclaration, HasDeclarationOfEnumType) { EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }", expr(hasType(pointsTo( - qualType(hasDeclaration(enumDecl(hasName("X"))))))))); + qualType(hasDeclaration(enumDecl(hasName("X"))))))))); } TEST(HasDeclaration, HasGetDeclTraitTest) { @@ -235,10 +229,10 @@ TEST(HasDeclaration, HasGetDeclTraitTest) { } TEST(HasDeclaration, ElaboratedType) { - EXPECT_TRUE(matches( - "namespace n { template struct X {}; }" - "void f(n::X);", - parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl())))))); + EXPECT_TRUE( + matches("namespace n { template struct X {}; }" + "void f(n::X);", + parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl())))))); EXPECT_TRUE(matches( "namespace n { template struct X {}; }" "void f(n::X);", @@ -310,24 +304,21 @@ TEST(HasUnderlyingDecl, Matches) { TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) { TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); EXPECT_TRUE( - matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); + matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); EXPECT_TRUE( - notMatches("class X {}; void y(X *x) { x; }", - expr(hasType(ClassX)))); - EXPECT_TRUE( - matches("class X {}; void y(X *x) { x; }", - expr(hasType(pointsTo(ClassX))))); + notMatches("class X {}; void y(X *x) { x; }", expr(hasType(ClassX)))); + EXPECT_TRUE(matches("class X {}; void y(X *x) { x; }", + expr(hasType(pointsTo(ClassX))))); } TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) { TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); EXPECT_TRUE( - matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); - EXPECT_TRUE( - notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); + matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); EXPECT_TRUE( - matches("class X {}; void y() { X *x; }", - varDecl(hasType(pointsTo(ClassX))))); + notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); + EXPECT_TRUE(matches("class X {}; void y() { X *x; }", + varDecl(hasType(pointsTo(ClassX))))); } TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) { @@ -342,18 +333,17 @@ TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) { TEST(HasType, TakesDeclMatcherAndMatchesExpr) { DeclarationMatcher ClassX = recordDecl(hasName("X")); EXPECT_TRUE( - matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); + matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); EXPECT_TRUE( - notMatches("class X {}; void y(X *x) { x; }", - expr(hasType(ClassX)))); + notMatches("class X {}; void y(X *x) { x; }", expr(hasType(ClassX)))); } TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) { DeclarationMatcher ClassX = recordDecl(hasName("X")); EXPECT_TRUE( - matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); + matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); EXPECT_TRUE( - notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); + notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); } TEST(HasType, TakesDeclMatcherAndMatchesCXXBaseSpecifier) { @@ -376,13 +366,15 @@ TEST(HasType, MatchesTypedefDecl) { } TEST(HasType, MatchesTypedefNameDecl) { - EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int"))))); + EXPECT_TRUE( + matches("using X = int;", typedefNameDecl(hasType(asString("int"))))); EXPECT_TRUE(matches("using T = const int;", typedefNameDecl(hasType(asString("const int"))))); EXPECT_TRUE(notMatches("using T = const int;", typedefNameDecl(hasType(asString("int"))))); - EXPECT_TRUE(matches("using foo = int; using bar = foo;", - typedefNameDecl(hasType(asString("foo")), hasName("bar")))); + EXPECT_TRUE( + matches("using foo = int; using bar = foo;", + typedefNameDecl(hasType(asString("foo")), hasName("bar")))); } TEST(HasTypeLoc, MatchesBlockDecl) { @@ -491,7 +483,7 @@ TEST(Callee, MatchesDeclarations) { CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl()))); EXPECT_TRUE( - matches("struct Y { operator int() const; }; int i = Y();", CallMethodX)); + matches("struct Y { operator int() const; }; int i = Y();", CallMethodX)); EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();", CallMethodX)); } @@ -499,21 +491,21 @@ TEST(Callee, MatchesDeclarations) { TEST(Callee, MatchesMemberExpressions) { EXPECT_TRUE(matches("class Y { void x() { this->x(); } };", callExpr(callee(memberExpr())))); - EXPECT_TRUE( - notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr())))); + EXPECT_TRUE(notMatches("class Y { void x() { this->x(); } };", + callExpr(callee(callExpr())))); } TEST(Matcher, Argument) { - StatementMatcher CallArgumentY = callExpr( - hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))); + StatementMatcher CallArgumentY = callExpr(hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))))); EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY)); EXPECT_TRUE( - matches("class X { void x(int) { int y; x(y); } };", CallArgumentY)); + matches("class X { void x(int) { int y; x(y); } };", CallArgumentY)); EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY)); - StatementMatcher WrongIndex = callExpr( - hasArgument(42, declRefExpr(to(varDecl(hasName("y")))))); + StatementMatcher WrongIndex = callExpr(hasArgument( + 42, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))))); EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex)); } @@ -718,78 +710,68 @@ void coro() try { )cpp"; EXPECT_TRUE(matchesConditionally( CoroWithTryCatchDeclCode, - coroutineBodyStmt(hasBody(compoundStmt(has(cxxTryStmt(has(compoundStmt(has( - declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))))))), + coroutineBodyStmt( + hasBody(compoundStmt(has(cxxTryStmt(has(compoundStmt(has(declStmt( + containsDeclaration(0, varDecl(hasName("thevar")))))))))))), true, {"-std=c++20", "-I/"}, M)); } TEST(Matcher, isClassMessage) { - EXPECT_TRUE(matchesObjC( - "@interface NSString +(NSString *) stringWithFormat; @end " - "void f() { [NSString stringWithFormat]; }", - objcMessageExpr(isClassMessage()))); + EXPECT_TRUE( + matchesObjC("@interface NSString +(NSString *) stringWithFormat; @end " + "void f() { [NSString stringWithFormat]; }", + objcMessageExpr(isClassMessage()))); - EXPECT_FALSE(matchesObjC( - "@interface NSString @end " - "void f(NSString *x) {" - "[x containsString];" - "}", - objcMessageExpr(isClassMessage()))); + EXPECT_FALSE(matchesObjC("@interface NSString @end " + "void f(NSString *x) {" + "[x containsString];" + "}", + objcMessageExpr(isClassMessage()))); } TEST(Matcher, isInstanceMessage) { - EXPECT_TRUE(matchesObjC( - "@interface NSString @end " - "void f(NSString *x) {" - "[x containsString];" - "}", - objcMessageExpr(isInstanceMessage()))); - - EXPECT_FALSE(matchesObjC( - "@interface NSString +(NSString *) stringWithFormat; @end " - "void f() { [NSString stringWithFormat]; }", - objcMessageExpr(isInstanceMessage()))); + EXPECT_TRUE(matchesObjC("@interface NSString @end " + "void f(NSString *x) {" + "[x containsString];" + "}", + objcMessageExpr(isInstanceMessage()))); + EXPECT_FALSE( + matchesObjC("@interface NSString +(NSString *) stringWithFormat; @end " + "void f() { [NSString stringWithFormat]; }", + objcMessageExpr(isInstanceMessage()))); } TEST(Matcher, isClassMethod) { - EXPECT_TRUE(matchesObjC( - "@interface Bar + (void)bar; @end", - objcMethodDecl(isClassMethod()))); + EXPECT_TRUE(matchesObjC("@interface Bar + (void)bar; @end", + objcMethodDecl(isClassMethod()))); - EXPECT_TRUE(matchesObjC( - "@interface Bar @end" - "@implementation Bar + (void)bar {} @end", - objcMethodDecl(isClassMethod()))); + EXPECT_TRUE(matchesObjC("@interface Bar @end" + "@implementation Bar + (void)bar {} @end", + objcMethodDecl(isClassMethod()))); - EXPECT_FALSE(matchesObjC( - "@interface Foo - (void)foo; @end", - objcMethodDecl(isClassMethod()))); + EXPECT_FALSE(matchesObjC("@interface Foo - (void)foo; @end", + objcMethodDecl(isClassMethod()))); - EXPECT_FALSE(matchesObjC( - "@interface Foo @end " - "@implementation Foo - (void)foo {} @end", - objcMethodDecl(isClassMethod()))); + EXPECT_FALSE(matchesObjC("@interface Foo @end " + "@implementation Foo - (void)foo {} @end", + objcMethodDecl(isClassMethod()))); } TEST(Matcher, isInstanceMethod) { - EXPECT_TRUE(matchesObjC( - "@interface Foo - (void)foo; @end", - objcMethodDecl(isInstanceMethod()))); + EXPECT_TRUE(matchesObjC("@interface Foo - (void)foo; @end", + objcMethodDecl(isInstanceMethod()))); - EXPECT_TRUE(matchesObjC( - "@interface Foo @end " - "@implementation Foo - (void)foo {} @end", - objcMethodDecl(isInstanceMethod()))); + EXPECT_TRUE(matchesObjC("@interface Foo @end " + "@implementation Foo - (void)foo {} @end", + objcMethodDecl(isInstanceMethod()))); - EXPECT_FALSE(matchesObjC( - "@interface Bar + (void)bar; @end", - objcMethodDecl(isInstanceMethod()))); + EXPECT_FALSE(matchesObjC("@interface Bar + (void)bar; @end", + objcMethodDecl(isInstanceMethod()))); - EXPECT_FALSE(matchesObjC( - "@interface Bar @end" - "@implementation Bar + (void)bar {} @end", - objcMethodDecl(isInstanceMethod()))); + EXPECT_FALSE(matchesObjC("@interface Bar @end" + "@implementation Bar + (void)bar {} @end", + objcMethodDecl(isInstanceMethod()))); } TEST(MatcherCXXMemberCallExpr, On) { @@ -887,10 +869,10 @@ TEST(Matcher, HasObjectExpr) { TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) { StatementMatcher ArgumentY = - declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); StatementMatcher CallExpr = - callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); // IntParam does not match. EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr)); @@ -900,77 +882,75 @@ TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) { TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) { StatementMatcher ArgumentY = - declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); StatementMatcher CallExpr = - callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); EXPECT_TRUE(matchAndVerifyResultTrue( - "struct S {" + "struct S {" " const S& operator[](int i) { return *this; }" "};" "void f(S S1) {" " int y = 1;" " S1[y];" "}", - CallExpr, std::make_unique>("param", 1))); + CallExpr, std::make_unique>("param", 1))); StatementMatcher CallExpr2 = - callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); EXPECT_TRUE(matchAndVerifyResultTrue( - "struct S {" + "struct S {" " static void g(int i);" "};" "void f() {" " int y = 1;" " S::g(y);" "}", - CallExpr2, std::make_unique>("param", 1))); + CallExpr2, std::make_unique>("param", 1))); } TEST(ForEachArgumentWithParam, MatchesCallExpr) { StatementMatcher ArgumentY = - declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); StatementMatcher CallExpr = - callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); - EXPECT_TRUE( - matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, - std::make_unique>( - "param"))); - EXPECT_TRUE( - matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, - std::make_unique>( - "arg"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "void f(int i) { int y; f(y); }", CallExpr, + std::make_unique>("param"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "void f(int i) { int y; f(y); }", CallExpr, + std::make_unique>("arg"))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void f(int i, int j) { int y; f(y, y); }", CallExpr, - std::make_unique>("param", 2))); + "void f(int i, int j) { int y; f(y, y); }", CallExpr, + std::make_unique>("param", 2))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void f(int i, int j) { int y; f(y, y); }", CallExpr, - std::make_unique>("arg", 2))); + "void f(int i, int j) { int y; f(y, y); }", CallExpr, + std::make_unique>("arg", 2))); } TEST(ForEachArgumentWithParam, MatchesConstructExpr) { StatementMatcher ArgumentY = - declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); StatementMatcher ConstructExpr = traverse( TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam))); EXPECT_TRUE(matchAndVerifyResultTrue( - "struct C {" + "struct C {" " C(int i) {}" "};" "int y = 0;" "C Obj(y);", - ConstructExpr, - std::make_unique>("param"))); + ConstructExpr, + std::make_unique>("param"))); } TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) { EXPECT_TRUE(matchAndVerifyResultTrue( - "void g(int i, int j) {" + "void g(int i, int j) {" " int a;" " int b;" " int c;" @@ -978,11 +958,11 @@ TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) { " g(a, b);" " g(0, b);" "}", - functionDecl( - forEachDescendant(varDecl().bind("v")), - forEachDescendant(callExpr(forEachArgumentWithParam( - declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))), - std::make_unique>("v", 4))); + functionDecl( + forEachDescendant(varDecl().bind("v")), + forEachDescendant(callExpr(forEachArgumentWithParam( + declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))), + std::make_unique>("v", 4))); } TEST_P(ASTMatchersTest, @@ -1233,14 +1213,14 @@ TEST_P(ASTMatchersTest, TEST(QualType, hasCanonicalType) { EXPECT_TRUE(notMatches("typedef int &int_ref;" - "int a;" - "int_ref b = a;", + "int a;" + "int_ref b = a;", varDecl(hasType(qualType(referenceType()))))); EXPECT_TRUE( - matches("typedef int &int_ref;" + matches("typedef int &int_ref;" "int a;" "int_ref b = a;", - varDecl(hasType(qualType(hasCanonicalType(referenceType())))))); + varDecl(hasType(qualType(hasCanonicalType(referenceType())))))); } TEST(HasParameter, CallsInnerMatcher) { @@ -1261,26 +1241,26 @@ TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) { TEST(HasType, MatchesParameterVariableTypesStrictly) { EXPECT_TRUE(matches( - "class X { void x(X x) {} };", - cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); + "class X { void x(X x) {} };", + cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); EXPECT_TRUE(notMatches( - "class X { void x(const X &x) {} };", - cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); + "class X { void x(const X &x) {} };", + cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); EXPECT_TRUE(matches("class X { void x(const X *x) {} };", cxxMethodDecl(hasParameter( - 0, hasType(pointsTo(recordDecl(hasName("X")))))))); + 0, hasType(pointsTo(recordDecl(hasName("X")))))))); EXPECT_TRUE(matches("class X { void x(const X &x) {} };", cxxMethodDecl(hasParameter( - 0, hasType(references(recordDecl(hasName("X")))))))); + 0, hasType(references(recordDecl(hasName("X")))))))); } TEST(HasAnyParameter, MatchesIndependentlyOfPosition) { EXPECT_TRUE(matches( - "class Y {}; class X { void x(X x, Y y) {} };", - cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); + "class Y {}; class X { void x(X x, Y y) {} };", + cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); EXPECT_TRUE(matches( - "class Y {}; class X { void x(Y y, X x) {} };", - cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); + "class Y {}; class X { void x(Y y, X x) {} };", + cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end", objcMethodDecl(hasAnyParameter(hasName("x"))))); EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }", @@ -1292,21 +1272,21 @@ TEST(Returns, MatchesReturnTypes) { functionDecl(returns(asString("int"))))); EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };", functionDecl(returns(asString("float"))))); - EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };", - functionDecl(returns(hasDeclaration( - recordDecl(hasName("Y"))))))); + EXPECT_TRUE( + matches("class Y { Y getMe() { return *this; } };", + functionDecl(returns(hasDeclaration(recordDecl(hasName("Y"))))))); } TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) { EXPECT_TRUE(notMatches( - "class Y {}; class X { void x(int) {} };", - cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); + "class Y {}; class X { void x(int) {} };", + cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); } TEST(HasAnyParameter, DoesNotMatchThisPointer) { EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };", cxxMethodDecl(hasAnyParameter( - hasType(pointsTo(recordDecl(hasName("X")))))))); + hasType(pointsTo(recordDecl(hasName("X")))))))); } TEST(HasName, MatchesParameterVariableDeclarations) { @@ -1317,11 +1297,10 @@ TEST(HasName, MatchesParameterVariableDeclarations) { } TEST(Matcher, MatchesTypeTemplateArgument) { - EXPECT_TRUE(matches( - "template struct B {};" - "B b;", - classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType( - asString("int")))))); + EXPECT_TRUE(matches("template struct B {};" + "B b;", + classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToType(asString("int")))))); } TEST(Matcher, MatchesTemplateTemplateArgument) { @@ -1333,113 +1312,102 @@ TEST(Matcher, MatchesTemplateTemplateArgument) { } TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) { - EXPECT_TRUE(matches( - "struct B { int next; };" - "template struct A {};" - "A<&B::next> a;", - classTemplateSpecializationDecl(hasAnyTemplateArgument( - refersToDeclaration(fieldDecl(hasName("next"))))))); + EXPECT_TRUE(matches("struct B { int next; };" + "template struct A {};" + "A<&B::next> a;", + classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToDeclaration(fieldDecl(hasName("next"))))))); - EXPECT_TRUE(notMatches( - "template struct A {};" - "A a;", - classTemplateSpecializationDecl(hasAnyTemplateArgument( - refersToDeclaration(decl()))))); + EXPECT_TRUE(notMatches("template struct A {};" + "A a;", + classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToDeclaration(decl()))))); EXPECT_TRUE(matches( - "struct B { int next; };" + "struct B { int next; };" "template struct A {};" "A<&B::next> a;", - templateSpecializationType(hasAnyTemplateArgument(isExpr( - hasDescendant(declRefExpr(to(fieldDecl(hasName("next")))))))))); + templateSpecializationType(hasAnyTemplateArgument(isExpr( + hasDescendant(declRefExpr(to(fieldDecl(hasName("next")))))))))); - EXPECT_TRUE(notMatches( - "template struct A {};" - "A a;", - templateSpecializationType(hasAnyTemplateArgument( - refersToDeclaration(decl()))))); + EXPECT_TRUE(notMatches("template struct A {};" + "A a;", + templateSpecializationType(hasAnyTemplateArgument( + refersToDeclaration(decl()))))); } - TEST(Matcher, MatchesSpecificArgument) { - EXPECT_TRUE(matches( - "template class A {};" - "A a;", - classTemplateSpecializationDecl(hasTemplateArgument( - 1, refersToType(asString("int")))))); - EXPECT_TRUE(notMatches( - "template class A {};" - "A a;", - classTemplateSpecializationDecl(hasTemplateArgument( - 1, refersToType(asString("int")))))); - - EXPECT_TRUE(matches( - "template class A {};" - "A a;", - templateSpecializationType(hasTemplateArgument( - 1, refersToType(asString("int")))))); - EXPECT_TRUE(notMatches( - "template class A {};" - "A a;", - templateSpecializationType(hasTemplateArgument( - 1, refersToType(asString("int")))))); - - EXPECT_TRUE(matches( - "template void f() {};" + EXPECT_TRUE(matches("template class A {};" + "A a;", + classTemplateSpecializationDecl(hasTemplateArgument( + 1, refersToType(asString("int")))))); + EXPECT_TRUE(notMatches("template class A {};" + "A a;", + classTemplateSpecializationDecl(hasTemplateArgument( + 1, refersToType(asString("int")))))); + + EXPECT_TRUE(matches("template class A {};" + "A a;", + templateSpecializationType(hasTemplateArgument( + 1, refersToType(asString("int")))))); + EXPECT_TRUE(notMatches("template class A {};" + "A a;", + templateSpecializationType(hasTemplateArgument( + 1, refersToType(asString("int")))))); + + EXPECT_TRUE(matches( + "template void f() {};" "void func() { f(); }", - functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); + functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); EXPECT_TRUE(notMatches( - "template void f() {};", - functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); + "template void f() {};", + functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); } TEST(TemplateArgument, Matches) { EXPECT_TRUE(matches("template struct C {}; C c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(templateArgument())))); + hasAnyTemplateArgument(templateArgument())))); EXPECT_TRUE(matches( - "template struct C {}; C c;", - templateSpecializationType(hasAnyTemplateArgument(templateArgument())))); + "template struct C {}; C c;", + templateSpecializationType(hasAnyTemplateArgument(templateArgument())))); - EXPECT_TRUE(matches( - "template void f() {};" - "void func() { f(); }", - functionDecl(hasAnyTemplateArgument(templateArgument())))); + EXPECT_TRUE( + matches("template void f() {};" + "void func() { f(); }", + functionDecl(hasAnyTemplateArgument(templateArgument())))); } TEST(TemplateTypeParmDecl, CXXMethodDecl) { - const char input[] = - "template\n" - "class Class {\n" - " void method();\n" - "};\n" - "template\n" - "void Class::method() {}\n"; + const char input[] = "template\n" + "class Class {\n" + " void method();\n" + "};\n" + "template\n" + "void Class::method() {}\n"; EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); } TEST(TemplateTypeParmDecl, VarDecl) { - const char input[] = - "template\n" - "class Class {\n" - " static T pi;\n" - "};\n" - "template\n" - "U Class::pi = U(3.1415926535897932385);\n"; + const char input[] = "template\n" + "class Class {\n" + " static T pi;\n" + "};\n" + "template\n" + "U Class::pi = U(3.1415926535897932385);\n"; EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); } TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) { - const char input[] = - "template\n" - "struct Struct {\n" - " template static int field;\n" - "};\n" - "template\n" - "template\n" - "int Struct::field = 123;\n"; + const char input[] = "template\n" + "struct Struct {\n" + " template static int field;\n" + "};\n" + "template\n" + "template\n" + "int Struct::field = 123;\n"; EXPECT_TRUE( matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater())); EXPECT_TRUE( @@ -1451,14 +1419,13 @@ TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) { } TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) { - const char input[] = - "template\n" - "class Class {\n" - " template struct Struct;\n" - "};\n" - "template\n" - "template\n" - "struct Class::Struct {};\n"; + const char input[] = "template\n" + "class Class {\n" + " template struct Struct;\n" + "};\n" + "template\n" + "template\n" + "struct Class::Struct {};\n"; EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); @@ -1466,42 +1433,39 @@ TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) { } TEST(TemplateTypeParmDecl, EnumDecl) { - const char input[] = - "template\n" - "struct Struct {\n" - " enum class Enum : T;\n" - "};\n" - "template\n" - "enum class Struct::Enum : U {\n" - " e1,\n" - " e2\n" - "};\n"; + const char input[] = "template\n" + "struct Struct {\n" + " enum class Enum : T;\n" + "};\n" + "template\n" + "enum class Struct::Enum : U {\n" + " e1,\n" + " e2\n" + "};\n"; EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); } TEST(TemplateTypeParmDecl, RecordDecl) { - const char input[] = - "template\n" - "class Class {\n" - " struct Struct;\n" - "};\n" - "template\n" - "struct Class::Struct {\n" - " U field;\n" - "};\n"; + const char input[] = "template\n" + "class Class {\n" + " struct Struct;\n" + "};\n" + "template\n" + "struct Class::Struct {\n" + " U field;\n" + "};\n"; EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); } TEST(RefersToIntegralType, Matches) { EXPECT_TRUE(matches("template struct C {}; C<42> c;", - classTemplateSpecializationDecl( - hasAnyTemplateArgument(refersToIntegralType( - asString("int")))))); + classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToIntegralType(asString("int")))))); EXPECT_TRUE(notMatches("template struct C {}; C<42> c;", classTemplateSpecializationDecl(hasAnyTemplateArgument( - refersToIntegralType(asString("int")))))); + refersToIntegralType(asString("int")))))); } TEST(ConstructorDeclaration, SimpleCase) { @@ -1517,92 +1481,98 @@ TEST(DestructorDeclaration, MatchesVirtualDestructor) { } TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) { - EXPECT_TRUE(notMatches("class Foo {};", - cxxDestructorDecl(ofClass(hasName("Foo"))))); + EXPECT_TRUE( + notMatches("class Foo {};", cxxDestructorDecl(ofClass(hasName("Foo"))))); } TEST(HasAnyConstructorInitializer, SimpleCase) { EXPECT_TRUE( - notMatches("class Foo { Foo() { } };", - cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); + notMatches("class Foo { Foo() { } };", + cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); EXPECT_TRUE( - matches("class Foo {" + matches("class Foo {" " Foo() : foo_() { }" " int foo_;" "};", - cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); + cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); } TEST(HasAnyConstructorInitializer, ForField) { - static const char Code[] = - "class Baz { };" - "class Foo {" - " Foo() : foo_(), bar_() { }" - " Baz foo_;" - " struct {" - " Baz bar_;" - " };" - "};"; + static const char Code[] = "class Baz { };" + "class Foo {" + " Foo() : foo_(), bar_() { }" + " Baz foo_;" + " struct {" + " Baz bar_;" + " };" + "};"; + EXPECT_TRUE( + matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( + forField(hasType(recordDecl(hasName("Baz")))))))); EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - forField(hasType(recordDecl(hasName("Baz")))))))); + forField(hasName("foo_")))))); EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - forField(hasName("foo_")))))); - EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - forField(hasName("bar_")))))); - EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - forField(hasType(recordDecl(hasName("Bar")))))))); + forField(hasName("bar_")))))); + EXPECT_TRUE( + notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( + forField(hasType(recordDecl(hasName("Bar")))))))); } TEST(HasAnyConstructorInitializer, WithInitializer) { - static const char Code[] = - "class Foo {" - " Foo() : foo_(0) { }" - " int foo_;" - "};"; + static const char Code[] = "class Foo {" + " Foo() : foo_(0) { }" + " int foo_;" + "};"; EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - withInitializer(integerLiteral(equals(0))))))); - EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - withInitializer(integerLiteral(equals(1))))))); + withInitializer(integerLiteral(equals(0))))))); + EXPECT_TRUE( + notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( + withInitializer(integerLiteral(equals(1))))))); } TEST(HasAnyConstructorInitializer, IsWritten) { - static const char Code[] = - "struct Bar { Bar(){} };" - "class Foo {" - " Foo() : foo_() { }" - " Bar foo_;" - " Bar bar_;" - "};"; - EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - allOf(forField(hasName("foo_")), isWritten()))))); - EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - allOf(forField(hasName("bar_")), isWritten()))))); - EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( - allOf(forField(hasName("bar_")), unless(isWritten())))))); + static const char Code[] = "struct Bar { Bar(){} };" + "class Foo {" + " Foo() : foo_() { }" + " Bar foo_;" + " Bar bar_;" + "};"; + EXPECT_TRUE( + matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( + allOf(forField(hasName("foo_")), isWritten()))))); + EXPECT_TRUE( + notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( + allOf(forField(hasName("bar_")), isWritten()))))); + EXPECT_TRUE( + matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(allOf( + forField(hasName("bar_")), unless(isWritten())))))); } TEST(HasAnyConstructorInitializer, IsBaseInitializer) { - static const char Code[] = - "struct B {};" - "struct D : B {" - " int I;" - " D(int i) : I(i) {}" - "};" - "struct E : B {" - " E() : B() {}" - "};"; - EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf( - hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())), - hasName("E"))))); - EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf( - hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())), - hasName("D"))))); - EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf( - hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())), - hasName("D"))))); - EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf( - hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())), - hasName("E"))))); + static const char Code[] = "struct B {};" + "struct D : B {" + " int I;" + " D(int i) : I(i) {}" + "};" + "struct E : B {" + " E() : B() {}" + "};"; + EXPECT_TRUE(matches( + Code, cxxConstructorDecl(allOf(hasAnyConstructorInitializer(allOf( + isBaseInitializer(), isWritten())), + hasName("E"))))); + EXPECT_TRUE(notMatches( + Code, cxxConstructorDecl(allOf(hasAnyConstructorInitializer(allOf( + isBaseInitializer(), isWritten())), + hasName("D"))))); + EXPECT_TRUE(matches( + Code, cxxConstructorDecl(allOf(hasAnyConstructorInitializer(allOf( + isMemberInitializer(), isWritten())), + hasName("D"))))); + EXPECT_TRUE(notMatches( + Code, cxxConstructorDecl(allOf(hasAnyConstructorInitializer(allOf( + isMemberInitializer(), isWritten())), + hasName("E"))))); } TEST(IfStmt, ChildTraversalMatchers) { @@ -1638,8 +1608,8 @@ TEST(MatchBinaryOperator, HasAnyOperatorName) { TEST(MatchBinaryOperator, HasLHSAndHasRHS) { StatementMatcher OperatorTrueFalse = - binaryOperator(hasLHS(cxxBoolLiteral(equals(true))), - hasRHS(cxxBoolLiteral(equals(false)))); + binaryOperator(hasLHS(cxxBoolLiteral(equals(true))), + hasRHS(cxxBoolLiteral(equals(false)))); EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse)); EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse)); @@ -1733,7 +1703,7 @@ void opFree() TEST(MatchBinaryOperator, HasEitherOperand) { StatementMatcher HasOperand = - binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false)))); + binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false)))); EXPECT_TRUE(matches("void x() { true || false; }", HasOperand)); EXPECT_TRUE(matches("void x() { false && true; }", HasOperand)); @@ -1756,100 +1726,86 @@ TEST(Matcher, BinaryOperatorTypes) { // a way we expect. // FIXME: Operator ',' EXPECT_TRUE( - matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(",")))); + matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(",")))); + EXPECT_TRUE(matches("bool b; bool c = (b = true);", + binaryOperator(hasOperatorName("=")))); EXPECT_TRUE( - matches("bool b; bool c = (b = true);", - binaryOperator(hasOperatorName("=")))); + matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!=")))); EXPECT_TRUE( - matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!=")))); - EXPECT_TRUE( - matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("==")))); + matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("==")))); EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<")))); EXPECT_TRUE( - matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<=")))); - EXPECT_TRUE( - matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<")))); + matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<=")))); EXPECT_TRUE( - matches("int i = 1; int j = (i <<= 2);", - binaryOperator(hasOperatorName("<<=")))); + matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<")))); + EXPECT_TRUE(matches("int i = 1; int j = (i <<= 2);", + binaryOperator(hasOperatorName("<<=")))); EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">")))); EXPECT_TRUE( - matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">=")))); - EXPECT_TRUE( - matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>")))); - EXPECT_TRUE( - matches("int i = 1; int j = (i >>= 2);", - binaryOperator(hasOperatorName(">>=")))); - EXPECT_TRUE( - matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^")))); - EXPECT_TRUE( - matches("int i = 42; int j = (i ^= 42);", - binaryOperator(hasOperatorName("^=")))); - EXPECT_TRUE( - matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%")))); - EXPECT_TRUE( - matches("int i = 42; int j = (i %= 42);", - binaryOperator(hasOperatorName("%=")))); - EXPECT_TRUE( - matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&")))); + matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">=")))); EXPECT_TRUE( - matches("bool b = true && false;", - binaryOperator(hasOperatorName("&&")))); + matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>")))); + EXPECT_TRUE(matches("int i = 1; int j = (i >>= 2);", + binaryOperator(hasOperatorName(">>=")))); EXPECT_TRUE( - matches("bool b = true; bool c = (b &= false);", - binaryOperator(hasOperatorName("&=")))); + matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^")))); + EXPECT_TRUE(matches("int i = 42; int j = (i ^= 42);", + binaryOperator(hasOperatorName("^=")))); EXPECT_TRUE( - matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|")))); + matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%")))); + EXPECT_TRUE(matches("int i = 42; int j = (i %= 42);", + binaryOperator(hasOperatorName("%=")))); EXPECT_TRUE( - matches("bool b = true || false;", - binaryOperator(hasOperatorName("||")))); + matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&")))); + EXPECT_TRUE(matches("bool b = true && false;", + binaryOperator(hasOperatorName("&&")))); + EXPECT_TRUE(matches("bool b = true; bool c = (b &= false);", + binaryOperator(hasOperatorName("&=")))); EXPECT_TRUE( - matches("bool b = true; bool c = (b |= false);", - binaryOperator(hasOperatorName("|=")))); + matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|")))); + EXPECT_TRUE(matches("bool b = true || false;", + binaryOperator(hasOperatorName("||")))); + EXPECT_TRUE(matches("bool b = true; bool c = (b |= false);", + binaryOperator(hasOperatorName("|=")))); EXPECT_TRUE( - matches("int i = 42 *23;", binaryOperator(hasOperatorName("*")))); + matches("int i = 42 *23;", binaryOperator(hasOperatorName("*")))); + EXPECT_TRUE(matches("int i = 42; int j = (i *= 23);", + binaryOperator(hasOperatorName("*=")))); EXPECT_TRUE( - matches("int i = 42; int j = (i *= 23);", - binaryOperator(hasOperatorName("*=")))); + matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/")))); + EXPECT_TRUE(matches("int i = 42; int j = (i /= 23);", + binaryOperator(hasOperatorName("/=")))); EXPECT_TRUE( - matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/")))); + matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+")))); + EXPECT_TRUE(matches("int i = 42; int j = (i += 23);", + binaryOperator(hasOperatorName("+=")))); EXPECT_TRUE( - matches("int i = 42; int j = (i /= 23);", - binaryOperator(hasOperatorName("/=")))); + matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-")))); + EXPECT_TRUE(matches("int i = 42; int j = (i -= 23);", + binaryOperator(hasOperatorName("-=")))); EXPECT_TRUE( - matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+")))); + matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };", + binaryOperator(hasOperatorName("->*")))); EXPECT_TRUE( - matches("int i = 42; int j = (i += 23);", - binaryOperator(hasOperatorName("+=")))); - EXPECT_TRUE( - matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-")))); - EXPECT_TRUE( - matches("int i = 42; int j = (i -= 23);", - binaryOperator(hasOperatorName("-=")))); - EXPECT_TRUE( - matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };", - binaryOperator(hasOperatorName("->*")))); - EXPECT_TRUE( - matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };", - binaryOperator(hasOperatorName(".*")))); + matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };", + binaryOperator(hasOperatorName(".*")))); // Member expressions as operators are not supported in matches. - EXPECT_TRUE( - notMatches("struct A { void x(A *a) { a->x(this); } };", - binaryOperator(hasOperatorName("->")))); + EXPECT_TRUE(notMatches("struct A { void x(A *a) { a->x(this); } };", + binaryOperator(hasOperatorName("->")))); // Initializer assignments are not represented as operator equals. EXPECT_TRUE( - notMatches("bool b = true;", binaryOperator(hasOperatorName("=")))); + notMatches("bool b = true;", binaryOperator(hasOperatorName("=")))); // Array indexing is not represented as operator. EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator())); // Overloaded operators do not match at all. EXPECT_TRUE(notMatches( - "struct A { bool operator&&(const A &a) const { return false; } };" + "struct A { bool operator&&(const A &a) const { return false; } };" "void x() { A a, b; a && b; }", - binaryOperator())); + binaryOperator())); } TEST(MatchUnaryOperator, HasOperatorName) { @@ -1873,7 +1829,7 @@ TEST(MatchUnaryOperator, HasAnyOperatorName) { TEST(MatchUnaryOperator, HasUnaryOperand) { StatementMatcher OperatorOnFalse = - unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false)))); + unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false)))); EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse)); EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse)); @@ -2033,22 +1989,22 @@ TEST(Matcher, UnaryOperatorTypes) { // a way we expect. EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!")))); EXPECT_TRUE( - matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&")))); + matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&")))); EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~")))); EXPECT_TRUE( - matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*")))); + matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*")))); EXPECT_TRUE( - matches("int i; int j = +i;", unaryOperator(hasOperatorName("+")))); + matches("int i; int j = +i;", unaryOperator(hasOperatorName("+")))); EXPECT_TRUE( - matches("int i; int j = -i;", unaryOperator(hasOperatorName("-")))); + matches("int i; int j = -i;", unaryOperator(hasOperatorName("-")))); EXPECT_TRUE( - matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++")))); + matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++")))); EXPECT_TRUE( - matches("int i; int j = i++;", unaryOperator(hasOperatorName("++")))); + matches("int i; int j = i++;", unaryOperator(hasOperatorName("++")))); EXPECT_TRUE( - matches("int i; int j = --i;", unaryOperator(hasOperatorName("--")))); + matches("int i; int j = --i;", unaryOperator(hasOperatorName("--")))); EXPECT_TRUE( - matches("int i; int j = i--;", unaryOperator(hasOperatorName("--")))); + matches("int i; int j = i--;", unaryOperator(hasOperatorName("--")))); // We don't match conversion operators. EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator())); @@ -2058,9 +2014,10 @@ TEST(Matcher, UnaryOperatorTypes) { // Overloaded operators do not match at all. // FIXME: We probably want to add that. - EXPECT_TRUE(notMatches( - "struct A { bool operator!() const { return false; } };" - "void x() { A a; !a; }", unaryOperator(hasOperatorName("!")))); + EXPECT_TRUE( + notMatches("struct A { bool operator!() const { return false; } };" + "void x() { A a; !a; }", + unaryOperator(hasOperatorName("!")))); } TEST_P(ASTMatchersTest, HasInit) { @@ -2204,15 +2161,13 @@ TEST_P(ASTMatchersTest, Callee) { } TEST(ArraySubscriptMatchers, ArrayIndex) { - EXPECT_TRUE(matches( - "int i[2]; void f() { i[1] = 1; }", - arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); - EXPECT_TRUE(matches( - "int i[2]; void f() { 1[i] = 1; }", - arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); - EXPECT_TRUE(notMatches( - "int i[2]; void f() { i[1] = 1; }", - arraySubscriptExpr(hasIndex(integerLiteral(equals(0)))))); + EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }", + arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); + EXPECT_TRUE(matches("int i[2]; void f() { 1[i] = 1; }", + arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); + EXPECT_TRUE( + notMatches("int i[2]; void f() { i[1] = 1; }", + arraySubscriptExpr(hasIndex(integerLiteral(equals(0)))))); } TEST(ArraySubscriptMatchers, MatchesArrayBase) { @@ -2223,28 +2178,26 @@ TEST(ArraySubscriptMatchers, MatchesArrayBase) { } TEST(Matcher, OfClass) { - StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl( - ofClass(hasName("X"))))); + StatementMatcher Constructor = + cxxConstructExpr(hasDeclaration(cxxMethodDecl(ofClass(hasName("X"))))); EXPECT_TRUE( - matches("class X { public: X(); }; void x(int) { X x; }", Constructor)); - EXPECT_TRUE( - matches("class X { public: X(); }; void x(int) { X x = X(); }", - Constructor)); - EXPECT_TRUE( - notMatches("class Y { public: Y(); }; void x(int) { Y y; }", - Constructor)); + matches("class X { public: X(); }; void x(int) { X x; }", Constructor)); + EXPECT_TRUE(matches("class X { public: X(); }; void x(int) { X x = X(); }", + Constructor)); + EXPECT_TRUE(notMatches("class Y { public: Y(); }; void x(int) { Y y; }", + Constructor)); } TEST(Matcher, VisitsTemplateInstantiations) { EXPECT_TRUE(matches( - "class A { public: void x(); };" + "class A { public: void x(); };" "template class B { public: void y() { T t; t.x(); } };" "void f() { B b; b.y(); }", - callExpr(callee(cxxMethodDecl(hasName("x")))))); + callExpr(callee(cxxMethodDecl(hasName("x")))))); EXPECT_TRUE(matches( - "class A { public: void x(); };" + "class A { public: void x(); };" "class C {" " public:" " template class B { public: void y() { T t; t.x(); } };" @@ -2252,28 +2205,27 @@ TEST(Matcher, VisitsTemplateInstantiations) { "void f() {" " C::B b; b.y();" "}", - recordDecl(hasName("C"), hasDescendant(callExpr( - callee(cxxMethodDecl(hasName("x")))))))); + recordDecl(hasName("C"), hasDescendant(callExpr( + callee(cxxMethodDecl(hasName("x")))))))); } TEST(Matcher, HasCondition) { - StatementMatcher IfStmt = - ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); + StatementMatcher IfStmt = ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt)); EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt)); StatementMatcher ForStmt = - forStmt(hasCondition(cxxBoolLiteral(equals(true)))); + forStmt(hasCondition(cxxBoolLiteral(equals(true)))); EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt)); EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt)); StatementMatcher WhileStmt = - whileStmt(hasCondition(cxxBoolLiteral(equals(true)))); + whileStmt(hasCondition(cxxBoolLiteral(equals(true)))); EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt)); EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt)); StatementMatcher SwitchStmt = - switchStmt(hasCondition(integerLiteral(equals(42)))); + switchStmt(hasCondition(integerLiteral(equals(42)))); EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt)); EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt)); } @@ -2289,8 +2241,8 @@ TEST(For, ForRangeLoopInternals) { EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }", cxxForRangeStmt(hasLoopVariable(anything())))); EXPECT_TRUE(matches( - "void f(){ int a[] {1, 2}; for (int i : a); }", - cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))))); + "void f(){ int a[] {1, 2}; for (int i : a); }", + cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))))); } TEST(For, NegativeForLoopInternals) { @@ -2301,10 +2253,10 @@ TEST(For, NegativeForLoopInternals) { } TEST(HasBody, FindsBodyOfForWhileDoLoops) { - EXPECT_TRUE(matches("void f() { for(;;) {} }", - forStmt(hasBody(compoundStmt())))); - EXPECT_TRUE(notMatches("void f() { for(;;); }", - forStmt(hasBody(compoundStmt())))); + EXPECT_TRUE( + matches("void f() { for(;;) {} }", forStmt(hasBody(compoundStmt())))); + EXPECT_TRUE( + notMatches("void f() { for(;;); }", forStmt(hasBody(compoundStmt())))); EXPECT_TRUE(matches("void f() { while(true) {} }", whileStmt(hasBody(compoundStmt())))); EXPECT_TRUE(matches("void f() { do {} while(true); }", @@ -2336,8 +2288,8 @@ TEST(HasBody, FindsBodyOfFunctions) { TEST(HasAnyBody, FindsAnyBodyOfFunctions) { EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt())))); - EXPECT_TRUE(notMatches("void f();", - functionDecl(hasAnyBody(compoundStmt())))); + EXPECT_TRUE( + notMatches("void f();", functionDecl(hasAnyBody(compoundStmt())))); EXPECT_TRUE(matchAndVerifyResultTrue( "void f(); void f() {}", functionDecl(hasAnyBody(compoundStmt())).bind("func"), @@ -2400,7 +2352,7 @@ TEST(Member, MatchesMemberAllocationFunction) { TEST(HasDestinationType, MatchesSimpleCase) { EXPECT_TRUE(matches("char* p = static_cast(0);", cxxStaticCastExpr(hasDestinationType( - pointsTo(TypeMatcher(anything())))))); + pointsTo(TypeMatcher(anything())))))); } TEST(HasImplicitDestinationType, MatchesSimpleCase) { @@ -2418,13 +2370,13 @@ TEST(HasImplicitDestinationType, MatchesSimpleCase) { TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) { // This test creates an implicit cast from int to char. - EXPECT_TRUE(notMatches("char c = 0;", - implicitCastExpr(hasImplicitDestinationType( - unless(anything()))))); + EXPECT_TRUE(notMatches( + "char c = 0;", + implicitCastExpr(hasImplicitDestinationType(unless(anything()))))); // This test creates an implicit array-to-pointer cast. - EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;", - implicitCastExpr(hasImplicitDestinationType( - unless(anything()))))); + EXPECT_TRUE(notMatches( + "int arr[3]; int *p = arr;", + implicitCastExpr(hasImplicitDestinationType(unless(anything()))))); } TEST(Matcher, IgnoresElidableConstructors) { @@ -2436,20 +2388,20 @@ TEST(Matcher, IgnoresElidableConstructors) { " D1 = B(B(1));" "}", cxxOperatorCallExpr(hasArgument( - 1, callExpr(hasArgument( - 0, ignoringElidableConstructorCall(callExpr()))))), - langCxx11OrLater())); - EXPECT_TRUE( - matches("struct H {};" - "template H B(T A);" - "void f() {" - " H D1;" - " D1 = B(1);" - "}", - cxxOperatorCallExpr(hasArgument( - 1, callExpr(hasArgument(0, ignoringElidableConstructorCall( - integerLiteral()))))), + 1, ignoringParenImpCasts(callExpr(hasArgument( + 0, ignoringElidableConstructorCall(callExpr())))))), langCxx11OrLater())); + EXPECT_TRUE(matches( + "struct H {};" + "template H B(T A);" + "void f() {" + " H D1;" + " D1 = B(1);" + "}", + cxxOperatorCallExpr(hasArgument( + 1, ignoringParenImpCasts(callExpr(hasArgument( + 0, ignoringElidableConstructorCall(integerLiteral())))))), + langCxx11OrLater())); EXPECT_TRUE(matches( "struct H {};" "H G();" @@ -2632,9 +2584,10 @@ void bar() foo(7.0); } )cpp"; - EXPECT_TRUE( - matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource, - hasArgument(0, floatLiteral()))))); + EXPECT_TRUE(matches( + Code, callExpr(traverse( + TK_IgnoreUnlessSpelledInSource, + hasArgument(0, ignoringParenImpCasts(floatLiteral())))))); EXPECT_TRUE( matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource, @@ -2720,13 +2673,13 @@ void stringConstruct() Code, traverse( TK_AsIs, - functionDecl(hasName("stringConstruct"), - hasDescendant(cxxOperatorCallExpr( - isAssignmentOperator(), - hasArgument(1, ignoringImplicit( - cxxConstructExpr(hasArgument( - 0, ignoringImplicit(stringLiteral()))))) - )))))); + functionDecl( + hasName("stringConstruct"), + hasDescendant(cxxOperatorCallExpr( + isAssignmentOperator(), + hasArgument( + 1, ignoringImplicit(cxxConstructExpr(hasArgument( + 0, ignoringImplicit(stringLiteral()))))))))))); EXPECT_TRUE(matches( Code, traverse(TK_IgnoreUnlessSpelledInSource, @@ -2735,12 +2688,14 @@ void stringConstruct() hasName("s"), hasInitializer(stringLiteral()))))))); - EXPECT_TRUE( - matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, - functionDecl(hasName("stringConstruct"), - hasDescendant(cxxOperatorCallExpr( - isAssignmentOperator(), - hasArgument(1, stringLiteral()))))))); + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + functionDecl(hasName("stringConstruct"), + hasDescendant(cxxOperatorCallExpr( + isAssignmentOperator(), + hasArgument(1, ignoringParenImpCasts( + stringLiteral())))))))); Code = R"cpp( @@ -3679,7 +3634,8 @@ void callDefaultArg() EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); } { - auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr())); + auto M = hasDefaultArgCall( + hasArgument(1, ignoringParenImpCasts(cxxDefaultArgExpr()))); EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); } @@ -3937,8 +3893,9 @@ void func15() { Code, traverse(TK_IgnoreUnlessSpelledInSource, returnStmt(forFunction(functionDecl(hasName("func2"))), - hasReturnValue(cxxTemporaryObjectExpr( - hasArgument(0, integerLiteral(equals(42))))))), + hasReturnValue(cxxTemporaryObjectExpr(hasArgument( + 0, ignoringParenImpCasts( + integerLiteral(equals(42)))))))), langCxx20OrLater())); EXPECT_TRUE(matches( Code, @@ -3954,7 +3911,8 @@ void func15() { traverse(TK_IgnoreUnlessSpelledInSource, returnStmt(forFunction(functionDecl(hasName("func3"))), hasReturnValue(cxxConstructExpr(hasArgument( - 0, integerLiteral(equals(42))))))), + 0, ignoringParenImpCasts( + integerLiteral(equals(42)))))))), langCxx20OrLater())); EXPECT_TRUE(matches( @@ -4313,8 +4271,10 @@ void binop() )cpp"; auto withArgs = [](StringRef lName, StringRef rName) { return cxxOperatorCallExpr( - hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))), - hasArgument(1, declRefExpr(to(varDecl(hasName(rName)))))); + hasArgument( + 0, ignoringParenImpCasts(declRefExpr(to(varDecl(hasName(lName)))))), + hasArgument(1, ignoringParenImpCasts( + declRefExpr(to(varDecl(hasName(rName))))))); }; { auto M = ifStmt(hasCondition(cxxOperatorCallExpr( @@ -4751,7 +4711,8 @@ void f() { )cpp"; EXPECT_TRUE(matches(Code, integerLiteral(equals(42)))); - EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42)))))); + EXPECT_TRUE( + matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42)))))); } TEST(IgnoringImpCasts, MatchesImpCasts) { @@ -4760,39 +4721,38 @@ TEST(IgnoringImpCasts, MatchesImpCasts) { // Note that this test creates an implicit const cast. EXPECT_TRUE(matches("int x = 0; const int y = x;", varDecl(hasInitializer(ignoringImpCasts( - declRefExpr(to(varDecl(hasName("x"))))))))); + declRefExpr(to(varDecl(hasName("x"))))))))); // This test creates an implict cast from int to char. - EXPECT_TRUE(matches("char x = 0;", - varDecl(hasInitializer(ignoringImpCasts( - integerLiteral(equals(0))))))); + EXPECT_TRUE(matches("char x = 0;", varDecl(hasInitializer(ignoringImpCasts( + integerLiteral(equals(0))))))); } TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) { // These tests verify that ignoringImpCasts does not match if the inner // matcher does not match. // Note that the first test creates an implicit const cast. - EXPECT_TRUE(notMatches("int x; const int y = x;", - varDecl(hasInitializer(ignoringImpCasts( - unless(anything())))))); - EXPECT_TRUE(notMatches("int x; int y = x;", - varDecl(hasInitializer(ignoringImpCasts( - unless(anything())))))); + EXPECT_TRUE(notMatches( + "int x; const int y = x;", + varDecl(hasInitializer(ignoringImpCasts(unless(anything())))))); + EXPECT_TRUE(notMatches( + "int x; int y = x;", + varDecl(hasInitializer(ignoringImpCasts(unless(anything())))))); // These tests verify that ignoringImplictCasts does not look through explicit // casts or parentheses. - EXPECT_TRUE(notMatches("char* p = static_cast(0);", - varDecl(hasInitializer(ignoringImpCasts( - integerLiteral()))))); + EXPECT_TRUE( + notMatches("char* p = static_cast(0);", + varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))); EXPECT_TRUE(notMatches( "int i = (0);", traverse(TK_AsIs, varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))))); - EXPECT_TRUE(notMatches("float i = (float)0;", - varDecl(hasInitializer(ignoringImpCasts( - integerLiteral()))))); - EXPECT_TRUE(notMatches("float i = float(0);", - varDecl(hasInitializer(ignoringImpCasts( - integerLiteral()))))); + EXPECT_TRUE( + notMatches("float i = (float)0;", + varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))); + EXPECT_TRUE( + notMatches("float i = float(0);", + varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))); } TEST(IgnoringImpCasts, MatchesWithoutImpCasts) { @@ -4800,56 +4760,54 @@ TEST(IgnoringImpCasts, MatchesWithoutImpCasts) { // still match the inner matcher. EXPECT_TRUE(matches("int x = 0; int &y = x;", varDecl(hasInitializer(ignoringImpCasts( - declRefExpr(to(varDecl(hasName("x"))))))))); + declRefExpr(to(varDecl(hasName("x"))))))))); } TEST(IgnoringParenCasts, MatchesParenCasts) { // This test checks that ignoringParenCasts matches when parentheses and/or // casts are present and its inner matcher alone does not match. - EXPECT_TRUE(matches("int x = (0);", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); - EXPECT_TRUE(matches("int x = (((((0)))));", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); + EXPECT_TRUE(matches("int x = (0);", varDecl(hasInitializer(ignoringParenCasts( + integerLiteral(equals(0))))))); + EXPECT_TRUE(matches( + "int x = (((((0)))));", + varDecl(hasInitializer(ignoringParenCasts(integerLiteral(equals(0))))))); // This test creates an implict cast from int to char in addition to the // parentheses. - EXPECT_TRUE(matches("char x = (0);", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); + EXPECT_TRUE(matches( + "char x = (0);", + varDecl(hasInitializer(ignoringParenCasts(integerLiteral(equals(0))))))); - EXPECT_TRUE(matches("char x = (char)0;", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); - EXPECT_TRUE(matches("char* p = static_cast(0);", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); + EXPECT_TRUE(matches( + "char x = (char)0;", + varDecl(hasInitializer(ignoringParenCasts(integerLiteral(equals(0))))))); + EXPECT_TRUE(matches( + "char* p = static_cast(0);", + varDecl(hasInitializer(ignoringParenCasts(integerLiteral(equals(0))))))); } TEST(IgnoringParenCasts, MatchesWithoutParenCasts) { // This test verifies that expressions that do not have any casts still match. - EXPECT_TRUE(matches("int x = 0;", - varDecl(hasInitializer(ignoringParenCasts( - integerLiteral(equals(0))))))); + EXPECT_TRUE(matches("int x = 0;", varDecl(hasInitializer(ignoringParenCasts( + integerLiteral(equals(0))))))); } TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) { // These tests verify that ignoringImpCasts does not match if the inner // matcher does not match. - EXPECT_TRUE(notMatches("int x = ((0));", - varDecl(hasInitializer(ignoringParenCasts( - unless(anything())))))); + EXPECT_TRUE(notMatches( + "int x = ((0));", + varDecl(hasInitializer(ignoringParenCasts(unless(anything())))))); // This test creates an implicit cast from int to char in addition to the // parentheses. - EXPECT_TRUE(notMatches("char x = ((0));", - varDecl(hasInitializer(ignoringParenCasts( - unless(anything())))))); + EXPECT_TRUE(notMatches( + "char x = ((0));", + varDecl(hasInitializer(ignoringParenCasts(unless(anything())))))); - EXPECT_TRUE(notMatches("char *x = static_cast((0));", - varDecl(hasInitializer(ignoringParenCasts( - unless(anything())))))); + EXPECT_TRUE(notMatches( + "char *x = static_cast((0));", + varDecl(hasInitializer(ignoringParenCasts(unless(anything())))))); } TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) { @@ -4859,11 +4817,11 @@ TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) { // Note that this test creates an implicit const cast. EXPECT_TRUE(matches("int x = 0; const int y = x;", varDecl(hasInitializer(ignoringParenImpCasts( - declRefExpr(to(varDecl(hasName("x"))))))))); + declRefExpr(to(varDecl(hasName("x"))))))))); // This test creates an implicit cast from int to char. EXPECT_TRUE(matches("const char x = (0);", - varDecl(hasInitializer(ignoringParenImpCasts( - integerLiteral(equals(0))))))); + varDecl(hasInitializer( + ignoringParenImpCasts(integerLiteral(equals(0))))))); } TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) { @@ -4871,30 +4829,30 @@ TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) { // implicit casts still match. EXPECT_TRUE(matches("int x = 0; int &y = x;", varDecl(hasInitializer(ignoringParenImpCasts( - declRefExpr(to(varDecl(hasName("x"))))))))); + declRefExpr(to(varDecl(hasName("x"))))))))); EXPECT_TRUE(matches("int x = 0;", - varDecl(hasInitializer(ignoringParenImpCasts( - integerLiteral(equals(0))))))); + varDecl(hasInitializer( + ignoringParenImpCasts(integerLiteral(equals(0))))))); } TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) { // These tests verify that ignoringParenImpCasts does not match if // the inner matcher does not match. // This test creates an implicit cast. - EXPECT_TRUE(notMatches("char c = ((3));", - varDecl(hasInitializer(ignoringParenImpCasts( - unless(anything())))))); + EXPECT_TRUE(notMatches( + "char c = ((3));", + varDecl(hasInitializer(ignoringParenImpCasts(unless(anything())))))); // These tests verify that ignoringParenAndImplictCasts does not look // through explicit casts. - EXPECT_TRUE(notMatches("float y = (float(0));", - varDecl(hasInitializer(ignoringParenImpCasts( - integerLiteral()))))); - EXPECT_TRUE(notMatches("float y = (float)0;", - varDecl(hasInitializer(ignoringParenImpCasts( - integerLiteral()))))); - EXPECT_TRUE(notMatches("char* p = static_cast(0);", - varDecl(hasInitializer(ignoringParenImpCasts( - integerLiteral()))))); + EXPECT_TRUE(notMatches( + "float y = (float(0));", + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral()))))); + EXPECT_TRUE(notMatches( + "float y = (float)0;", + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral()))))); + EXPECT_TRUE(notMatches( + "char* p = static_cast(0);", + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral()))))); } TEST(HasSourceExpression, MatchesImplicitCasts) { @@ -4912,30 +4870,28 @@ TEST(HasSourceExpression, MatchesExplicitCasts) { } TEST(UsingDeclaration, MatchesSpecificTarget) { - EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;", - usingDecl(hasAnyUsingShadowDecl( - hasTargetDecl(functionDecl()))))); - EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;", - usingDecl(hasAnyUsingShadowDecl( - hasTargetDecl(functionDecl()))))); + EXPECT_TRUE( + matches("namespace f { int a; void b(); } using f::b;", + usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))))); + EXPECT_TRUE(notMatches( + "namespace f { int a; void b(); } using f::a;", + usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))))); } TEST(UsingDeclaration, ThroughUsingDeclaration) { - EXPECT_TRUE(matches( - "namespace a { void f(); } using a::f; void g() { f(); }", - declRefExpr(throughUsingDecl(anything())))); - EXPECT_TRUE(notMatches( - "namespace a { void f(); } using a::f; void g() { a::f(); }", - declRefExpr(throughUsingDecl(anything())))); + EXPECT_TRUE(matches("namespace a { void f(); } using a::f; void g() { f(); }", + declRefExpr(throughUsingDecl(anything())))); + EXPECT_TRUE( + notMatches("namespace a { void f(); } using a::f; void g() { a::f(); }", + declRefExpr(throughUsingDecl(anything())))); } TEST(SingleDecl, IsSingleDecl) { StatementMatcher SingleDeclStmt = - declStmt(hasSingleDecl(varDecl(hasInitializer(anything())))); + declStmt(hasSingleDecl(varDecl(hasInitializer(anything())))); EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt)); EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt)); - EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}", - SingleDeclStmt)); + EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}", SingleDeclStmt)); } TEST(DeclStmt, ContainsDeclaration) { @@ -4947,9 +4903,9 @@ TEST(DeclStmt, ContainsDeclaration) { declStmt(containsDeclaration(0, MatchesInit), containsDeclaration(1, MatchesInit)))); unsigned WrongIndex = 42; - EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}", - declStmt(containsDeclaration(WrongIndex, - MatchesInit)))); + EXPECT_TRUE( + notMatches("void f() {int a = 4, b = 3;}", + declStmt(containsDeclaration(WrongIndex, MatchesInit)))); } TEST(SwitchCase, MatchesEachCase) { @@ -4960,8 +4916,8 @@ TEST(SwitchCase, MatchesEachCase) { EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt(forEachSwitchCase(caseStmt())))); EXPECT_TRUE(notMatches( - "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }", - ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt())))))); + "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }", + ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt())))))); EXPECT_TRUE(matches( "void x() { switch(42) { case 1+1: case 4:; } }", traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant( @@ -4975,9 +4931,9 @@ TEST(SwitchCase, MatchesEachCase) { traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant( constantExpr(has(integerLiteral()))))))))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void x() { switch (42) { case 1: case 2: case 3: default:; } }", - switchStmt(forEachSwitchCase(caseStmt().bind("x"))), - std::make_unique>("x", 3))); + "void x() { switch (42) { case 1: case 2: case 3: default:; } }", + switchStmt(forEachSwitchCase(caseStmt().bind("x"))), + std::make_unique>("x", 3))); } TEST(Declaration, HasExplicitSpecifier) { @@ -5042,8 +4998,8 @@ TEST(Declaration, HasExplicitSpecifier) { TEST(ForEachConstructorInitializer, MatchesInitializers) { EXPECT_TRUE(matches( - "struct X { X() : i(42), j(42) {} int i, j; };", - cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer())))); + "struct X { X() : i(42), j(42) {} int i, j; };", + cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer())))); } TEST(ForEachLambdaCapture, MatchesCaptures) { @@ -5107,38 +5063,37 @@ TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) { } TEST(HasConditionVariableStatement, DoesNotMatchCondition) { - EXPECT_TRUE(notMatches( - "void x() { if(true) {} }", - ifStmt(hasConditionVariableStatement(declStmt())))); - EXPECT_TRUE(notMatches( - "void x() { int x; if((x = 42)) {} }", - ifStmt(hasConditionVariableStatement(declStmt())))); + EXPECT_TRUE(notMatches("void x() { if(true) {} }", + ifStmt(hasConditionVariableStatement(declStmt())))); + EXPECT_TRUE(notMatches("void x() { int x; if((x = 42)) {} }", + ifStmt(hasConditionVariableStatement(declStmt())))); } TEST(HasConditionVariableStatement, MatchesConditionVariables) { - EXPECT_TRUE(matches( - "void x() { if(int* a = 0) {} }", - ifStmt(hasConditionVariableStatement(declStmt())))); + EXPECT_TRUE(matches("void x() { if(int* a = 0) {} }", + ifStmt(hasConditionVariableStatement(declStmt())))); } TEST(ForEach, BindsOneNode) { - EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };", - recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))), - std::make_unique>("x", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class C { int x; };", + recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))), + std::make_unique>("x", 1))); } TEST(ForEach, BindsMultipleNodes) { - EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };", - recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))), - std::make_unique>("f", 3))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class C { int x; int y; int z; };", + recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))), + std::make_unique>("f", 3))); } TEST(ForEach, BindsRecursiveCombinations) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { class D { int x; int y; }; class E { int y; int z; }; };", - recordDecl(hasName("C"), - forEach(recordDecl(forEach(fieldDecl().bind("f"))))), - std::make_unique>("f", 4))); + "class C { class D { int x; int y; }; class E { int y; int z; }; };", + recordDecl(hasName("C"), + forEach(recordDecl(forEach(fieldDecl().bind("f"))))), + std::make_unique>("f", 4))); } TEST(ForEach, DoesNotIgnoreImplicit) { @@ -5174,53 +5129,54 @@ void foo() } TEST(ForEachDescendant, BindsOneNode) { - EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };", - recordDecl(hasName("C"), - forEachDescendant(fieldDecl(hasName("x")).bind("x"))), - std::make_unique>("x", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class C { class D { int x; }; };", + recordDecl(hasName("C"), + forEachDescendant(fieldDecl(hasName("x")).bind("x"))), + std::make_unique>("x", 1))); } TEST(ForEachDescendant, NestedForEachDescendant) { - DeclarationMatcher m = recordDecl( - isDefinition(), decl().bind("x"), hasName("C")); + DeclarationMatcher m = + recordDecl(isDefinition(), decl().bind("x"), hasName("C")); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B { class C {}; }; };", - recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))), - std::make_unique>("x", "C"))); + "class A { class B { class C {}; }; };", + recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))), + std::make_unique>("x", "C"))); // Check that a partial match of 'm' that binds 'x' in the // first part of anyOf(m, anything()) will not overwrite the // binding created by the earlier binding in the hasDescendant. EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B { class C {}; }; };", - recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))), - std::make_unique>("x", "C"))); + "class A { class B { class C {}; }; };", + recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))), + std::make_unique>("x", "C"))); } TEST(ForEachDescendant, BindsMultipleNodes) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { class D { int x; int y; }; " + "class C { class D { int x; int y; }; " " class E { class F { int y; int z; }; }; };", - recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))), - std::make_unique>("f", 4))); + recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))), + std::make_unique>("f", 4))); } TEST(ForEachDescendant, BindsRecursiveCombinations) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { class D { " + "class C { class D { " " class E { class F { class G { int y; int z; }; }; }; }; };", - recordDecl(hasName("C"), forEachDescendant(recordDecl( - forEachDescendant(fieldDecl().bind("f"))))), - std::make_unique>("f", 8))); + recordDecl(hasName("C"), forEachDescendant(recordDecl( + forEachDescendant(fieldDecl().bind("f"))))), + std::make_unique>("f", 8))); } TEST(ForEachDescendant, BindsCombinations) { EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while " + "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while " "(true) {} }", - compoundStmt(forEachDescendant(ifStmt().bind("if")), - forEachDescendant(whileStmt().bind("while"))), - std::make_unique>("if", 6))); + compoundStmt(forEachDescendant(ifStmt().bind("if")), + forEachDescendant(whileStmt().bind("while"))), + std::make_unique>("if", 6))); } TEST(ForEachTemplateArgument, OnFunctionDecl) { @@ -5281,8 +5237,8 @@ Matrix M; TEST(Has, DoesNotDeleteBindings) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())), - std::make_unique>("x", 1))); + "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())), + std::make_unique>("x", 1))); } TEST(TemplateArgumentLoc, Matches) { @@ -5319,325 +5275,312 @@ TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) { // the direct parent matches the inner matcher. EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { int y; };", - recordDecl( - recordDecl().bind("x"), hasName("::X"), - anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())), - std::make_unique>("x", 1))); + "class X { int y; };", + recordDecl( + recordDecl().bind("x"), hasName("::X"), + anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"), - anyOf(unless(anything()), anything())), - std::make_unique>("x", 1))); + "class X {};", + recordDecl(recordDecl().bind("x"), hasName("::X"), + anyOf(unless(anything()), anything())), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "template class X {}; X x;", - classTemplateSpecializationDecl( - decl().bind("x"), - hasAnyTemplateArgument(refersToType(asString("int")))), - std::make_unique>("x", 1))); + "template class X {}; X x;", + classTemplateSpecializationDecl( + decl().bind("x"), + hasAnyTemplateArgument(refersToType(asString("int")))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { void f(); void g(); };", - cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))), - std::make_unique>("x", 1))); + "class X { void f(); void g(); };", + cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { X() : a(1), b(2) {} double a; int b; };", - recordDecl(decl().bind("x"), - has(cxxConstructorDecl( - hasAnyConstructorInitializer(forField(hasName("b")))))), - std::make_unique>("x", 1))); + "class X { X() : a(1), b(2) {} double a; int b; };", + recordDecl(decl().bind("x"), + has(cxxConstructorDecl( + hasAnyConstructorInitializer(forField(hasName("b")))))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void x(int, int) { x(0, 42); }", - callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))), - std::make_unique>("x", 1))); + "void x(int, int) { x(0, 42); }", + callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void x(int, int y) {}", - functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))), - std::make_unique>("x", 1))); + "void x(int, int y) {}", + functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "void x() { return; if (true) {} }", - functionDecl(decl().bind("x"), - has(compoundStmt(hasAnySubstatement(ifStmt())))), - std::make_unique>("x", 1))); + "void x() { return; if (true) {} }", + functionDecl(decl().bind("x"), + has(compoundStmt(hasAnySubstatement(ifStmt())))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "namespace X { void b(int); void b(); }" + "namespace X { void b(int); void b(); }" "using X::b;", - usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl( - functionDecl(parameterCountIs(1))))), - std::make_unique>("x", 1))); + usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl( + functionDecl(parameterCountIs(1))))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A{}; class B{}; class C : B, A {};", - cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")), - std::make_unique>("x", 1))); + "class A{}; class B{}; class C : B, A {};", + cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A{}; typedef A B; typedef A C; typedef A D;" + "class A{}; typedef A B; typedef A C; typedef A D;" "class E : A {};", - cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")), - std::make_unique>("x", 1))); + cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B { void f() {} }; };", - functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))), - std::make_unique>("x", 1))); + "class A { class B { void f() {} }; };", + functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "template struct A { struct B {" + "template struct A { struct B {" " void f() { if(true) {} }" "}; };" "void t() { A::B b; b.f(); }", - ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))), - std::make_unique>("x", 2))); + ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))), + std::make_unique>("x", 2))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A {};", - recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))), - std::make_unique>("x", 1))); + "class A {};", + recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))), + std::make_unique>("x", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { A() : s(), i(42) {} const char *s; int i; };", - cxxConstructorDecl(hasName("::A::A"), decl().bind("x"), - forEachConstructorInitializer(forField(hasName("i")))), - std::make_unique>("x", 1))); + "class A { A() : s(), i(42) {} const char *s; int i; };", + cxxConstructorDecl(hasName("::A::A"), decl().bind("x"), + forEachConstructorInitializer(forField(hasName("i")))), + std::make_unique>("x", 1))); } TEST(ForEachDescendant, BindsCorrectNodes) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { void f(); int i; };", - recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), - std::make_unique>("decl", 1))); + "class C { void f(); int i; };", + recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), + std::make_unique>("decl", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { void f() {} int i; };", - recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), - std::make_unique>("decl", 1))); + "class C { void f() {} int i; };", + recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), + std::make_unique>("decl", 1))); } TEST(FindAll, BindsNodeOnMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A {};", - recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))), - std::make_unique>("v", 1))); + "class A {};", + recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))), + std::make_unique>("v", 1))); } TEST(FindAll, BindsDescendantNodeOnMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int b; };", - recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))), - std::make_unique>("v", 2))); + "class A { int a; int b; };", + recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))), + std::make_unique>("v", 2))); } TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int b; };", - recordDecl(hasName("::A"), - findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"), - fieldDecl().bind("v"))))), - std::make_unique>("v", 3))); + "class A { int a; int b; };", + recordDecl(hasName("::A"), + findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"), + fieldDecl().bind("v"))))), + std::make_unique>("v", 3))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B {}; class C {}; };", - recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))), - std::make_unique>("v", 3))); + "class A { class B {}; class C {}; };", + recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))), + std::make_unique>("v", 3))); } TEST(HasAncenstor, MatchesDeclarationAncestors) { - EXPECT_TRUE(matches( - "class A { class B { class C {}; }; };", - recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A")))))); + EXPECT_TRUE( + matches("class A { class B { class C {}; }; };", + recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A")))))); } TEST(HasAncenstor, FailsIfNoAncestorMatches) { EXPECT_TRUE(notMatches( - "class A { class B { class C {}; }; };", - recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X")))))); + "class A { class B { class C {}; }; };", + recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X")))))); } TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) { EXPECT_TRUE(matches( - "class A { class B { void f() { C c; } class C {}; }; };", - varDecl(hasName("c"), hasType(recordDecl(hasName("C"), - hasAncestor(recordDecl(hasName("A")))))))); + "class A { class B { void f() { C c; } class C {}; }; };", + varDecl(hasName("c"), + hasType(recordDecl(hasName("C"), + hasAncestor(recordDecl(hasName("A")))))))); } TEST(HasAncenstor, MatchesStatementAncestors) { - EXPECT_TRUE(matches( - "void f() { if (true) { while (false) { 42; } } }", - integerLiteral(equals(42), hasAncestor(ifStmt())))); + EXPECT_TRUE(matches("void f() { if (true) { while (false) { 42; } } }", + integerLiteral(equals(42), hasAncestor(ifStmt())))); } TEST(HasAncestor, DrillsThroughDifferentHierarchies) { EXPECT_TRUE(matches( - "void f() { if (true) { int x = 42; } }", - integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f")))))); + "void f() { if (true) { int x = 42; } }", + integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f")))))); } TEST(HasAncestor, BindsRecursiveCombinations) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { class D { class E { class F { int y; }; }; }; };", - fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))), - std::make_unique>("r", 1))); + "class C { class D { class E { class F { int y; }; }; }; };", + fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))), + std::make_unique>("r", 1))); } TEST(HasAncestor, BindsCombinationsWithHasDescendant) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class C { class D { class E { class F { int y; }; }; }; };", - fieldDecl(hasAncestor( - decl( - hasDescendant(recordDecl(isDefinition(), - hasAncestor(recordDecl()))) - ).bind("d") - )), - std::make_unique>("d", "E"))); + "class C { class D { class E { class F { int y; }; }; }; };", + fieldDecl( + hasAncestor(decl(hasDescendant(recordDecl(isDefinition(), + hasAncestor(recordDecl())))) + .bind("d"))), + std::make_unique>("d", "E"))); } TEST(HasAncestor, MatchesClosestAncestor) { EXPECT_TRUE(matchAndVerifyResultTrue( - "template struct C {" + "template struct C {" " void f(int) {" " struct I { void g(T) { int x; } } i; i.g(42);" " }" "};" "template struct C;", - varDecl(hasName("x"), - hasAncestor(functionDecl(hasParameter( - 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"), - std::make_unique>("f", "g", 2))); + varDecl(hasName("x"), + hasAncestor(functionDecl(hasParameter(0, varDecl(hasType( + asString("int"))))) + .bind("f"))) + .bind("v"), + std::make_unique>("f", "g", 2))); } TEST(HasAncestor, MatchesInTemplateInstantiations) { EXPECT_TRUE(matches( - "template struct A { struct B { struct C { T t; }; }; }; " + "template struct A { struct B { struct C { T t; }; }; }; " "A::B::C a;", - fieldDecl(hasType(asString("int")), - hasAncestor(recordDecl(hasName("A")))))); + fieldDecl(hasType(asString("int")), + hasAncestor(recordDecl(hasName("A")))))); } TEST(HasAncestor, MatchesInImplicitCode) { - EXPECT_TRUE(matches( - "struct X {}; struct A { A() {} X x; };", - cxxConstructorDecl( - hasAnyConstructorInitializer(withInitializer(expr( - hasAncestor(recordDecl(hasName("A"))))))))); + EXPECT_TRUE( + matches("struct X {}; struct A { A() {} X x; };", + cxxConstructorDecl(hasAnyConstructorInitializer(withInitializer( + expr(hasAncestor(recordDecl(hasName("A"))))))))); } TEST(HasParent, MatchesOnlyParent) { - EXPECT_TRUE(matches( - "void f() { if (true) { int x = 42; } }", - compoundStmt(hasParent(ifStmt())))); - EXPECT_TRUE(notMatches( - "void f() { for (;;) { int x = 42; } }", - compoundStmt(hasParent(ifStmt())))); - EXPECT_TRUE(notMatches( - "void f() { if (true) for (;;) { int x = 42; } }", - compoundStmt(hasParent(ifStmt())))); + EXPECT_TRUE(matches("void f() { if (true) { int x = 42; } }", + compoundStmt(hasParent(ifStmt())))); + EXPECT_TRUE(notMatches("void f() { for (;;) { int x = 42; } }", + compoundStmt(hasParent(ifStmt())))); + EXPECT_TRUE(notMatches("void f() { if (true) for (;;) { int x = 42; } }", + compoundStmt(hasParent(ifStmt())))); } TEST(MatcherMemoize, HasParentDiffersFromHas) { // Test introduced after detecting a bug in memoization constexpr auto code = "void f() { throw 1; }"; - EXPECT_TRUE(notMatches( - code, - cxxThrowExpr(hasParent(expr())))); - EXPECT_TRUE(matches( - code, - cxxThrowExpr(has(expr())))); - EXPECT_TRUE(matches( - code, - cxxThrowExpr(anyOf(hasParent(expr()), has(expr()))))); + EXPECT_TRUE(notMatches(code, cxxThrowExpr(hasParent(expr())))); + EXPECT_TRUE(matches(code, cxxThrowExpr(has(expr())))); + EXPECT_TRUE( + matches(code, cxxThrowExpr(anyOf(hasParent(expr()), has(expr()))))); } TEST(MatcherMemoize, HasDiffersFromHasDescendant) { // Test introduced after detecting a bug in memoization constexpr auto code = "void f() { throw 1+1; }"; - EXPECT_TRUE(notMatches( - code, - cxxThrowExpr(has(integerLiteral())))); - EXPECT_TRUE(matches( - code, - cxxThrowExpr(hasDescendant(integerLiteral())))); + EXPECT_TRUE(notMatches(code, cxxThrowExpr(has(integerLiteral())))); + EXPECT_TRUE(matches(code, cxxThrowExpr(hasDescendant(integerLiteral())))); EXPECT_TRUE( notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()), has(integerLiteral()))))); } TEST(HasAncestor, MatchesAllAncestors) { EXPECT_TRUE(matches( - "template struct C { static void f() { 42; } };" + "template struct C { static void f() { 42; } };" "void t() { C::f(); }", - integerLiteral( - equals(42), - allOf( - hasAncestor(cxxRecordDecl(isTemplateInstantiation())), - hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation()))))))); + integerLiteral( + equals(42), + allOf( + hasAncestor(cxxRecordDecl(isTemplateInstantiation())), + hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation()))))))); } TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) { EXPECT_TRUE(matches("struct MyClass {\n" - " int c[1];\n" - " static MyClass Create() { return MyClass(); }\n" - "};", + " int c[1];\n" + " static MyClass Create() { return MyClass(); }\n" + "};", declRefExpr(to(decl(hasAncestor(decl())))))); } TEST(HasAncestor, AnonymousUnionMemberExpr) { EXPECT_TRUE(matches("int F() {\n" - " union { int i; };\n" - " return i;\n" - "}\n", + " union { int i; };\n" + " return i;\n" + "}\n", memberExpr(member(hasAncestor(decl()))))); EXPECT_TRUE(matches("void f() {\n" - " struct {\n" - " struct { int a; int b; };\n" - " } s;\n" - " s.a = 4;\n" - "}\n", + " struct {\n" + " struct { int a; int b; };\n" + " } s;\n" + " s.a = 4;\n" + "}\n", memberExpr(member(hasAncestor(decl()))))); EXPECT_TRUE(matches("void f() {\n" - " struct {\n" - " struct { int a; int b; };\n" - " } s;\n" - " s.a = 4;\n" - "}\n", + " struct {\n" + " struct { int a; int b; };\n" + " } s;\n" + " s.a = 4;\n" + "}\n", declRefExpr(to(decl(hasAncestor(decl())))))); } TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) { EXPECT_TRUE(matches("struct PartitionAllocator {\n" - " template\n" - " static int quantizedSize(int count) {\n" - " return count;\n" - " }\n" - " void f() { quantizedSize(10); }\n" - "};", + " template\n" + " static int quantizedSize(int count) {\n" + " return count;\n" + " }\n" + " void f() { quantizedSize(10); }\n" + "};", declRefExpr(to(decl(hasAncestor(decl())))))); } TEST(HasAncestor, AddressOfExplicitSpecializationFunction) { EXPECT_TRUE(matches("template void f();\n" - "template <> void f();\n" - "void (*get_f())() { return f; }\n", + "template <> void f();\n" + "void (*get_f())() { return f; }\n", declRefExpr(to(decl(hasAncestor(decl())))))); } TEST(HasParent, MatchesAllParents) { EXPECT_TRUE(matches( - "template struct C { static void f() { 42; } };" + "template struct C { static void f() { 42; } };" "void t() { C::f(); }", - integerLiteral( - equals(42), - hasParent(compoundStmt(hasParent(functionDecl( - hasParent(cxxRecordDecl(isTemplateInstantiation()))))))))); + integerLiteral(equals(42), + hasParent(compoundStmt(hasParent(functionDecl(hasParent( + cxxRecordDecl(isTemplateInstantiation()))))))))); EXPECT_TRUE( - matches("template struct C { static void f() { 42; } };" + matches("template struct C { static void f() { 42; } };" "void t() { C::f(); }", - integerLiteral( - equals(42), - hasParent(compoundStmt(hasParent(functionDecl(hasParent( - cxxRecordDecl(unless(isTemplateInstantiation())))))))))); + integerLiteral( + equals(42), + hasParent(compoundStmt(hasParent(functionDecl(hasParent( + cxxRecordDecl(unless(isTemplateInstantiation())))))))))); EXPECT_TRUE(matches( - "template struct C { static void f() { 42; } };" + "template struct C { static void f() { 42; } };" "void t() { C::f(); }", - integerLiteral(equals(42), - hasParent(compoundStmt( - allOf(hasParent(functionDecl(hasParent( - cxxRecordDecl(isTemplateInstantiation())))), - hasParent(functionDecl(hasParent(cxxRecordDecl( - unless(isTemplateInstantiation()))))))))))); - EXPECT_TRUE( - notMatches("template struct C { static void f() {} };" + integerLiteral(equals(42), + hasParent(compoundStmt( + allOf(hasParent(functionDecl(hasParent( + cxxRecordDecl(isTemplateInstantiation())))), + hasParent(functionDecl(hasParent(cxxRecordDecl( + unless(isTemplateInstantiation()))))))))))); + EXPECT_TRUE( + notMatches("template struct C { static void f() {} };" "void t() { C::f(); }", - compoundStmt(hasParent(recordDecl())))); + compoundStmt(hasParent(recordDecl())))); } TEST(HasParent, NoDuplicateParents) { @@ -5656,9 +5599,9 @@ TEST(HasParent, NoDuplicateParents) { } }; EXPECT_FALSE(matchAndVerifyResultTrue( - "template int Foo() { return 1 + 2; }\n" + "template int Foo() { return 1 + 2; }\n" "int x = Foo() + Foo();", - stmt().bind("node"), std::make_unique())); + stmt().bind("node"), std::make_unique())); } TEST(HasAnyBase, BindsInnerBoundNodes) { @@ -5674,73 +5617,68 @@ TEST(HasAnyBase, BindsInnerBoundNodes) { } TEST(TypeMatching, PointeeTypes) { - EXPECT_TRUE(matches("int b; int &a = b;", - referenceType(pointee(builtinType())))); + EXPECT_TRUE( + matches("int b; int &a = b;", referenceType(pointee(builtinType())))); EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType())))); - EXPECT_TRUE(matches("int *a;", - loc(pointerType(pointee(builtinType()))))); + EXPECT_TRUE(matches("int *a;", loc(pointerType(pointee(builtinType()))))); - EXPECT_TRUE(matches( - "int const *A;", - pointerType(pointee(isConstQualified(), builtinType())))); + EXPECT_TRUE(matches("int const *A;", + pointerType(pointee(isConstQualified(), builtinType())))); EXPECT_TRUE(notMatches( - "int *A;", - pointerType(pointee(isConstQualified(), builtinType())))); + "int *A;", pointerType(pointee(isConstQualified(), builtinType())))); } TEST(ElaboratedTypeNarrowing, hasQualifier) { - EXPECT_TRUE(matches( - "namespace N {" - " namespace M {" - " class D {};" - " }" - "}" - "N::M::D d;", - elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))))); - EXPECT_TRUE(notMatches( - "namespace M {" - " class D {};" - "}" - "M::D d;", - elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))))); - EXPECT_TRUE(notMatches( - "struct D {" - "} d;", - elaboratedType(hasQualifier(nestedNameSpecifier())))); + EXPECT_TRUE(matches("namespace N {" + " namespace M {" + " class D {};" + " }" + "}" + "N::M::D d;", + elaboratedType(hasQualifier( + hasPrefix(specifiesNamespace(hasName("N"))))))); + EXPECT_TRUE(notMatches("namespace M {" + " class D {};" + "}" + "M::D d;", + elaboratedType(hasQualifier( + hasPrefix(specifiesNamespace(hasName("N"))))))); + EXPECT_TRUE(notMatches("struct D {" + "} d;", + elaboratedType(hasQualifier(nestedNameSpecifier())))); } TEST(ElaboratedTypeNarrowing, namesType) { - EXPECT_TRUE(matches( - "namespace N {" - " namespace M {" - " class D {};" - " }" - "}" - "N::M::D d;", - elaboratedType(elaboratedType(namesType(recordType( - hasDeclaration(namedDecl(hasName("D"))))))))); - EXPECT_TRUE(notMatches( - "namespace M {" - " class D {};" - "}" - "M::D d;", - elaboratedType(elaboratedType(namesType(typedefType()))))); + EXPECT_TRUE(matches("namespace N {" + " namespace M {" + " class D {};" + " }" + "}" + "N::M::D d;", + elaboratedType(elaboratedType(namesType(recordType( + hasDeclaration(namedDecl(hasName("D"))))))))); + EXPECT_TRUE( + notMatches("namespace M {" + " class D {};" + "}" + "M::D d;", + elaboratedType(elaboratedType(namesType(typedefType()))))); } TEST(NNS, BindsNestedNameSpecifiers) { EXPECT_TRUE(matchAndVerifyResultTrue( - "namespace ns { struct E { struct B {}; }; } ns::E::B b;", - nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"), - std::make_unique>( - "nns", "ns::struct E::"))); + "namespace ns { struct E { struct B {}; }; } ns::E::B b;", + nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"), + std::make_unique>( + "nns", "ns::struct E::"))); } TEST(NNS, BindsNestedNameSpecifierLocs) { EXPECT_TRUE(matchAndVerifyResultTrue( - "namespace ns { struct B {}; } ns::B b;", - loc(nestedNameSpecifier()).bind("loc"), - std::make_unique>("loc", 1))); + "namespace ns { struct B {}; } ns::B b;", + loc(nestedNameSpecifier()).bind("loc"), + std::make_unique>("loc", 1))); } TEST(NNS, DescendantsOfNestedNameSpecifiers) { @@ -5748,44 +5686,39 @@ TEST(NNS, DescendantsOfNestedNameSpecifiers) { "namespace a { struct A { struct B { struct C {}; }; }; };" "void f() { a::A::B::C c; }"; EXPECT_TRUE(matches( - Fragment, - nestedNameSpecifier(specifiesType(asString("struct a::A::B")), - hasDescendant(nestedNameSpecifier( - specifiesNamespace(hasName("a"))))))); + Fragment, nestedNameSpecifier(specifiesType(asString("struct a::A::B")), + hasDescendant(nestedNameSpecifier( + specifiesNamespace(hasName("a"))))))); EXPECT_TRUE(notMatches( - Fragment, - nestedNameSpecifier(specifiesType(asString("struct a::A::B")), - has(nestedNameSpecifier( - specifiesNamespace(hasName("a"))))))); + Fragment, nestedNameSpecifier(specifiesType(asString("struct a::A::B")), + has(nestedNameSpecifier( + specifiesNamespace(hasName("a"))))))); EXPECT_TRUE(matches( - Fragment, - nestedNameSpecifier(specifiesType(asString("struct a::A")), - has(nestedNameSpecifier( - specifiesNamespace(hasName("a"))))))); + Fragment, nestedNameSpecifier(specifiesType(asString("struct a::A")), + has(nestedNameSpecifier( + specifiesNamespace(hasName("a"))))))); // Not really useful because a NestedNameSpecifier can af at most one child, // but to complete the interface. EXPECT_TRUE(matchAndVerifyResultTrue( - Fragment, - nestedNameSpecifier(specifiesType(asString("struct a::A::B")), - forEach(nestedNameSpecifier().bind("x"))), - std::make_unique>("x", 1))); + Fragment, + nestedNameSpecifier(specifiesType(asString("struct a::A::B")), + forEach(nestedNameSpecifier().bind("x"))), + std::make_unique>("x", 1))); } TEST(NNS, NestedNameSpecifiersAsDescendants) { StringRef Fragment = "namespace a { struct A { struct B { struct C {}; }; }; };" "void f() { a::A::B::C c; }"; - EXPECT_TRUE(matches( - Fragment, - decl(hasDescendant(nestedNameSpecifier(specifiesType( - asString("struct a::A"))))))); + EXPECT_TRUE(matches(Fragment, decl(hasDescendant(nestedNameSpecifier( + specifiesType(asString("struct a::A"))))))); EXPECT_TRUE(matchAndVerifyResultTrue( - Fragment, - functionDecl(hasName("f"), - forEachDescendant(nestedNameSpecifier().bind("x"))), - // Nested names: a, a::A and a::A::B. - std::make_unique>("x", 3))); + Fragment, + functionDecl(hasName("f"), + forEachDescendant(nestedNameSpecifier().bind("x"))), + // Nested names: a, a::A and a::A::B. + std::make_unique>("x", 3))); } TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) { @@ -5793,42 +5726,41 @@ TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) { "namespace a { struct A { struct B { struct C {}; }; }; };" "void f() { a::A::B::C c; }"; EXPECT_TRUE(matches( - Fragment, - nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), - hasDescendant(loc(nestedNameSpecifier( - specifiesNamespace(hasName("a")))))))); + Fragment, + nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), + hasDescendant(loc(nestedNameSpecifier( + specifiesNamespace(hasName("a")))))))); EXPECT_TRUE(notMatches( - Fragment, - nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), - has(loc(nestedNameSpecifier( - specifiesNamespace(hasName("a")))))))); + Fragment, + nestedNameSpecifierLoc( + loc(specifiesType(asString("struct a::A::B"))), + has(loc(nestedNameSpecifier(specifiesNamespace(hasName("a")))))))); EXPECT_TRUE(matches( - Fragment, - nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))), - has(loc(nestedNameSpecifier( - specifiesNamespace(hasName("a")))))))); + Fragment, + nestedNameSpecifierLoc( + loc(specifiesType(asString("struct a::A"))), + has(loc(nestedNameSpecifier(specifiesNamespace(hasName("a")))))))); EXPECT_TRUE(matchAndVerifyResultTrue( - Fragment, - nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), - forEach(nestedNameSpecifierLoc().bind("x"))), - std::make_unique>("x", 1))); + Fragment, + nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), + forEach(nestedNameSpecifierLoc().bind("x"))), + std::make_unique>("x", 1))); } TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) { StringRef Fragment = "namespace a { struct A { struct B { struct C {}; }; }; };" "void f() { a::A::B::C c; }"; - EXPECT_TRUE(matches( - Fragment, - decl(hasDescendant(loc(nestedNameSpecifier(specifiesType( - asString("struct a::A")))))))); + EXPECT_TRUE( + matches(Fragment, decl(hasDescendant(loc(nestedNameSpecifier( + specifiesType(asString("struct a::A")))))))); EXPECT_TRUE(matchAndVerifyResultTrue( - Fragment, - functionDecl(hasName("f"), - forEachDescendant(nestedNameSpecifierLoc().bind("x"))), - // Nested names: a, a::A and a::A::B. - std::make_unique>("x", 3))); + Fragment, + functionDecl(hasName("f"), + forEachDescendant(nestedNameSpecifierLoc().bind("x"))), + // Nested names: a, a::A and a::A::B. + std::make_unique>("x", 3))); } TEST(Attr, AttrsAsDescendants) { @@ -5852,16 +5784,16 @@ template class VerifyMatchOnNode : public BoundNodesCallback { public: VerifyMatchOnNode(StringRef Id, const internal::Matcher &InnerMatcher, StringRef InnerId) - : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) { - } + : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {} bool run(const BoundNodes *Nodes) override { return false; } bool run(const BoundNodes *Nodes, ASTContext *Context) override { const T *Node = Nodes->getNodeAs(Id); return selectFirst(InnerId, match(InnerMatcher, *Node, *Context)) != - nullptr; + nullptr; } + private: std::string Id; internal::Matcher InnerMatcher; @@ -5870,37 +5802,37 @@ template class VerifyMatchOnNode : public BoundNodesCallback { TEST(MatchFinder, CanMatchDeclarationsRecursively) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), - std::make_unique>( - "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))), - "Y"))); + "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), + std::make_unique>( + "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))), + "Y"))); EXPECT_TRUE(matchAndVerifyResultFalse( - "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), - std::make_unique>( - "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))), - "Z"))); + "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), + std::make_unique>( + "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))), + "Z"))); } TEST(MatchFinder, CanMatchStatementsRecursively) { EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), - std::make_unique>( - "if", stmt(hasDescendant(forStmt().bind("for"))), "for"))); + "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), + std::make_unique>( + "if", stmt(hasDescendant(forStmt().bind("for"))), "for"))); EXPECT_TRUE(matchAndVerifyResultFalse( - "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), - std::make_unique>( - "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl"))); + "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), + std::make_unique>( + "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl"))); } TEST(MatchFinder, CanMatchSingleNodesRecursively) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), - std::make_unique>( - "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y"))); + "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), + std::make_unique>( + "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y"))); EXPECT_TRUE(matchAndVerifyResultFalse( - "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), - std::make_unique>( - "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z"))); + "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), + std::make_unique>( + "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z"))); } TEST(StatementMatcher, HasReturnValue) { @@ -5924,21 +5856,14 @@ TEST(StatementMatcher, ForFunction) { " }" " };" "}"; - EXPECT_TRUE( - matches( - CppString1, - returnStmt(forFunction(hasName("operator=")), - has(unaryOperator(hasOperatorName("*")))))); - EXPECT_TRUE( - notMatches( - CppString1, - returnStmt(forFunction(hasName("operator=")), - has(integerLiteral())))); - EXPECT_TRUE( - matches( - CppString1, - returnStmt(forFunction(hasName("operator()")), - has(integerLiteral())))); + EXPECT_TRUE(matches(CppString1, + returnStmt(forFunction(hasName("operator=")), + has(unaryOperator(hasOperatorName("*")))))); + EXPECT_TRUE( + notMatches(CppString1, returnStmt(forFunction(hasName("operator=")), + has(integerLiteral())))); + EXPECT_TRUE(matches(CppString1, returnStmt(forFunction(hasName("operator()")), + has(integerLiteral())))); EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2"))))); EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F"))))); } @@ -5959,21 +5884,15 @@ TEST(StatementMatcher, ForCallable) { " };" "}"; - EXPECT_TRUE( - matches( - CppString1, - returnStmt(forCallable(functionDecl(hasName("operator="))), - has(unaryOperator(hasOperatorName("*")))))); - EXPECT_TRUE( - notMatches( - CppString1, - returnStmt(forCallable(functionDecl(hasName("operator="))), - has(integerLiteral())))); - EXPECT_TRUE( - matches( - CppString1, - returnStmt(forCallable(functionDecl(hasName("operator()"))), - has(integerLiteral())))); + EXPECT_TRUE(matches( + CppString1, returnStmt(forCallable(functionDecl(hasName("operator="))), + has(unaryOperator(hasOperatorName("*")))))); + EXPECT_TRUE(notMatches( + CppString1, returnStmt(forCallable(functionDecl(hasName("operator="))), + has(integerLiteral())))); + EXPECT_TRUE(matches( + CppString1, returnStmt(forCallable(functionDecl(hasName("operator()"))), + has(integerLiteral())))); EXPECT_TRUE(matches(CppString2, returnStmt(forCallable(functionDecl(hasName("F2")))))); EXPECT_TRUE(notMatches(CppString2, @@ -5990,14 +5909,10 @@ TEST(StatementMatcher, ForCallable) { "@end"; EXPECT_TRUE( - matchesObjC( - ObjCString1, - binaryOperator(forCallable(blockDecl())))); + matchesObjC(ObjCString1, binaryOperator(forCallable(blockDecl())))); - EXPECT_TRUE( - notMatchesObjC( - ObjCString1, - binaryOperator(forCallable(objcMethodDecl())))); + EXPECT_TRUE(notMatchesObjC(ObjCString1, + binaryOperator(forCallable(objcMethodDecl())))); StringRef ObjCString2 = "@interface I" "-(void) foo;" @@ -6010,14 +5925,10 @@ TEST(StatementMatcher, ForCallable) { "@end"; EXPECT_TRUE( - matchesObjC( - ObjCString2, - binaryOperator(forCallable(objcMethodDecl())))); + matchesObjC(ObjCString2, binaryOperator(forCallable(objcMethodDecl())))); EXPECT_TRUE( - notMatchesObjC( - ObjCString2, - binaryOperator(forCallable(blockDecl())))); + notMatchesObjC(ObjCString2, binaryOperator(forCallable(blockDecl())))); } TEST(Matcher, ForEachOverriden) { @@ -6036,7 +5947,7 @@ TEST(Matcher, ForEachOverriden) { EXPECT_TRUE(matchAndVerifyResultTrue( Code1, ForEachOverriddenInClass("C"), std::make_unique>("overridden", "f", - 1))); + 1))); // B::f overrides A::f. EXPECT_TRUE(matchAndVerifyResultTrue( Code1, ForEachOverriddenInClass("B"), @@ -6044,14 +5955,13 @@ TEST(Matcher, ForEachOverriden) { EXPECT_TRUE(matchAndVerifyResultTrue( Code1, ForEachOverriddenInClass("B"), std::make_unique>("overridden", "f", - 1))); + 1))); // A::f overrides nothing. EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A"))); - static const char Code2[] = - "class A1 { virtual void f(); };" - "class A2 { virtual void f(); };" - "class B : public A1, public A2 { void f(); };"; + static const char Code2[] = "class A1 { virtual void f(); };" + "class A2 { virtual void f(); };" + "class B : public A1, public A2 { void f(); };"; // B::f overrides A1::f and A2::f. This produces two matches. EXPECT_TRUE(matchAndVerifyResultTrue( Code2, ForEachOverriddenInClass("B"), @@ -6059,7 +5969,7 @@ TEST(Matcher, ForEachOverriden) { EXPECT_TRUE(matchAndVerifyResultTrue( Code2, ForEachOverriddenInClass("B"), std::make_unique>("overridden", "f", - 2))); + 2))); // A1::f overrides nothing. EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1"))); } diff --git a/clang/unittests/Tooling/StencilTest.cpp b/clang/unittests/Tooling/StencilTest.cpp index 26257cf2ca3a5f..980b0941fc04c7 100644 --- a/clang/unittests/Tooling/StencilTest.cpp +++ b/clang/unittests/Tooling/StencilTest.cpp @@ -580,10 +580,10 @@ TEST_F(StencilTest, CatOfMacroRangeSucceeds) { double foo(double d); foo(MACRO);)cpp"; - auto StmtMatch = - matchStmt(Snippet, callExpr(callee(functionDecl(hasName("foo"))), - argumentCountIs(1), - hasArgument(0, expr().bind("arg")))); + auto StmtMatch = matchStmt( + Snippet, + callExpr(callee(functionDecl(hasName("foo"))), argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))))); ASSERT_TRUE(StmtMatch); Stencil S = cat(node("arg")); EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("MACRO")); @@ -608,9 +608,10 @@ TEST_F(StencilTest, CatOfMacroArgSubRangeSucceeds) { MACRO(2, foo(3));)cpp"; auto StmtMatch = matchStmt( - Snippet, binaryOperator(hasRHS(callExpr( - callee(functionDecl(hasName("foo"))), argumentCountIs(1), - hasArgument(0, expr().bind("arg")))))); + Snippet, + binaryOperator(hasRHS(callExpr( + callee(functionDecl(hasName("foo"))), argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))))))); ASSERT_TRUE(StmtMatch); Stencil S = cat(node("arg")); EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("3")); @@ -622,10 +623,10 @@ TEST_F(StencilTest, CatOfInvalidRangeFails) { double foo(double d); foo(MACRO);)cpp"; - auto StmtMatch = - matchStmt(Snippet, callExpr(callee(functionDecl(hasName("foo"))), - argumentCountIs(1), - hasArgument(0, expr().bind("arg")))); + auto StmtMatch = matchStmt( + Snippet, + callExpr(callee(functionDecl(hasName("foo"))), argumentCountIs(1), + hasArgument(0, ignoringParenImpCasts(expr().bind("arg"))))); ASSERT_TRUE(StmtMatch); Stencil S = cat(node("arg")); Expected Result = S->eval(StmtMatch->Result); diff --git a/clang/unittests/Tooling/TransformerTest.cpp b/clang/unittests/Tooling/TransformerTest.cpp index cbd84ab794a49a..a96fe3e499c952 100644 --- a/clang/unittests/Tooling/TransformerTest.cpp +++ b/clang/unittests/Tooling/TransformerTest.cpp @@ -208,11 +208,13 @@ static RewriteRuleWith ruleStrlenSize() { StringRef StringExpr = "strexpr"; auto StringType = namedDecl(hasAnyName("::basic_string", "::string")); auto R = makeRule( - callExpr(callee(functionDecl(hasName("strlen"))), - hasArgument(0, cxxMemberCallExpr( - on(expr(hasType(isOrPointsTo(StringType))) - .bind(StringExpr)), - callee(cxxMethodDecl(hasName("c_str")))))), + callExpr( + callee(functionDecl(hasName("strlen"))), + hasArgument( + 0, + ignoringParenImpCasts(cxxMemberCallExpr( + on(expr(hasType(isOrPointsTo(StringType))).bind(StringExpr)), + callee(cxxMethodDecl(hasName("c_str"))))))), changeTo(cat("REPLACED")), cat("Use size() method directly on string.")); return R; }