[clang-tools-extra] a72307c - Set traversal explicitly where needed in clang-tidy

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Thu May 21 14:41:41 PDT 2020


Author: Stephen Kelly
Date: 2020-05-21T22:34:37+01:00
New Revision: a72307c3a6f15badc2efb4614b212e6c5fee1ee9

URL: https://github.com/llvm/llvm-project/commit/a72307c3a6f15badc2efb4614b212e6c5fee1ee9
DIFF: https://github.com/llvm/llvm-project/commit/a72307c3a6f15badc2efb4614b212e6c5fee1ee9.diff

LOG: Set traversal explicitly where needed in clang-tidy

Reviewers: aaron.ballman

Subscribers: nemanjai, kbarton, arphaman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72530

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp
    clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
    clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
    clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp
    clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
    clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
    clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
    clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp
    clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
    clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
    clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
    clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
    clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
    clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
    clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
    clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
    clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp
    clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
    clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
    clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
    clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
    clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
    clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
    clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
    clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp
    clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
    clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
    clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
    clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
    clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
    clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp
    clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp
    clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
    clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp
    clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
    clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp
    clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
    clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
    clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
    clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
    clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp
    clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
    clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
    clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
    clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
    clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
    clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
    clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp
    clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
    clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
    clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp
    clang-tools-extra/clang-tidy/utils/ExprSequence.cpp
    clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp
