diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp @@ -22,7 +22,7 @@ const auto DurationExpr = expr(hasType(cxxRecordDecl(hasName("::absl::Duration")))); - finder->addMatcher( + finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr( hasSourceExpression(ignoringParenCasts( cxxOperatorCallExpr(hasOverloadedOperatorName("/"), @@ -32,7 +32,7 @@ hasImplicitDestinationType(qualType(unless(isInteger()))), unless(hasParent(cxxStaticCastExpr())), unless(hasParent(cStyleCastExpr())), - unless(isInTemplateInstantiation())), + unless(isInTemplateInstantiation()))), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp @@ -81,20 +81,21 @@ // Find uses of absl::StrSplit(..., "x") and absl::StrSplit(..., // absl::ByAnyChar("x")) to transform them into absl::StrSplit(..., 'x'). - Finder->addMatcher(callExpr(callee(functionDecl(hasName("::absl::StrSplit"))), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + callExpr(callee(functionDecl(hasName("::absl::StrSplit"))), hasArgument(1, anyOf(ByAnyCharArg, SingleChar)), unless(isInTemplateInstantiation())) - .bind("StrSplit"), + .bind("StrSplit")), this); // Find uses of absl::MaxSplits("x", N) and // absl::MaxSplits(absl::ByAnyChar("x"), N) to transform them into // absl::MaxSplits('x', N). - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, callExpr( callee(functionDecl(hasName("::absl::MaxSplits"))), hasArgument(0, anyOf(ByAnyCharArg, ignoringParenCasts(SingleChar))), - unless(isInTemplateInstantiation())), + unless(isInTemplateInstantiation()))), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp --- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp @@ -68,9 +68,9 @@ has(callExpr(callee(functionDecl(*Strcat))).bind("StrCat"))); if (const auto* SubStrcatCall = selectFirst( "StrCat", - match(stmt(anyOf( + match(stmt(traverse(ast_type_traits::TK_AsIs, anyOf( cxxConstructExpr(IsAlphanum, hasArgument(0, IsStrcat)), - IsStrcat)), + IsStrcat))), *Arg->IgnoreParenImpCasts(), *Result.Context))) { RemoveCallLeaveArgs(SubStrcatCall, CheckResult); return SubStrcatCall; diff --git a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp --- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp @@ -45,8 +45,8 @@ if (!getLangOpts().CPlusPlus) return; 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")), @@ -59,7 +59,7 @@ // Now look for calls to operator= with an object on the LHS and a call to // 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( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxOperatorCallExpr( unless(isInTemplateInstantiation()), hasOverloadedOperatorName("="), hasArgument(0, declRefExpr(to(decl().bind("LHS")))), @@ -67,7 +67,7 @@ callExpr(callee(StrCat), hasArgument(0, AlphaNum), unless(HasAnotherReferenceToLhs)) .bind("Call")))) - .bind("Op"), + .bind("Op")), this); } diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -102,6 +102,7 @@ // `absl::Hours(x)` // where `x` is not of a built-in type. Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, implicitCastExpr( anyOf(hasCastKind(CK_UserDefinedConversion), has(implicitCastExpr(hasCastKind(CK_UserDefinedConversion)))), @@ -109,7 +110,7 @@ callee(functionDecl(DurationFactoryFunction(), unless(hasParent(functionTemplateDecl())))), hasArgument(0, expr().bind("arg"))))) - .bind("OuterExpr"), + .bind("OuterExpr")), this); } @@ -119,6 +120,8 @@ "implicit conversion to 'int64_t' is deprecated in this context; use an " "explicit cast instead"; + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + const auto *ArgExpr = Result.Nodes.getNodeAs("arg"); SourceLocation Loc = ArgExpr->getBeginLoc(); diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp @@ -84,7 +84,8 @@ void AssertSideEffectCheck::registerMatchers(MatchFinder *Finder) { auto DescendantWithSideEffect = - hasDescendant(expr(hasSideEffect(CheckFunctionCalls))); + traverse(ast_type_traits::TK_AsIs, + hasDescendant(expr(hasSideEffect(CheckFunctionCalls)))); auto ConditionWithSideEffect = hasCondition(DescendantWithSideEffect); Finder->addMatcher( stmt( diff --git a/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp @@ -18,6 +18,7 @@ // Look for ifs that have an implicit bool* to bool conversion in the // condition. Filter negations. Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, ifStmt(hasCondition(findAll(implicitCastExpr( unless(hasParent(unaryOperator(hasOperatorName("!")))), hasSourceExpression( @@ -25,7 +26,7 @@ ignoringParenImpCasts(declRefExpr().bind("expr")))), hasCastKind(CK_PointerToBoolean)))), unless(isInTemplateInstantiation())) - .bind("if"), + .bind("if")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -117,29 +117,33 @@ // Find 'Handle foo = ReturnsAValue();' Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, varDecl( hasType(hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(IsAHandle))))), unless(parmVarDecl()), hasInitializer(exprWithCleanups(has(ignoringParenImpCasts(handleFrom( IsAHandle, ConvertedHandle)))) - .bind("bad_stmt"))), + .bind("bad_stmt")))), this); // Find 'foo = ReturnsAValue(); // foo is Handle' Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(IsAHandle))), hasOverloadedOperatorName("="), hasArgument(1, ConvertedHandle)) - .bind("bad_stmt"), + .bind("bad_stmt")), this); // Container insertions that will dangle. - Finder->addMatcher(makeContainerMatcher(IsAHandle).bind("bad_stmt"), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makeContainerMatcher(IsAHandle).bind("bad_stmt")), this); } void DanglingHandleCheck::registerMatchersForReturn(MatchFinder *Finder) { // Return a local. Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, returnStmt( // The AST contains two constructor calls: // 1. Value to Handle conversion. @@ -158,14 +162,14 @@ unless(IsAHandle)))))))))))))), // Temporary fix for false positives inside lambdas. unless(hasAncestor(lambdaExpr()))) - .bind("bad_stmt"), + .bind("bad_stmt")), this); // Return a temporary. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom( IsAHandle, handleFromTemporaryValue(IsAHandle))))))) - .bind("bad_stmt"), + .bind("bad_stmt")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp @@ -36,14 +36,14 @@ const auto DeclInStd = type(hasUnqualifiedDesugaredType( tagType(hasDeclaration(decl(isInStdNamespace()))))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxMemberCallExpr( on(anyOf(hasType(DeclInStd), hasType(pointsTo(DeclInStd)))), callee(cxxMethodDecl(hasName("erase"))), argumentCountIs(1), hasArgument(0, has(ignoringImplicit( anyOf(EndCall, has(ignoringImplicit(EndCall)))))), unless(isInTemplateInstantiation())) - .bind("erase"), + .bind("erase")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp @@ -51,10 +51,11 @@ // Find expressions of cast to int of the sum of a floating point expression // and 0.5. MatchFinder->addMatcher( + traverse(ast_type_traits::TK_AsIs, implicitCastExpr( hasImplicitDestinationType(isInteger()), ignoringParenCasts(binaryOperator(hasOperatorName("+"), OneSideHalf))) - .bind("CastExpr"), + .bind("CastExpr")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp @@ -34,6 +34,7 @@ callExpr(IntType), explicitCastExpr(IntType), UnaryOperators); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, binaryOperator( hasOperatorName("/"), hasLHS(expr(IntType)), hasRHS(expr(IntType)), hasAncestor( @@ -41,7 +42,7 @@ unless(hasAncestor( expr(Exceptions, hasAncestor(castExpr(equalsBoundNode("FloatCast"))))))) - .bind("IntDiv"), + .bind("IntDiv")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp @@ -57,16 +57,18 @@ hasInitializer(ignoringParenImpCasts( declRefExpr(hasDeclaration(Alloc1Func))))); - Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))), hasArgument(0, BadArg)) - .bind("Alloc"), + .bind("Alloc")), this); - Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))), hasArgument(1, BadArg)) - .bind("Alloc"), + .bind("Alloc")), this); - Finder->addMatcher( - cxxNewExpr(isArray(), hasArraySize(BadArg)).bind("Alloc"), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxNewExpr(isArray(), hasArraySize(BadArg)).bind("Alloc")), this); } void MisplacedOperatorInStrlenInAllocCheck::check( diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp @@ -41,7 +41,8 @@ const auto ImplicitCast = implicitCastExpr(hasImplicitDestinationType(isInteger()), has(ignoringParenImpCasts(Calc))); - const auto Cast = expr(anyOf(ExplicitCast, ImplicitCast)).bind("Cast"); + const auto Cast = traverse(ast_type_traits::TK_AsIs, + expr(anyOf(ExplicitCast, ImplicitCast)).bind("Cast")); Finder->addMatcher(varDecl(hasInitializer(Cast)), this); Finder->addMatcher(returnStmt(hasReturnValue(Cast)), this); diff --git a/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp @@ -83,6 +83,7 @@ void ParentVirtualCallCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxMemberCallExpr( callee(memberExpr(hasDescendant(implicitCastExpr( hasImplicitDestinationType(pointsTo( @@ -90,7 +91,7 @@ hasSourceExpression(cxxThisExpr(hasType( type(anything()).bind("thisType"))))))) .bind("member")), - callee(cxxMethodDecl(isVirtual()))), + callee(cxxMethodDecl(isVirtual())))), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -67,13 +67,13 @@ const auto AssignmentOperatorExpr = expr(binaryOperator( hasOperatorName("="), hasLHS(hasType(IntegerType)), hasRHS(CastExpr))); - Finder->addMatcher(AssignmentOperatorExpr, this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, AssignmentOperatorExpr), this); // Catch declarations with the suspicious type conversion. const auto Declaration = varDecl(isDefinition(), hasType(IntegerType), hasInitializer(CastExpr)); - Finder->addMatcher(Declaration, this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, Declaration), this); } void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp @@ -89,7 +89,8 @@ initListExpr(hasType(constantArrayType()), has(ignoringParenImpCasts(expr(ConcatenatedStringLiteral)))); - Finder->addMatcher(StringsInitializerList.bind("list"), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + StringsInitializerList.bind("list")), this); } void SuspiciousMissingCommaCheck::check( diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp @@ -135,10 +135,10 @@ } // Detect suspicious cast to an inconsistant type (i.e. not integer type). - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr(unless(hasType(isInteger())), hasSourceExpression(StringCompareCallExpr)) - .bind("invalid-conversion"), + .bind("invalid-conversion")), this); // Detect suspicious operator with string compare function as operand. diff --git a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp @@ -59,9 +59,10 @@ // We need to catch only those comparisons which contain any integer cast. StatementMatcher LoopVarConversionMatcher = + traverse(ast_type_traits::TK_AsIs, implicitCastExpr(hasImplicitDestinationType(isInteger()), has(ignoringParenImpCasts(LoopVarMatcher))) - .bind(LoopVarCastName); + .bind(LoopVarCastName)); // We are interested in only those cases when the loop bound is a variable // value (not const, enum, etc.). diff --git a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp @@ -60,6 +60,7 @@ return; Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, compoundStmt( hasParent( cxxConstructorDecl(ofClass(cxxRecordDecl().bind("parent")))), @@ -67,7 +68,7 @@ cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(baseOfBoundNode("parent")))))) .bind("construct"))), - unless(isInTemplateInstantiation())), + unless(isInTemplateInstantiation()))), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -50,10 +50,15 @@ // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. // In the non-template case, we can search for the copy constructor call. - const auto HasNonTemplateSelfCopy = cxxMethodDecl( - ofClass(cxxRecordDecl(unless(hasAncestor(classTemplateDecl())))), - hasDescendant(cxxConstructExpr(hasDeclaration(cxxConstructorDecl( - isCopyConstructor(), ofClass(equalsBoundNode("class"))))))); + const auto HasNonTemplateSelfCopy = traverse(ast_type_traits::TK_AsIs, + cxxMethodDecl( + ofClass(cxxRecordDecl(unless(hasAncestor(classTemplateDecl())))), + hasDescendant(cxxConstructExpr(hasDeclaration(cxxConstructorDecl( + isCopyConstructor(), + ofClass(equalsBoundNode("class")) + )))) + ) + ); // In the template case, we need to handle two separate cases: 1) a local // variable is created with the copy, 2) copy is created only as a temporary @@ -96,7 +101,7 @@ HasReferenceParam, HasNoSelfCheck, unless(HasNonTemplateSelfCopy), unless(HasTemplateSelfCopy), - HasNoNestedSelfAssign, AdditionalMatcher) + HasNoNestedSelfAssign, AdditionalMatcher ) .bind("copyAssignmentOperator"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -36,13 +36,14 @@ cxxBindTemporaryExpr(unless(has(ignoringParenImpCasts(callExpr())))) .bind("temp"); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, exprWithCleanups(unless(isInTemplateInstantiation()), hasParent(compoundStmt().bind("compound")), hasType(cxxRecordDecl(hasNonTrivialDestructor())), anyOf(has(ignoringParenImpCasts(BindTemp)), has(ignoringParenImpCasts(cxxFunctionalCastExpr( has(ignoringParenImpCasts(BindTemp))))))) - .bind("expr"), + .bind("expr")), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -253,7 +253,8 @@ unless(inDecltypeOrTemplateArg())) .bind("declref"); - addDeclRefs(match(findAll(DeclRefMatcher), *S->getStmt(), *Context)); + addDeclRefs(match(traverse(ast_type_traits::TK_AsIs, + findAll(DeclRefMatcher)), *S->getStmt(), *Context)); addDeclRefs(match( findAll(cxxOperatorCallExpr(anyOf(hasOverloadedOperatorName("*"), hasOverloadedOperatorName("->"), @@ -320,7 +321,7 @@ // Passing variable to a function as a non-const lvalue reference // (unless that function is std::move()). callExpr(forEachArgumentWithParam( - DeclRefMatcher, + traverse(ast_type_traits::TK_AsIs, DeclRefMatcher), unless(parmVarDecl(hasType( references(qualType(isConstQualified())))))), unless(callee(functionDecl(hasName("::std::move"))))))) @@ -386,6 +387,7 @@ .bind("call-move"); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, // To find the Stmt that we assume performs the actual move, we look for // the direct ancestor of the std::move() that isn't one of the node // types ignored by ignoringParenImpCasts(). @@ -398,11 +400,12 @@ // different code locations for the same move. unless(initListExpr()), unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move"))))) - .bind("moving-call"), + .bind("moving-call")), this); } void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { + const auto *ContainingLambda = Result.Nodes.getNodeAs("containing-lambda"); const auto *ContainingFunc = diff --git a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp --- a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp @@ -56,11 +56,11 @@ callee(IsSelfMutatingMemberFunction)) .bind(MutatingCallName); - const auto MutatesSource = allOf( + const auto MutatesSource = traverse(ast_type_traits::TK_AsIs, allOf( hasParameter( 0, parmVarDecl(hasType(lValueReferenceType())).bind(SourceDeclName)), anyOf(forEachDescendant(IsSourceMutatingAssignment), - forEachDescendant(IsSourceMutatingMemberCall))); + forEachDescendant(IsSourceMutatingMemberCall)))); Finder->addMatcher(cxxConstructorDecl(isCopyConstructor(), MutatesSource), this); diff --git a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp b/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp --- a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp @@ -61,8 +61,8 @@ // const int x = 1; // std::mt19937 engine(x); // ^ - Finder->addMatcher( - cxxConstructExpr(RandomGeneratorEngineTypeMatcher).bind("ctor"), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxConstructExpr(RandomGeneratorEngineTypeMatcher).bind("ctor")), this); // srand(); // ^ diff --git a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp --- a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp @@ -23,7 +23,7 @@ // Match any static or thread_local variable declaration that has an // initializer that can throw. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()), unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())), hasAncestor(functionDecl()))), @@ -33,7 +33,7 @@ functionDecl(unless(isNoThrow())).bind("func")))), hasDescendant(callExpr(hasDeclaration( functionDecl(unless(isNoThrow())).bind("func")))))) - .bind("var"), + .bind("var")), this); } diff --git a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp --- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp @@ -21,11 +21,11 @@ if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxThrowExpr(has(ignoringParenImpCasts( cxxConstructExpr(hasDeclaration(cxxConstructorDecl( isCopyConstructor(), unless(isNoThrow())))) - .bind("expr")))), + .bind("expr"))))), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp @@ -27,10 +27,10 @@ const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration( varDecl(GlobalVarDecl, unless(isDefinition())).bind("referencee"))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, varDecl(GlobalVarDecl, isDefinition(), hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar)))) - .bind("var"), + .bind("var")), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp @@ -39,17 +39,19 @@ // i = 0.5; // void f(int); f(0.5); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, implicitCastExpr(hasImplicitDestinationType(builtinType()), hasSourceExpression(hasType(builtinType())), unless(hasSourceExpression(IsCeilFloorCallExpr)), unless(hasParent(castExpr())), unless(isInTemplateInstantiation())) - .bind("cast"), + .bind("cast")), this); // Binary operators: // i += 0.5; - Finder->addMatcher(binaryOperator(isAssignmentOperator(), + Finder->addMatcher( + binaryOperator(isAssignmentOperator(), hasLHS(expr(hasType(builtinType()))), hasRHS(expr(hasType(builtinType()))), unless(hasRHS(IsCeilFloorCallExpr)), diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp @@ -71,11 +71,11 @@ const auto ConsideredOwner = eachOf(IsOwnerType, CreatesOwner); // Find delete expressions that delete non-owners. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxDeleteExpr( hasDescendant( declRefExpr(unless(ConsideredOwner)).bind("deleted_variable"))) - .bind("delete_expr"), + .bind("delete_expr")), this); // Ignoring the implicit casts is vital because the legacy owners do not work @@ -85,25 +85,26 @@ // Furthermore, legacy owner functions are assumed to use raw pointers for // resources. This check assumes that all pointer arguments of a legacy // functions shall be 'gsl::owner<>'. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, callExpr(callee(LegacyOwnerConsumers), hasAnyArgument(expr(unless(ignoringImpCasts(ConsideredOwner)), hasType(pointerType())))) - .bind("legacy_consumer"), + .bind("legacy_consumer")), this); // Matching assignment to owners, with the rhs not being an owner nor creating // one. - Finder->addMatcher(binaryOperator(matchers::isAssignmentOperator(), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + binaryOperator(matchers::isAssignmentOperator(), hasLHS(IsOwnerType), hasRHS(unless(ConsideredOwner))) - .bind("owner_assignment"), + .bind("owner_assignment")), this); // Matching initialization of owners with non-owners, nor creating owners. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, namedDecl(varDecl(hasInitializer(unless(ConsideredOwner)), IsOwnerType) - .bind("owner_initialization")), + .bind("owner_initialization"))), this); const auto HasConstructorInitializerForOwner = @@ -118,59 +119,62 @@ // Match class member initialization that expects owners, but does not get // them. - Finder->addMatcher(cxxRecordDecl(HasConstructorInitializerForOwner), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxRecordDecl(HasConstructorInitializerForOwner)), this); // Matching on assignment operations where the RHS is a newly created owner, // but the LHS is not an owner. - Finder->addMatcher(binaryOperator(matchers::isAssignmentOperator(), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + binaryOperator(matchers::isAssignmentOperator(), hasLHS(unless(IsOwnerType)), hasRHS(CreatesOwner)) - .bind("bad_owner_creation_assignment"), + .bind("bad_owner_creation_assignment")), this); // Matching on initialization operations where the initial value is a newly // created owner, but the LHS is not an owner. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, namedDecl(varDecl(eachOf(allOf(hasInitializer(CreatesOwner), unless(IsOwnerType)), allOf(hasInitializer(ConsideredOwner), hasType(autoType().bind("deduced_type"))))) - .bind("bad_owner_creation_variable")), + .bind("bad_owner_creation_variable"))), this); // Match on all function calls that expect owners as arguments, but didn't // get them. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, callExpr(forEachArgumentWithParam( expr(unless(ConsideredOwner)).bind("expected_owner_argument"), - parmVarDecl(IsOwnerType))), + parmVarDecl(IsOwnerType)))), this); // Matching for function calls where one argument is a created owner, but the // parameter type is not an owner. - Finder->addMatcher(callExpr(forEachArgumentWithParam( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + callExpr(forEachArgumentWithParam( expr(CreatesOwner).bind("bad_owner_creation_argument"), parmVarDecl(unless(IsOwnerType)) - .bind("bad_owner_creation_parameter"))), + .bind("bad_owner_creation_parameter")))), this); // Matching on functions, that return an owner/resource, but don't declare // their return type as owner. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, functionDecl(hasDescendant(returnStmt(hasReturnValue(ConsideredOwner)) .bind("bad_owner_return")), unless(returns(qualType(hasDeclaration(OwnerDecl))))) - .bind("function_decl"), + .bind("function_decl")), this); // Match on classes that have an owner as member, but don't declare a // destructor to properly release the owner. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxRecordDecl( has(fieldDecl(IsOwnerType).bind("undestructed_owner_member")), anyOf(unless(has(cxxDestructorDecl())), has(cxxDestructorDecl(anyOf(isDefaulted(), isDeleted()))))) - .bind("non_destructor_class"), + .bind("non_destructor_class")), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp @@ -56,13 +56,13 @@ // 1) just before array subscription // 2) inside a range-for over an array // 3) if it converts a string literal to a pointer - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr( unless(hasParent(arraySubscriptExpr())), unless(hasParentIgnoringImpCasts(explicitCastExpr())), unless(isInsideOfRangeBeginEndStmt()), unless(hasSourceExpression(ignoringParens(stringLiteral())))) - .bind("cast"), + .bind("cast")), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp @@ -62,8 +62,8 @@ // constructor in DerivedDecl's constructors. unless(IsWithinDerivedCtor)); - Finder->addMatcher( - expr(anyOf(SlicesObjectInAssignment, SlicesObjectInCtor)).bind("Call"), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + expr(anyOf(SlicesObjectInAssignment, SlicesObjectInCtor)).bind("Call")), this); } diff --git a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp --- a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp @@ -33,7 +33,7 @@ if (!getLangOpts().CPlusPlus11) return; - Finder->addMatcher(varDecl( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, varDecl( // Match global, statically stored objects... isGlobalStatic(), // ... that have C++ constructors... @@ -42,7 +42,7 @@ hasDeclaration(cxxConstructorDecl(isConstexpr())), // ... and is statically initialized. isConstantInitializer()))))) - .bind("decl"), + .bind("decl")), this); } diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp @@ -54,7 +54,7 @@ cxxMemberCallExpr().bind("arg")))))) .bind("rhs"); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, stmt(anyOf(ifStmt(Any), whileStmt(Any), doStmt(Condition), binaryOperator( allOf(unless(isExpansionInFileMatching( @@ -63,12 +63,15 @@ hasLHS(implicitCastExpr().bind("lhs")), hasRHS(anyOf(implicitCastExpr(has(CallExpression)), CallExpression)))) - .bind("and"))), + .bind("and")))), this); } void PreferIsaOrDynCastInConditionalsCheck::check( const MatchFinder::MatchResult &Result) { + + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + if (const auto *MatchedDecl = Result.Nodes.getNodeAs("assign")) { SourceLocation StartLoc = MatchedDecl->getCallee()->getExprLoc(); SourceLocation EndLoc = diff --git a/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp --- a/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp @@ -20,14 +20,14 @@ auto RegisterClassMatch = hasType( cxxRecordDecl(hasName("::llvm::Register")).bind("registerClassDecl")); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, valueDecl(allOf( hasType(qualType(isUnsignedInteger()).bind("varType")), varDecl(hasInitializer(exprWithCleanups(has(implicitCastExpr(has( cxxMemberCallExpr(allOf(on(RegisterClassMatch), has(memberExpr(hasDeclaration( cxxConversionDecl()))))))))))) - .bind("var"))), + .bind("var")))), this); } diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -696,7 +696,7 @@ integerLiteral(expandedByMacro(KnownBannedMacroNames)); // Binary with equivalent operands, like (X != 2 && X != 2). - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, binaryOperator(anyOf(hasOperatorName("-"), hasOperatorName("/"), hasOperatorName("%"), hasOperatorName("|"), hasOperatorName("&"), hasOperatorName("^"), @@ -711,19 +711,20 @@ unless(hasEitherOperand(hasType(realFloatingPointType()))), unless(hasLHS(AnyLiteralExpr)), unless(hasDescendant(BannedIntegerLiteral))) - .bind("binary"), + .bind("binary")), this); // Conditional (trenary) operator with equivalent operands, like (Y ? X : X). - Finder->addMatcher(conditionalOperator(expressionsAreEquivalent(), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + conditionalOperator(expressionsAreEquivalent(), // Filter noisy false positives. unless(conditionalOperatorIsInMacro()), unless(isInTemplateInstantiation())) - .bind("cond"), + .bind("cond")), this); // Overloaded operators with equivalent operands. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxOperatorCallExpr( anyOf( hasOverloadedOperatorName("-"), hasOverloadedOperatorName("/"), @@ -737,11 +738,11 @@ parametersAreEquivalent(), // Filter noisy false positives. unless(isMacro()), unless(isInTemplateInstantiation())) - .bind("call"), + .bind("call")), this); // Match expressions like: !(1 | 2 | 3) - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr( hasImplicitDestinationType(isInteger()), has(unaryOperator( @@ -752,11 +753,11 @@ hasOperatorName("&"))), integerLiteral())), hasRHS(integerLiteral()))))) - .bind("logical-bitwise-confusion"))), + .bind("logical-bitwise-confusion")))), this); // Match expressions like: (X << 8) & 0xFF - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, binaryOperator(hasOperatorName("&"), hasEitherOperand(ignoringParenImpCasts(binaryOperator( hasOperatorName("<<"), @@ -764,7 +765,7 @@ integerLiteral().bind("shift-const")))))), hasEitherOperand(ignoringParenImpCasts( integerLiteral().bind("and-const")))) - .bind("left-right-shift-confusion"), + .bind("left-right-shift-confusion")), this); // Match common expressions and apply more checks to find redundant @@ -779,26 +780,28 @@ const auto SymRight = matchSymbolicExpr("rhs"); // Match expressions like: x 0xFF == 0xF00. - Finder->addMatcher(binaryOperator(isComparisonOperator(), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + binaryOperator(isComparisonOperator(), hasEitherOperand(BinOpCstLeft), hasEitherOperand(CstRight)) - .bind("binop-const-compare-to-const"), + .bind("binop-const-compare-to-const")), this); // Match expressions like: x 0xFF == x. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, binaryOperator(isComparisonOperator(), anyOf(allOf(hasLHS(BinOpCstLeft), hasRHS(SymRight)), allOf(hasLHS(SymRight), hasRHS(BinOpCstLeft)))) - .bind("binop-const-compare-to-sym"), + .bind("binop-const-compare-to-sym")), this); // Match expressions like: x 10 == x 12. - Finder->addMatcher(binaryOperator(isComparisonOperator(), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + binaryOperator(isComparisonOperator(), hasLHS(BinOpCstLeft), hasRHS(BinOpCstRight), // Already reported as redundant. unless(operandsAreEquivalent())) - .bind("binop-const-compare-to-binop-const"), + .bind("binop-const-compare-to-binop-const")), this); // Match relational expressions combined with logical operators and find @@ -808,12 +811,12 @@ // Match expressions like: x < 2 && x > 2. const auto ComparisonLeft = matchRelationalIntegerConstantExpr("lhs"); const auto ComparisonRight = matchRelationalIntegerConstantExpr("rhs"); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, binaryOperator(anyOf(hasOperatorName("||"), hasOperatorName("&&")), hasLHS(ComparisonLeft), hasRHS(ComparisonRight), // Already reported as redundant. unless(operandsAreEquivalent())) - .bind("comparisons-of-symbol-and-const"), + .bind("comparisons-of-symbol-and-const")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -486,9 +486,12 @@ if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher(makeArrayLoopMatcher(), this); - Finder->addMatcher(makeIteratorLoopMatcher(), this); - Finder->addMatcher(makePseudoArrayLoopMatcher(), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makeArrayLoopMatcher()), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makeIteratorLoopMatcher()), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makePseudoArrayLoopMatcher()), this); } /// Given the range of a single declaration, such as: @@ -810,6 +813,8 @@ Confidence ConfidenceLevel(Confidence::CL_Safe); ASTContext *Context = Result.Context; + TraversalKindScope raii(*Context, ast_type_traits::TK_AsIs); + const ForStmt *Loop; LoopFixerKind FixerKind; RangeDescriptor Descriptor; diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -85,6 +85,7 @@ cxxConstructExpr(hasDeclaration(decl(unless(isPublic()))))))); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxBindTemporaryExpr(has(ignoringParenImpCasts( cxxConstructExpr( hasType(getSmartPointerTypeMatcher()), argumentCountIs(1), @@ -94,16 +95,17 @@ CanCallCtor) .bind(NewExpression)), unless(isInTemplateInstantiation())) - .bind(ConstructorCall)))), + .bind(ConstructorCall))))), this); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxMemberCallExpr( thisPointerType(getSmartPointerTypeMatcher()), callee(cxxMethodDecl(hasName("reset"))), hasArgument(0, cxxNewExpr(CanCallCtor).bind(NewExpression)), unless(isInTemplateInstantiation())) - .bind(ResetCall), + .bind(ResetCall)), this); } @@ -112,6 +114,8 @@ // pointer, 'make_smart_ptr' refers to 'std::make_shared' or // 'std::make_unique' or other function that creates smart_ptr. + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + SourceManager &SM = *Result.SourceManager; const auto *Construct = Result.Nodes.getNodeAs(ConstructorCall); diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp @@ -136,6 +136,7 @@ return; Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxConstructorDecl( forEachConstructorInitializer( cxxCtorInitializer( @@ -160,7 +161,7 @@ hasDeclContext( cxxRecordDecl(isMoveConstructible()))))))) .bind("Initializer"))) - .bind("Ctor"), + .bind("Ctor")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -99,18 +99,20 @@ // // std::auto_ptr fn(std::auto_ptr); // ^~~~~~~~~~~~~ ^~~~~~~~~~~~~ - Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType, + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + typeLoc(loc(qualType(AutoPtrType, // Skip elaboratedType() as the named // type will match soon thereafter. unless(elaboratedType())))) - .bind(AutoPtrTokenId), + .bind(AutoPtrTokenId)), this); // using std::auto_ptr; // ^~~~~~~~~~~~~~~~~~~ - Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(namedDecl( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(namedDecl( hasName("auto_ptr"), isFromStdNamespace())))) - .bind(AutoPtrTokenId), + .bind(AutoPtrTokenId)), this); // Find ownership transfers via copy construction and assignment. @@ -122,13 +124,14 @@ auto MovableArgumentMatcher = expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxOperatorCallExpr(hasOverloadedOperatorName("="), callee(cxxMethodDecl(ofClass(AutoPtrDecl))), - hasArgument(1, MovableArgumentMatcher)), + hasArgument(1, MovableArgumentMatcher))), this); - Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1), - hasArgument(0, MovableArgumentMatcher)), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1), + hasArgument(0, MovableArgumentMatcher))), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -33,12 +33,12 @@ const auto Begin = hasArgument(0, expr()); const auto End = hasArgument(1, expr()); const auto RandomFunc = hasArgument(2, expr().bind("randomFunc")); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, callExpr(anyOf(allOf(Begin, End, argumentCountIs(2)), allOf(Begin, End, RandomFunc, argumentCountIs(3))), hasDeclaration(functionDecl(hasName("::std::random_shuffle"))), has(implicitCastExpr(has(declRefExpr().bind("name"))))) - .bind("match"), + .bind("match")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp @@ -34,12 +34,12 @@ auto CtorAsArgument = materializeTemporaryExpr(anyOf( has(ConstructExpr), has(cxxFunctionalCastExpr(has(ConstructExpr))))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, functionDecl(isDefinition(), // Declarations don't have return statements. returns(unless(anyOf(builtinType(), autoType()))), hasDescendant(returnStmt(hasReturnValue( has(cxxConstructExpr(has(CtorAsArgument))))))) - .bind("fn"), + .bind("fn")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp @@ -40,7 +40,7 @@ unaryOperator(has(ignoringParenImpCasts(declRefExpr( hasDeclaration(equalsBoundNode("ContainerDecl")))))))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxMemberCallExpr( on(hasType(hasCanonicalType(hasDeclaration(namedDecl( hasAnyName("std::basic_string", "std::deque", "std::vector")))))), @@ -48,7 +48,7 @@ has(ignoringParenImpCasts(memberExpr(hasDescendant(CopyCtorCall)))), hasArgument(0, SwapParam.bind("ContainerToShrink")), unless(isInTemplateInstantiation())) - .bind("CopyAndSwapTrick"), + .bind("CopyAndSwapTrick")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -328,7 +328,8 @@ // Only register the matchers for C++; the functionality currently does not // provide any benefit to other languages, despite being benign. if (getLangOpts().CPlusPlus) { - Finder->addMatcher(makeCombinedMatcher(), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makeCombinedMatcher()), this); } } diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -27,14 +27,16 @@ return; Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, implicitCastExpr( has(ignoringParenImpCasts(integerLiteral().bind("literal"))), hasImplicitDestinationType(qualType(booleanType())), unless(isInTemplateInstantiation()), - anyOf(hasParent(explicitCastExpr().bind("cast")), anything())), + anyOf(hasParent(explicitCastExpr().bind("cast")), anything()))), this); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, conditionalOperator( hasParent(implicitCastExpr( hasImplicitDestinationType(qualType(booleanType())), @@ -42,7 +44,8 @@ eachOf(hasTrueExpression( ignoringParenImpCasts(integerLiteral().bind("literal"))), hasFalseExpression( - ignoringParenImpCasts(integerLiteral().bind("literal"))))), + ignoringParenImpCasts( + integerLiteral().bind("literal")))))), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -112,9 +112,10 @@ anyOf(has(MakeTuple), has(MakeTupleCtor), HasConstructExpr, has(cxxFunctionalCastExpr(HasConstructExpr)))); - Finder->addMatcher(cxxMemberCallExpr(CallPushBack, has(SoughtParam), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxMemberCallExpr(CallPushBack, has(SoughtParam), unless(isInTemplateInstantiation())) - .bind("call"), + .bind("call")), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -74,7 +74,7 @@ for (const auto *Base : BasesToInit) { // The initialization of a base class should be a call to a copy // constructor of the base. - if (match( + if (match(traverse(ast_type_traits::TK_AsIs, cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer( isBaseInitializer(), withInitializer(cxxConstructExpr( @@ -82,7 +82,7 @@ hasDeclaration(cxxConstructorDecl(isCopyConstructor())), argumentCountIs(1), hasArgument( - 0, declRefExpr(to(varDecl(equalsNode(Param)))))))))), + 0, declRefExpr(to(varDecl(equalsNode(Param))))))))))), *Ctor, *Context) .empty()) return false; @@ -92,7 +92,7 @@ for (const auto *Field : FieldsToInit) { auto AccessToFieldInParam = accessToFieldInVar(Field, Param); // The initialization is a CXXConstructExpr for class types. - if (match( + if (match(traverse(ast_type_traits::TK_AsIs, cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer( isMemberInitializer(), forField(equalsNode(Field)), withInitializer(anyOf( @@ -101,7 +101,7 @@ cxxConstructExpr( hasDeclaration(cxxConstructorDecl(isCopyConstructor())), argumentCountIs(1), - hasArgument(0, AccessToFieldInParam))))))), + hasArgument(0, AccessToFieldInParam)))))))), *Ctor, *Context) .empty()) return false; @@ -130,8 +130,9 @@ // statement: // return *this; if (Compound->body_empty() || - match(returnStmt(has(ignoringParenImpCasts(unaryOperator( - hasOperatorName("*"), hasUnaryOperand(cxxThisExpr()))))), + match(traverse(ast_type_traits::TK_AsIs, + returnStmt(has(ignoringParenImpCasts(unaryOperator( + hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())))))), *Compound->body_back(), *Context) .empty()) return false; @@ -145,7 +146,7 @@ // ((Base*)this)->operator=((Base)Other); // // So we are looking for a member call that fulfills: - if (match( + if (match(traverse(ast_type_traits::TK_AsIs, compoundStmt(has(ignoringParenImpCasts(cxxMemberCallExpr( // - The object is an implicit cast of 'this' to a pointer to // a base class. @@ -158,7 +159,8 @@ // - 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, + declRefExpr(to(varDecl(equalsNode(Param)))))))))), *Compound, *Context) .empty()) return false; @@ -173,12 +175,12 @@ auto LHS = memberExpr(hasObjectExpression(cxxThisExpr()), member(fieldDecl(equalsNode(Field)))); auto RHS = accessToFieldInVar(Field, Param); - if (match( + if (match(traverse(ast_type_traits::TK_AsIs, compoundStmt(has(ignoringParenImpCasts(stmt(anyOf( binaryOperator(hasOperatorName("="), hasLHS(LHS), hasRHS(RHS)), cxxOperatorCallExpr(hasOverloadedOperatorName("="), argumentCountIs(2), hasArgument(0, LHS), - hasArgument(1, RHS))))))), + hasArgument(1, RHS)))))))), *Compound, *Context) .empty()) return false; @@ -212,9 +214,10 @@ return; // Destructor. - Finder->addMatcher(cxxDestructorDecl(isDefinition()).bind(SpecialFunction), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxDestructorDecl(isDefinition()).bind(SpecialFunction)), this); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxConstructorDecl( isDefinition(), anyOf( @@ -227,16 +230,16 @@ // constructor because all the other arguments have // default values. parameterCountIs(1)))) - .bind(SpecialFunction), + .bind(SpecialFunction)), this); // Copy-assignment operator. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxMethodDecl(isDefinition(), isCopyAssignmentOperator(), // isCopyAssignmentOperator() allows the parameter to be // passed by value, and in this case it cannot be // defaulted. hasParameter(0, hasType(lValueReferenceType()))) - .bind(SpecialFunction), + .bind(SpecialFunction)), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -477,13 +477,16 @@ // modernization, it is reasonable to run it on any C++ standard with the // assumption the user is trying to modernize their codebase. if (getLangOpts().CPlusPlus) - Finder->addMatcher(makeCastSequenceMatcher(), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + makeCastSequenceMatcher()), this); } void UseNullptrCheck::check(const MatchFinder::MatchResult &Result) { const auto *NullCast = Result.Nodes.getNodeAs(CastSequence); assert(NullCast && "Bad Callback. No node provided"); + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + // Given an implicit null-ptr cast or an explicit cast with an implicit // null-to-pointer cast within use CastSequenceVisitor to identify sequences // of explicit casts that can be converted into 'nullptr'. diff --git a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp @@ -43,14 +43,17 @@ hasDeclaration(namedDecl( matchers::matchesAnyListedName(AllowedTypes))))))), unless(hasInitializer(expr(hasDescendant(materializeTemporaryExpr()))))); - Finder->addMatcher(cxxForRangeStmt(hasLoopVariable(LoopVar.bind("loopVar"))) - .bind("forRange"), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxForRangeStmt(hasLoopVariable(LoopVar.bind("loopVar"))) + .bind("forRange")), this); } void ForRangeCopyCheck::check(const MatchFinder::MatchResult &Result) { const auto *Var = Result.Nodes.getNodeAs("loopVar"); + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + // Ignore code in macros since we can't place the fixes correctly. if (Var->getBeginLoc().isMacroID()) return; diff --git a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp @@ -46,7 +46,7 @@ // conversion operator, the node is a CXXMemberCallExpr, not a // CXXOperatorCallExpr, so it should not get caught by the // cxxOperatorCallExpr() matcher. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxForRangeStmt(hasLoopVariable( varDecl( hasType(qualType(references(qualType(isConstQualified())))), @@ -56,7 +56,7 @@ hasDescendant(unaryOperator(hasOperatorName("*")) .bind("operator-call")))) .bind("init"))) - .bind("faulty-var"))), + .bind("faulty-var")))), this); } diff --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp @@ -40,7 +40,7 @@ "::std::unordered_set", "::std::unordered_map", "::std::unordered_multiset", "::std::unordered_multimap")); - const auto Matcher = + const auto Matcher = traverse(ast_type_traits::TK_AsIs, callExpr( callee(functionDecl(Algorithms)), hasArgument( @@ -59,7 +59,7 @@ hasDeclaration(equalsBoundNode("IneffContObj"))))))))), hasArgument(2, expr().bind("AlgParam")), unless(isInTemplateInstantiation())) - .bind("IneffAlg"); + .bind("IneffAlg")); Finder->addMatcher(Matcher, this); } diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp @@ -48,13 +48,16 @@ unless(isInTemplateInstantiation())) .bind("call-move"); - Finder->addMatcher(MoveCallMatcher, this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + MoveCallMatcher), this); auto ConstParamMatcher = forEachArgumentWithParam( MoveCallMatcher, parmVarDecl(hasType(references(isConstQualified())))); - Finder->addMatcher(callExpr(ConstParamMatcher).bind("receiving-expr"), this); - Finder->addMatcher(cxxConstructExpr(ConstParamMatcher).bind("receiving-expr"), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + callExpr(ConstParamMatcher).bind("receiving-expr")), this); + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxConstructExpr(ConstParamMatcher).bind("receiving-expr")), this); } diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp @@ -32,14 +32,14 @@ if (!getLangOpts().CPlusPlus11) return; - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxConstructorDecl( unless(isImplicit()), isMoveConstructor(), hasAnyConstructorInitializer( cxxCtorInitializer( withInitializer(cxxConstructExpr(hasDeclaration( cxxConstructorDecl(isCopyConstructor()).bind("ctor"))))) - .bind("move-init"))), + .bind("move-init")))), this); } diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp @@ -47,13 +47,13 @@ hasParameter(0, hasType(rValueReferenceType( pointee(type(equalsBoundNode("SrcT"))))))))))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, returnStmt( hasReturnValue(ignoringElidableConstructorCall(ignoringParenImpCasts( cxxConstructExpr(hasDeclaration(LValueRefCtor), hasArgument(0, ignoringParenImpCasts(declRefExpr( to(ConstLocalVariable))))) - .bind("ctor_call"))))), + .bind("ctor_call")))))), this); } diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -79,12 +79,14 @@ .bind("blockStmt"); }; - Finder->addMatcher(localVarCopiedFrom(anyOf(ConstRefReturningFunctionCall, - ConstRefReturningMethodCall)), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + localVarCopiedFrom(anyOf(ConstRefReturningFunctionCall, + ConstRefReturningMethodCall))), this); - Finder->addMatcher(localVarCopiedFrom(declRefExpr( - to(varDecl(hasLocalStorage()).bind("oldVarDecl")))), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + localVarCopiedFrom(declRefExpr( + to(varDecl(hasLocalStorage()).bind("oldVarDecl"))))), this); } @@ -96,6 +98,8 @@ const auto *BlockStmt = Result.Nodes.getNodeAs("blockStmt"); const auto *CtorCall = Result.Nodes.getNodeAs("ctorCall"); + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + // Do not propose fixes if the DeclStmt has multiple VarDecls or in macros // since we cannot place them correctly. bool IssueFix = diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -42,10 +42,11 @@ bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context) { auto Matches = - match(decl(forEachDescendant(declRefExpr( + match(traverse(ast_type_traits::TK_AsIs, + decl(forEachDescendant(declRefExpr( equalsNode(&DeclRef), unless(hasAncestor(stmt(anyOf(forStmt(), cxxForRangeStmt(), - whileStmt(), doStmt()))))))), + whileStmt(), doStmt())))))))), Decl, Context); return Matches.empty(); } @@ -84,11 +85,11 @@ hasDeclaration(namedDecl( matchers::matchesAnyListedName(AllowedTypes))))))), decl().bind("param")); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, functionDecl(hasBody(stmt()), isDefinition(), unless(isImplicit()), unless(cxxMethodDecl(anyOf(isOverride(), isFinal()))), has(typeLoc(forEach(ExpensiveValueParamDecl))), - unless(isInstantiated()), decl().bind("functionDecl")), + unless(isInstantiated()), decl().bind("functionDecl"))), this); } @@ -96,6 +97,8 @@ const auto *Param = Result.Nodes.getNodeAs("param"); const auto *Function = Result.Nodes.getNodeAs("functionDecl"); + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + FunctionParmMutationAnalyzer &Analyzer = MutationAnalyzers.try_emplace(Function, *Function, *Result.Context) .first->second; diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -61,7 +61,9 @@ cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer), hasType(pointsTo(ValidContainer)), hasType(references(ValidContainer))))), - callee(cxxMethodDecl(hasName("size"))), WrongUse, + callee(cxxMethodDecl(hasName("size"))), + traverse(ast_type_traits::TK_AsIs, + cxxMemberCallExpr(WrongUse)), unless(hasAncestor(cxxMethodDecl( ofClass(equalsBoundNode("container")))))) .bind("SizeCallExpr"), @@ -89,6 +91,7 @@ expr(hasType(pointsTo(ValidContainer))).bind("Pointee"))), expr(hasType(ValidContainer)).bind("STLObject")); Finder->addMatcher( + traverse(ast_type_traits::TK_AsIs, cxxOperatorCallExpr( anyOf(hasOverloadedOperatorName("=="), hasOverloadedOperatorName("!=")), @@ -96,7 +99,7 @@ allOf(hasArgument(0, STLArg), hasArgument(1, WrongComparend))), unless(hasAncestor( cxxMethodDecl(ofClass(equalsBoundNode("container")))))) - .bind("BinCmp"), + .bind("BinCmp")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp @@ -39,14 +39,14 @@ binaryOperator(hasEitherOperand(castExpr(hasCastKind(CK_NullToPointer))), hasEitherOperand(PointerExpr)); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, ifStmt(hasCondition(anyOf(PointerCondition, BinaryPointerCheckCondition)), hasThen(anyOf( DeleteExpr, DeleteMemberExpr, compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)), statementCountIs(1)) .bind("compound")))) - .bind("ifWithDelete"), + .bind("ifWithDelete")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -278,7 +278,7 @@ auto boolXor = binaryOperator(hasOperatorName("^"), hasLHS(implicitCastFromBool), hasRHS(implicitCastFromBool)); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr( anyOf(hasCastKind(CK_IntegralToBoolean), hasCastKind(CK_FloatingToBoolean), @@ -296,7 +296,7 @@ anyOf(hasParent(stmt().bind("parentStmt")), anything()), unless(isInTemplateInstantiation()), unless(hasAncestor(functionTemplateDecl()))) - .bind("implicitCastToBool"), + .bind("implicitCastToBool")), this); auto boolComparison = binaryOperator( @@ -310,7 +310,7 @@ auto bitfieldConstruct = cxxConstructorDecl(hasDescendant(cxxCtorInitializer( withInitializer(equalsBoundNode("implicitCastFromBool")), forField(hasBitWidth(1))))); - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, implicitCastExpr( implicitCastFromBool, // Exclude comparisons of bools, as they are always cast to integers @@ -325,12 +325,15 @@ anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")), anything()), unless(isInTemplateInstantiation()), - unless(hasAncestor(functionTemplateDecl()))), + unless(hasAncestor(functionTemplateDecl())))), this); } void ImplicitBoolConversionCheck::check( const MatchFinder::MatchResult &Result) { + + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + if (const auto *CastToBool = Result.Nodes.getNodeAs("implicitCastToBool")) { const auto *Parent = Result.Nodes.getNodeAs("parentStmt"); diff --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp @@ -119,6 +119,9 @@ } void MagicNumbersCheck::check(const MatchFinder::MatchResult &Result) { + + TraversalKindScope raii(*Result.Context, ast_type_traits::TK_AsIs); + checkBoundMatch(Result, "integer"); checkBoundMatch(Result, "float"); } diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -211,7 +211,7 @@ if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxMethodDecl( isDefinition(), isUserProvided(), unless(anyOf( @@ -226,7 +226,7 @@ isInsideMacroDefinition(), hasCanonicalDecl(isInsideMacroDefinition()))), usesThisAsConst()) - .bind("x"), + .bind("x")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp b/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp @@ -19,9 +19,10 @@ namespace readability { void MisplacedArrayIndexCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(arraySubscriptExpr(hasLHS(hasType(isInteger())), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + arraySubscriptExpr(hasLHS(hasType(isInteger())), hasRHS(hasType(isAnyPointer()))) - .bind("expr"), + .bind("expr")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp @@ -28,11 +28,12 @@ Finder->addMatcher(declRefExpr().bind("Ref"), this); // Analyse parameter usage in function. - Finder->addMatcher(stmt(anyOf(unaryOperator(anyOf(hasOperatorName("++"), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + stmt(anyOf(unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--"))), binaryOperator(), callExpr(), returnStmt(), cxxConstructExpr())) - .bind("Mark"), + .bind("Mark")), this); Finder->addMatcher(varDecl(hasInitializer(anything())).bind("Mark"), this); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp @@ -17,10 +17,11 @@ namespace readability { void RedundantFunctionPtrDereferenceCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(unaryOperator(hasOperatorName("*"), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + unaryOperator(hasOperatorName("*"), has(implicitCastExpr( hasCastKind(CK_FunctionToPointerDecay)))) - .bind("op"), + .bind("op")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -35,19 +35,19 @@ cxxRecordDecl(unless(isTriviallyDefaultConstructible())))))) .bind("construct"); - Finder->addMatcher( - cxxConstructorDecl( - unless(isDelegatingConstructor()), - ofClass(unless( - anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))), - forEachConstructorInitializer( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxConstructorDecl( + unless(isDelegatingConstructor()), + ofClass(unless( + anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))), + forEachConstructorInitializer( cxxCtorInitializer( isWritten(), withInitializer(ignoringImplicit(Construct)), unless(forField(hasType(isConstQualified()))), unless(forField(hasParent(recordDecl(isUnion()))))) .bind("init"))) - .bind("constructor"), - this); + .bind("constructor")), + this); } void RedundantMemberInitCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -95,8 +95,9 @@ .bind("call"); // Detect redundant 'c_str()' calls through a string constructor. - Finder->addMatcher(cxxConstructExpr(StringConstructorExpr, - hasArgument(0, StringCStrCallExpr)), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + cxxConstructExpr(StringConstructorExpr, + hasArgument(0, StringCStrCallExpr))), this); // Detect: 's == str.c_str()' -> 's == str' @@ -153,7 +154,7 @@ this); // Detect redundant 'c_str()' calls through a StringRef constructor. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxConstructExpr( // Implicit constructors of these classes are overloaded // wrt. string types and they internally make a StringRef @@ -167,7 +168,7 @@ // a constructor from string which is more efficient (avoids // strlen), so we can construct StringRef from the string // directly. - hasArgument(0, StringCStrCallExpr)), + hasArgument(0, StringCStrCallExpr))), this); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -69,16 +69,16 @@ // Examples: // string foo = ""; // string bar(""); - Finder->addMatcher( - namedDecl( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + namedDecl( varDecl( hasType(hasUnqualifiedDesugaredType(recordType( hasDeclaration(cxxRecordDecl(hasStringTypeName))))), hasInitializer(expr(ignoringImplicit(anyOf( EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries))))) .bind("vardecl"), - unless(parmVarDecl())), - this); + unless(parmVarDecl()))), + this); } void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp @@ -34,17 +34,18 @@ callee(memberExpr().bind("str1"))); // First and second case: cast str.compare(str) to boolean. - Finder->addMatcher(implicitCastExpr(hasImplicitDestinationType(booleanType()), + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, + implicitCastExpr(hasImplicitDestinationType(booleanType()), has(StrCompare)) - .bind("match1"), + .bind("match1")), this); // Third and fourth case: str.compare(str) == 0 and str.compare(str) != 0. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("!=")), hasEitherOperand(StrCompare.bind("compare")), hasEitherOperand(integerLiteral(equals(0)).bind("zero"))) - .bind("match2"), + .bind("match2")), this); } diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -196,12 +196,12 @@ // Sadly, we can't check whether the literal has sufix or not. // E.g. i32 suffix still results in 'BuiltinType::Kind::Int'. // And such an info is not stored in the *Literal itself. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name), floatLiteral().bind(FloatingLiteralCheck::Name)), unless(anyOf(hasParent(userDefinedLiteral()), hasAncestor(isImplicit()), - hasAncestor(substNonTypeTemplateParmExpr())))), + hasAncestor(substNonTypeTemplateParmExpr()))))), this); } diff --git a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp --- a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp @@ -28,6 +28,7 @@ ASTContext *Context) { SmallVector Result; + TraversalKindScope raii(*Context, ast_type_traits::TK_AsIs); ASTContext::DynTypedNodeList Parents = Context->getParents(*S); SmallVector NodesToProcess(Parents.begin(), diff --git a/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp b/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp --- a/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp +++ b/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp @@ -28,18 +28,18 @@ void TemporaryObjectsCheck::registerMatchers(MatchFinder *Finder) { // Matcher for default constructors. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxTemporaryObjectExpr(hasDeclaration(cxxConstructorDecl(hasParent( cxxRecordDecl(matchesAnyName(Names)))))) - .bind("temps"), + .bind("temps")), this); // Matcher for user-defined constructors. - Finder->addMatcher( + Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, cxxConstructExpr(hasParent(cxxFunctionalCastExpr()), hasDeclaration(cxxConstructorDecl( hasParent(cxxRecordDecl(matchesAnyName(Names)))))) - .bind("temps"), + .bind("temps")), this); }