index 7055ff57fdcb..01e01469acee 100644
--- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp
@@ -20,16 +20,17 @@ void DurationDivisionCheck::registerMatchers(MatchFinder *finder) {
   const auto DurationExpr =
       expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))));
   finder->addMatcher(
-      implicitCastExpr(
-          hasSourceExpression(ignoringParenCasts(
-              cxxOperatorCallExpr(hasOverloadedOperatorName("/"),
-                                  hasArgument(0, DurationExpr),
-                                  hasArgument(1, DurationExpr))
-                  .bind("OpCall"))),
-          hasImplicitDestinationType(qualType(unless(isInteger()))),
-          unless(hasParent(cxxStaticCastExpr())),
-          unless(hasParent(cStyleCastExpr())),
-          unless(isInTemplateInstantiation())),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(
+                   hasSourceExpression(ignoringParenCasts(
+                       cxxOperatorCallExpr(hasOverloadedOperatorName("/"),
+                                           hasArgument(0, DurationExpr),
+                                           hasArgument(1, DurationExpr))
+                           .bind("OpCall"))),
+                   hasImplicitDestinationType(qualType(unless(isInteger()))),
+                   unless(hasParent(cxxStaticCastExpr())),
+                   unless(hasParent(cStyleCastExpr())),
+                   unless(isInTemplateInstantiation()))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
index bca606a7bc3a..ef260d9b1f6b 100644
--- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
@@ -78,20 +78,23 @@ void FasterStrsplitDelimiterCheck::registerMatchers(MatchFinder *Finder) {
 
   // 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"))),
-                              hasArgument(1, anyOf(ByAnyCharArg, SingleChar)),
-                              unless(isInTemplateInstantiation()))
-                         .bind("StrSplit"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               callExpr(callee(functionDecl(hasName("::absl::StrSplit"))),
+                        hasArgument(1, anyOf(ByAnyCharArg, SingleChar)),
+                        unless(isInTemplateInstantiation()))
+                   .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(
-      callExpr(
-          callee(functionDecl(hasName("::absl::MaxSplits"))),
-          hasArgument(0, anyOf(ByAnyCharArg, ignoringParenCasts(SingleChar))),
-          unless(isInTemplateInstantiation())),
+      traverse(ast_type_traits::TK_AsIs,
+               callExpr(callee(functionDecl(hasName("::absl::MaxSplits"))),
+                        hasArgument(0, 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 982d59e2cbe6..e7d037743f67 100644
--- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
@@ -64,11 +64,12 @@ const clang::CallExpr* ProcessArgument(const Expr* Arg,
   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<const CallExpr>(
+  if (const auto *SubStrcatCall = selectFirst<const CallExpr>(
           "StrCat",
-          match(stmt(anyOf(
-                    cxxConstructExpr(IsAlphanum, hasArgument(0, IsStrcat)),
-                    IsStrcat)),
+          match(stmt(traverse(ast_type_traits::TK_AsIs,
+                              anyOf(cxxConstructExpr(IsAlphanum,
+                                                     hasArgument(0, 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
index 0e8943f8545e..7aaf976a9c58 100644
--- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp
@@ -58,14 +58,17 @@ 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(
-      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(ast_type_traits::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")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
index 2d0ffce73303..a660cbdebda5 100644
--- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
@@ -99,14 +99,17 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) {
   //   `absl::Hours(x)`
   // where `x` is not of a built-in type.
   Finder->addMatcher(
-      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(
+          ast_type_traits::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")),
       this);
 }
 
@@ -116,6 +119,8 @@ void UpgradeDurationConversionsCheck::check(
       "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<Expr>("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
index 4e3f76544dc8..5cb55639db78 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -84,7 +84,8 @@ void AssertSideEffectCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 
 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
index b7f5b0d60e77..b764bdbf7c4c 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
@@ -18,14 +18,16 @@ void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *Finder) {
   // Look for ifs that have an implicit bool* to bool conversion in the
   // condition. Filter negations.
   Finder->addMatcher(
-      ifStmt(hasCondition(findAll(implicitCastExpr(
-                 unless(hasParent(unaryOperator(hasOperatorName("!")))),
-                 hasSourceExpression(
-                     expr(hasType(pointerType(pointee(booleanType()))),
-                          ignoringParenImpCasts(declRefExpr().bind("expr")))),
-                 hasCastKind(CK_PointerToBoolean)))),
-             unless(isInTemplateInstantiation()))
-          .bind("if"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          ifStmt(hasCondition(findAll(implicitCastExpr(
+                     unless(hasParent(unaryOperator(hasOperatorName("!")))),
+                     hasSourceExpression(expr(
+                         hasType(pointerType(pointee(booleanType()))),
+                         ignoringParenImpCasts(declRefExpr().bind("expr")))),
+                     hasCastKind(CK_PointerToBoolean)))),
+                 unless(isInTemplateInstantiation()))
+              .bind("if")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
index 74ad2e7535fc..5f771e49f808 100644
--- a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
@@ -117,55 +117,63 @@ void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {
 
   // Find 'Handle foo = ReturnsAValue();'
   Finder->addMatcher(
-      varDecl(
-          hasType(hasUnqualifiedDesugaredType(
-              recordType(hasDeclaration(cxxRecordDecl(IsAHandle))))),
-          unless(parmVarDecl()),
-          hasInitializer(exprWithCleanups(has(ignoringParenImpCasts(handleFrom(
+      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(
-      cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(IsAHandle))),
-                          hasOverloadedOperatorName("="),
-                          hasArgument(1, ConvertedHandle))
-          .bind("bad_stmt"),
+      traverse(ast_type_traits::TK_AsIs,
+               cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(IsAHandle))),
+                                   hasOverloadedOperatorName("="),
+                                   hasArgument(1, ConvertedHandle))
+                   .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(
-      returnStmt(
-          // The AST contains two constructor calls:
-          //   1. Value to Handle conversion.
-          //   2. Handle copy construction.
-          // We have to match both.
-          has(ignoringImplicit(handleFrom(
-              IsAHandle,
-              handleFrom(IsAHandle,
-                         declRefExpr(to(varDecl(
-                             // Is function scope ...
-                             hasAutomaticStorageDuration(),
-                             // ... and it is a local array or Value.
-                             anyOf(hasType(arrayType()),
-                                   hasType(hasUnqualifiedDesugaredType(
-                                       recordType(hasDeclaration(recordDecl(
-                                           unless(IsAHandle)))))))))))))),
-          // Temporary fix for false positives inside lambdas.
-          unless(hasAncestor(lambdaExpr())))
-          .bind("bad_stmt"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          returnStmt(
+              // The AST contains two constructor calls:
+              //   1. Value to Handle conversion.
+              //   2. Handle copy construction.
+              // We have to match both.
+              has(ignoringImplicit(handleFrom(
+                  IsAHandle,
+                  handleFrom(IsAHandle,
+                             declRefExpr(to(varDecl(
+                                 // Is function scope ...
+                                 hasAutomaticStorageDuration(),
+                                 // ... and it is a local array or Value.
+                                 anyOf(hasType(arrayType()),
+                                       hasType(hasUnqualifiedDesugaredType(
+                                           recordType(hasDeclaration(recordDecl(
+                                               unless(IsAHandle)))))))))))))),
+              // Temporary fix for false positives inside lambdas.
+              unless(hasAncestor(lambdaExpr())))
+              .bind("bad_stmt")),
       this);
 
   // Return a temporary.
   Finder->addMatcher(
-      returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom(
-                     IsAHandle, handleFromTemporaryValue(IsAHandle)))))))
-          .bind("bad_stmt"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom(
+                         IsAHandle, handleFromTemporaryValue(IsAHandle)))))))
+              .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 ef45f00d3e46..19e91b44b41a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp
@@ -32,13 +32,15 @@ void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
   const auto DeclInStd = type(hasUnqualifiedDesugaredType(
       tagType(hasDeclaration(decl(isInStdNamespace())))));
   Finder->addMatcher(
-      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"),
+      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")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
index bc58e8e62b7a..7b0682b31eb7 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
@@ -51,10 +51,11 @@ void IncorrectRoundingsCheck::registerMatchers(MatchFinder *MatchFinder) {
   // Find expressions of cast to int of the sum of a floating point expression
   // and 0.5.
   MatchFinder->addMatcher(
-      implicitCastExpr(
-          hasImplicitDestinationType(isInteger()),
-          ignoringParenCasts(binaryOperator(hasOperatorName("+"), OneSideHalf)))
-          .bind("CastExpr"),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(hasImplicitDestinationType(isInteger()),
+                                ignoringParenCasts(binaryOperator(
+                                    hasOperatorName("+"), OneSideHalf)))
+                   .bind("CastExpr")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp
index 82993cb313ce..9214a7da2729 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IntegerDivisionCheck.cpp
@@ -30,14 +30,16 @@ void IntegerDivisionCheck::registerMatchers(MatchFinder *Finder) {
             callExpr(IntType), explicitCastExpr(IntType), UnaryOperators);
 
   Finder->addMatcher(
-      binaryOperator(
-          hasOperatorName("/"), hasLHS(expr(IntType)), hasRHS(expr(IntType)),
-          hasAncestor(
-              castExpr(hasCastKind(CK_IntegralToFloating)).bind("FloatCast")),
-          unless(hasAncestor(
-              expr(Exceptions,
-                   hasAncestor(castExpr(equalsBoundNode("FloatCast")))))))
-          .bind("IntDiv"),
+      traverse(ast_type_traits::TK_AsIs,
+               binaryOperator(
+                   hasOperatorName("/"), hasLHS(expr(IntType)),
+                   hasRHS(expr(IntType)),
+                   hasAncestor(castExpr(hasCastKind(CK_IntegralToFloating))
+                                   .bind("FloatCast")),
+                   unless(hasAncestor(expr(
+                       Exceptions,
+                       hasAncestor(castExpr(equalsBoundNode("FloatCast")))))))
+                   .bind("IntDiv")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
index 10bbcb85420f..ed2c17607169 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
@@ -57,16 +57,22 @@ void MisplacedOperatorInStrlenInAllocCheck::registerMatchers(
               hasInitializer(ignoringParenImpCasts(
                   declRefExpr(hasDeclaration(Alloc1Func)))));
 
-  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))),
-                              hasArgument(0, BadArg))
-                         .bind("Alloc"),
-                     this);
-  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))),
-                              hasArgument(1, BadArg))
-                         .bind("Alloc"),
-                     this);
   Finder->addMatcher(
-      cxxNewExpr(isArray(), hasArraySize(BadArg)).bind("Alloc"), this);
+      traverse(ast_type_traits::TK_AsIs,
+               callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))),
+                        hasArgument(0, BadArg))
+                   .bind("Alloc")),
+      this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))),
+                        hasArgument(1, 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
index 89fcda32a630..13f0e41a7a3e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
@@ -39,7 +39,9 @@ void MisplacedWideningCastCheck::registerMatchers(MatchFinder *Finder) {
   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
index acc258a5bc56..cfe556e55610 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
@@ -83,14 +83,16 @@ static std::string getExprAsString(const clang::Expr &E,
 
 void ParentVirtualCallCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      cxxMemberCallExpr(
-          callee(memberExpr(hasDescendant(implicitCastExpr(
-                                hasImplicitDestinationType(pointsTo(
-                                    type(anything()).bind("castToType"))),
-                                hasSourceExpression(cxxThisExpr(hasType(
-                                    type(anything()).bind("thisType")))))))
-                     .bind("member")),
-          callee(cxxMethodDecl(isVirtual()))),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxMemberCallExpr(
+              callee(memberExpr(hasDescendant(implicitCastExpr(
+                                    hasImplicitDestinationType(pointsTo(
+                                        type(anything()).bind("castToType"))),
+                                    hasSourceExpression(cxxThisExpr(hasType(
+                                        type(anything()).bind("thisType")))))))
+                         .bind("member")),
+              callee(cxxMethodDecl(isVirtual())))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
index 3f72e5d516c5..555f8e11dff9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
@@ -70,8 +70,9 @@ BindableMatcher<clang::Stmt> SignedCharMisuseCheck::charCastExpression(
   // We catch any type of casts to an integer. We need to have these cast
   // expressions explicitly to catch only those casts which are direct children
   // of the checked expressions. (e.g. assignment, declaration).
-  return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, StaticCastExpr,
-                    FunctionalCastExpr));
+  return traverse(ast_type_traits::TK_AsIs,
+                  expr(anyOf(ImplicitCastExpr, CStyleCastExpr, StaticCastExpr,
+                             FunctionalCastExpr)));
 }
 
 void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) {

diff  --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
index b21fea185e21..3de6dfed6356 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
@@ -22,6 +22,8 @@ bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx,
                                      const StringLiteral *Lit) {
   // String literals surrounded by parentheses are assumed to be on purpose.
   //    i.e.:  const char* Array[] = { ("a" "b" "c"), "d", [...] };
+
+  TraversalKindScope RAII(*Ctx, ast_type_traits::TK_AsIs);
   auto Parents = Ctx->getParents(*Lit);
   if (Parents.size() == 1 && Parents[0].get<ParenExpr>() != nullptr)
     return true;

diff  --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
index ee4850e9dce2..b4def0f9aa9d 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
@@ -135,9 +135,10 @@ void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) {
 
   // Detect suspicious cast to an inconsistant type (i.e. not integer type).
   Finder->addMatcher(
-      implicitCastExpr(unless(hasType(isInteger())),
-                       hasSourceExpression(StringCompareCallExpr))
-          .bind("invalid-conversion"),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(unless(hasType(isInteger())),
+                                hasSourceExpression(StringCompareCallExpr))
+                   .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
index d8b11c9f1a2f..be5a4697e94b 100644
--- a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
@@ -59,9 +59,10 @@ void TooSmallLoopVariableCheck::registerMatchers(MatchFinder *Finder) {
 
   // We need to catch only those comparisons which contain any integer cast.
   StatementMatcher LoopVarConversionMatcher =
-      implicitCastExpr(hasImplicitDestinationType(isInteger()),
-                       has(ignoringParenImpCasts(LoopVarMatcher)))
-          .bind(LoopVarCastName);
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(hasImplicitDestinationType(isInteger()),
+                                has(ignoringParenImpCasts(LoopVarMatcher)))
+                   .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
index 1dd9568734ab..839bc71fa594 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
@@ -55,14 +55,16 @@ void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
   // instantiations to reduce the number of duplicated warnings.
 
   Finder->addMatcher(
-      compoundStmt(
-          hasParent(
-              cxxConstructorDecl(ofClass(cxxRecordDecl().bind("parent")))),
-          forEach(ignoringTemporaryExpr(
-              cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass(
+      traverse(
+          ast_type_traits::TK_AsIs,
+          compoundStmt(hasParent(cxxConstructorDecl(
+                           ofClass(cxxRecordDecl().bind("parent")))),
+                       forEach(ignoringTemporaryExpr(
+                           cxxConstructExpr(
+                               hasDeclaration(cxxConstructorDecl(ofClass(
                                    cxxRecordDecl(baseOfBoundNode("parent"))))))
-                  .bind("construct"))),
-          unless(isInTemplateInstantiation())),
+                               .bind("construct"))),
+                       unless(isInTemplateInstantiation()))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
index d91353e21fb1..1f1158f0479f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
@@ -52,8 +52,9 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
   // 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")))))));
+      traverse(ast_type_traits::TK_AsIs,
+               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

diff  --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
index 409950834c40..34a489e324e4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
@@ -31,13 +31,15 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) {
       cxxBindTemporaryExpr(unless(has(ignoringParenImpCasts(callExpr()))))
           .bind("temp");
   Finder->addMatcher(
-      exprWithCleanups(unless(isInTemplateInstantiation()),
-                       hasParent(compoundStmt().bind("compound")),
-                       hasType(cxxRecordDecl(hasNonTrivialDestructor())),
-                       anyOf(has(ignoringParenImpCasts(BindTemp)),
-                             has(ignoringParenImpCasts(cxxFunctionalCastExpr(
-                                 has(ignoringParenImpCasts(BindTemp)))))))
-          .bind("expr"),
+      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")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
index c9722a2f1b24..f65c02853a73 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -275,7 +275,9 @@ void UseAfterMoveFinder::getDeclRefs(
                                       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(
                                   hasAnyOverloadedOperatorName("*", "->", "[]"),
                                   hasArgument(0, DeclRefMatcher))
@@ -340,7 +342,7 @@ void UseAfterMoveFinder::getReinits(
                // 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")))))))
@@ -403,19 +405,22 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) {
           .bind("call-move");
 
   Finder->addMatcher(
-      // 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().
-      stmt(forEach(expr(ignoringParenImpCasts(CallMoveMatcher))),
-           // Don't allow an InitListExpr to be the moving call. An InitListExpr
-           // has both a syntactic and a semantic form, and the parent-child
-           // relationships are 
diff erent between the two. This could cause an
-           // InitListExpr to be analyzed as the moving call in addition to the
-           // Expr that we actually want, resulting in two diagnostics with
-           // 
diff erent code locations for the same move.
-           unless(initListExpr()),
-           unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move")))))
-          .bind("moving-call"),
+      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().
+          stmt(
+              forEach(expr(ignoringParenImpCasts(CallMoveMatcher))),
+              // Don't allow an InitListExpr to be the moving call. An
+              // InitListExpr has both a syntactic and a semantic form, and the
+              // parent-child relationships are 
diff erent between the two. This
+              // could cause an InitListExpr to be analyzed as the moving call
+              // in addition to the Expr that we actually want, resulting in two
+              // diagnostics with 
diff erent code locations for the same move.
+              unless(initListExpr()),
+              unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move")))))
+              .bind("moving-call")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
index 4de328f3249d..678e7408bf45 100644
--- a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
@@ -29,12 +29,13 @@ void MutatingCopyCheck::registerMatchers(MatchFinder *Finder) {
       allOf(unless(hasDescendant(expr(unless(MemberExprOrSourceObject)))),
             MemberExprOrSourceObject);
 
-  const auto IsSourceMutatingAssignment =
+  const auto IsSourceMutatingAssignment = traverse(
+      ast_type_traits::TK_AsIs,
       expr(anyOf(binaryOperator(isAssignmentOperator(), hasLHS(IsPartOfSource))
                      .bind(MutatingOperatorName),
                  cxxOperatorCallExpr(isAssignmentOperator(),
                                      hasArgument(0, IsPartOfSource))
-                     .bind(MutatingOperatorName)));
+                     .bind(MutatingOperatorName))));
 
   const auto MemberExprOrSelf = anyOf(memberExpr(), cxxThisExpr());
 

diff  --git a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp b/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
index 3be83cf419b9..3fddbffeb1ed 100644
--- a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
@@ -62,7 +62,9 @@ void ProperlySeededRandomGeneratorCheck::registerMatchers(MatchFinder *Finder) {
   // std::mt19937 engine(x);
   //              ^
   Finder->addMatcher(
-      cxxConstructExpr(RandomGeneratorEngineTypeMatcher).bind("ctor"), this);
+      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
index 233bd29cc864..9e255659bee7 100644
--- a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp
@@ -21,7 +21,10 @@ void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
   // Match any static or thread_local variable declaration that has an
   // initializer that can throw.
   Finder->addMatcher(
-      varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          varDecl(
+              anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
               unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())),
                            hasAncestor(functionDecl()))),
               anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(
@@ -30,7 +33,7 @@ void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
                         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
index ca44c002239f..6a6aab7eaf6f 100644
--- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
@@ -19,10 +19,12 @@ namespace cert {
 
 void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      cxxThrowExpr(has(ignoringParenImpCasts(
-          cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
-                               isCopyConstructor(), unless(isNoThrow()))))
-              .bind("expr")))),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxThrowExpr(has(ignoringParenImpCasts(
+              cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
+                                   isCopyConstructor(), unless(isNoThrow()))))
+                  .bind("expr"))))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
index d9c91b230b1f..fb19daf34172 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
@@ -27,11 +27,12 @@ void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
   const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
       varDecl(GlobalVarDecl, unless(isDefinition())).bind("referencee")));
 
-  Finder->addMatcher(
-      varDecl(GlobalVarDecl, isDefinition(),
-              hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
-          .bind("var"),
-      this);
+  Finder->addMatcher(traverse(ast_type_traits::TK_AsIs,
+                              varDecl(GlobalVarDecl, isDefinition(),
+                                      hasInitializer(expr(hasDescendant(
+                                          ReferencesUndefinedGlobalVar))))
+                                  .bind("var")),
+                     this);
 }
 
 void InterfacesGlobalInitCheck::check(const MatchFinder::MatchResult &Result) {

diff  --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
index 2f521ce6eefe..2ae21a303ef7 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
@@ -39,12 +39,14 @@ void NarrowingConversionsCheck::registerMatchers(MatchFinder *Finder) {
   //   i = 0.5;
   //   void f(int); f(0.5);
   Finder->addMatcher(
-      implicitCastExpr(hasImplicitDestinationType(builtinType()),
-                       hasSourceExpression(hasType(builtinType())),
-                       unless(hasSourceExpression(IsCeilFloorCallExpr)),
-                       unless(hasParent(castExpr())),
-                       unless(isInTemplateInstantiation()))
-          .bind("cast"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          implicitCastExpr(hasImplicitDestinationType(builtinType()),
+                           hasSourceExpression(hasType(builtinType())),
+                           unless(hasSourceExpression(IsCeilFloorCallExpr)),
+                           unless(hasParent(castExpr())),
+                           unless(isInTemplateInstantiation()))
+              .bind("cast")),
       this);
 
   // Binary operators:

diff  --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
index 27ee0e48bb59..79c1b6ccd615 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
@@ -69,10 +69,10 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
 
   // Find delete expressions that delete non-owners.
   Finder->addMatcher(
-      cxxDeleteExpr(
-          hasDescendant(
-              declRefExpr(unless(ConsideredOwner)).bind("deleted_variable")))
-          .bind("delete_expr"),
+      traverse(ast_type_traits::TK_AsIs,
+               cxxDeleteExpr(hasDescendant(declRefExpr(unless(ConsideredOwner))
+                                               .bind("deleted_variable")))
+                   .bind("delete_expr")),
       this);
 
   // Ignoring the implicit casts is vital because the legacy owners do not work
@@ -83,23 +83,29 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
   // resources. This check assumes that all pointer arguments of a legacy
   // functions shall be 'gsl::owner<>'.
   Finder->addMatcher(
-      callExpr(callee(LegacyOwnerConsumers),
-               hasAnyArgument(expr(unless(ignoringImpCasts(ConsideredOwner)),
-                                   hasType(pointerType()))))
-          .bind("legacy_consumer"),
+      traverse(ast_type_traits::TK_AsIs,
+               callExpr(callee(LegacyOwnerConsumers),
+                        hasAnyArgument(
+                            expr(unless(ignoringImpCasts(ConsideredOwner)),
+                                 hasType(pointerType()))))
+                   .bind("legacy_consumer")),
       this);
 
   // Matching assignment to owners, with the rhs not being an owner nor creating
   // one.
-  Finder->addMatcher(binaryOperator(isAssignmentOperator(), hasLHS(IsOwnerType),
-                                    hasRHS(unless(ConsideredOwner)))
-                         .bind("owner_assignment"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               binaryOperator(isAssignmentOperator(), hasLHS(IsOwnerType),
+                              hasRHS(unless(ConsideredOwner)))
+                   .bind("owner_assignment")),
+      this);
 
   // Matching initialization of owners with non-owners, nor creating owners.
   Finder->addMatcher(
-      namedDecl(varDecl(hasInitializer(unless(ConsideredOwner)), IsOwnerType)
-                    .bind("owner_initialization")),
+      traverse(ast_type_traits::TK_AsIs,
+               namedDecl(
+                   varDecl(hasInitializer(unless(ConsideredOwner)), IsOwnerType)
+                       .bind("owner_initialization"))),
       this);
 
   const auto HasConstructorInitializerForOwner =
@@ -114,7 +120,9 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
 
   // 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.
@@ -127,11 +135,14 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
   // Matching on initialization operations where the initial value is a newly
   // created owner, but the LHS is not an owner.
   Finder->addMatcher(
-      namedDecl(varDecl(eachOf(allOf(hasInitializer(CreatesOwner),
-                                     unless(IsOwnerType)),
-                               allOf(hasInitializer(ConsideredOwner),
-                                     hasType(autoType().bind("deduced_type")))))
-                    .bind("bad_owner_creation_variable")),
+      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"))),
       this);
 
   // Match on all function calls that expect owners as arguments, but didn't

diff  --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
index cdea1375aba7..2b80c0ba25d6 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
@@ -54,12 +54,13 @@ void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) {
   // 2) inside a range-for over an array
   // 3) if it converts a string literal to a pointer
   Finder->addMatcher(
-      implicitCastExpr(
-          unless(hasParent(arraySubscriptExpr())),
-          unless(hasParentIgnoringImpCasts(explicitCastExpr())),
-          unless(isInsideOfRangeBeginEndStmt()),
-          unless(hasSourceExpression(ignoringParens(stringLiteral()))))
-          .bind("cast"),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(
+                   unless(hasParent(arraySubscriptExpr())),
+                   unless(hasParentIgnoringImpCasts(explicitCastExpr())),
+                   unless(isInsideOfRangeBeginEndStmt()),
+                   unless(hasSourceExpression(ignoringParens(stringLiteral()))))
+                   .bind("cast")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 6f0afe989d41..62d752f299d3 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -63,7 +63,9 @@ void SlicingCheck::registerMatchers(MatchFinder *Finder) {
       unless(IsWithinDerivedCtor));
 
   Finder->addMatcher(
-      expr(anyOf(SlicesObjectInAssignment, SlicesObjectInCtor)).bind("Call"),
+      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
index ca2f85fc106c..b76c9f5fb6b6 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
@@ -28,17 +28,19 @@ void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) {
   // Constructing global, non-trivial objects with static storage is
   // disallowed, unless the object is statically initialized with a constexpr 
   // constructor or has no explicit constructor.
-  Finder->addMatcher(varDecl(
-                         // Match global, statically stored objects...
-                         isGlobalStatic(),
-                         // ... that have C++ constructors...
-                         hasDescendant(cxxConstructExpr(unless(allOf(
-                             // ... unless it is constexpr ...
-                             hasDeclaration(cxxConstructorDecl(isConstexpr())),
-                             // ... and is statically initialized.
-                             isConstantInitializer())))))
-                         .bind("decl"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               varDecl(
+                   // Match global, statically stored objects...
+                   isGlobalStatic(),
+                   // ... that have C++ constructors...
+                   hasDescendant(cxxConstructExpr(unless(allOf(
+                       // ... unless it is constexpr ...
+                       hasDeclaration(cxxConstructorDecl(isConstexpr())),
+                       // ... and is statically initialized.
+                       isConstantInitializer())))))
+                   .bind("decl")),
+      this);
 }
 
 void StaticallyConstructedObjectsCheck::check(

diff  --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
index b9743e94fe34..2ca976fd4bc9 100644
--- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
@@ -52,15 +52,17 @@ void PreferIsaOrDynCastInConditionalsCheck::registerMatchers(
           .bind("rhs");
 
   Finder->addMatcher(
-      stmt(anyOf(ifStmt(Any), whileStmt(Any), doStmt(Condition),
-                 binaryOperator(
-                     allOf(unless(isExpansionInFileMatching(
-                               "llvm/include/llvm/Support/Casting.h")),
-                           hasOperatorName("&&"),
-                           hasLHS(implicitCastExpr().bind("lhs")),
-                           hasRHS(anyOf(implicitCastExpr(has(CallExpression)),
-                                        CallExpression))))
-                     .bind("and"))),
+      traverse(ast_type_traits::TK_AsIs,
+               stmt(anyOf(
+                   ifStmt(Any), whileStmt(Any), doStmt(Condition),
+                   binaryOperator(
+                       allOf(unless(isExpansionInFileMatching(
+                                 "llvm/include/llvm/Support/Casting.h")),
+                             hasOperatorName("&&"),
+                             hasLHS(implicitCastExpr().bind("lhs")),
+                             hasRHS(anyOf(implicitCastExpr(has(CallExpression)),
+                                          CallExpression))))
+                       .bind("and")))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp
index 3b2e9911d9d1..006c8df1b07c 100644
--- a/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvm/PreferRegisterOverUnsignedCheck.cpp
@@ -21,13 +21,15 @@ void PreferRegisterOverUnsignedCheck::registerMatchers(MatchFinder *Finder) {
       cxxRecordDecl(hasName("::llvm::Register")).bind("registerClassDecl"));
 
   Finder->addMatcher(
-      valueDecl(allOf(
-          hasType(qualType(isUnsignedInteger()).bind("varType")),
-          varDecl(hasInitializer(exprWithCleanups(has(implicitCastExpr(has(
-                      cxxMemberCallExpr(allOf(on(RegisterClassMatch),
-                                              has(memberExpr(hasDeclaration(
-                                                  cxxConversionDecl())))))))))))
-              .bind("var"))),
+      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")))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 4d54489e71b6..edb765b287f9 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -828,18 +828,20 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
 
   // Binary with equivalent operands, like (X != 2 && X != 2).
   Finder->addMatcher(
-      binaryOperator(anyOf(isComparisonOperator(),
-                           hasAnyOperatorName("-", "/", "%", "|", "&", "^",
-                                              "&&", "||", "=")),
-                     operandsAreEquivalent(),
-                     // Filter noisy false positives.
-                     unless(isInTemplateInstantiation()),
-                     unless(binaryOperatorIsInMacro()),
-                     unless(hasType(realFloatingPointType())),
-                     unless(hasEitherOperand(hasType(realFloatingPointType()))),
-                     unless(hasLHS(AnyLiteralExpr)),
-                     unless(hasDescendant(BannedIntegerLiteral)))
-          .bind("binary"),
+      traverse(ast_type_traits::TK_AsIs,
+               binaryOperator(
+                   anyOf(isComparisonOperator(),
+                         hasAnyOperatorName("-", "/", "%", "|", "&", "^", "&&",
+                                            "||", "=")),
+                   operandsAreEquivalent(),
+                   // Filter noisy false positives.
+                   unless(isInTemplateInstantiation()),
+                   unless(binaryOperatorIsInMacro()),
+                   unless(hasType(realFloatingPointType())),
+                   unless(hasEitherOperand(hasType(realFloatingPointType()))),
+                   unless(hasLHS(AnyLiteralExpr)),
+                   unless(hasDescendant(BannedIntegerLiteral)))
+                   .bind("binary")),
       this);
 
   // Logical or bitwise operator with equivalent nested operands, like (X && Y
@@ -856,23 +858,27 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
       this);
 
   // Conditional (trenary) operator with equivalent operands, like (Y ? X : X).
-  Finder->addMatcher(conditionalOperator(expressionsAreEquivalent(),
-                                         // Filter noisy false positives.
-                                         unless(conditionalOperatorIsInMacro()),
-                                         unless(isInTemplateInstantiation()))
-                         .bind("cond"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               conditionalOperator(expressionsAreEquivalent(),
+                                   // Filter noisy false positives.
+                                   unless(conditionalOperatorIsInMacro()),
+                                   unless(isInTemplateInstantiation()))
+                   .bind("cond")),
+      this);
 
   // Overloaded operators with equivalent operands.
-  Finder->addMatcher(cxxOperatorCallExpr(
-                         hasAnyOverloadedOperatorName(
-                             "-", "/", "%", "|", "&", "^", "==", "!=", "<",
-                             "<=", ">", ">=", "&&", "||", "="),
-                         parametersAreEquivalent(),
-                         // Filter noisy false positives.
-                         unless(isMacro()), unless(isInTemplateInstantiation()))
-                         .bind("call"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxOperatorCallExpr(
+                   hasAnyOverloadedOperatorName("-", "/", "%", "|", "&", "^",
+                                                "==", "!=", "<", "<=", ">",
+                                                ">=", "&&", "||", "="),
+                   parametersAreEquivalent(),
+                   // Filter noisy false positives.
+                   unless(isMacro()), unless(isInTemplateInstantiation()))
+                   .bind("call")),
+      this);
 
   // Overloaded operators with equivalent operands.
   Finder->addMatcher(
@@ -886,30 +892,34 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
 
   // Match expressions like: !(1 | 2 | 3)
   Finder->addMatcher(
-      implicitCastExpr(
-          hasImplicitDestinationType(isInteger()),
-          has(unaryOperator(
-                  hasOperatorName("!"),
-                  hasUnaryOperand(ignoringParenImpCasts(binaryOperator(
-                      hasAnyOperatorName("|", "&"),
-                      hasLHS(anyOf(binaryOperator(hasAnyOperatorName("|", "&")),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(
+                   hasImplicitDestinationType(isInteger()),
+                   has(unaryOperator(
+                           hasOperatorName("!"),
+                           hasUnaryOperand(ignoringParenImpCasts(binaryOperator(
+                               hasAnyOperatorName("|", "&"),
+                               hasLHS(anyOf(
+                                   binaryOperator(hasAnyOperatorName("|", "&")),
                                    integerLiteral())),
-                      hasRHS(integerLiteral())))))
-                  .bind("logical-bitwise-confusion"))),
+                               hasRHS(integerLiteral())))))
+                           .bind("logical-bitwise-confusion")))),
       this);
 
-  // Match expressions like: (X << 8) & 0xFF
-  Finder->addMatcher(
+   // Match expressions like: (X << 8) & 0xFF
+   Finder->addMatcher(
+          traverse(
+          ast_type_traits::TK_AsIs,
       binaryOperator(
           hasOperatorName("&"),
           hasOperands(
               ignoringParenImpCasts(
                   binaryOperator(hasOperatorName("<<"),
-                                 hasRHS(ignoringParenImpCasts(
+                              hasRHS(ignoringParenImpCasts(
                                      integerLiteral().bind("shift-const"))))),
               ignoringParenImpCasts(integerLiteral().bind("and-const"))))
-          .bind("left-right-shift-confusion"),
-      this);
+          .bind("left-right-shift-confusion")),
+       this);
 
   // Match common expressions and apply more checks to find redundant
   // sub-expressions.
@@ -923,26 +933,32 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
   const auto SymRight = matchSymbolicExpr("rhs");
 
   // Match expressions like: x <op> 0xFF == 0xF00.
-  Finder->addMatcher(binaryOperator(isComparisonOperator(),
-                                    hasOperands(BinOpCstLeft, CstRight))
-                         .bind("binop-const-compare-to-const"),
+  Finder->addMatcher(traverse(ast_type_traits::TK_AsIs,
+                              binaryOperator(isComparisonOperator(),
+                                             hasOperands(BinOpCstLeft,
+                                             CstRight))
+                                  .bind("binop-const-compare-to-const")),
                      this);
 
   // Match expressions like: x <op> 0xFF == x.
   Finder->addMatcher(
-      binaryOperator(isComparisonOperator(),
-                     anyOf(allOf(hasLHS(BinOpCstLeft), hasRHS(SymRight)),
-                           allOf(hasLHS(SymRight), hasRHS(BinOpCstLeft))))
-          .bind("binop-const-compare-to-sym"),
+      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")),
       this);
 
   // Match expressions like: x <op> 10 == x <op> 12.
-  Finder->addMatcher(binaryOperator(isComparisonOperator(),
-                                    hasLHS(BinOpCstLeft), hasRHS(BinOpCstRight),
-                                    // Already reported as redundant.
-                                    unless(operandsAreEquivalent()))
-                         .bind("binop-const-compare-to-binop-const"),
-                     this);
+  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")),
+      this);
 
   // Match relational expressions combined with logical operators and find
   // redundant sub-expressions.
@@ -951,13 +967,14 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
   // Match expressions like: x < 2 && x > 2.
   const auto ComparisonLeft = matchRelationalIntegerConstantExpr("lhs");
   const auto ComparisonRight = matchRelationalIntegerConstantExpr("rhs");
-  Finder->addMatcher(binaryOperator(hasAnyOperatorName("||", "&&"),
-                                    hasLHS(ComparisonLeft),
-                                    hasRHS(ComparisonRight),
-                                    // Already reported as redundant.
-                                    unless(operandsAreEquivalent()))
-                         .bind("comparisons-of-symbol-and-const"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               binaryOperator(hasAnyOperatorName("||", "&&"),
+                              hasLHS(ComparisonLeft), hasRHS(ComparisonRight),
+                              // Already reported as redundant.
+                              unless(operandsAreEquivalent()))
+                   .bind("comparisons-of-symbol-and-const")),
+      this);
 }
 
 void RedundantExpressionCheck::checkArithmeticExpr(

diff  --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
index 011da5e8840d..aa914ef7bbf5 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -489,9 +489,12 @@ void LoopConvertCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 }
 
 void LoopConvertCheck::registerMatchers(MatchFinder *Finder) {
-  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:
@@ -897,6 +900,7 @@ void LoopConvertCheck::check(const MatchFinder::MatchResult &Result) {
   }
 
   // Find out which qualifiers we have to use in the loop range.
+  TraversalKindScope RAII(*Context, ast_type_traits::TK_AsIs);
   const UsageResult &Usages = Finder.getUsages();
   determineRangeDescriptor(Context, Nodes, Loop, FixerKind, ContainerExpr,
                            Usages, Descriptor);

diff  --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index c49f7665d490..e34fd7038bb8 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -83,27 +83,29 @@ void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
   auto IsPlacement = hasAnyPlacementArg(anything());
 
   Finder->addMatcher(
-      cxxBindTemporaryExpr(has(ignoringParenImpCasts(
-          cxxConstructExpr(
-              hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
-              hasArgument(0,
-                          cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
-                                         equalsBoundNode(PointerType))))),
-                                     CanCallCtor, unless(IsPlacement))
-                              .bind(NewExpression)),
-              unless(isInTemplateInstantiation()))
-              .bind(ConstructorCall)))),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxBindTemporaryExpr(has(ignoringParenImpCasts(
+              cxxConstructExpr(
+                  hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
+                  hasArgument(
+                      0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
+                                        equalsBoundNode(PointerType))))),
+                                    CanCallCtor, unless(IsPlacement))
+                             .bind(NewExpression)),
+                  unless(isInTemplateInstantiation()))
+                  .bind(ConstructorCall))))),
       this);
 
   Finder->addMatcher(
-      cxxMemberCallExpr(
-          thisPointerType(getSmartPointerTypeMatcher()),
-          callee(cxxMethodDecl(hasName("reset"))),
-          hasArgument(
-              0,
-              cxxNewExpr(CanCallCtor, unless(IsPlacement)).bind(NewExpression)),
-          unless(isInTemplateInstantiation()))
-          .bind(ResetCall),
+      traverse(ast_type_traits::TK_AsIs,
+               cxxMemberCallExpr(
+                   thisPointerType(getSmartPointerTypeMatcher()),
+                   callee(cxxMethodDecl(hasName("reset"))),
+                   hasArgument(0, cxxNewExpr(CanCallCtor, unless(IsPlacement))
+                                      .bind(NewExpression)),
+                   unless(isInTemplateInstantiation()))
+                   .bind(ResetCall)),
       this);
 }
 
@@ -255,6 +257,8 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
                                    const CXXNewExpr *New, SourceManager &SM,
                                    ASTContext *Ctx) {
   auto SkipParensParents = [&](const Expr *E) {
+    TraversalKindScope RAII(*Ctx, ast_type_traits::TK_AsIs);
+
     for (const Expr *OldE = nullptr; E != OldE;) {
       OldE = E;
       for (const auto &Node : Ctx->getParents(*E)) {

diff  --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
index ae4837fe3893..633f3781f4d8 100644
--- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
@@ -133,33 +133,36 @@ void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 
 void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      cxxConstructorDecl(
-          forEachConstructorInitializer(
-              cxxCtorInitializer(
-                  unless(isBaseInitializer()),
-                  // Clang builds a CXXConstructExpr only when it knows which
-                  // constructor will be called. In dependent contexts a
-                  // ParenListExpr is generated instead of a CXXConstructExpr,
-                  // filtering out templates automatically for us.
-                  withInitializer(cxxConstructExpr(
-                      has(ignoringParenImpCasts(declRefExpr(
-                          to(parmVarDecl(
-                                 hasType(qualType(
-                                     // Match only const-ref or a non-const
-                                     // value parameters. Rvalues,
-                                     // TemplateSpecializationValues and
-                                     // const-values shouldn't be modified.
-                                     ValuesOnly
-                                         ? nonConstValueType()
-                                         : anyOf(notTemplateSpecConstRefType(),
-                                                 nonConstValueType()))))
-                                 .bind("Param"))))),
-                      hasDeclaration(cxxConstructorDecl(
-                          isCopyConstructor(), unless(isDeleted()),
-                          hasDeclContext(
-                              cxxRecordDecl(isMoveConstructible())))))))
-                  .bind("Initializer")))
-          .bind("Ctor"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxConstructorDecl(
+              forEachConstructorInitializer(
+                  cxxCtorInitializer(
+                      unless(isBaseInitializer()),
+                      // Clang builds a CXXConstructExpr only when it knows
+                      // which constructor will be called. In dependent contexts
+                      // a ParenListExpr is generated instead of a
+                      // CXXConstructExpr, filtering out templates automatically
+                      // for us.
+                      withInitializer(cxxConstructExpr(
+                          has(ignoringParenImpCasts(declRefExpr(to(
+                              parmVarDecl(
+                                  hasType(qualType(
+                                      // Match only const-ref or a non-const
+                                      // value parameters. Rvalues,
+                                      // TemplateSpecializationValues and
+                                      // const-values shouldn't be modified.
+                                      ValuesOnly
+                                          ? nonConstValueType()
+                                          : anyOf(notTemplateSpecConstRefType(),
+                                                  nonConstValueType()))))
+                                  .bind("Param"))))),
+                          hasDeclaration(cxxConstructorDecl(
+                              isCopyConstructor(), unless(isDeleted()),
+                              hasDeclContext(
+                                  cxxRecordDecl(isMoveConstructible())))))))
+                      .bind("Initializer")))
+              .bind("Ctor")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
index ade2bec3a98b..515b2146f06c 100644
--- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -123,9 +123,11 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
                           callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
                           hasArgument(1, MovableArgumentMatcher)),
       this);
-  Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
-                                      hasArgument(0, MovableArgumentMatcher)),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
+                                hasArgument(0, MovableArgumentMatcher))),
+      this);
 }
 
 void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM,

diff  --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
index e7c2bdb256e1..550772972923 100644
--- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
@@ -32,11 +32,14 @@ void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
   const auto End = hasArgument(1, expr());
   const auto RandomFunc = hasArgument(2, expr().bind("randomFunc"));
   Finder->addMatcher(
-      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"),
+      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")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
index d37b276d93cf..d94e1cee227a 100644
--- a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
@@ -31,11 +31,13 @@ void ReturnBracedInitListCheck::registerMatchers(MatchFinder *Finder) {
       has(ConstructExpr), has(cxxFunctionalCastExpr(has(ConstructExpr)))));
 
   Finder->addMatcher(
-      functionDecl(isDefinition(), // Declarations don't have return statements.
+      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
index 8f6f80cbc957..d967e5283fa0 100644
--- a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp
@@ -42,7 +42,8 @@ void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) {
           on(hasType(hasCanonicalType(hasDeclaration(namedDecl(
               hasAnyName("std::basic_string", "std::deque", "std::vector")))))),
           callee(cxxMethodDecl(hasName("swap"))),
-          has(ignoringParenImpCasts(memberExpr(hasDescendant(CopyCtorCall)))),
+          has(ignoringParenImpCasts(memberExpr(traverse(
+              ast_type_traits::TK_AsIs, hasDescendant(CopyCtorCall))))),
           hasArgument(0, SwapParam.bind("ContainerToShrink")),
           unless(isInTemplateInstantiation()))
           .bind("CopyAndSwapTrick"),

diff  --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
index 4791bd6060d6..eed9321d688c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
@@ -325,7 +325,8 @@ void UseAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 }
 
 void UseAutoCheck::registerMatchers(MatchFinder *Finder) {
-    Finder->addMatcher(makeCombinedMatcher(), this);
+  Finder->addMatcher(traverse(ast_type_traits::TK_AsIs, makeCombinedMatcher()),
+                     this);
 }
 
 void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) {

diff  --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
index 65646d6bdad1..5ddda30764fc 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
@@ -24,22 +24,25 @@ UseBoolLiteralsCheck::UseBoolLiteralsCheck(StringRef Name,
 
 void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      implicitCastExpr(
-          has(ignoringParenImpCasts(integerLiteral().bind("literal"))),
-          hasImplicitDestinationType(qualType(booleanType())),
-          unless(isInTemplateInstantiation()),
-          anyOf(hasParent(explicitCastExpr().bind("cast")), anything())),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          implicitCastExpr(
+              has(ignoringParenImpCasts(integerLiteral().bind("literal"))),
+              hasImplicitDestinationType(qualType(booleanType())),
+              unless(isInTemplateInstantiation()),
+              anyOf(hasParent(explicitCastExpr().bind("cast")), anything()))),
       this);
 
   Finder->addMatcher(
-      conditionalOperator(
-          hasParent(implicitCastExpr(
-              hasImplicitDestinationType(qualType(booleanType())),
-              unless(isInTemplateInstantiation()))),
-          eachOf(hasTrueExpression(
-                     ignoringParenImpCasts(integerLiteral().bind("literal"))),
-                 hasFalseExpression(
-                     ignoringParenImpCasts(integerLiteral().bind("literal"))))),
+      traverse(ast_type_traits::TK_AsIs,
+               conditionalOperator(
+                   hasParent(implicitCastExpr(
+                       hasImplicitDestinationType(qualType(booleanType())),
+                       unless(isInTemplateInstantiation()))),
+                   eachOf(hasTrueExpression(ignoringParenImpCasts(
+                              integerLiteral().bind("literal"))),
+                          hasFalseExpression(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
index b84b0cd865e5..823b119dace0 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -109,10 +109,12 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
       anyOf(has(MakeTuple), has(MakeTupleCtor),
             HasConstructExpr, has(cxxFunctionalCastExpr(HasConstructExpr))));
 
-  Finder->addMatcher(cxxMemberCallExpr(CallPushBack, has(SoughtParam),
-                                       unless(isInTemplateInstantiation()))
-                         .bind("call"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxMemberCallExpr(CallPushBack, has(SoughtParam),
+                                 unless(isInTemplateInstantiation()))
+                   .bind("call")),
+      this);
 }
 
 void UseEmplaceCheck::check(const MatchFinder::MatchResult &Result) {

diff  --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
index 09603497e682..23e48c0a9ab2 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -75,14 +75,17 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context,
     // The initialization of a base class should be a call to a copy
     // constructor of the base.
     if (match(
-            cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer(
-                isBaseInitializer(),
-                withInitializer(cxxConstructExpr(
-                    hasType(equalsNode(Base)),
-                    hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
-                    argumentCountIs(1),
-                    hasArgument(
-                        0, declRefExpr(to(varDecl(equalsNode(Param)))))))))),
+            traverse(ast_type_traits::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)
             .empty())
       return false;
@@ -92,17 +95,20 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context,
   for (const auto *Field : FieldsToInit) {
     auto AccessToFieldInParam = accessToFieldInVar(Field, Param);
     // The initialization is a CXXConstructExpr for class types.
-    if (match(
-            cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer(
-                isMemberInitializer(), forField(equalsNode(Field)),
-                withInitializer(anyOf(
-                    AccessToFieldInParam,
-                    initListExpr(has(AccessToFieldInParam)),
-                    cxxConstructExpr(
-                        hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
-                        argumentCountIs(1),
-                        hasArgument(0, AccessToFieldInParam))))))),
-            *Ctor, *Context)
+    if (match(traverse(
+                  ast_type_traits::TK_AsIs,
+                  cxxConstructorDecl(
+                      forEachConstructorInitializer(cxxCtorInitializer(
+                          isMemberInitializer(), forField(equalsNode(Field)),
+                          withInitializer(anyOf(
+                              AccessToFieldInParam,
+                              initListExpr(has(AccessToFieldInParam)),
+                              cxxConstructExpr(
+                                  hasDeclaration(
+                                      cxxConstructorDecl(isCopyConstructor())),
+                                  argumentCountIs(1),
+                                  hasArgument(0, AccessToFieldInParam)))))))),
+              *Ctor, *Context)
             .empty())
       return false;
   }
@@ -130,8 +136,10 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context,
   // 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,21 +153,23 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context,
     //   ((Base*)this)->operator=((Base)Other);
     //
     // So we are looking for a member call that fulfills:
-    if (match(
-            compoundStmt(has(ignoringParenImpCasts(cxxMemberCallExpr(
-                // - The object is an implicit cast of 'this' to a pointer to
-                //   a base class.
-                onImplicitObjectArgument(
-                    implicitCastExpr(hasImplicitDestinationType(
-                                         pointsTo(type(equalsNode(Base)))),
-                                     hasSourceExpression(cxxThisExpr()))),
-                // - The called method is the operator=.
-                callee(cxxMethodDecl(isCopyAssignmentOperator())),
-                // - The argument is (an implicit cast to a Base of) the
-                // argument taken by "Operator".
-                argumentCountIs(1),
-                hasArgument(0, declRefExpr(to(varDecl(equalsNode(Param))))))))),
-            *Compound, *Context)
+    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.
+                           onImplicitObjectArgument(implicitCastExpr(
+                               hasImplicitDestinationType(
+                                   pointsTo(type(equalsNode(Base)))),
+                               hasSourceExpression(cxxThisExpr()))),
+                           // - The called method is the operator=.
+                           callee(cxxMethodDecl(isCopyAssignmentOperator())),
+                           // - The argument is (an implicit cast to a Base of)
+                           // the argument taken by "Operator".
+                           argumentCountIs(1),
+                           hasArgument(0, declRefExpr(to(varDecl(
+                                              equalsNode(Param)))))))))),
+              *Compound, *Context)
             .empty())
       return false;
   }
@@ -174,11 +184,13 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context,
                           member(fieldDecl(equalsNode(Field))));
     auto RHS = accessToFieldInVar(Field, Param);
     if (match(
-            compoundStmt(has(ignoringParenImpCasts(stmt(anyOf(
-                binaryOperator(hasOperatorName("="), hasLHS(LHS), hasRHS(RHS)),
-                cxxOperatorCallExpr(hasOverloadedOperatorName("="),
-                                    argumentCountIs(2), hasArgument(0, LHS),
-                                    hasArgument(1, RHS))))))),
+            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)))))))),
             *Compound, *Context)
             .empty())
       return false;

diff  --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index 37e4d24e9898..7e30c174a615 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -41,10 +41,12 @@ StatementMatcher makeCastSequenceMatcher() {
       unless(hasImplicitDestinationType(qualType(substTemplateTypeParmType()))),
       unless(hasSourceExpression(hasType(sugaredNullptrType()))));
 
-  return castExpr(anyOf(ImplicitCastToNull,
-                        explicitCastExpr(hasDescendant(ImplicitCastToNull))),
-                  unless(hasAncestor(explicitCastExpr())))
-      .bind(CastSequence);
+  return traverse(
+      ast_type_traits::TK_AsIs,
+      castExpr(anyOf(ImplicitCastToNull,
+                     explicitCastExpr(hasDescendant(ImplicitCastToNull))),
+               unless(hasAncestor(explicitCastExpr())))
+          .bind(CastSequence));
 }
 
 bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,

diff  --git a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp
index 520bdc3b9f12..ecbf0953ec6d 100644
--- a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp
@@ -101,23 +101,26 @@ fixItHintForVarDecl(const VarDecl *VD, const SourceManager &SM,
 
 void NSInvocationArgumentLifetimeCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      objcMessageExpr(
-          hasReceiverType(asString("NSInvocation *")),
-          anyOf(hasSelector("getArgument:atIndex:"),
-                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())))))
-          .bind("call"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          objcMessageExpr(
+              hasReceiverType(asString("NSInvocation *")),
+              anyOf(hasSelector("getArgument:atIndex:"),
+                    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())))))
+              .bind("call")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp
index 38dba7b89707..84a4ac922fa5 100644
--- a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.cpp
@@ -49,9 +49,11 @@ void ForRangeCopyCheck::registerMatchers(MatchFinder *Finder) {
       varDecl(HasReferenceOrPointerTypeOrIsAllowed,
               unless(hasInitializer(expr(hasDescendant(expr(anyOf(
                   materializeTemporaryExpr(), IteratorReturnsValueType)))))));
-  Finder->addMatcher(cxxForRangeStmt(hasLoopVariable(LoopVar.bind("loopVar")))
-                         .bind("forRange"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxForRangeStmt(hasLoopVariable(LoopVar.bind("loopVar")))
+                   .bind("forRange")),
+      this);
 }
 
 void ForRangeCopyCheck::check(const MatchFinder::MatchResult &Result) {

diff  --git a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
index a52065540917..9cddd2b4d31c 100644
--- a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
@@ -47,16 +47,19 @@ void ImplicitConversionInLoopCheck::registerMatchers(MatchFinder *Finder) {
   // CXXOperatorCallExpr, so it should not get caught by the
   // cxxOperatorCallExpr() matcher.
   Finder->addMatcher(
-      cxxForRangeStmt(hasLoopVariable(
-          varDecl(
-              hasType(qualType(references(qualType(isConstQualified())))),
-              hasInitializer(
-                  expr(anyOf(hasDescendant(
-                                 cxxOperatorCallExpr().bind("operator-call")),
-                             hasDescendant(unaryOperator(hasOperatorName("*"))
-                                               .bind("operator-call"))))
-                      .bind("init")))
-              .bind("faulty-var"))),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxForRangeStmt(hasLoopVariable(
+              varDecl(
+                  hasType(qualType(references(qualType(isConstQualified())))),
+                  hasInitializer(
+                      expr(anyOf(
+                               hasDescendant(
+                                   cxxOperatorCallExpr().bind("operator-call")),
+                               hasDescendant(unaryOperator(hasOperatorName("*"))
+                                                 .bind("operator-call"))))
+                          .bind("init")))
+                  .bind("faulty-var")))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp
index 8dda7a802214..dfea0104614c 100644
--- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp
@@ -35,7 +35,8 @@ void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) {
       "::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(
@@ -54,7 +55,7 @@ void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) {
                          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
index 17eb62a41a1d..95aa33863d65 100644
--- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
@@ -51,8 +51,10 @@ void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) {
       MoveCallMatcher, parmVarDecl(hasType(references(isConstQualified()))));
 
   Finder->addMatcher(callExpr(ConstParamMatcher).bind("receiving-expr"), this);
-  Finder->addMatcher(cxxConstructExpr(ConstParamMatcher).bind("receiving-expr"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxConstructExpr(ConstParamMatcher).bind("receiving-expr")),
+      this);
 }
 
 void MoveConstArgCheck::check(const MatchFinder::MatchResult &Result) {

diff  --git a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp
index 853e07f6001b..d09673fa7f23 100644
--- a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp
@@ -29,13 +29,15 @@ MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name,
 
 void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      cxxConstructorDecl(
-          unless(isImplicit()), isMoveConstructor(),
-          hasAnyConstructorInitializer(
-              cxxCtorInitializer(
-                  withInitializer(cxxConstructExpr(hasDeclaration(
-                      cxxConstructorDecl(isCopyConstructor()).bind("ctor")))))
-                  .bind("move-init"))),
+      traverse(ast_type_traits::TK_AsIs,
+               cxxConstructorDecl(
+                   unless(isImplicit()), isMoveConstructor(),
+                   hasAnyConstructorInitializer(
+                       cxxCtorInitializer(
+                           withInitializer(cxxConstructExpr(hasDeclaration(
+                               cxxConstructorDecl(isCopyConstructor())
+                                   .bind("ctor")))))
+                           .bind("move-init")))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
index 8ce8bb479ee5..057e10d3c21e 100644
--- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
@@ -44,12 +44,14 @@ void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
                               pointee(type(equalsBoundNode("SrcT")))))))))));
 
   Finder->addMatcher(
-      returnStmt(
-          hasReturnValue(ignoringElidableConstructorCall(ignoringParenImpCasts(
-              cxxConstructExpr(hasDeclaration(LValueRefCtor),
-                               hasArgument(0, ignoringParenImpCasts(declRefExpr(
-                                                  to(ConstLocalVariable)))))
-                  .bind("ctor_call"))))),
+      traverse(ast_type_traits::TK_AsIs,
+               returnStmt(hasReturnValue(
+                   ignoringElidableConstructorCall(ignoringParenImpCasts(
+                       cxxConstructExpr(
+                           hasDeclaration(LValueRefCtor),
+                           hasArgument(0, ignoringParenImpCasts(declRefExpr(
+                                              to(ConstLocalVariable)))))
+                           .bind("ctor_call")))))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index c9ae37d036ca..f7b21a50203c 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -68,12 +68,13 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
                                            matchers::matchesAnyListedName(
                                                AllowedTypes)))))),
                                    unless(isImplicit()),
-                                   hasInitializer(
+                                   hasInitializer(traverse(
+                                       ast_type_traits::TK_AsIs,
                                        cxxConstructExpr(
                                            hasDeclaration(cxxConstructorDecl(
                                                isCopyConstructor())),
                                            hasArgument(0, CopyCtorArg))
-                                           .bind("ctorCall")))
+                                           .bind("ctorCall"))))
                                .bind("newVarDecl")))
                        .bind("declStmt")))
         .bind("blockStmt");
@@ -96,6 +97,8 @@ void UnnecessaryCopyInitialization::check(
   const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt");
   const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("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
index 5b71d8996dab..9dea42409513 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
@@ -41,12 +41,13 @@ bool isReferencedOutsideOfCallExpr(const FunctionDecl &Function,
 
 bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
                          ASTContext &Context) {
-  auto Matches =
-      match(decl(forEachDescendant(declRefExpr(
-                equalsNode(&DeclRef),
-                unless(hasAncestor(stmt(anyOf(forStmt(), cxxForRangeStmt(),
-                                              whileStmt(), doStmt()))))))),
-            Decl, Context);
+  auto Matches = match(
+      traverse(ast_type_traits::TK_AsIs,
+               decl(forEachDescendant(declRefExpr(
+                   equalsNode(&DeclRef),
+                   unless(hasAncestor(stmt(anyOf(forStmt(), cxxForRangeStmt(),
+                                                 whileStmt(), doStmt())))))))),
+      Decl, Context);
   return Matches.empty();
 }
 
@@ -82,10 +83,12 @@ void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
                            matchers::matchesAnyListedName(AllowedTypes))))))),
       decl().bind("param"));
   Finder->addMatcher(
-      functionDecl(hasBody(stmt()), isDefinition(), unless(isImplicit()),
-                   unless(cxxMethodDecl(anyOf(isOverride(), isFinal()))),
-                   has(typeLoc(forEach(ExpensiveValueParamDecl))),
-                   unless(isInstantiated()), decl().bind("functionDecl")),
+      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"))),
       this);
 }
 
@@ -93,6 +96,8 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param");
   const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("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
index 992a3fa11639..bcd3e248df77 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -39,18 +39,20 @@ void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
                       .bind("empty")))
               .bind("container")))))));
 
-  const auto WrongUse = anyOf(
-      hasParent(binaryOperator(
-                    isComparisonOperator(),
-                    hasEitherOperand(ignoringImpCasts(anyOf(
-                        integerLiteral(equals(1)), integerLiteral(equals(0))))))
-                    .bind("SizeBinaryOp")),
-      hasParent(implicitCastExpr(
-          hasImplicitDestinationType(booleanType()),
-          anyOf(
-              hasParent(unaryOperator(hasOperatorName("!")).bind("NegOnSize")),
-              anything()))),
-      hasParent(explicitCastExpr(hasDestinationType(booleanType()))));
+  const auto WrongUse = traverse(
+      ast_type_traits::TK_AsIs,
+      anyOf(
+          hasParent(binaryOperator(isComparisonOperator(),
+                                   hasEitherOperand(ignoringImpCasts(
+                                       anyOf(integerLiteral(equals(1)),
+                                             integerLiteral(equals(0))))))
+                        .bind("SizeBinaryOp")),
+          hasParent(implicitCastExpr(
+              hasImplicitDestinationType(booleanType()),
+              anyOf(hasParent(
+                        unaryOperator(hasOperatorName("!")).bind("NegOnSize")),
+                    anything()))),
+          hasParent(explicitCastExpr(hasDestinationType(booleanType())))));
 
   Finder->addMatcher(
       cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer),

diff  --git a/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp
index 18a775e87e3d..57b1a0c9e141 100644
--- a/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/DeleteNullPointerCheck.cpp
@@ -39,13 +39,15 @@ void DeleteNullPointerCheck::registerMatchers(MatchFinder *Finder) {
       hasOperands(castExpr(hasCastKind(CK_NullToPointer)), PointerExpr));
 
   Finder->addMatcher(
-      ifStmt(hasCondition(anyOf(PointerCondition, BinaryPointerCheckCondition)),
-             hasThen(anyOf(
-                 DeleteExpr, DeleteMemberExpr,
-                 compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)),
-                              statementCountIs(1))
-                     .bind("compound"))))
-          .bind("ifWithDelete"),
+      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")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index 22fce443a3e0..d7a782bfd182 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -221,6 +221,9 @@ bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
                               ASTContext &Context) {
   std::queue<const Stmt *> Q;
   Q.push(Cast);
+
+  TraversalKindScope RAII(Context, ast_type_traits::TK_AsIs);
+
   while (!Q.empty()) {
     for (const auto &N : Context.getParents(*Q.front())) {
       const Stmt *S = N.get<Stmt>();
@@ -273,24 +276,25 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
       binaryOperator(hasOperatorName("^"), hasLHS(implicitCastFromBool),
                      hasRHS(implicitCastFromBool));
   Finder->addMatcher(
-      implicitCastExpr(
-          anyOf(hasCastKind(CK_IntegralToBoolean),
-                hasCastKind(CK_FloatingToBoolean),
-                hasCastKind(CK_PointerToBoolean),
-                hasCastKind(CK_MemberPointerToBoolean)),
-          // Exclude case of using if or while statements with variable
-          // declaration, e.g.:
-          //   if (int var = functionCall()) {}
-          unless(
-              hasParent(stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))),
-          // Exclude cases common to implicit cast to and from bool.
-          unless(exceptionCases), unless(has(boolXor)),
-          // Retrieve also parent statement, to check if we need additional
-          // parens in replacement.
-          anyOf(hasParent(stmt().bind("parentStmt")), anything()),
-          unless(isInTemplateInstantiation()),
-          unless(hasAncestor(functionTemplateDecl())))
-          .bind("implicitCastToBool"),
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(
+                   anyOf(hasCastKind(CK_IntegralToBoolean),
+                         hasCastKind(CK_FloatingToBoolean),
+                         hasCastKind(CK_PointerToBoolean),
+                         hasCastKind(CK_MemberPointerToBoolean)),
+                   // Exclude case of using if or while statements with variable
+                   // declaration, e.g.:
+                   //   if (int var = functionCall()) {}
+                   unless(hasParent(
+                       stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))),
+                   // Exclude cases common to implicit cast to and from bool.
+                   unless(exceptionCases), unless(has(boolXor)),
+                   // Retrieve also parent statement, to check if we need
+                   // additional parens in replacement.
+                   anyOf(hasParent(stmt().bind("parentStmt")), anything()),
+                   unless(isInTemplateInstantiation()),
+                   unless(hasAncestor(functionTemplateDecl())))
+                   .bind("implicitCastToBool")),
       this);
 
   auto boolComparison = binaryOperator(hasAnyOperatorName("==", "!="),
@@ -304,26 +308,30 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
       withInitializer(equalsBoundNode("implicitCastFromBool")),
       forField(hasBitWidth(1)))));
   Finder->addMatcher(
-      implicitCastExpr(
-          implicitCastFromBool,
-          // Exclude comparisons of bools, as they are always cast to integers
-          // in such context:
-          //   bool_expr_a == bool_expr_b
-          //   bool_expr_a != bool_expr_b
-          unless(hasParent(binaryOperator(anyOf(
-              boolComparison, boolXor, boolOpAssignment, bitfieldAssignment)))),
-          implicitCastExpr().bind("implicitCastFromBool"),
-          unless(hasParent(bitfieldConstruct)),
-          // Check also for nested casts, for example: bool -> int -> float.
-          anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
-                anything()),
-          unless(isInTemplateInstantiation()),
-          unless(hasAncestor(functionTemplateDecl()))),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          implicitCastExpr(
+              implicitCastFromBool,
+              // Exclude comparisons of bools, as they are always cast to
+              // integers in such context:
+              //   bool_expr_a == bool_expr_b
+              //   bool_expr_a != bool_expr_b
+              unless(hasParent(
+                  binaryOperator(anyOf(boolComparison, boolXor,
+                                       boolOpAssignment, bitfieldAssignment)))),
+              implicitCastExpr().bind("implicitCastFromBool"),
+              unless(hasParent(bitfieldConstruct)),
+              // Check also for nested casts, for example: bool -> int -> float.
+              anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
+                    anything()),
+              unless(isInTemplateInstantiation()),
+              unless(hasAncestor(functionTemplateDecl())))),
       this);
 }
 
 void ImplicitBoolConversionCheck::check(
     const MatchFinder::MatchResult &Result) {
+
   if (const auto *CastToBool =
           Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) {
     const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt");

diff  --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
index 86443a155069..df2229ae5f03 100644
--- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -119,6 +119,9 @@ void MagicNumbersCheck::registerMatchers(MatchFinder *Finder) {
 }
 
 void MagicNumbersCheck::check(const MatchFinder::MatchResult &Result) {
+
+  TraversalKindScope RAII(*Result.Context, ast_type_traits::TK_AsIs);
+
   checkBoundMatch<IntegerLiteral>(Result, "integer");
   checkBoundMatch<FloatingLiteral>(Result, "float");
 }

diff  --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
index cf31ad00d95c..ee087e3b3133 100644
--- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
@@ -210,21 +210,23 @@ AST_MATCHER(CXXMethodDecl, usesThisAsConst) {
 
 void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      cxxMethodDecl(
-          isDefinition(), isUserProvided(),
-          unless(anyOf(
-              isExpansionInSystemHeader(), isVirtual(), isConst(), isStatic(),
-              hasTrivialBody(), cxxConstructorDecl(), cxxDestructorDecl(),
-              isTemplate(), isDependentContext(),
-              ofClass(anyOf(
-                  isLambda(),
-                  hasAnyDependentBases()) // Method might become virtual
-                                          // depending on template base class.
-                      ),
-              isInsideMacroDefinition(),
-              hasCanonicalDecl(isInsideMacroDefinition()))),
-          usesThisAsConst())
-          .bind("x"),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxMethodDecl(
+              isDefinition(), isUserProvided(),
+              unless(anyOf(
+                  isExpansionInSystemHeader(), isVirtual(), isConst(),
+                  isStatic(), hasTrivialBody(), cxxConstructorDecl(),
+                  cxxDestructorDecl(), isTemplate(), isDependentContext(),
+                  ofClass(anyOf(isLambda(),
+                                hasAnyDependentBases()) // Method might become
+                                                        // virtual depending on
+                                                        // template base class.
+                          ),
+                  isInsideMacroDefinition(),
+                  hasCanonicalDecl(isInsideMacroDefinition()))),
+              usesThisAsConst())
+              .bind("x")),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp b/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
index 7b39012b7693..c5112da413db 100644
--- a/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
@@ -19,10 +19,12 @@ namespace tidy {
 namespace readability {
 
 void MisplacedArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(arraySubscriptExpr(hasLHS(hasType(isInteger())),
-                                        hasRHS(hasType(isAnyPointer())))
-                         .bind("expr"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               arraySubscriptExpr(hasLHS(hasType(isInteger())),
+                                  hasRHS(hasType(isAnyPointer())))
+                   .bind("expr")),
+      this);
 }
 
 void MisplacedArrayIndexCheck::check(const MatchFinder::MatchResult &Result) {

diff  --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
index 9d5a18f93585..688547ca2975 100644
--- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
@@ -28,11 +28,13 @@ void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(declRefExpr().bind("Ref"), this);
 
   // Analyse parameter usage in function.
-  Finder->addMatcher(stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")),
-                                binaryOperator(), callExpr(), returnStmt(),
-                                cxxConstructExpr()))
-                         .bind("Mark"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")),
+                          binaryOperator(), callExpr(), returnStmt(),
+                          cxxConstructExpr()))
+                   .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
index f2360a09149f..56565ff2115c 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
@@ -17,10 +17,11 @@ namespace tidy {
 namespace readability {
 
 void RedundantFunctionPtrDereferenceCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(unaryOperator(hasOperatorName("*"),
-                                   has(implicitCastExpr(
-                                       hasCastKind(CK_FunctionToPointerDecay))))
-                         .bind("op"),
+  Finder->addMatcher(traverse(ast_type_traits::TK_AsIs,
+                              unaryOperator(hasOperatorName("*"),
+                                            has(implicitCastExpr(hasCastKind(
+                                                CK_FunctionToPointerDecay))))
+                                  .bind("op")),
                      this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp
index 09be12a71926..027146f12aad 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp
@@ -33,17 +33,19 @@ void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) {
           .bind("construct");
 
   Finder->addMatcher(
-      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"),
+      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);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
index e41cdfcc08d8..bea02a6ba111 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
@@ -96,11 +96,13 @@ void RedundantStringCStrCheck::registerMatchers(
   // Detect redundant 'c_str()' calls through a string constructor.
   // If CxxConstructExpr is the part of some CallExpr we need to
   // check that matched ParamDecl of the ancestor CallExpr is not rvalue.
-  Finder->addMatcher(cxxConstructExpr(StringConstructorExpr,
-                                      hasArgument(0, StringCStrCallExpr),
-                                      unless(hasParent(materializeTemporaryExpr(
-                                          unless(isBoundToLValue()))))),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               cxxConstructExpr(StringConstructorExpr,
+                                hasArgument(0, StringCStrCallExpr),
+                                unless(hasParent(materializeTemporaryExpr(
+                                    unless(isBoundToLValue())))))),
+      this);
 
   // Detect: 's == str.c_str()'  ->  's == str'
   Finder->addMatcher(
@@ -153,20 +155,22 @@ void RedundantStringCStrCheck::registerMatchers(
 
   // Detect redundant 'c_str()' calls through a StringRef constructor.
   Finder->addMatcher(
-      cxxConstructExpr(
-          // Implicit constructors of these classes are overloaded
-          // wrt. string types and they internally make a StringRef
-          // referring to the argument.  Passing a string directly to
-          // them is preferred to passing a char pointer.
-          hasDeclaration(cxxMethodDecl(hasAnyName(
-              "::llvm::StringRef::StringRef", "::llvm::Twine::Twine"))),
-          argumentCountIs(1),
-          // The only argument must have the form x.c_str() or p->c_str()
-          // where the method is string::c_str().  StringRef also has
-          // a constructor from string which is more efficient (avoids
-          // strlen), so we can construct StringRef from the string
-          // directly.
-          hasArgument(0, StringCStrCallExpr)),
+      traverse(
+          ast_type_traits::TK_AsIs,
+          cxxConstructExpr(
+              // Implicit constructors of these classes are overloaded
+              // wrt. string types and they internally make a StringRef
+              // referring to the argument.  Passing a string directly to
+              // them is preferred to passing a char pointer.
+              hasDeclaration(cxxMethodDecl(hasAnyName(
+                  "::llvm::StringRef::StringRef", "::llvm::Twine::Twine"))),
+              argumentCountIs(1),
+              // The only argument must have the form x.c_str() or p->c_str()
+              // where the method is string::c_str().  StringRef also has
+              // a constructor from string which is more efficient (avoids
+              // strlen), so we can construct StringRef from the string
+              // directly.
+              hasArgument(0, StringCStrCallExpr))),
       this);
 }
 

diff  --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
index 6c54ca874401..78bf744eba8d 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -104,9 +104,10 @@ void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
   //     string foo = "";
   //     string bar("");
   Finder->addMatcher(
-      namedDecl(
-          varDecl(StringType, hasInitializer(EmptyStringInit)).bind("vardecl"),
-          unless(parmVarDecl())),
+      traverse(ast_type_traits::TK_AsIs,
+               namedDecl(varDecl(StringType, hasInitializer(EmptyStringInit))
+                             .bind("vardecl"),
+                         unless(parmVarDecl()))),
       this);
   // Match a field declaration with an empty string literal as initializer.
   Finder->addMatcher(

diff  --git a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp
index e82324578711..19d40c54f12c 100644
--- a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp
@@ -31,10 +31,12 @@ void StringCompareCheck::registerMatchers(MatchFinder *Finder) {
       callee(memberExpr().bind("str1")));
 
   // First and second case: cast str.compare(str) to boolean.
-  Finder->addMatcher(implicitCastExpr(hasImplicitDestinationType(booleanType()),
-                                      has(StrCompare))
-                         .bind("match1"),
-                     this);
+  Finder->addMatcher(
+      traverse(ast_type_traits::TK_AsIs,
+               implicitCastExpr(hasImplicitDestinationType(booleanType()),
+                                has(StrCompare))
+                   .bind("match1")),
+      this);
 
   // Third and fourth case: str.compare(str) == 0 and str.compare(str) != 0.
   Finder->addMatcher(

diff  --git a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp
index 3505f31c92a2..8fddf4d4996a 100644
--- a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp
@@ -28,6 +28,7 @@ static SmallVector<const Stmt *, 1> getParentStmts(const Stmt *S,
                                                    ASTContext *Context) {
   SmallVector<const Stmt *, 1> Result;
 
+  TraversalKindScope RAII(*Context, ast_type_traits::TK_AsIs);
   DynTypedNodeList Parents = Context->getParents(*S);
 
   SmallVector<ast_type_traits::DynTypedNode, 1> NodesToProcess(Parents.begin(),

diff  --git a/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp b/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp
index d3fac14f713d..d816f0ba1866 100644
--- a/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/zircon/TemporaryObjectsCheck.cpp
@@ -36,10 +36,11 @@ void TemporaryObjectsCheck::registerMatchers(MatchFinder *Finder) {
 
   // Matcher for user-defined constructors.
   Finder->addMatcher(
-      cxxConstructExpr(hasParent(cxxFunctionalCastExpr()),
-                       hasDeclaration(cxxConstructorDecl(
-                           hasParent(cxxRecordDecl(matchesAnyName(Names))))))
-          .bind("temps"),
+      traverse(ast_type_traits::TK_AsIs,
+               cxxConstructExpr(hasParent(cxxFunctionalCastExpr()),
+                                hasDeclaration(cxxConstructorDecl(hasParent(
+                                    cxxRecordDecl(matchesAnyName(Names))))))
+                   .bind("temps")),
       this);
 }
 


        


More information about the cfe-commits mailing list