[clang] [Clang] [NFC] Introduce `DynamicRecursiveASTVisitor` (PR #105195)

via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 20 11:42:48 PDT 2024


https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/105195

>From a43092cd2a63f141e80fa914f4a0f5845f768154 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Thu, 6 Jun 2024 16:43:19 +0200
Subject: [PATCH 01/27] [Clang] Introduce DynamicRecursiveASTVisitor

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 174 ++++++++++++
 clang/include/clang/AST/RecursiveASTVisitor.h |   8 +-
 clang/lib/AST/CMakeLists.txt                  |   1 +
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  | 267 ++++++++++++++++++
 clang/lib/Sema/SemaDeclCXX.cpp                |  53 ++--
 clang/lib/Sema/SemaExpr.cpp                   |  49 ++--
 clang/lib/Sema/SemaExprCXX.cpp                |   6 +-
 clang/lib/Sema/SemaStmt.cpp                   |  10 +-
 clang/lib/Sema/SemaTemplate.cpp               |  45 ++-
 clang/utils/TableGen/ClangAttrEmitter.cpp     |  42 ++-
 10 files changed, 563 insertions(+), 92 deletions(-)
 create mode 100644 clang/include/clang/AST/DynamicRecursiveASTVisitor.h
 create mode 100644 clang/lib/AST/DynamicRecursiveASTVisitor.cpp

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
new file mode 100644
index 00000000000000..58797d9e19fe43
--- /dev/null
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -0,0 +1,174 @@
+#ifndef LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
+#define LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/AST/TypeLoc.h"
+
+namespace clang {
+class ASTContext;
+
+/// Recursive AST visitor that supports extension via dynamic dispatch.
+///
+/// \see RecursiveASTVisitor
+class DynamicRecursiveASTVisitor {
+public:
+  using DataRecursionQueue =
+      SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>;
+
+  /// Whether this visitor should recurse into template instantiations.
+  bool ShouldVisitTemplateInstantiations = false;
+
+  /// Whether this visitor should recurse into the types of TypeLocs.
+  bool ShouldWalkTypesOfTypeLocs = true;
+
+  /// Whether this visitor should recurse into implicit code, e.g.
+  /// implicit constructors and destructors.
+  bool ShouldVisitImplicitCode = false;
+
+  /// Whether this visitor should recurse into lambda body
+  bool ShouldVisitLambdaBody = true;
+
+  /// Return whether this visitor should traverse post-order.
+  bool ShouldTraversePostOrder = false;
+
+protected:
+  DynamicRecursiveASTVisitor() = default;
+
+public:
+  // Copying/moving a polymorphic type is a bad idea.
+  DynamicRecursiveASTVisitor(DynamicRecursiveASTVisitor &&) = delete;
+  DynamicRecursiveASTVisitor(const DynamicRecursiveASTVisitor &) = delete;
+  DynamicRecursiveASTVisitor &operator=(DynamicRecursiveASTVisitor &&) = delete;
+  DynamicRecursiveASTVisitor &
+  operator=(const DynamicRecursiveASTVisitor &) = delete;
+
+  // Declared out of line as a vtable anchor.
+  virtual ~DynamicRecursiveASTVisitor();
+
+  /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
+  /// \returns false if visitation was terminated early.
+  virtual bool TraverseAST(ASTContext &AST);
+
+  /// Recursively visit an attribute, by dispatching to
+  /// Traverse*Attr() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  virtual bool TraverseAttr(Attr *At);
+
+  /// Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the name.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+  /// Recursively visit a declaration, by dispatching to
+  /// Traverse*Decl() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  virtual bool TraverseDecl(Decl *D);
+
+  /// Recursively visit a statement or expression, by
+  /// dispatching to Traverse*() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is nullptr).
+  virtual bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
+
+  /// Recursively visit a template argument and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: migrate callers to TemplateArgumentLoc instead.
+  virtual bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+  /// Recursively visit a set of template arguments.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+  bool
+  TraverseTemplateArguments(ArrayRef<TemplateArgument> Args); // NOT virtual
+
+  /// Recursively visit a template name and dispatch to the
+  /// appropriate method.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseTemplateName(TemplateName Template);
+
+  /// Recursively visit a type, by dispatching to
+  /// Traverse*Type() based on the argument's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type).
+  virtual bool TraverseType(QualType T);
+
+  /// Recursively visit a type with location, by dispatching to
+  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  virtual bool TraverseTypeLoc(TypeLoc TL);
+
+  /// Traverse a concept (requirement).
+  virtual bool TraverseTypeConstraint(const TypeConstraint *C);
+  virtual bool TraverseConceptRequirement(concepts::Requirement *R);
+  virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
+  virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
+  virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
+
+  /// Visit a node.
+  virtual bool VisitAttr(Attr *A) { return true; }
+  virtual bool VisitDecl(Decl *D) { return true; }
+  virtual bool VisitStmt(Stmt *S) { return true; }
+  virtual bool VisitType(Type *T) { return true; }
+  virtual bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+  /// Walk up from a node.
+  virtual bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); }
+  virtual bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); }
+  virtual bool WalkUpFromType(Type *T) { return VisitType(T); }
+  virtual bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
+
+  /*// Declare Traverse*() and friends for attributes.
+#define DYNAMIC_ATTR_VISITOR_DECLS
+#include "clang/AST/AttrVisitor.inc"
+#undef DYNAMIC_ATTR_VISITOR_DECLS*/
+
+  // Declare Traverse*() for and friends all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);                          \
+  virtual bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D);                        \
+  virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+  // Declare Traverse*() and friends for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  virtual bool Traverse##CLASS(CLASS *S);                                      \
+  virtual bool WalkUpFrom##CLASS(CLASS *S);                                    \
+  virtual bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+  // Declare Traverse*() and friends for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  virtual bool Traverse##CLASS##Type(CLASS##Type *T);                          \
+  virtual bool WalkUpFrom##CLASS##Type(CLASS##Type *T);                        \
+  virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.inc"
+
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);                    \
+  virtual bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL);                  \
+  virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeLocNodes.def"
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 4bbb4380cdd7fd..d91e54c555297d 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -327,11 +327,11 @@ template <typename Derived> class RecursiveASTVisitor {
   bool VisitAttr(Attr *A) { return true; }
 
 // Declare Traverse* and empty Visit* for all Attr classes.
-#define ATTR_VISITOR_DECLS_ONLY
+#define ATTR_VISITOR_DECLS
 #include "clang/AST/AttrVisitor.inc"
-#undef ATTR_VISITOR_DECLS_ONLY
+#undef ATTR_VISITOR_DECLS
 
-// ---- Methods on Stmts ----
+  // ---- Methods on Stmts ----
 
   Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
 
@@ -727,9 +727,11 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
 }
 
 // Define the Traverse*Attr(Attr* A) methods
+#define ATTR_VISITOR_IMPL
 #define VISITORCLASS RecursiveASTVisitor
 #include "clang/AST/AttrVisitor.inc"
 #undef VISITORCLASS
+#undef ATTR_VISITOR_IMPL
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599fb..dcae3b6f8fedf2 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -53,6 +53,7 @@ add_clang_library(clangAST
   DeclOpenMP.cpp
   DeclPrinter.cpp
   DeclTemplate.cpp
+  DynamicRecursiveASTVisitor.cpp
   ParentMapContext.cpp
   Expr.cpp
   ExprClassification.cpp
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
new file mode 100644
index 00000000000000..b9994f31a0730e
--- /dev/null
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -0,0 +1,267 @@
+//=== DynamicRecursiveASTVisitor.cpp - Dynamic AST Visitor Implementation -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an AST visitor that does not require any template
+// instantiation to allow users to override this behaviour.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+
+namespace {
+struct Impl : RecursiveASTVisitor<Impl> {
+  DynamicRecursiveASTVisitor &Visitor;
+  Impl(DynamicRecursiveASTVisitor &Visitor) : Visitor(Visitor) {}
+
+  bool shouldVisitTemplateInstantiations() const {
+    return Visitor.ShouldVisitTemplateInstantiations;
+  }
+
+  bool shouldWalkTypesOfTypeLocs() const {
+    return Visitor.ShouldWalkTypesOfTypeLocs;
+  }
+
+  bool shouldVisitImplicitCode() const {
+    return Visitor.ShouldVisitImplicitCode;
+  }
+
+  bool shouldVisitLambdaBody() const { return Visitor.ShouldVisitLambdaBody; }
+
+  bool shouldTraversePostOrder() const {
+    return Visitor.ShouldTraversePostOrder;
+  }
+
+  bool TraverseAST(ASTContext &AST) { return Visitor.TraverseAST(AST); }
+  bool TraverseAttr(Attr *At) { return Visitor.TraverseAttr(At); }
+  bool TraverseDecl(Decl *D) { return Visitor.TraverseDecl(D); }
+  bool TraverseType(QualType T) { return Visitor.TraverseType(T); }
+  bool TraverseTypeLoc(TypeLoc TL) { return Visitor.TraverseTypeLoc(TL); }
+  bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr) {
+    return Visitor.TraverseStmt(S, Queue);
+  }
+
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+    return Visitor.TraverseConstructorInitializer(Init);
+  }
+
+  bool TraverseTemplateArgument(const TemplateArgument &Arg) {
+    return Visitor.TraverseTemplateArgument(Arg);
+  }
+
+  bool TraverseTemplateName(TemplateName Template) {
+    return Visitor.TraverseTemplateName(Template);
+  }
+
+  bool TraverseTypeConstraint(const TypeConstraint *C) {
+    return Visitor.TraverseTypeConstraint(C);
+  }
+  bool TraverseConceptRequirement(concepts::Requirement *R) {
+    return Visitor.TraverseConceptRequirement(R);
+  }
+  bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R) {
+    return Visitor.TraverseConceptTypeRequirement(R);
+  }
+  bool TraverseConceptExprRequirement(concepts::ExprRequirement *R) {
+    return Visitor.TraverseConceptExprRequirement(R);
+  }
+  bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R) {
+    return Visitor.TraverseConceptNestedRequirement(R);
+  }
+
+  /// Visit a node.
+  bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }
+  bool VisitDecl(Decl *D) { return Visitor.VisitDecl(D); }
+  bool VisitStmt(Stmt *S) { return Visitor.VisitStmt(S); }
+  bool VisitType(Type *T) { return Visitor.VisitType(T); }
+  bool VisitTypeLoc(TypeLoc TL) { return Visitor.VisitTypeLoc(TL); }
+
+  /// Walk up from a node.
+  bool WalkUpFromDecl(Decl *D) { return Visitor.WalkUpFromDecl(D); }
+  bool WalkUpFromStmt(Stmt *S) { return Visitor.WalkUpFromStmt(S); }
+  bool WalkUpFromType(Type *T) { return Visitor.WalkUpFromType(T); }
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return Visitor.WalkUpFromTypeLoc(TL); }
+
+  /*#define ATTR_VISITOR_DECLS
+  #include "clang/AST/AttrVisitor.inc"
+  #undef ATTR_VISITOR_DECLS*/
+
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  bool Traverse##CLASS##Decl(CLASS##Decl *D) {                                 \
+    return Visitor.Traverse##CLASS##Decl(D);                                   \
+  }                                                                            \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
+    return Visitor.WalkUpFrom##CLASS##Decl(D);                                 \
+  }                                                                            \
+  bool Visit##CLASS##Decl(CLASS##Decl *D) {                                    \
+    return Visitor.Visit##CLASS##Decl(D);                                      \
+  }
+#include "clang/AST/DeclNodes.inc"
+
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  bool Traverse##CLASS(CLASS *S) { return Visitor.Traverse##CLASS(S); }        \
+  bool WalkUpFrom##CLASS(CLASS *S) { return Visitor.WalkUpFrom##CLASS(S); }    \
+  bool Visit##CLASS(CLASS *S) { return Visitor.Visit##CLASS(S); }
+#include "clang/AST/StmtNodes.inc"
+
+  // Declare Traverse*() and friends for all concrete Typeclasses.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  bool Traverse##CLASS##Type(CLASS##Type *T) {                                 \
+    return Visitor.Traverse##CLASS##Type(T);                                   \
+  }                                                                            \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
+    return Visitor.WalkUpFrom##CLASS##Type(T);                                 \
+  }                                                                            \
+  bool Visit##CLASS##Type(CLASS##Type *T) {                                    \
+    return Visitor.Visit##CLASS##Type(T);                                      \
+  }
+#include "clang/AST/TypeNodes.inc"
+
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL) {                           \
+    return Visitor.Traverse##CLASS##TypeLoc(TL);                               \
+  }                                                                            \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
+    return Visitor.WalkUpFrom##CLASS##TypeLoc(TL);                             \
+  }                                                                            \
+  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) {                              \
+    return Visitor.Visit##CLASS##TypeLoc(TL);                                  \
+  }
+#include "clang/AST/TypeLocNodes.def"
+};
+} // namespace
+
+// Declared out of line to serve as a vtable anchor.
+DynamicRecursiveASTVisitor::~DynamicRecursiveASTVisitor() = default;
+
+bool DynamicRecursiveASTVisitor::TraverseAST(ASTContext &AST) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAST(AST);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseAttr(Attr *At) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAttr(At);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseConstructorInitializer(
+    CXXCtorInitializer *Init) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConstructorInitializer(
+      Init);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseDecl(Decl *D) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseDecl(D);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseStmt(Stmt *S,
+                                              DataRecursionQueue *Queue) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseStmt(S, Queue);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseTemplateArgument(
+    const TemplateArgument &Arg) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArgument(Arg);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseTemplateArguments(
+    ArrayRef<TemplateArgument> Args) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArguments(Args);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseTemplateName(TemplateName Template) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateName(Template);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseType(QualType T) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseType(T);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLoc TL) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeLoc(TL);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseTypeConstraint(
+    const TypeConstraint *C) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeConstraint(C);
+}
+bool DynamicRecursiveASTVisitor::TraverseConceptRequirement(
+    concepts::Requirement *R) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptRequirement(R);
+}
+bool DynamicRecursiveASTVisitor::TraverseConceptTypeRequirement(
+    concepts::TypeRequirement *R) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptTypeRequirement(
+      R);
+}
+bool DynamicRecursiveASTVisitor::TraverseConceptExprRequirement(
+    concepts::ExprRequirement *R) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptExprRequirement(
+      R);
+}
+bool DynamicRecursiveASTVisitor::TraverseConceptNestedRequirement(
+    concepts::NestedRequirement *R) {
+  return Impl(*this)
+      .RecursiveASTVisitor<Impl>::TraverseConceptNestedRequirement(R);
+}
+
+/*
+#define DYNAMIC_ATTR_VISITOR_IMPL
+#include "clang/AST/AttrVisitor.inc"
+#undef DYNAMIC_ATTR_VISITOR_IMPL
+*/
+
+// Declare Traverse*() for and friends all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  bool DynamicRecursiveASTVisitor::Traverse##CLASS##Decl(CLASS##Decl *D) {     \
+    return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##Decl(D);    \
+  }                                                                            \
+  bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {   \
+    return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##Decl(D);  \
+  }
+#include "clang/AST/DeclNodes.inc"
+
+// Declare Traverse*() and friends for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  bool DynamicRecursiveASTVisitor::Traverse##CLASS(CLASS *S) {                 \
+    return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS(S);          \
+  }                                                                            \
+  bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS(CLASS *S) {               \
+    return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS(S);        \
+  }
+#include "clang/AST/StmtNodes.inc"
+
+// Declare Traverse*() and friends for all concrete Typeclasses.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  bool DynamicRecursiveASTVisitor::Traverse##CLASS##Type(CLASS##Type *T) {     \
+    return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##Type(T);    \
+  }                                                                            \
+  bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Type(CLASS##Type *T) {   \
+    return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##Type(T);  \
+  }
+#include "clang/AST/TypeNodes.inc"
+
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  bool DynamicRecursiveASTVisitor::Traverse##CLASS##TypeLoc(                   \
+      CLASS##TypeLoc TL) {                                                     \
+    return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##TypeLoc(    \
+        TL);                                                                   \
+  }                                                                            \
+  bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##TypeLoc(                 \
+      CLASS##TypeLoc TL) {                                                     \
+    return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##TypeLoc(  \
+        TL);                                                                   \
+  }
+#include "clang/AST/TypeLocNodes.def"
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 631fd4e354927f..bc859293d52dba 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -19,11 +19,11 @@
 #include "clang/AST/ComparisonCategories.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
@@ -2511,10 +2511,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
   assert(FD->isImmediateEscalating() && !FD->isConsteval() &&
          "expected an immediate function");
   assert(FD->hasBody() && "expected the function to have a body");
-  struct ImmediateEscalatingExpressionsVisitor
-      : public RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor> {
-
-    using Base = RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor>;
+  struct ImmediateEscalatingExpressionsVisitor : DynamicRecursiveASTVisitor {
     Sema &SemaRef;
 
     const FunctionDecl *ImmediateFn;
@@ -2524,10 +2521,10 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
 
     ImmediateEscalatingExpressionsVisitor(Sema &SemaRef, FunctionDecl *FD)
         : SemaRef(SemaRef), ImmediateFn(FD),
-          ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) {}
-
-    bool shouldVisitImplicitCode() const { return true; }
-    bool shouldVisitLambdaBody() const { return false; }
+          ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) {
+      ShouldVisitImplicitCode = true;
+      ShouldVisitLambdaBody = false;
+    }
 
     void Diag(const Expr *E, const FunctionDecl *Fn, bool IsCall) {
       SourceLocation Loc = E->getBeginLoc();
@@ -2547,7 +2544,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
           << (CurrentInit && !CurrentInit->isWritten())
           << InitializedField << Range;
     }
-    bool TraverseCallExpr(CallExpr *E) {
+    bool TraverseCallExpr(CallExpr *E) override {
       if (const auto *DR =
               dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImplicit());
           DR && DR->isImmediateEscalating()) {
@@ -2556,13 +2553,13 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
       }
 
       for (Expr *A : E->arguments())
-        if (!getDerived().TraverseStmt(A))
+        if (!TraverseStmt(A))
           return false;
 
       return true;
     }
 
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
+    bool VisitDeclRefExpr(DeclRefExpr *E) override {
       if (const auto *ReferencedFn = dyn_cast<FunctionDecl>(E->getDecl());
           ReferencedFn && E->isImmediateEscalating()) {
         Diag(E, ReferencedFn, /*IsCall=*/false);
@@ -2572,7 +2569,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
       return true;
     }
 
-    bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+    bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
       CXXConstructorDecl *D = E->getConstructor();
       if (E->isImmediateEscalating()) {
         Diag(E, D, /*IsCall=*/true);
@@ -2581,18 +2578,18 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
       return true;
     }
 
-    bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+    bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
       llvm::SaveAndRestore RAII(CurrentInit, Init);
-      return Base::TraverseConstructorInitializer(Init);
+      return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
     }
 
-    bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) {
+    bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) override {
       llvm::SaveAndRestore RAII(CurrentConstructor, Ctr);
-      return Base::TraverseCXXConstructorDecl(Ctr);
+      return DynamicRecursiveASTVisitor::TraverseCXXConstructorDecl(Ctr);
     }
 
-    bool TraverseType(QualType T) { return true; }
-    bool VisitBlockExpr(BlockExpr *T) { return true; }
+    bool TraverseType(QualType T) override { return true; }
+    bool VisitBlockExpr(BlockExpr *T) override { return true; }
 
   } Visitor(*this, FD);
   Visitor.TraverseDecl(FD);
@@ -18876,18 +18873,18 @@ void Sema::CheckDelegatingCtorCycles() {
 
 namespace {
   /// AST visitor that finds references to the 'this' expression.
-  class FindCXXThisExpr : public RecursiveASTVisitor<FindCXXThisExpr> {
-    Sema &S;
+class FindCXXThisExpr : public DynamicRecursiveASTVisitor {
+  Sema &S;
 
-  public:
-    explicit FindCXXThisExpr(Sema &S) : S(S) { }
+public:
+  explicit FindCXXThisExpr(Sema &S) : S(S) {}
 
-    bool VisitCXXThisExpr(CXXThisExpr *E) {
-      S.Diag(E->getLocation(), diag::err_this_static_member_func)
+  bool VisitCXXThisExpr(CXXThisExpr *E) override {
+    S.Diag(E->getLocation(), diag::err_this_static_member_func)
         << E->isImplicit();
-      return false;
-    }
-  };
+    return false;
+  }
+};
 }
 
 bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fb4154757775bc..7c353df69ae179 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -26,7 +27,6 @@
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Builtins.h"
@@ -5443,32 +5443,33 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
   return false;
 }
 
-struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {
+struct ImmediateCallVisitor : DynamicRecursiveASTVisitor {
   const ASTContext &Context;
-  ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {}
+  ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {
+    ShouldVisitImplicitCode = true;
+  }
 
   bool HasImmediateCalls = false;
-  bool shouldVisitImplicitCode() const { return true; }
 
-  bool VisitCallExpr(CallExpr *E) {
+  bool VisitCallExpr(CallExpr *E) override {
     if (const FunctionDecl *FD = E->getDirectCallee())
       HasImmediateCalls |= FD->isImmediateFunction();
-    return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+    return DynamicRecursiveASTVisitor::VisitStmt(E);
   }
 
-  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+  bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
     if (const FunctionDecl *FD = E->getConstructor())
       HasImmediateCalls |= FD->isImmediateFunction();
-    return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+    return DynamicRecursiveASTVisitor::VisitStmt(E);
   }
 
   // SourceLocExpr are not immediate invocations
   // but CXXDefaultInitExpr/CXXDefaultArgExpr containing a SourceLocExpr
   // need to be rebuilt so that they refer to the correct SourceLocation and
   // DeclContext.
-  bool VisitSourceLocExpr(SourceLocExpr *E) {
+  bool VisitSourceLocExpr(SourceLocExpr *E) override {
     HasImmediateCalls = true;
-    return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+    return DynamicRecursiveASTVisitor::VisitStmt(E);
   }
 
   // A nested lambda might have parameters with immediate invocations
@@ -5477,15 +5478,15 @@ struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {
   // subexpression).
   // FIXME: We should consider visiting and transforming captures
   // with init expressions.
-  bool VisitLambdaExpr(LambdaExpr *E) {
+  bool VisitLambdaExpr(LambdaExpr *E) override {
     return VisitCXXMethodDecl(E->getCallOperator());
   }
 
-  bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
     return TraverseStmt(E->getExpr());
   }
 
-  bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
+  bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) override {
     return TraverseStmt(E->getExpr());
   }
 };
@@ -17604,10 +17605,10 @@ HandleImmediateInvocations(Sema &SemaRef,
         RemoveNestedImmediateInvocation(SemaRef, Rec, It);
   } else if (Rec.ImmediateInvocationCandidates.size() == 1 &&
              Rec.ReferenceToConsteval.size()) {
-    struct SimpleRemove : RecursiveASTVisitor<SimpleRemove> {
+    struct SimpleRemove : DynamicRecursiveASTVisitor {
       llvm::SmallPtrSetImpl<DeclRefExpr *> &DRSet;
       SimpleRemove(llvm::SmallPtrSetImpl<DeclRefExpr *> &S) : DRSet(S) {}
-      bool VisitDeclRefExpr(DeclRefExpr *E) {
+      bool VisitDeclRefExpr(DeclRefExpr *E) override {
         DRSet.erase(E);
         return DRSet.size();
       }
@@ -19898,17 +19899,15 @@ namespace {
   // TreeTransforms rebuilding the type in a new context. Rather than
   // duplicating the TreeTransform logic, we should consider reusing it here.
   // Currently that causes problems when rebuilding LambdaExprs.
-  class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
-    Sema &S;
-    SourceLocation Loc;
-
-  public:
-    typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited;
+class MarkReferencedDecls : public DynamicRecursiveASTVisitor {
+  Sema &S;
+  SourceLocation Loc;
 
-    MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
+public:
+  MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) {}
 
-    bool TraverseTemplateArgument(const TemplateArgument &Arg);
-  };
+  bool TraverseTemplateArgument(const TemplateArgument &Arg) override;
+};
 }
 
 bool MarkReferencedDecls::TraverseTemplateArgument(
@@ -19925,7 +19924,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument(
     }
   }
 
-  return Inherited::TraverseTemplateArgument(Arg);
+  return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
 }
 
 void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 4487c618862c5e..5e4508075d6187 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -18,10 +18,10 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/AlignedAllocation.h"
@@ -8716,13 +8716,13 @@ static ExprResult attemptRecovery(Sema &SemaRef,
 }
 
 namespace {
-class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> {
+class FindTypoExprs : public DynamicRecursiveASTVisitor {
   llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
 
 public:
   explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs)
       : TypoExprs(TypoExprs) {}
-  bool VisitTypoExpr(TypoExpr *TE) {
+  bool VisitTypoExpr(TypoExpr *TE) override {
     TypoExprs.insert(TE);
     return true;
   }
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 57465d4a77ac29..7349a92eecf171 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -16,11 +16,11 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/IgnoreExpr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/TypeLoc.h"
@@ -3662,15 +3662,15 @@ namespace {
 /// others. Pretend that all local typedefs are always referenced, to not warn
 /// on this. This isn't necessary if f has internal linkage, or the typedef
 /// is private.
-class LocalTypedefNameReferencer
-    : public RecursiveASTVisitor<LocalTypedefNameReferencer> {
+class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor {
 public:
   LocalTypedefNameReferencer(Sema &S) : S(S) {}
-  bool VisitRecordType(const RecordType *RT);
+  bool VisitRecordType(RecordType *RT) override;
+
 private:
   Sema &S;
 };
-bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) {
+bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
   auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());
   if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
       R->isDependentType())
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3e3ed77de710e5..0c8bffc6650b1f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -14,9 +14,9 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/Builtins.h"
@@ -2691,27 +2691,26 @@ struct ConvertConstructorToDeductionGuideTransform {
 SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
     ArrayRef<NamedDecl *> TemplateParams,
     ArrayRef<TemplateArgument> DeducedArgs) {
-  struct TemplateParamsReferencedFinder
-      : public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
+  struct TemplateParamsReferencedFinder : DynamicRecursiveASTVisitor {
     llvm::DenseSet<NamedDecl *> TemplateParams;
     llvm::DenseSet<const NamedDecl *> ReferencedTemplateParams;
 
     TemplateParamsReferencedFinder(ArrayRef<NamedDecl *> TemplateParams)
         : TemplateParams(TemplateParams.begin(), TemplateParams.end()) {}
 
-    bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
+    bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) override {
       MarkAppeared(TTP->getDecl());
       return true;
     }
-    bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+    bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
       MarkAppeared(DRE->getFoundDecl());
       return true;
     }
 
-    bool TraverseTemplateName(TemplateName Template) {
+    bool TraverseTemplateName(TemplateName Template) override {
       if (auto *TD = Template.getAsTemplateDecl())
         MarkAppeared(TD);
-      return RecursiveASTVisitor::TraverseTemplateName(Template);
+      return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
     }
 
     void MarkAppeared(NamedDecl *ND) {
@@ -3806,9 +3805,7 @@ namespace {
 
 /// A class which looks for a use of a certain level of template
 /// parameter.
-struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
-  typedef RecursiveASTVisitor<DependencyChecker> super;
-
+struct DependencyChecker : DynamicRecursiveASTVisitor {
   unsigned Depth;
 
   // Whether we're looking for a use of a template parameter that makes the
@@ -3846,7 +3843,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
     return false;
   }
 
-  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) {
+  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) override {
     // Prune out non-type-dependent expressions if requested. This can
     // sometimes result in us failing to find a template parameter reference
     // (if a value-dependent expression creates a dependent type), but this
@@ -3854,51 +3851,51 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
     if (auto *E = dyn_cast_or_null<Expr>(S))
       if (IgnoreNonTypeDependent && !E->isTypeDependent())
         return true;
-    return super::TraverseStmt(S, Q);
+    return DynamicRecursiveASTVisitor::TraverseStmt(S, Q);
   }
 
-  bool TraverseTypeLoc(TypeLoc TL) {
+  bool TraverseTypeLoc(TypeLoc TL) override {
     if (IgnoreNonTypeDependent && !TL.isNull() &&
         !TL.getType()->isDependentType())
       return true;
-    return super::TraverseTypeLoc(TL);
+    return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
   }
 
-  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
     return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc());
   }
 
-  bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
+  bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
     // For a best-effort search, keep looking until we find a location.
     return IgnoreNonTypeDependent || !Matches(T->getDepth());
   }
 
-  bool TraverseTemplateName(TemplateName N) {
+  bool TraverseTemplateName(TemplateName N) override {
     if (TemplateTemplateParmDecl *PD =
           dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl()))
       if (Matches(PD->getDepth()))
         return false;
-    return super::TraverseTemplateName(N);
+    return DynamicRecursiveASTVisitor::TraverseTemplateName(N);
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     if (NonTypeTemplateParmDecl *PD =
           dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
       if (Matches(PD->getDepth(), E->getExprLoc()))
         return false;
-    return super::VisitDeclRefExpr(E);
+    return DynamicRecursiveASTVisitor::VisitDeclRefExpr(E);
   }
 
-  bool VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+  bool VisitSubstTemplateTypeParmType(SubstTemplateTypeParmType *T) override {
     return TraverseType(T->getReplacementType());
   }
 
-  bool
-  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
+  bool VisitSubstTemplateTypeParmPackType(
+      SubstTemplateTypeParmPackType *T) override {
     return TraverseTemplateArgument(T->getArgumentPack());
   }
 
-  bool TraverseInjectedClassNameType(const InjectedClassNameType *T) {
+  bool TraverseInjectedClassNameType(InjectedClassNameType *T) override {
     return TraverseType(T->getInjectedSpecializationType());
   }
 };
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index ca7630adfbb7b5..23789027583bd8 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3822,7 +3822,7 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
   OS << "  return 0;\n";
 }
 
-// Emits code used by RecursiveASTVisitor to visit attributes
+// Emits code used by (Dynamic)RecursiveASTVisitor to visit attributes
 void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS,
                        Records);
@@ -3832,7 +3832,7 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
   // Write method declarations for Traverse* methods.
   // We emit this here because we only generate methods for attributes that
   // are declared as ASTNodes.
-  OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n";
+  OS << "#ifdef ATTR_VISITOR_DECLS\n\n";
   for (const auto *Attr : Attrs) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
@@ -3844,9 +3844,10 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
        << "    return true; \n"
        << "  }\n";
   }
-  OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n";
+  OS << "\n#endif // ATTR_VISITOR_DECLS\n\n";
 
   // Write individual Traverse* methods for each attribute class.
+  OS << "#ifdef ATTR_VISITOR_IMPL\n\n";
   for (const auto *Attr : Attrs) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
@@ -3892,7 +3893,40 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
   OS << "  }\n";  // end switch
   OS << "  llvm_unreachable(\"bad attribute kind\");\n";
   OS << "}\n";  // end function
-  OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
+  OS << "#endif  // ATTR_VISITOR_IMPL\n";
+
+  // Write virtual function declarations / trivial definitions.
+  OS << "#ifdef DYNAMIC_ATTR_VISITOR_DECLS\n\n";
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+    if (!R.getValueAsBit("ASTNode"))
+      continue;
+    OS << "  virtual bool Traverse" << R.getName() << "Attr(" << R.getName()
+       << "Attr *A);\n";
+    OS << "  virtual bool Visit" << R.getName() << "Attr(" << R.getName()
+       << "Attr *A) {\n"
+       << "    return true; \n"
+       << "  }\n";
+  }
+  OS << "\n#endif // DYNAMIC_ATTR_VISITOR_DECLS\n\n";
+
+  // Write traversal functions that dispatch to the appropriate visitor.
+  OS << "#ifdef DYNAMIC_ATTR_VISITOR_IMPL\n\n";
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+    if (!R.getValueAsBit("ASTNode"))
+      continue;
+    OS << "bool Impl::Traverse" << R.getName() << "Attr(" << R.getName()
+       << "Attr *A) {\n"
+       << "  return Visitor.Traverse" << R.getName() << "Attr(A);\n"
+       << "}\n";
+    OS << "bool DynamicRecursiveASTVisitor::Traverse" << R.getName() << "Attr("
+       << R.getName() << "Attr *A) {\n"
+       << "  return Impl(*this).RecursiveASTVisitor<Impl>::Traverse"
+       << R.getName() << "Attr(A);\n"
+       << "}\n";
+  }
+  OS << "\n#endif // DYNAMIC_ATTR_VISITOR_IMPL\n\n";
 }
 
 void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,

>From 5db2b4cafa8eb2d991ba0f337a47a0806f2dbc0f Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Thu, 6 Jun 2024 17:16:48 +0200
Subject: [PATCH 02/27] [Clang] CollectUnexpandedParameterPacksVisitor

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    |  35 ++
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  61 +++
 clang/lib/Sema/SemaTemplateVariadic.cpp       | 407 +++++++++---------
 3 files changed, 298 insertions(+), 205 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 58797d9e19fe43..bf9d91576f7b18 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -65,6 +65,12 @@ class DynamicRecursiveASTVisitor {
   /// \returns false if the visitation was terminated early, true otherwise.
   virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
 
+  /// Recursively visit a base specifier. This can be overridden by a
+  /// subclass.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
+
   /// Recursively visit a declaration, by dispatching to
   /// Traverse*Decl() based on the argument's dynamic type.
   ///
@@ -72,6 +78,29 @@ class DynamicRecursiveASTVisitor {
   /// otherwise (including when the argument is NULL).
   virtual bool TraverseDecl(Decl *D);
 
+  /// Recursively visit a name with its location information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+  /// Recursively visit a lambda capture. \c Init is the expression that
+  /// will be used to initialize the capture.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
+                                     Expr *Init);
+
+  /// Recursively visit a C++ nested-name-specifier.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// Recursively visit a C++ nested-name-specifier with location
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
   /// Recursively visit a statement or expression, by
   /// dispatching to Traverse*() based on the argument's dynamic type.
   ///
@@ -86,6 +115,12 @@ class DynamicRecursiveASTVisitor {
   // FIXME: migrate callers to TemplateArgumentLoc instead.
   virtual bool TraverseTemplateArgument(const TemplateArgument &Arg);
 
+  /// Recursively visit a template argument location and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
   /// Recursively visit a set of template arguments.
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index b9994f31a0730e..24c2a9dcfa0812 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -55,6 +55,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseTemplateArgument(Arg);
   }
 
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
+    return Visitor.TraverseTemplateArgumentLoc(ArgLoc);
+  }
+
   bool TraverseTemplateName(TemplateName Template) {
     return Visitor.TraverseTemplateName(Template);
   }
@@ -75,6 +79,27 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseConceptNestedRequirement(R);
   }
 
+  bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
+    return Visitor.TraverseCXXBaseSpecifier(Base);
+  }
+
+  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo) {
+    return Visitor.TraverseDeclarationNameInfo(NameInfo);
+  }
+
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
+                             Expr *Init) {
+    return Visitor.TraverseLambdaCapture(LE, C, Init);
+  }
+
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
+    return Visitor.TraverseNestedNameSpecifier(NNS);
+  }
+
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+    return Visitor.TraverseNestedNameSpecifierLoc(NNS);
+  }
+
   /// Visit a node.
   bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }
   bool VisitDecl(Decl *D) { return Visitor.VisitDecl(D); }
@@ -162,6 +187,13 @@ bool DynamicRecursiveASTVisitor::TraverseDecl(Decl *D) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseDecl(D);
 }
 
+bool DynamicRecursiveASTVisitor::TraverseLambdaCapture(LambdaExpr *LE,
+                                                       const LambdaCapture *C,
+                                                       Expr *Init) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseLambdaCapture(LE, C,
+                                                                      Init);
+}
+
 bool DynamicRecursiveASTVisitor::TraverseStmt(Stmt *S,
                                               DataRecursionQueue *Queue) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseStmt(S, Queue);
@@ -177,6 +209,12 @@ bool DynamicRecursiveASTVisitor::TraverseTemplateArguments(
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArguments(Args);
 }
 
+bool DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(
+    const TemplateArgumentLoc &ArgLoc) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArgumentLoc(
+      ArgLoc);
+}
+
 bool DynamicRecursiveASTVisitor::TraverseTemplateName(TemplateName Template) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateName(Template);
 }
@@ -213,6 +251,29 @@ bool DynamicRecursiveASTVisitor::TraverseConceptNestedRequirement(
       .RecursiveASTVisitor<Impl>::TraverseConceptNestedRequirement(R);
 }
 
+bool DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(
+    const CXXBaseSpecifier &Base) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseCXXBaseSpecifier(Base);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseDeclarationNameInfo(
+    DeclarationNameInfo NameInfo) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseDeclarationNameInfo(
+      NameInfo);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifier(
+    NestedNameSpecifier *NNS) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseNestedNameSpecifier(
+      NNS);
+}
+
+bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
+    NestedNameSpecifierLoc NNS) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseNestedNameSpecifierLoc(
+      NNS);
+}
+
 /*
 #define DYNAMIC_ATTR_VISITOR_IMPL
 #include "clang/AST/AttrVisitor.inc"
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 7a44b978aacdb7..f1ed39d816bf5b 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -8,14 +8,14 @@
 //  This file implements semantic analysis for C++0x variadic templates.
 //===----------------------------------------------------------------------===/
 
-#include "clang/Sema/Sema.h"
 #include "TypeLocBuilder.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
 #include <optional>
@@ -28,259 +28,256 @@ using namespace clang;
 
 namespace {
   /// A class that collects unexpanded parameter packs.
-  class CollectUnexpandedParameterPacksVisitor :
-    public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
-  {
-    typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
-      inherited;
-
-    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
-
-    bool InLambda = false;
-    unsigned DepthLimit = (unsigned)-1;
-
-    void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
-      if (auto *VD = dyn_cast<VarDecl>(ND)) {
-        // For now, the only problematic case is a generic lambda's templated
-        // call operator, so we don't need to look for all the other ways we
-        // could have reached a dependent parameter pack.
-        auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
-        auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
-        if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
-          return;
-      } else if (getDepthAndIndex(ND).first >= DepthLimit)
+class CollectUnexpandedParameterPacksVisitor
+    : public DynamicRecursiveASTVisitor {
+  SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
+
+  bool InLambda = false;
+  unsigned DepthLimit = (unsigned)-1;
+
+  void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
+    if (auto *VD = dyn_cast<VarDecl>(ND)) {
+      // For now, the only problematic case is a generic lambda's templated
+      // call operator, so we don't need to look for all the other ways we
+      // could have reached a dependent parameter pack.
+      auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
+      auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
+      if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
         return;
+    } else if (getDepthAndIndex(ND).first >= DepthLimit)
+      return;
 
-      Unexpanded.push_back({ND, Loc});
-    }
-    void addUnexpanded(const TemplateTypeParmType *T,
-                       SourceLocation Loc = SourceLocation()) {
-      if (T->getDepth() < DepthLimit)
-        Unexpanded.push_back({T, Loc});
-    }
+    Unexpanded.push_back({ND, Loc});
+  }
+  void addUnexpanded(const TemplateTypeParmType *T,
+                     SourceLocation Loc = SourceLocation()) {
+    if (T->getDepth() < DepthLimit)
+      Unexpanded.push_back({T, Loc});
+  }
 
-  public:
-    explicit CollectUnexpandedParameterPacksVisitor(
-        SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
-        : Unexpanded(Unexpanded) {}
+public:
+  explicit CollectUnexpandedParameterPacksVisitor(
+      SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
+      : Unexpanded(Unexpanded) {
+    ShouldWalkTypesOfTypeLocs = false;
+    ShouldVisitImplicitCode = true;
+  }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
+  //------------------------------------------------------------------------
+  // Recording occurrences of (unexpanded) parameter packs.
+  //------------------------------------------------------------------------
 
-    // We need this so we can find e.g. attributes on lambdas.
-    bool shouldVisitImplicitCode() const { return true; }
+  /// Record occurrences of template type parameter packs.
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
+    if (TL.getTypePtr()->isParameterPack())
+      addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
+    return true;
+  }
 
-    //------------------------------------------------------------------------
-    // Recording occurrences of (unexpanded) parameter packs.
-    //------------------------------------------------------------------------
+  /// Record occurrences of template type parameter packs
+  /// when we don't have proper source-location information for
+  /// them.
+  ///
+  /// Ideally, this routine would never be used.
+  bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
+    if (T->isParameterPack())
+      addUnexpanded(T);
 
-    /// Record occurrences of template type parameter packs.
-    bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
-      if (TL.getTypePtr()->isParameterPack())
-        addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
-      return true;
-    }
+    return true;
+  }
 
-    /// Record occurrences of template type parameter packs
-    /// when we don't have proper source-location information for
-    /// them.
-    ///
-    /// Ideally, this routine would never be used.
-    bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
-      if (T->isParameterPack())
-        addUnexpanded(T);
+  /// Record occurrences of function and non-type template
+  /// parameter packs in an expression.
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
+    if (E->getDecl()->isParameterPack())
+      addUnexpanded(E->getDecl(), E->getLocation());
 
-      return true;
+    return true;
+  }
+
+  /// Record occurrences of template template parameter packs.
+  bool TraverseTemplateName(TemplateName Template) override {
+    if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
+            Template.getAsTemplateDecl())) {
+      if (TTP->isParameterPack())
+        addUnexpanded(TTP);
     }
 
-    /// Record occurrences of function and non-type template
-    /// parameter packs in an expression.
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
-      if (E->getDecl()->isParameterPack())
-        addUnexpanded(E->getDecl(), E->getLocation());
+    return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
+  }
 
+  /// Suppress traversal into Objective-C container literal
+  /// elements that are pack expansions.
+  bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override {
+    if (!E->containsUnexpandedParameterPack())
       return true;
-    }
 
-    /// Record occurrences of template template parameter packs.
-    bool TraverseTemplateName(TemplateName Template) {
-      if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
-              Template.getAsTemplateDecl())) {
-        if (TTP->isParameterPack())
-          addUnexpanded(TTP);
-      }
+    for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
+      ObjCDictionaryElement Element = E->getKeyValueElement(I);
+      if (Element.isPackExpansion())
+        continue;
 
-      return inherited::TraverseTemplateName(Template);
+      TraverseStmt(Element.Key);
+      TraverseStmt(Element.Value);
     }
+    return true;
+  }
+  //------------------------------------------------------------------------
+  // Pruning the search for unexpanded parameter packs.
+  //------------------------------------------------------------------------
 
-    /// Suppress traversal into Objective-C container literal
-    /// elements that are pack expansions.
-    bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
-      if (!E->containsUnexpandedParameterPack())
-        return true;
+  /// Suppress traversal into statements and expressions that
+  /// do not contain unexpanded parameter packs.
+  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) override {
+    Expr *E = dyn_cast_or_null<Expr>(S);
+    if ((E && E->containsUnexpandedParameterPack()) || InLambda)
+      return DynamicRecursiveASTVisitor::TraverseStmt(S, Q);
 
-      for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
-        ObjCDictionaryElement Element = E->getKeyValueElement(I);
-        if (Element.isPackExpansion())
-          continue;
+    return true;
+  }
 
-        TraverseStmt(Element.Key);
-        TraverseStmt(Element.Value);
-      }
-      return true;
-    }
-    //------------------------------------------------------------------------
-    // Pruning the search for unexpanded parameter packs.
-    //------------------------------------------------------------------------
+  /// Suppress traversal into types that do not contain
+  /// unexpanded parameter packs.
+  bool TraverseType(QualType T) override {
+    if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
+      return DynamicRecursiveASTVisitor::TraverseType(T);
 
-    /// Suppress traversal into statements and expressions that
-    /// do not contain unexpanded parameter packs.
-    bool TraverseStmt(Stmt *S) {
-      Expr *E = dyn_cast_or_null<Expr>(S);
-      if ((E && E->containsUnexpandedParameterPack()) || InLambda)
-        return inherited::TraverseStmt(S);
+    return true;
+  }
 
-      return true;
-    }
+  /// Suppress traversal into types with location information
+  /// that do not contain unexpanded parameter packs.
+  bool TraverseTypeLoc(TypeLoc TL) override {
+    if ((!TL.getType().isNull() &&
+         TL.getType()->containsUnexpandedParameterPack()) ||
+        InLambda)
+      return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
 
-    /// Suppress traversal into types that do not contain
-    /// unexpanded parameter packs.
-    bool TraverseType(QualType T) {
-      if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
-        return inherited::TraverseType(T);
+    return true;
+  }
 
+  /// Suppress traversal of parameter packs.
+  bool TraverseDecl(Decl *D) override {
+    // A function parameter pack is a pack expansion, so cannot contain
+    // an unexpanded parameter pack. Likewise for a template parameter
+    // pack that contains any references to other packs.
+    if (D && D->isParameterPack())
       return true;
-    }
 
-    /// Suppress traversal into types with location information
-    /// that do not contain unexpanded parameter packs.
-    bool TraverseTypeLoc(TypeLoc TL) {
-      if ((!TL.getType().isNull() &&
-           TL.getType()->containsUnexpandedParameterPack()) ||
-          InLambda)
-        return inherited::TraverseTypeLoc(TL);
+    return DynamicRecursiveASTVisitor::TraverseDecl(D);
+  }
 
+  /// Suppress traversal of pack-expanded attributes.
+  bool TraverseAttr(Attr *A) override {
+    if (A->isPackExpansion())
       return true;
-    }
 
-    /// Suppress traversal of parameter packs.
-    bool TraverseDecl(Decl *D) {
-      // A function parameter pack is a pack expansion, so cannot contain
-      // an unexpanded parameter pack. Likewise for a template parameter
-      // pack that contains any references to other packs.
-      if (D && D->isParameterPack())
-        return true;
-
-      return inherited::TraverseDecl(D);
-    }
-
-    /// Suppress traversal of pack-expanded attributes.
-    bool TraverseAttr(Attr *A) {
-      if (A->isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseAttr(A);
+  }
 
-      return inherited::TraverseAttr(A);
-    }
+  /// Suppress traversal of pack expansion expressions and types.
+  ///@{
+  bool TraversePackExpansionType(PackExpansionType *T) override { return true; }
+  bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) override {
+    return true;
+  }
+  bool TraversePackExpansionExpr(PackExpansionExpr *E) override { return true; }
+  bool TraverseCXXFoldExpr(CXXFoldExpr *E) override { return true; }
+  bool TraversePackIndexingExpr(PackIndexingExpr *E) override {
+    return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
+  }
+  bool TraversePackIndexingType(PackIndexingType *E) override {
+    return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
+  }
+  bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) override {
+    return DynamicRecursiveASTVisitor::TraverseStmt(TL.getIndexExpr());
+  }
 
-    /// Suppress traversal of pack expansion expressions and types.
-    ///@{
-    bool TraversePackExpansionType(PackExpansionType *T) { return true; }
-    bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
-    bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
-    bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
-    bool TraversePackIndexingExpr(PackIndexingExpr *E) {
-      return inherited::TraverseStmt(E->getIndexExpr());
-    }
-    bool TraversePackIndexingType(PackIndexingType *E) {
-      return inherited::TraverseStmt(E->getIndexExpr());
-    }
-    bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) {
-      return inherited::TraverseStmt(TL.getIndexExpr());
-    }
+  ///@}
 
-    ///@}
+  /// Suppress traversal of using-declaration pack expansion.
+  bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) override {
+    if (D->isPackExpansion())
+      return true;
 
-    /// Suppress traversal of using-declaration pack expansion.
-    bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
-      if (D->isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingValueDecl(D);
+  }
 
-      return inherited::TraverseUnresolvedUsingValueDecl(D);
-    }
+  /// Suppress traversal of using-declaration pack expansion.
+  bool
+  TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) override {
+    if (D->isPackExpansion())
+      return true;
 
-    /// Suppress traversal of using-declaration pack expansion.
-    bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
-      if (D->isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingTypenameDecl(D);
+  }
 
-      return inherited::TraverseUnresolvedUsingTypenameDecl(D);
-    }
+  /// Suppress traversal of template argument pack expansions.
+  bool TraverseTemplateArgument(const TemplateArgument &Arg) override {
+    if (Arg.isPackExpansion())
+      return true;
 
-    /// Suppress traversal of template argument pack expansions.
-    bool TraverseTemplateArgument(const TemplateArgument &Arg) {
-      if (Arg.isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
+  }
 
-      return inherited::TraverseTemplateArgument(Arg);
-    }
+  /// Suppress traversal of template argument pack expansions.
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override {
+    if (ArgLoc.getArgument().isPackExpansion())
+      return true;
 
-    /// Suppress traversal of template argument pack expansions.
-    bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
-      if (ArgLoc.getArgument().isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(ArgLoc);
+  }
 
-      return inherited::TraverseTemplateArgumentLoc(ArgLoc);
-    }
+  /// Suppress traversal of base specifier pack expansions.
+  bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) override {
+    if (Base.isPackExpansion())
+      return true;
 
-    /// Suppress traversal of base specifier pack expansions.
-    bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
-      if (Base.isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(Base);
+  }
 
-      return inherited::TraverseCXXBaseSpecifier(Base);
-    }
+  /// Suppress traversal of mem-initializer pack expansions.
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
+    if (Init->isPackExpansion())
+      return true;
 
-    /// Suppress traversal of mem-initializer pack expansions.
-    bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
-      if (Init->isPackExpansion())
-        return true;
+    return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
+  }
 
-      return inherited::TraverseConstructorInitializer(Init);
-    }
+  /// Note whether we're traversing a lambda containing an unexpanded
+  /// parameter pack. In this case, the unexpanded pack can occur anywhere,
+  /// including all the places where we normally wouldn't look. Within a
+  /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
+  /// outside an expression.
+  bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
+    // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
+    // even if it's contained within another lambda.
+    if (!Lambda->containsUnexpandedParameterPack())
+      return true;
 
-    /// Note whether we're traversing a lambda containing an unexpanded
-    /// parameter pack. In this case, the unexpanded pack can occur anywhere,
-    /// including all the places where we normally wouldn't look. Within a
-    /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
-    /// outside an expression.
-    bool TraverseLambdaExpr(LambdaExpr *Lambda) {
-      // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
-      // even if it's contained within another lambda.
-      if (!Lambda->containsUnexpandedParameterPack())
-        return true;
+    bool WasInLambda = InLambda;
+    unsigned OldDepthLimit = DepthLimit;
 
-      bool WasInLambda = InLambda;
-      unsigned OldDepthLimit = DepthLimit;
+    InLambda = true;
+    if (auto *TPL = Lambda->getTemplateParameterList())
+      DepthLimit = TPL->getDepth();
 
-      InLambda = true;
-      if (auto *TPL = Lambda->getTemplateParameterList())
-        DepthLimit = TPL->getDepth();
+    DynamicRecursiveASTVisitor::TraverseLambdaExpr(Lambda);
 
-      inherited::TraverseLambdaExpr(Lambda);
+    InLambda = WasInLambda;
+    DepthLimit = OldDepthLimit;
+    return true;
+  }
 
-      InLambda = WasInLambda;
-      DepthLimit = OldDepthLimit;
+  /// Suppress traversal within pack expansions in lambda captures.
+  bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
+                             Expr *Init) override {
+    if (C->isPackExpansion())
       return true;
-    }
 
-    /// Suppress traversal within pack expansions in lambda captures.
-    bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
-                               Expr *Init) {
-      if (C->isPackExpansion())
-        return true;
-
-      return inherited::TraverseLambdaCapture(Lambda, C, Init);
-    }
-  };
+    return DynamicRecursiveASTVisitor::TraverseLambdaCapture(Lambda, C, Init);
+  }
+};
 }
 
 /// Determine whether it's possible for an unexpanded parameter pack to

>From ac15b6d005788cff0bbb5e393d43de916caead7f Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Thu, 6 Jun 2024 17:33:08 +0200
Subject: [PATCH 03/27] [Clang] CodeGen

---
 clang/lib/CodeGen/CGDebugInfo.cpp   | 21 ++++++++++-----------
 clang/lib/CodeGen/CodeGenModule.cpp | 21 ++++++++++-----------
 2 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 1713f7065e7a20..1451a28eeceec3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -24,9 +24,9 @@
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/VTableBuilder.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -5364,10 +5364,9 @@ static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args) {
     case TemplateArgument::Pack:
       return ReferencesAnonymousEntity(TA.getPackAsArray());
     case TemplateArgument::Type: {
-      struct ReferencesAnonymous
-          : public RecursiveASTVisitor<ReferencesAnonymous> {
+      struct ReferencesAnonymous : DynamicRecursiveASTVisitor {
         bool RefAnon = false;
-        bool VisitRecordType(RecordType *RT) {
+        bool VisitRecordType(RecordType *RT) override {
           if (ReferencesAnonymousEntity(RT)) {
             RefAnon = true;
             return false;
@@ -5388,17 +5387,17 @@ static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args) {
   });
 }
 namespace {
-struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
+struct ReconstitutableType : DynamicRecursiveASTVisitor {
   bool Reconstitutable = true;
-  bool VisitVectorType(VectorType *FT) {
+  bool VisitVectorType(VectorType *FT) override {
     Reconstitutable = false;
     return false;
   }
-  bool VisitAtomicType(AtomicType *FT) {
+  bool VisitAtomicType(AtomicType *FT) override {
     Reconstitutable = false;
     return false;
   }
-  bool VisitType(Type *T) {
+  bool VisitType(Type *T) override {
     // _BitInt(N) isn't reconstitutable because the bit width isn't encoded in
     // the DWARF, only the byte width.
     if (T->isBitIntType()) {
@@ -5407,7 +5406,7 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
     }
     return true;
   }
-  bool TraverseEnumType(EnumType *ET) {
+  bool TraverseEnumType(EnumType *ET) override {
     // Unnamed enums can't be reconstituted due to a lack of column info we
     // produce in the DWARF, so we can't get Clang's full name back.
     if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
@@ -5422,13 +5421,13 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
     }
     return true;
   }
-  bool VisitFunctionProtoType(FunctionProtoType *FT) {
+  bool VisitFunctionProtoType(FunctionProtoType *FT) override {
     // noexcept is not encoded in DWARF, so the reversi
     Reconstitutable &= !isNoexceptExceptionSpec(FT->getExceptionSpecType());
     Reconstitutable &= !FT->getNoReturnAttr();
     return Reconstitutable;
   }
-  bool VisitRecordType(RecordType *RT) {
+  bool VisitRecordType(RecordType *RT) override {
     if (ReferencesAnonymousEntity(RT)) {
       Reconstitutable = false;
       return false;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c2314c3a57d330..fd229b67ea724a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -34,8 +34,8 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/CharInfo.h"
@@ -3890,13 +3890,12 @@ namespace {
   };
 
   // Make sure we're not referencing non-imported vars or functions.
-  struct DLLImportFunctionVisitor
-      : public RecursiveASTVisitor<DLLImportFunctionVisitor> {
+  struct DLLImportFunctionVisitor : DynamicRecursiveASTVisitor {
     bool SafeToInline = true;
 
-    bool shouldVisitImplicitCode() const { return true; }
+    DLLImportFunctionVisitor() { ShouldVisitImplicitCode = true; }
 
-    bool VisitVarDecl(VarDecl *VD) {
+    bool VisitVarDecl(VarDecl *VD) override {
       if (VD->getTLSKind()) {
         // A thread-local variable cannot be imported.
         SafeToInline = false;
@@ -3910,13 +3909,13 @@ namespace {
       return SafeToInline;
     }
 
-    bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+    bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) override {
       if (const auto *D = E->getTemporary()->getDestructor())
         SafeToInline = D->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
 
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
+    bool VisitDeclRefExpr(DeclRefExpr *E) override {
       ValueDecl *VD = E->getDecl();
       if (isa<FunctionDecl>(VD))
         SafeToInline = VD->hasAttr<DLLImportAttr>();
@@ -3925,12 +3924,12 @@ namespace {
       return SafeToInline;
     }
 
-    bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+    bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
       SafeToInline = E->getConstructor()->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
 
-    bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+    bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) override {
       CXXMethodDecl *M = E->getMethodDecl();
       if (!M) {
         // Call through a pointer to member function. This is safe to inline.
@@ -3941,12 +3940,12 @@ namespace {
       return SafeToInline;
     }
 
-    bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+    bool VisitCXXDeleteExpr(CXXDeleteExpr *E) override {
       SafeToInline = E->getOperatorDelete()->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
 
-    bool VisitCXXNewExpr(CXXNewExpr *E) {
+    bool VisitCXXNewExpr(CXXNewExpr *E) override {
       SafeToInline = E->getOperatorNew()->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }

>From 5b65237e559c0c0369dd37c2ddc1768d67205608 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Thu, 6 Jun 2024 18:25:19 +0200
Subject: [PATCH 04/27] [Clang] Separate Traverse() and friends

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 10 ++++++++--
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  | 20 +++++++++++++++----
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index bf9d91576f7b18..01567237ba7cb4 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -184,7 +184,10 @@ class DynamicRecursiveASTVisitor {
   // Declare Traverse*() and friends for all concrete Stmt classes.
 #define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                                                    \
-  virtual bool Traverse##CLASS(CLASS *S);                                      \
+  virtual bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+
+#define STMT(CLASS, PARENT)                                                    \
   virtual bool WalkUpFrom##CLASS(CLASS *S);                                    \
   virtual bool Visit##CLASS(CLASS *S) { return true; }
 #include "clang/AST/StmtNodes.inc"
@@ -199,7 +202,10 @@ class DynamicRecursiveASTVisitor {
 
 #define ABSTRACT_TYPELOC(CLASS, BASE)
 #define TYPELOC(CLASS, BASE)                                                   \
-  virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);                    \
+  virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+
+#define TYPELOC(CLASS, BASE)                                                   \
   virtual bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL);                  \
   virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
 #include "clang/AST/TypeLocNodes.def"
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index 24c2a9dcfa0812..52bfea86d4cc30 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -132,7 +132,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
 
 #define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                                                    \
-  bool Traverse##CLASS(CLASS *S) { return Visitor.Traverse##CLASS(S); }        \
+  bool Traverse##CLASS(CLASS *S) { return Visitor.Traverse##CLASS(S); }
+#include "clang/AST/StmtNodes.inc"
+
+#define STMT(CLASS, PARENT)                                                    \
   bool WalkUpFrom##CLASS(CLASS *S) { return Visitor.WalkUpFrom##CLASS(S); }    \
   bool Visit##CLASS(CLASS *S) { return Visitor.Visit##CLASS(S); }
 #include "clang/AST/StmtNodes.inc"
@@ -155,7 +158,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
 #define TYPELOC(CLASS, BASE)                                                   \
   bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL) {                           \
     return Visitor.Traverse##CLASS##TypeLoc(TL);                               \
-  }                                                                            \
+  }
+#include "clang/AST/TypeLocNodes.def"
+
+#define TYPELOC(CLASS, BASE)                                                   \
   bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
     return Visitor.WalkUpFrom##CLASS##TypeLoc(TL);                             \
   }                                                                            \
@@ -296,7 +302,10 @@ bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
 #define STMT(CLASS, PARENT)                                                    \
   bool DynamicRecursiveASTVisitor::Traverse##CLASS(CLASS *S) {                 \
     return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS(S);          \
-  }                                                                            \
+  }
+#include "clang/AST/StmtNodes.inc"
+
+#define STMT(CLASS, PARENT)                                                    \
   bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS(CLASS *S) {               \
     return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS(S);        \
   }
@@ -319,7 +328,10 @@ bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
       CLASS##TypeLoc TL) {                                                     \
     return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##TypeLoc(    \
         TL);                                                                   \
-  }                                                                            \
+  }
+#include "clang/AST/TypeLocNodes.def"
+
+#define TYPELOC(CLASS, BASE)                                                   \
   bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##TypeLoc(                 \
       CLASS##TypeLoc TL) {                                                     \
     return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##TypeLoc(  \

>From 79ff93d59ef56c293a622e6a48afd2dc185c1d40 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Thu, 6 Jun 2024 19:49:17 +0200
Subject: [PATCH 05/27] [Clang] Migrate most of ARCMigrate

---
 clang/lib/ARCMigrate/ObjCMT.cpp               | 113 +++++++++---------
 clang/lib/ARCMigrate/TransAPIUses.cpp         |   4 +-
 clang/lib/ARCMigrate/TransARCAssign.cpp       |   4 +-
 clang/lib/ARCMigrate/TransAutoreleasePool.cpp |  13 +-
 .../lib/ARCMigrate/TransBlockObjCVariable.cpp |  18 ++-
 .../TransEmptyStatementsAndDealloc.cpp        |   7 +-
 clang/lib/ARCMigrate/TransGCAttrs.cpp         |  16 ++-
 clang/lib/ARCMigrate/TransGCCalls.cpp         |   8 +-
 clang/lib/ARCMigrate/TransProtectedScope.cpp  |   8 +-
 .../ARCMigrate/TransZeroOutPropsInDealloc.cpp |  21 ++--
 clang/lib/ARCMigrate/Transforms.cpp           |  48 ++++----
 clang/lib/ARCMigrate/Transforms.h             |   1 +
 12 files changed, 127 insertions(+), 134 deletions(-)

diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 4357c8e3f09a55..4164e452059307 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -308,67 +308,68 @@ namespace {
     return true;
   }
 
-class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
-  ObjCMigrateASTConsumer &Consumer;
-  ParentMap &PMap;
-
-public:
-  ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
-    : Consumer(consumer), PMap(PMap) { }
-
-  bool shouldVisitTemplateInstantiations() const { return false; }
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) {
-      edit::Commit commit(*Consumer.Editor);
-      edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
-      Consumer.Editor->commit(commit);
+  class ObjCMigrator : public DynamicRecursiveASTVisitor {
+    ObjCMigrateASTConsumer &Consumer;
+    ParentMap &PMap;
+
+  public:
+    ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
+        : Consumer(consumer), PMap(PMap) {
+      ShouldVisitTemplateInstantiations = false;
+      ShouldWalkTypesOfTypeLocs = false;
     }
 
-    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) {
-      edit::Commit commit(*Consumer.Editor);
-      edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
-      Consumer.Editor->commit(commit);
-    }
+    bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
+      if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) {
+        edit::Commit commit(*Consumer.Editor);
+        edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
+        Consumer.Editor->commit(commit);
+      }
 
-    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_PropertyDotSyntax) {
-      edit::Commit commit(*Consumer.Editor);
-      rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj,
-                                 commit, &PMap);
-      Consumer.Editor->commit(commit);
-    }
+      if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) {
+        edit::Commit commit(*Consumer.Editor);
+        edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
+        Consumer.Editor->commit(commit);
+      }
 
-    return true;
-  }
+      if (Consumer.ASTMigrateActions &
+          FrontendOptions::ObjCMT_PropertyDotSyntax) {
+        edit::Commit commit(*Consumer.Editor);
+        rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj, commit,
+                                   &PMap);
+        Consumer.Editor->commit(commit);
+      }
 
-  bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
-    // Do depth first; we want to rewrite the subexpressions first so that if
-    // we have to move expressions we will move them already rewritten.
-    for (Stmt *SubStmt : E->children())
-      if (!TraverseStmt(SubStmt))
-        return false;
+      return true;
+    }
 
-    return WalkUpFromObjCMessageExpr(E);
-  }
-};
+    bool TraverseObjCMessageExpr(ObjCMessageExpr *E) override {
+      // Do depth first; we want to rewrite the subexpressions first so that if
+      // we have to move expressions we will move them already rewritten.
+      for (Stmt *SubStmt : E->children())
+        if (!TraverseStmt(SubStmt))
+          return false;
 
-class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
-  ObjCMigrateASTConsumer &Consumer;
-  std::unique_ptr<ParentMap> PMap;
+      return WalkUpFromObjCMessageExpr(E);
+    }
+  };
 
-public:
-  BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
+  class BodyMigrator : public DynamicRecursiveASTVisitor {
+    ObjCMigrateASTConsumer &Consumer;
+    std::unique_ptr<ParentMap> PMap;
 
-  bool shouldVisitTemplateInstantiations() const { return false; }
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+  public:
+    BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) {
+      ShouldVisitTemplateInstantiations = false;
+      ShouldWalkTypesOfTypeLocs = false;
+    }
 
-  bool TraverseStmt(Stmt *S) {
-    PMap.reset(new ParentMap(S));
-    ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
-    return true;
-  }
-};
+    bool TraverseStmt(Stmt *S, DataRecursionQueue * = nullptr) override {
+      PMap.reset(new ParentMap(S));
+      ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
+      return true;
+    }
+  };
 } // end anonymous namespace
 
 void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
@@ -1671,12 +1672,14 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
 }
 
 namespace {
-class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
+class SuperInitChecker : public DynamicRecursiveASTVisitor {
 public:
-  bool shouldVisitTemplateInstantiations() const { return false; }
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+  SuperInitChecker() {
+    ShouldVisitTemplateInstantiations = false;
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
       if (E->getMethodFamily() == OMF_init)
         return false;
diff --git a/clang/lib/ARCMigrate/TransAPIUses.cpp b/clang/lib/ARCMigrate/TransAPIUses.cpp
index 8f5d4f4bde06ca..4525aa8718d890 100644
--- a/clang/lib/ARCMigrate/TransAPIUses.cpp
+++ b/clang/lib/ARCMigrate/TransAPIUses.cpp
@@ -27,7 +27,7 @@ using namespace trans;
 
 namespace {
 
-class APIChecker : public RecursiveASTVisitor<APIChecker> {
+class APIChecker : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
   Selector getReturnValueSel, setReturnValueSel;
@@ -51,7 +51,7 @@ class APIChecker : public RecursiveASTVisitor<APIChecker> {
     zoneSel = sels.getNullarySelector(&ids.get("zone"));
   }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     // NSInvocation.
     if (E->isInstanceMessage() &&
         E->getReceiverInterface() &&
diff --git a/clang/lib/ARCMigrate/TransARCAssign.cpp b/clang/lib/ARCMigrate/TransARCAssign.cpp
index d1d5b9e014b17a..672d9b7865d805 100644
--- a/clang/lib/ARCMigrate/TransARCAssign.cpp
+++ b/clang/lib/ARCMigrate/TransARCAssign.cpp
@@ -31,14 +31,14 @@ using namespace trans;
 
 namespace {
 
-class ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> {
+class ARCAssignChecker : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
   llvm::DenseSet<VarDecl *> ModifiedVars;
 
 public:
   ARCAssignChecker(MigrationPass &pass) : Pass(pass) { }
 
-  bool VisitBinaryOperator(BinaryOperator *Exp) {
+  bool VisitBinaryOperator(BinaryOperator *Exp) override {
     if (Exp->getType()->isDependentType())
       return true;
 
diff --git a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
index 6d501228e712b2..03dba2b20f95e9 100644
--- a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -39,7 +39,7 @@ using namespace trans;
 
 namespace {
 
-class ReleaseCollector : public RecursiveASTVisitor<ReleaseCollector> {
+class ReleaseCollector : public DynamicRecursiveASTVisitor {
   Decl *Dcl;
   SmallVectorImpl<ObjCMessageExpr *> &Releases;
 
@@ -47,7 +47,7 @@ class ReleaseCollector : public RecursiveASTVisitor<ReleaseCollector> {
   ReleaseCollector(Decl *D, SmallVectorImpl<ObjCMessageExpr *> &releases)
     : Dcl(D), Releases(releases) { }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     if (!E->isInstanceMessage())
       return true;
     if (E->getMethodFamily() != OMF_release)
@@ -60,7 +60,6 @@ class ReleaseCollector : public RecursiveASTVisitor<ReleaseCollector> {
     return true;
   }
 };
-
 }
 
 namespace {
@@ -245,7 +244,7 @@ class AutoreleasePoolRewriter
     }
   };
 
-  class NameReferenceChecker : public RecursiveASTVisitor<NameReferenceChecker>{
+  class NameReferenceChecker : public DynamicRecursiveASTVisitor {
     ASTContext &Ctx;
     SourceRange ScopeRange;
     SourceLocation &referenceLoc, &declarationLoc;
@@ -260,15 +259,15 @@ class AutoreleasePoolRewriter
                                (*scope.End)->getBeginLoc());
     }
 
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
+    bool VisitDeclRefExpr(DeclRefExpr *E) override {
       return checkRef(E->getLocation(), E->getDecl()->getLocation());
     }
 
-    bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    bool VisitTypedefTypeLoc(TypedefTypeLoc TL) override {
       return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation());
     }
 
-    bool VisitTagTypeLoc(TagTypeLoc TL) {
+    bool VisitTagTypeLoc(TagTypeLoc TL) override {
       return checkRef(TL.getBeginLoc(), TL.getDecl()->getLocation());
     }
 
diff --git a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 1e4db33135b6a1..3d4e34952a1798 100644
--- a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -36,18 +36,16 @@ using namespace trans;
 
 namespace {
 
-class RootBlockObjCVarRewriter :
-                          public RecursiveASTVisitor<RootBlockObjCVarRewriter> {
+class RootBlockObjCVarRewriter : public DynamicRecursiveASTVisitor {
   llvm::DenseSet<VarDecl *> &VarsToChange;
 
-  class BlockVarChecker : public RecursiveASTVisitor<BlockVarChecker> {
+  class BlockVarChecker : public DynamicRecursiveASTVisitor {
     VarDecl *Var;
 
-    typedef RecursiveASTVisitor<BlockVarChecker> base;
   public:
     BlockVarChecker(VarDecl *var) : Var(var) { }
 
-    bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) {
+    bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) override {
       if (DeclRefExpr *
             ref = dyn_cast<DeclRefExpr>(castE->getSubExpr())) {
         if (ref->getDecl() == Var) {
@@ -59,10 +57,10 @@ class RootBlockObjCVarRewriter :
         }
       }
 
-      return base::TraverseImplicitCastExpr(castE);
+      return DynamicRecursiveASTVisitor::TraverseImplicitCastExpr(castE);
     }
 
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
+    bool VisitDeclRefExpr(DeclRefExpr *E) override {
       if (E->getDecl() == Var)
         return false; // The reference of the variable, and not just its value,
                       //  is needed.
@@ -74,7 +72,7 @@ class RootBlockObjCVarRewriter :
   RootBlockObjCVarRewriter(llvm::DenseSet<VarDecl *> &VarsToChange)
     : VarsToChange(VarsToChange) { }
 
-  bool VisitBlockDecl(BlockDecl *block) {
+  bool VisitBlockDecl(BlockDecl *block) override {
     SmallVector<VarDecl *, 4> BlockVars;
 
     for (const auto &I : block->captures()) {
@@ -108,14 +106,14 @@ class RootBlockObjCVarRewriter :
   }
 };
 
-class BlockObjCVarRewriter : public RecursiveASTVisitor<BlockObjCVarRewriter> {
+class BlockObjCVarRewriter : public DynamicRecursiveASTVisitor {
   llvm::DenseSet<VarDecl *> &VarsToChange;
 
 public:
   BlockObjCVarRewriter(llvm::DenseSet<VarDecl *> &VarsToChange)
     : VarsToChange(VarsToChange) { }
 
-  bool TraverseBlockDecl(BlockDecl *block) {
+  bool TraverseBlockDecl(BlockDecl *block) override {
     RootBlockObjCVarRewriter(VarsToChange).TraverseDecl(block);
     return true;
   }
diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index e9c21b8106d7dd..51c07a1d4fc4ab 100644
--- a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -143,14 +143,13 @@ class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
   }
 };
 
-class EmptyStatementsRemover :
-                            public RecursiveASTVisitor<EmptyStatementsRemover> {
+class EmptyStatementsRemover : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
 public:
   EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { }
 
-  bool TraverseStmtExpr(StmtExpr *E) {
+  bool TraverseStmtExpr(StmtExpr *E) override {
     CompoundStmt *S = E->getSubStmt();
     for (CompoundStmt::body_iterator
            I = S->body_begin(), E = S->body_end(); I != E; ++I) {
@@ -161,7 +160,7 @@ class EmptyStatementsRemover :
     return true;
   }
 
-  bool VisitCompoundStmt(CompoundStmt *S) {
+  bool VisitCompoundStmt(CompoundStmt *S) override {
     for (auto *I : S->body())
       check(I);
     return true;
diff --git a/clang/lib/ARCMigrate/TransGCAttrs.cpp b/clang/lib/ARCMigrate/TransGCAttrs.cpp
index 85e3fe77660b5c..f4cc0d839e495e 100644
--- a/clang/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/clang/lib/ARCMigrate/TransGCAttrs.cpp
@@ -23,26 +23,24 @@ using namespace trans;
 namespace {
 
 /// Collects all the places where GC attributes __strong/__weak occur.
-class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
+class GCAttrsCollector : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
   bool FullyMigratable;
   std::vector<ObjCPropertyDecl *> &AllProps;
 
-  typedef RecursiveASTVisitor<GCAttrsCollector> base;
 public:
   GCAttrsCollector(MigrationContext &ctx,
                    std::vector<ObjCPropertyDecl *> &AllProps)
-    : MigrateCtx(ctx), FullyMigratable(false),
-      AllProps(AllProps) { }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+      : MigrateCtx(ctx), FullyMigratable(false), AllProps(AllProps) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-  bool VisitAttributedTypeLoc(AttributedTypeLoc TL) {
+  bool VisitAttributedTypeLoc(AttributedTypeLoc TL) override {
     handleAttr(TL);
     return true;
   }
 
-  bool TraverseDecl(Decl *D) {
+  bool TraverseDecl(Decl *D) override {
     if (!D || D->isImplicit())
       return true;
 
@@ -54,7 +52,7 @@ class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
     } else if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
       lookForAttribute(DD, DD->getTypeSourceInfo());
     }
-    return base::TraverseDecl(D);
+    return DynamicRecursiveASTVisitor::TraverseDecl(D);
   }
 
   void lookForAttribute(Decl *D, TypeSourceInfo *TInfo) {
diff --git a/clang/lib/ARCMigrate/TransGCCalls.cpp b/clang/lib/ARCMigrate/TransGCCalls.cpp
index 43233e2d0b456a..1da686cd7ec8c2 100644
--- a/clang/lib/ARCMigrate/TransGCCalls.cpp
+++ b/clang/lib/ARCMigrate/TransGCCalls.cpp
@@ -17,8 +17,7 @@ using namespace trans;
 
 namespace {
 
-class GCCollectableCallsChecker :
-                         public RecursiveASTVisitor<GCCollectableCallsChecker> {
+class GCCollectableCallsChecker : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
   IdentifierInfo *NSMakeCollectableII;
   IdentifierInfo *CFMakeCollectableII;
@@ -29,11 +28,10 @@ class GCCollectableCallsChecker :
     IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
     NSMakeCollectableII = &Ids.get("NSMakeCollectable");
     CFMakeCollectableII = &Ids.get("CFMakeCollectable");
+    ShouldWalkTypesOfTypeLocs = false;
   }
 
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-  bool VisitCallExpr(CallExpr *E) {
+  bool VisitCallExpr(CallExpr *E) override {
     TransformActions &TA = MigrateCtx.Pass.TA;
 
     if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
diff --git a/clang/lib/ARCMigrate/TransProtectedScope.cpp b/clang/lib/ARCMigrate/TransProtectedScope.cpp
index 154e0b54800f99..b6d4b1b7c771ae 100644
--- a/clang/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/clang/lib/ARCMigrate/TransProtectedScope.cpp
@@ -23,14 +23,14 @@ using namespace trans;
 
 namespace {
 
-class LocalRefsCollector : public RecursiveASTVisitor<LocalRefsCollector> {
+class LocalRefsCollector : public DynamicRecursiveASTVisitor {
   SmallVectorImpl<DeclRefExpr *> &Refs;
 
 public:
   LocalRefsCollector(SmallVectorImpl<DeclRefExpr *> &refs)
     : Refs(refs) { }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     if (ValueDecl *D = E->getDecl())
       if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
         Refs.push_back(E);
@@ -52,7 +52,7 @@ struct CaseInfo {
     : SC(S), Range(Range), State(St_Unchecked) {}
 };
 
-class CaseCollector : public RecursiveASTVisitor<CaseCollector> {
+class CaseCollector : public DynamicRecursiveASTVisitor {
   ParentMap &PMap;
   SmallVectorImpl<CaseInfo> &Cases;
 
@@ -60,7 +60,7 @@ class CaseCollector : public RecursiveASTVisitor<CaseCollector> {
   CaseCollector(ParentMap &PMap, SmallVectorImpl<CaseInfo> &Cases)
     : PMap(PMap), Cases(Cases) { }
 
-  bool VisitSwitchStmt(SwitchStmt *S) {
+  bool VisitSwitchStmt(SwitchStmt *S) override {
     SwitchCase *Curr = S->getSwitchCaseList();
     if (!Curr)
       return true;
diff --git a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 81e67628fb1f46..ea87b9288de13e 100644
--- a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -22,10 +22,7 @@ using namespace trans;
 
 namespace {
 
-class ZeroOutInDeallocRemover :
-                           public RecursiveASTVisitor<ZeroOutInDeallocRemover> {
-  typedef RecursiveASTVisitor<ZeroOutInDeallocRemover> base;
-
+class ZeroOutInDeallocRemover : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
   llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties;
@@ -39,7 +36,7 @@ class ZeroOutInDeallocRemover :
         Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize"));
   }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) override {
     ASTContext &Ctx = Pass.Ctx;
     TransformActions &TA = Pass.TA;
 
@@ -78,7 +75,7 @@ class ZeroOutInDeallocRemover :
     return true;
   }
 
-  bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
+  bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) override {
     if (isZeroingPropIvar(POE) && isRemovable(POE)) {
       Transaction Trans(Pass.TA);
       Pass.TA.removeStmt(POE);
@@ -87,7 +84,7 @@ class ZeroOutInDeallocRemover :
     return true;
   }
 
-  bool VisitBinaryOperator(BinaryOperator *BOE) {
+  bool VisitBinaryOperator(BinaryOperator *BOE) override {
     if (isZeroingPropIvar(BOE) && isRemovable(BOE)) {
       Transaction Trans(Pass.TA);
       Pass.TA.removeStmt(BOE);
@@ -96,7 +93,7 @@ class ZeroOutInDeallocRemover :
     return true;
   }
 
-  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
+  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) override {
     if (D->getMethodFamily() != OMF_dealloc &&
         !(D->isInstanceMethod() && D->getSelector() == FinalizeSel))
       return true;
@@ -128,7 +125,7 @@ class ZeroOutInDeallocRemover :
     }
 
     // Now, remove all zeroing of ivars etc.
-    base::TraverseObjCMethodDecl(D);
+    DynamicRecursiveASTVisitor::TraverseObjCMethodDecl(D);
 
     // clear out for next method.
     SynthesizedProperties.clear();
@@ -137,9 +134,9 @@ class ZeroOutInDeallocRemover :
     return true;
   }
 
-  bool TraverseFunctionDecl(FunctionDecl *D) { return true; }
-  bool TraverseBlockDecl(BlockDecl *block) { return true; }
-  bool TraverseBlockExpr(BlockExpr *block) { return true; }
+  bool TraverseFunctionDecl(FunctionDecl *D) override { return true; }
+  bool TraverseBlockDecl(BlockDecl *block) override { return true; }
+  bool TraverseBlockExpr(BlockExpr *block) override { return true; }
 
 private:
   bool isRemovable(Expr *E) const {
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index fda0e1c932fc0e..4c35bcda2c15da 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -211,14 +211,17 @@ StringRef trans::getNilString(MigrationPass &Pass) {
 
 namespace {
 
-class ReferenceClear : public RecursiveASTVisitor<ReferenceClear> {
+class ReferenceClear : public DynamicRecursiveASTVisitor {
   ExprSet &Refs;
 public:
   ReferenceClear(ExprSet &refs) : Refs(refs) { }
-  bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; }
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
+    Refs.erase(E);
+    return true;
+  }
 };
 
-class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
+class ReferenceCollector : public DynamicRecursiveASTVisitor {
   ValueDecl *Dcl;
   ExprSet &Refs;
 
@@ -226,23 +229,22 @@ class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
   ReferenceCollector(ValueDecl *D, ExprSet &refs)
     : Dcl(D), Refs(refs) { }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     if (E->getDecl() == Dcl)
       Refs.insert(E);
     return true;
   }
 };
 
-class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
+class RemovablesCollector : public DynamicRecursiveASTVisitor {
   ExprSet &Removables;
 
 public:
-  RemovablesCollector(ExprSet &removables)
-  : Removables(removables) { }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+  RemovablesCollector(ExprSet &removables) : Removables(removables) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-  bool TraverseStmtExpr(StmtExpr *E) {
+  bool TraverseStmtExpr(StmtExpr *E) override {
     CompoundStmt *S = E->getSubStmt();
     for (CompoundStmt::body_iterator
         I = S->body_begin(), E = S->body_end(); I != E; ++I) {
@@ -253,29 +255,29 @@ class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
     return true;
   }
 
-  bool VisitCompoundStmt(CompoundStmt *S) {
+  bool VisitCompoundStmt(CompoundStmt *S) override {
     for (auto *I : S->body())
       mark(I);
     return true;
   }
 
-  bool VisitIfStmt(IfStmt *S) {
+  bool VisitIfStmt(IfStmt *S) override {
     mark(S->getThen());
     mark(S->getElse());
     return true;
   }
 
-  bool VisitWhileStmt(WhileStmt *S) {
+  bool VisitWhileStmt(WhileStmt *S) override {
     mark(S->getBody());
     return true;
   }
 
-  bool VisitDoStmt(DoStmt *S) {
+  bool VisitDoStmt(DoStmt *S) override {
     mark(S->getBody());
     return true;
   }
 
-  bool VisitForStmt(ForStmt *S) {
+  bool VisitForStmt(ForStmt *S) override {
     mark(S->getInit());
     mark(S->getInc());
     mark(S->getBody());
@@ -315,26 +317,25 @@ void trans::collectRemovables(Stmt *S, ExprSet &exprs) {
 
 namespace {
 
-class ASTTransform : public RecursiveASTVisitor<ASTTransform> {
+class ASTTransform : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
-  typedef RecursiveASTVisitor<ASTTransform> base;
 
 public:
-  ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+  ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-  bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
+  bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) override {
     ObjCImplementationContext ImplCtx(MigrateCtx, D);
     for (MigrationContext::traverser_iterator
            I = MigrateCtx.traversers_begin(),
            E = MigrateCtx.traversers_end(); I != E; ++I)
       (*I)->traverseObjCImplementation(ImplCtx);
 
-    return base::TraverseObjCImplementationDecl(D);
+    return DynamicRecursiveASTVisitor::TraverseObjCImplementationDecl(D);
   }
 
-  bool TraverseStmt(Stmt *rootS) {
+  bool TraverseStmt(Stmt *rootS, DataRecursionQueue * = nullptr) override {
     if (!rootS)
       return true;
 
@@ -347,7 +348,6 @@ class ASTTransform : public RecursiveASTVisitor<ASTTransform> {
     return true;
   }
 };
-
 }
 
 MigrationContext::~MigrationContext() {
diff --git a/clang/lib/ARCMigrate/Transforms.h b/clang/lib/ARCMigrate/Transforms.h
index 37e2d6b2a7e12f..07de28e3b3e3d7 100644
--- a/clang/lib/ARCMigrate/Transforms.h
+++ b/clang/lib/ARCMigrate/Transforms.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
 #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
 
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "llvm/ADT/DenseSet.h"

>From 8133eac3a56bd0bc839b4db33b3df7122886f34a Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 10 Jun 2024 20:09:28 +0200
Subject: [PATCH 06/27] Disable post-order traversal and overriding WalkUpFromX

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 23 ++++++++++---------
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  | 20 +---------------
 2 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 01567237ba7cb4..00cf3da6656362 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -10,6 +10,10 @@ class ASTContext;
 
 /// Recursive AST visitor that supports extension via dynamic dispatch.
 ///
+/// This only supports some of the more common visitation operations; in
+/// particular, it does not support overriding WalkUpFromX or post-order
+/// traversal.
+///
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
 public:
@@ -29,9 +33,6 @@ class DynamicRecursiveASTVisitor {
   /// Whether this visitor should recurse into lambda body
   bool ShouldVisitLambdaBody = true;
 
-  /// Return whether this visitor should traverse post-order.
-  bool ShouldTraversePostOrder = false;
-
 protected:
   DynamicRecursiveASTVisitor() = default;
 
@@ -163,10 +164,10 @@ class DynamicRecursiveASTVisitor {
   virtual bool VisitTypeLoc(TypeLoc TL) { return true; }
 
   /// Walk up from a node.
-  virtual bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); }
-  virtual bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); }
-  virtual bool WalkUpFromType(Type *T) { return VisitType(T); }
-  virtual bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
+  bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); }
+  bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); }
+  bool WalkUpFromType(Type *T) { return VisitType(T); }
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
 
   /*// Declare Traverse*() and friends for attributes.
 #define DYNAMIC_ATTR_VISITOR_DECLS
@@ -177,7 +178,7 @@ class DynamicRecursiveASTVisitor {
 #define ABSTRACT_DECL(DECL)
 #define DECL(CLASS, BASE)                                                      \
   virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);                          \
-  virtual bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D);                        \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D);                                \
   virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
 #include "clang/AST/DeclNodes.inc"
 
@@ -188,7 +189,7 @@ class DynamicRecursiveASTVisitor {
 #include "clang/AST/StmtNodes.inc"
 
 #define STMT(CLASS, PARENT)                                                    \
-  virtual bool WalkUpFrom##CLASS(CLASS *S);                                    \
+  bool WalkUpFrom##CLASS(CLASS *S);                                            \
   virtual bool Visit##CLASS(CLASS *S) { return true; }
 #include "clang/AST/StmtNodes.inc"
 
@@ -196,7 +197,7 @@ class DynamicRecursiveASTVisitor {
 #define ABSTRACT_TYPE(CLASS, BASE)
 #define TYPE(CLASS, BASE)                                                      \
   virtual bool Traverse##CLASS##Type(CLASS##Type *T);                          \
-  virtual bool WalkUpFrom##CLASS##Type(CLASS##Type *T);                        \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T);                                \
   virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
 #include "clang/AST/TypeNodes.inc"
 
@@ -206,7 +207,7 @@ class DynamicRecursiveASTVisitor {
 #include "clang/AST/TypeLocNodes.def"
 
 #define TYPELOC(CLASS, BASE)                                                   \
-  virtual bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL);                  \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL);                          \
   virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
 #include "clang/AST/TypeLocNodes.def"
 };
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index 52bfea86d4cc30..c4bb1b4b0debd9 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -34,9 +34,7 @@ struct Impl : RecursiveASTVisitor<Impl> {
 
   bool shouldVisitLambdaBody() const { return Visitor.ShouldVisitLambdaBody; }
 
-  bool shouldTraversePostOrder() const {
-    return Visitor.ShouldTraversePostOrder;
-  }
+  bool shouldTraversePostOrder() const { return false; }
 
   bool TraverseAST(ASTContext &AST) { return Visitor.TraverseAST(AST); }
   bool TraverseAttr(Attr *At) { return Visitor.TraverseAttr(At); }
@@ -107,12 +105,6 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool VisitType(Type *T) { return Visitor.VisitType(T); }
   bool VisitTypeLoc(TypeLoc TL) { return Visitor.VisitTypeLoc(TL); }
 
-  /// Walk up from a node.
-  bool WalkUpFromDecl(Decl *D) { return Visitor.WalkUpFromDecl(D); }
-  bool WalkUpFromStmt(Stmt *S) { return Visitor.WalkUpFromStmt(S); }
-  bool WalkUpFromType(Type *T) { return Visitor.WalkUpFromType(T); }
-  bool WalkUpFromTypeLoc(TypeLoc TL) { return Visitor.WalkUpFromTypeLoc(TL); }
-
   /*#define ATTR_VISITOR_DECLS
   #include "clang/AST/AttrVisitor.inc"
   #undef ATTR_VISITOR_DECLS*/
@@ -122,9 +114,6 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool Traverse##CLASS##Decl(CLASS##Decl *D) {                                 \
     return Visitor.Traverse##CLASS##Decl(D);                                   \
   }                                                                            \
-  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
-    return Visitor.WalkUpFrom##CLASS##Decl(D);                                 \
-  }                                                                            \
   bool Visit##CLASS##Decl(CLASS##Decl *D) {                                    \
     return Visitor.Visit##CLASS##Decl(D);                                      \
   }
@@ -136,7 +125,6 @@ struct Impl : RecursiveASTVisitor<Impl> {
 #include "clang/AST/StmtNodes.inc"
 
 #define STMT(CLASS, PARENT)                                                    \
-  bool WalkUpFrom##CLASS(CLASS *S) { return Visitor.WalkUpFrom##CLASS(S); }    \
   bool Visit##CLASS(CLASS *S) { return Visitor.Visit##CLASS(S); }
 #include "clang/AST/StmtNodes.inc"
 
@@ -146,9 +134,6 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool Traverse##CLASS##Type(CLASS##Type *T) {                                 \
     return Visitor.Traverse##CLASS##Type(T);                                   \
   }                                                                            \
-  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
-    return Visitor.WalkUpFrom##CLASS##Type(T);                                 \
-  }                                                                            \
   bool Visit##CLASS##Type(CLASS##Type *T) {                                    \
     return Visitor.Visit##CLASS##Type(T);                                      \
   }
@@ -162,9 +147,6 @@ struct Impl : RecursiveASTVisitor<Impl> {
 #include "clang/AST/TypeLocNodes.def"
 
 #define TYPELOC(CLASS, BASE)                                                   \
-  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
-    return Visitor.WalkUpFrom##CLASS##TypeLoc(TL);                             \
-  }                                                                            \
   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) {                              \
     return Visitor.Visit##CLASS##TypeLoc(TL);                                  \
   }

>From 9a48ed0852e225e430c3a72e84088726ecd8e0c8 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 1 Jul 2024 16:44:06 +0200
Subject: [PATCH 07/27] Enable overriding Visit for abstract nodes

---
 clang/include/clang/AST/DynamicRecursiveASTVisitor.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 00cf3da6656362..c2903b76268598 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -176,8 +176,11 @@ class DynamicRecursiveASTVisitor {
 
   // Declare Traverse*() for and friends all concrete Decl classes.
 #define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+  virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+
 #define DECL(CLASS, BASE)                                                      \
-  virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);                          \
   bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D);                                \
   virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
 #include "clang/AST/DeclNodes.inc"
@@ -196,7 +199,10 @@ class DynamicRecursiveASTVisitor {
   // Declare Traverse*() and friends for all concrete Type classes.
 #define ABSTRACT_TYPE(CLASS, BASE)
 #define TYPE(CLASS, BASE)                                                      \
-  virtual bool Traverse##CLASS##Type(CLASS##Type *T);                          \
+  virtual bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.inc"
+
+#define TYPE(CLASS, BASE)                                                      \
   bool WalkUpFrom##CLASS##Type(CLASS##Type *T);                                \
   virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
 #include "clang/AST/TypeNodes.inc"

>From 8e5616ce722eadae4a0b47f4ad50c56b5d4632db Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 1 Jul 2024 17:30:47 +0200
Subject: [PATCH 08/27] Migrate more visitors in Sema

---
 clang/include/clang/Analysis/CallGraph.h | 15 ++++-----
 clang/lib/AST/ASTImporterLookupTable.cpp |  2 ++
 clang/lib/AST/StmtOpenACC.cpp            |  8 ++---
 clang/lib/Analysis/CallGraph.cpp         |  3 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp | 34 +++++++++----------
 clang/lib/Sema/SemaAvailability.cpp      | 42 +++++++++++++-----------
 clang/lib/Sema/SemaCodeComplete.cpp      | 16 ++++-----
 clang/lib/Sema/SemaDeclAttr.cpp          |  9 +++--
 clang/lib/Sema/SemaDeclObjC.cpp          |  9 +++--
 clang/lib/Sema/SemaHLSL.cpp              |  9 +++--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 14 ++++----
 11 files changed, 79 insertions(+), 82 deletions(-)

diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h
index 78f8d115550178..891c4c750011d2 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -18,7 +18,8 @@
 #define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
 
 #include "clang/AST/Decl.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/STLExtras.h"
@@ -39,7 +40,7 @@ class Stmt;
 /// The call graph extends itself with the given declarations by implementing
 /// the recursive AST visitor, which constructs the graph by visiting the given
 /// declarations.
-class CallGraph : public RecursiveASTVisitor<CallGraph> {
+class CallGraph : public DynamicRecursiveASTVisitor {
   friend class CallGraphNode;
 
   using FunctionMapTy =
@@ -109,7 +110,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
 
   /// Part of recursive declaration visitation. We recursively visit all the
   /// declarations to collect the root functions.
-  bool VisitFunctionDecl(FunctionDecl *FD) {
+  bool VisitFunctionDecl(FunctionDecl *FD) override {
     // We skip function template definitions, as their semantics is
     // only determined when they are instantiated.
     if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
@@ -124,7 +125,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
   }
 
   /// Part of recursive declaration visitation.
-  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override {
     if (includeInGraph(MD)) {
       addNodesForBlocks(MD);
       addNodeForDecl(MD, true);
@@ -133,11 +134,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
   }
 
   // We are only collecting the declarations, so do not step into the bodies.
-  bool TraverseStmt(Stmt *S) { return true; }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const { return true; }
+  bool TraverseStmt(Stmt *S, DataRecursionQueue*) override { return true; }
 
 private:
   /// Add the given declaration to the call graph.
diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp
index 07d39dcee2583a..307c03404e0121 100644
--- a/clang/lib/AST/ASTImporterLookupTable.cpp
+++ b/clang/lib/AST/ASTImporterLookupTable.cpp
@@ -20,6 +20,8 @@ namespace clang {
 
 namespace {
 
+// FIXME: This breaks if we try to use a dynamic visitor,
+// and I have no idea why.
 struct Builder : RecursiveASTVisitor<Builder> {
   ASTImporterLookupTable <
   Builder(ASTImporterLookupTable &LT) : LT(LT) {}
diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp
index 2d864a28857966..fbf0ef540eb685 100644
--- a/clang/lib/AST/StmtOpenACC.cpp
+++ b/clang/lib/AST/StmtOpenACC.cpp
@@ -12,7 +12,7 @@
 
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 using namespace clang;
 
@@ -44,17 +44,17 @@ OpenACCComputeConstruct *OpenACCComputeConstruct::Create(
 }
 
 void OpenACCComputeConstruct::findAndSetChildLoops() {
-  struct LoopConstructFinder : RecursiveASTVisitor<LoopConstructFinder> {
+  struct LoopConstructFinder : DynamicRecursiveASTVisitor {
     OpenACCComputeConstruct *Construct = nullptr;
 
     LoopConstructFinder(OpenACCComputeConstruct *Construct)
         : Construct(Construct) {}
 
-    bool TraverseOpenACCComputeConstruct(OpenACCComputeConstruct *C) {
+    bool TraverseOpenACCComputeConstruct(OpenACCComputeConstruct *C) override {
       // Stop searching if we find a compute construct.
       return true;
     }
-    bool TraverseOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
+    bool TraverseOpenACCLoopConstruct(OpenACCLoopConstruct *C) override {
       // Stop searching if we find a loop construct, after taking ownership of
       // it.
       C->setParentComputeConstruct(Construct);
diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp
index f892980ed31386..958dbfec426344 100644
--- a/clang/lib/Analysis/CallGraph.cpp
+++ b/clang/lib/Analysis/CallGraph.cpp
@@ -148,6 +148,9 @@ void CallGraph::addNodesForBlocks(DeclContext *D) {
 
 CallGraph::CallGraph() {
   Root = getOrInsertNode(nullptr);
+  ShouldWalkTypesOfTypeLocs = false;
+  ShouldVisitTemplateInstantiations = true;
+  ShouldVisitImplicitCode = true;
 }
 
 CallGraph::~CallGraph() = default;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 0f604c61fa3af9..b2b563759ea88d 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -22,7 +22,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -1067,11 +1067,12 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
 }
 
 namespace {
-  class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
+  class FallthroughMapper : public DynamicRecursiveASTVisitor {
   public:
     FallthroughMapper(Sema &S)
       : FoundSwitchStatements(false),
         S(S) {
+      ShouldWalkTypesOfTypeLocs = false;
     }
 
     bool foundSwitchStatements() const { return FoundSwitchStatements; }
@@ -1186,26 +1187,23 @@ namespace {
       return !!UnannotatedCnt;
     }
 
-    // RecursiveASTVisitor setup.
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-    bool VisitAttributedStmt(AttributedStmt *S) {
+    bool VisitAttributedStmt(AttributedStmt *S) override {
       if (asFallThroughAttr(S))
         FallthroughStmts.insert(S);
       return true;
     }
 
-    bool VisitSwitchStmt(SwitchStmt *S) {
+    bool VisitSwitchStmt(SwitchStmt *S) override {
       FoundSwitchStatements = true;
       return true;
     }
 
     // We don't want to traverse local type declarations. We analyze their
     // methods separately.
-    bool TraverseDecl(Decl *D) { return true; }
+    bool TraverseDecl(Decl *D) override { return true; }
 
     // We analyze lambda bodies separately. Skip them here.
-    bool TraverseLambdaExpr(LambdaExpr *LE) {
+    bool TraverseLambdaExpr(LambdaExpr *LE) override {
       // Traverse the captures, but not the body.
       for (const auto C : zip(LE->captures(), LE->capture_inits()))
         TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
@@ -2463,15 +2461,18 @@ static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
 
 // An AST Visitor that calls a callback function on each callable DEFINITION
 // that is NOT in a dependent context:
-class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
+class CallableVisitor : public DynamicRecursiveASTVisitor {
 private:
   llvm::function_ref<void(const Decl *)> Callback;
 
 public:
   CallableVisitor(llvm::function_ref<void(const Decl *)> Callback)
-      : Callback(Callback) {}
+      : Callback(Callback) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = false;
+  }
 
-  bool VisitFunctionDecl(FunctionDecl *Node) {
+  bool VisitFunctionDecl(FunctionDecl *Node) override {
     if (cast<DeclContext>(Node)->isDependentContext())
       return true; // Not to analyze dependent decl
     // `FunctionDecl->hasBody()` returns true if the function has a body
@@ -2482,14 +2483,14 @@ class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
     return true;
   }
 
-  bool VisitBlockDecl(BlockDecl *Node) {
+  bool VisitBlockDecl(BlockDecl *Node) override {
     if (cast<DeclContext>(Node)->isDependentContext())
       return true; // Not to analyze dependent decl
     Callback(Node);
     return true;
   }
 
-  bool VisitObjCMethodDecl(ObjCMethodDecl *Node) {
+  bool VisitObjCMethodDecl(ObjCMethodDecl *Node) override {
     if (cast<DeclContext>(Node)->isDependentContext())
       return true; // Not to analyze dependent decl
     if (Node->hasBody())
@@ -2497,12 +2498,9 @@ class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
     return true;
   }
 
-  bool VisitLambdaExpr(LambdaExpr *Node) {
+  bool VisitLambdaExpr(LambdaExpr *Node) override {
     return VisitFunctionDecl(Node->getCallOperator());
   }
-
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const { return false; }
 };
 
 void clang::sema::AnalysisBasedWarnings::IssueWarnings(
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index fed1c68d4d33a9..a365466c24d19e 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -12,8 +12,9 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/StmtObjC.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
@@ -710,11 +711,11 @@ bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) {
   }
 }
 
-class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
+class StmtUSEFinder : public DynamicRecursiveASTVisitor {
   const Stmt *Target;
 
 public:
-  bool VisitStmt(Stmt *S) { return S != Target; }
+  bool VisitStmt(Stmt *S) override { return S != Target; }
 
   /// Returns true if the given statement is present in the given declaration.
   static bool isContained(const Stmt *Target, const Decl *D) {
@@ -726,11 +727,11 @@ class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
 
 /// Traverses the AST and finds the last statement that used a given
 /// declaration.
-class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
+class LastDeclUSEFinder : public DynamicRecursiveASTVisitor {
   const Decl *D;
 
 public:
-  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
     if (DRE->getDecl() == D)
       return false;
     return true;
@@ -754,10 +755,7 @@ class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
 /// to a partially available declaration. Whenever we encounter an \c if of the
 /// form: \c if(@available(...)), we use the version from the condition to visit
 /// the then statement.
-class DiagnoseUnguardedAvailability
-    : public RecursiveASTVisitor<DiagnoseUnguardedAvailability> {
-  typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base;
-
+class DiagnoseUnguardedAvailability : public DynamicRecursiveASTVisitor {
   Sema &SemaRef;
   Decl *Ctx;
 
@@ -775,26 +773,30 @@ class DiagnoseUnguardedAvailability
         SemaRef.Context.getTargetInfo().getPlatformMinVersion());
   }
 
-  bool TraverseStmt(Stmt *S) {
+  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
     if (!S)
       return true;
     StmtStack.push_back(S);
-    bool Result = Base::TraverseStmt(S);
+    bool Result = DynamicRecursiveASTVisitor::TraverseStmt(S);
     StmtStack.pop_back();
     return Result;
   }
 
   void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
 
-  bool TraverseIfStmt(IfStmt *If);
+  bool TraverseIfStmt(IfStmt *If) override;
 
   // for 'case X:' statements, don't bother looking at the 'X'; it can't lead
   // to any useful diagnostics.
-  bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); }
+  bool TraverseCaseStmt(CaseStmt *CS) override {
+    return TraverseStmt(CS->getSubStmt());
+  }
 
-  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { return true; }
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) override {
+    return true;
+  }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
     if (ObjCMethodDecl *D = Msg->getMethodDecl()) {
       ObjCInterfaceDecl *ID = nullptr;
       QualType ReceiverTy = Msg->getClassReceiver();
@@ -807,25 +809,25 @@ class DiagnoseUnguardedAvailability
     return true;
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
     DiagnoseDeclAvailability(DRE->getDecl(),
                              SourceRange(DRE->getBeginLoc(), DRE->getEndLoc()));
     return true;
   }
 
-  bool VisitMemberExpr(MemberExpr *ME) {
+  bool VisitMemberExpr(MemberExpr *ME) override {
     DiagnoseDeclAvailability(ME->getMemberDecl(),
                              SourceRange(ME->getBeginLoc(), ME->getEndLoc()));
     return true;
   }
 
-  bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+  bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) override {
     SemaRef.Diag(E->getBeginLoc(), diag::warn_at_available_unchecked_use)
         << (!SemaRef.getLangOpts().ObjC);
     return true;
   }
 
-  bool VisitTypeLoc(TypeLoc Ty);
+  bool VisitTypeLoc(TypeLoc Ty) override;
 };
 
 void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
@@ -990,7 +992,7 @@ bool DiagnoseUnguardedAvailability::TraverseIfStmt(IfStmt *If) {
       return TraverseStmt(If->getThen()) && TraverseStmt(If->getElse());
   } else {
     // This isn't an availability checking 'if', we can just continue.
-    return Base::TraverseIfStmt(If);
+    return DynamicRecursiveASTVisitor::TraverseIfStmt(If);
   }
 
   AvailabilityStack.push_back(CondVersion);
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index cd1c5f9391ccd4..1bbcf468ddf7c2 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -22,7 +22,7 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/QualTypeNames.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/AttributeCommonInfo.h"
 #include "clang/Basic/CharInfo.h"
@@ -5426,7 +5426,7 @@ class ConceptInfo {
 
   // This visitor infers members of T based on traversing expressions/types
   // that involve T. It is invoked with code known to be valid for T.
-  class ValidVisitor : public RecursiveASTVisitor<ValidVisitor> {
+  class ValidVisitor : public DynamicRecursiveASTVisitor {
     ConceptInfo *Outer;
     const TemplateTypeParmType *T;
 
@@ -5444,7 +5444,7 @@ class ConceptInfo {
     }
 
     // In T.foo or T->foo, `foo` is a member function/variable.
-    bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+    bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
       const Type *Base = E->getBaseType().getTypePtr();
       bool IsArrow = E->isArrow();
       if (Base->isPointerType() && IsArrow) {
@@ -5457,14 +5457,14 @@ class ConceptInfo {
     }
 
     // In T::foo, `foo` is a static member function/variable.
-    bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+    bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override {
       if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T))
         addValue(E, E->getDeclName(), Member::Colons);
       return true;
     }
 
     // In T::typename foo, `foo` is a type.
-    bool VisitDependentNameType(DependentNameType *DNT) {
+    bool VisitDependentNameType(DependentNameType *DNT) override {
       const auto *Q = DNT->getQualifier();
       if (Q && isApprox(Q->getAsType(), T))
         addType(DNT->getIdentifier());
@@ -5473,7 +5473,7 @@ class ConceptInfo {
 
     // In T::foo::bar, `foo` must be a type.
     // VisitNNS() doesn't exist, and TraverseNNS isn't always called :-(
-    bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) {
+    bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) override {
       if (NNSL) {
         NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier();
         const auto *Q = NNS->getPrefix();
@@ -5481,14 +5481,14 @@ class ConceptInfo {
           addType(NNS->getAsIdentifier());
       }
       // FIXME: also handle T::foo<X>::bar
-      return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
+      return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
     }
 
     // FIXME also handle T::foo<X>
 
     // Track the innermost caller/callee relationship so we can tell if a
     // nested expr is being called as a function.
-    bool VisitCallExpr(CallExpr *CE) {
+    bool VisitCallExpr(CallExpr *CE) override {
       Caller = CE;
       Callee = CE->getCallee();
       return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b8842e9003e101..636b1b045ba76e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -20,7 +20,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Cuda.h"
@@ -730,8 +730,7 @@ static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
 namespace {
 /// Determines if a given Expr references any of the given function's
 /// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
-class ArgumentDependenceChecker
-    : public RecursiveASTVisitor<ArgumentDependenceChecker> {
+class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor {
 #ifndef NDEBUG
   const CXXRecordDecl *ClassType;
 #endif
@@ -755,14 +754,14 @@ class ArgumentDependenceChecker
     return Result;
   }
 
-  bool VisitCXXThisExpr(CXXThisExpr *E) {
+  bool VisitCXXThisExpr(CXXThisExpr *E) override {
     assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
            "`this` doesn't refer to the enclosing class?");
     Result = true;
     return false;
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
     if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
       if (Parms.count(PVD)) {
         Result = true;
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 807453400abdd0..4d0be8ff41daca 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
@@ -5320,8 +5320,7 @@ SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
 namespace {
 /// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property
 /// accessor references the backing ivar.
-class UnusedBackingIvarChecker
-    : public RecursiveASTVisitor<UnusedBackingIvarChecker> {
+class UnusedBackingIvarChecker : public DynamicRecursiveASTVisitor {
 public:
   Sema &S;
   const ObjCMethodDecl *Method;
@@ -5336,7 +5335,7 @@ class UnusedBackingIvarChecker
     assert(IvarD);
   }
 
-  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) override {
     if (E->getDecl() == IvarD) {
       AccessedIvar = true;
       return false;
@@ -5344,7 +5343,7 @@ class UnusedBackingIvarChecker
     return true;
   }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     if (E->getReceiverKind() == ObjCMessageExpr::Instance &&
         S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) {
       InvokedSelfMethod = true;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index eebe17a5b4bf72..31cc2674a02c0f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -11,7 +11,7 @@
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TargetInfo.h"
@@ -530,8 +530,7 @@ namespace {
 /// and of all exported functions, and any functions that are referenced
 /// from this AST. In other words, any functions that are reachable from
 /// the entry points.
-class DiagnoseHLSLAvailability
-    : public RecursiveASTVisitor<DiagnoseHLSLAvailability> {
+class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
 
   Sema &SemaRef;
 
@@ -634,14 +633,14 @@ class DiagnoseHLSLAvailability
   void RunOnTranslationUnit(const TranslationUnitDecl *TU);
   void RunOnFunction(const FunctionDecl *FD);
 
-  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
     FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(DRE->getDecl());
     if (FD)
       HandleFunctionOrMethodRef(FD, DRE);
     return true;
   }
 
-  bool VisitMemberExpr(MemberExpr *ME) {
+  bool VisitMemberExpr(MemberExpr *ME) override {
     FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(ME->getMemberDecl());
     if (FD)
       HandleFunctionOrMethodRef(FD, ME);
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index a432918cbf5e20..5a1cca32e7f900 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -23,7 +23,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
@@ -6459,8 +6459,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
 }
 
 namespace {
-struct MarkUsedTemplateParameterVisitor :
-    RecursiveASTVisitor<MarkUsedTemplateParameterVisitor> {
+struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
   llvm::SmallBitVector &Used;
   unsigned Depth;
 
@@ -6468,23 +6467,22 @@ struct MarkUsedTemplateParameterVisitor :
                                    unsigned Depth)
       : Used(Used), Depth(Depth) { }
 
-  bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
+  bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
     if (T->getDepth() == Depth)
       Used[T->getIndex()] = true;
     return true;
   }
 
-  bool TraverseTemplateName(TemplateName Template) {
+  bool TraverseTemplateName(TemplateName Template) override {
     if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
             Template.getAsTemplateDecl()))
       if (TTP->getDepth() == Depth)
         Used[TTP->getIndex()] = true;
-    RecursiveASTVisitor<MarkUsedTemplateParameterVisitor>::
-        TraverseTemplateName(Template);
+    DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
     return true;
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
       if (NTTP->getDepth() == Depth)
         Used[NTTP->getIndex()] = true;

>From 9f17945ff8030d78986545e9edeb861aa82709d7 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 1 Jul 2024 21:01:24 +0200
Subject: [PATCH 09/27] Migrate more visitors in the AST library

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 12 ++++++++
 .../clang/Analysis/FlowSensitive/ASTOps.h     | 28 +++++++++----------
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  8 ++++++
 clang/lib/Analysis/FlowSensitive/ASTOps.cpp   | 15 +++++-----
 .../FlowSensitive/DataflowEnvironment.cpp     | 10 +++----
 5 files changed, 46 insertions(+), 27 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index c2903b76268598..cb7fe93a5b76b5 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -14,6 +14,12 @@ class ASTContext;
 /// particular, it does not support overriding WalkUpFromX or post-order
 /// traversal.
 ///
+/// Features that are currently not supported:
+///
+///   - Visiting attributes
+///   - Post-order traversal
+///   - Overriding WalkUpFromX
+///
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
 public:
@@ -149,6 +155,12 @@ class DynamicRecursiveASTVisitor {
   /// otherwise (including when the argument is a Null type location).
   virtual bool TraverseTypeLoc(TypeLoc TL);
 
+  /// Recursively visit an Objective-C protocol reference with location
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
+
   /// Traverse a concept (requirement).
   virtual bool TraverseTypeConstraint(const TypeConstraint *C);
   virtual bool TraverseConceptRequirement(concepts::Requirement *R);
diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index 925b99af9141a3..2a359e8c69d366 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -15,7 +15,7 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Analysis/FlowSensitive/StorageLocation.h"
 #include "llvm/ADT/DenseSet.h"
@@ -88,14 +88,14 @@ class RecordInitListHelper {
 /// the function to analyze. Don't call `TraverseDecl()` on the function itself;
 /// this won't work as `TraverseDecl()` contains code to avoid traversing nested
 /// functions.
-template <class Derived>
-class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
+class AnalysisASTVisitor : public DynamicRecursiveASTVisitor {
 public:
-  bool shouldVisitImplicitCode() { return true; }
-
-  bool shouldVisitLambdaBody() const { return false; }
+  AnalysisASTVisitor() {
+    ShouldVisitImplicitCode = true;
+    ShouldVisitLambdaBody = false;
+  }
 
-  bool TraverseDecl(Decl *D) {
+  bool TraverseDecl(Decl *D) override {
     // Don't traverse nested record or function declarations.
     // - We won't be analyzing code contained in these anyway
     // - We don't model fields that are used only in these nested declaration,
@@ -104,26 +104,26 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
     if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D))
       return true;
 
-    return RecursiveASTVisitor<Derived>::TraverseDecl(D);
+    return DynamicRecursiveASTVisitor::TraverseDecl(D);
   }
 
   // Don't traverse expressions in unevaluated contexts, as we don't model
   // fields that are only used in these.
   // Note: The operand of the `noexcept` operator is an unevaluated operand, but
   // nevertheless it appears in the Clang CFG, so we don't exclude it here.
-  bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
-  bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
-  bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; }
-  bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
+  bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; }
+  bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; }
+  bool TraverseCXXTypeidExpr(CXXTypeidExpr *) override { return true; }
+  bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) override {
     return true;
   }
 
-  bool TraverseBindingDecl(BindingDecl *BD) {
+  bool TraverseBindingDecl(BindingDecl *BD) override {
     // `RecursiveASTVisitor` doesn't traverse holding variables for
     // `BindingDecl`s by itself, so we need to tell it to.
     if (VarDecl *HoldingVar = BD->getHoldingVar())
       TraverseDecl(HoldingVar);
-    return RecursiveASTVisitor<Derived>::TraverseBindingDecl(BD);
+    return DynamicRecursiveASTVisitor::TraverseBindingDecl(BD);
   }
 };
 
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index c4bb1b4b0debd9..b4ac4517f72096 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -61,6 +61,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseTemplateName(Template);
   }
 
+  bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
+    return Visitor.TraverseObjCProtocolLoc(ProtocolLoc);
+  }
+
   bool TraverseTypeConstraint(const TypeConstraint *C) {
     return Visitor.TraverseTypeConstraint(C);
   }
@@ -219,6 +223,10 @@ bool DynamicRecursiveASTVisitor::TraverseTypeConstraint(
     const TypeConstraint *C) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeConstraint(C);
 }
+bool DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseObjCProtocolLoc(ProtocolLoc);
+}
+
 bool DynamicRecursiveASTVisitor::TraverseConceptRequirement(
     concepts::Requirement *R) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptRequirement(R);
diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
index 27d42a7b508562..1b0a4287c851f3 100644
--- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
+++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
@@ -191,8 +191,7 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
   return nullptr;
 }
 
-class ReferencedDeclsVisitor
-    : public AnalysisASTVisitor<ReferencedDeclsVisitor> {
+class ReferencedDeclsVisitor : public AnalysisASTVisitor {
 public:
   ReferencedDeclsVisitor(ReferencedDecls &Referenced)
       : Referenced(Referenced) {}
@@ -218,19 +217,19 @@ class ReferencedDeclsVisitor
     }
   }
 
-  bool VisitDecl(Decl *D) {
+  bool VisitDecl(Decl *D) override {
     insertIfGlobal(*D, Referenced.Globals);
     insertIfFunction(*D, Referenced.Functions);
     return true;
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     insertIfGlobal(*E->getDecl(), Referenced.Globals);
     insertIfFunction(*E->getDecl(), Referenced.Functions);
     return true;
   }
 
-  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) {
+  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) override {
     // If this is a method that returns a member variable but does nothing else,
     // model the field of the return value.
     if (MemberExpr *E = getMemberForAccessor(*C))
@@ -239,7 +238,7 @@ class ReferencedDeclsVisitor
     return true;
   }
 
-  bool VisitMemberExpr(MemberExpr *E) {
+  bool VisitMemberExpr(MemberExpr *E) override {
     // FIXME: should we be using `E->getFoundDecl()`?
     const ValueDecl *VD = E->getMemberDecl();
     insertIfGlobal(*VD, Referenced.Globals);
@@ -249,14 +248,14 @@ class ReferencedDeclsVisitor
     return true;
   }
 
-  bool VisitInitListExpr(InitListExpr *InitList) {
+  bool VisitInitListExpr(InitListExpr *InitList) override {
     if (InitList->getType()->isRecordType())
       for (const auto *FD : getFieldsForInitListExpr(InitList))
         Referenced.Fields.insert(FD);
     return true;
   }
 
-  bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) {
+  bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) override {
     if (ParenInitList->getType()->isRecordType())
       for (const auto *FD : getFieldsForInitListExpr(ParenInitList))
         Referenced.Fields.insert(FD);
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 7c88917faf9c65..0de4cff346ecb5 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -297,7 +297,7 @@ namespace {
 // Visitor that builds a map from record prvalues to result objects.
 // For each result object that it encounters, it propagates the storage location
 // of the result object to all record prvalues that can initialize it.
-class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
+class ResultObjectVisitor : public AnalysisASTVisitor {
 public:
   // `ResultObjectMap` will be filled with a map from record prvalues to result
   // object. If this visitor will traverse a function that returns a record by
@@ -338,7 +338,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
     }
   }
 
-  bool VisitVarDecl(VarDecl *VD) {
+  bool VisitVarDecl(VarDecl *VD) override {
     if (VD->getType()->isRecordType() && VD->hasInit())
       PropagateResultObject(
           VD->getInit(),
@@ -346,7 +346,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
     return true;
   }
 
-  bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) {
+  bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) override {
     if (MTE->getType()->isRecordType())
       PropagateResultObject(
           MTE->getSubExpr(),
@@ -354,7 +354,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
     return true;
   }
 
-  bool VisitReturnStmt(ReturnStmt *Return) {
+  bool VisitReturnStmt(ReturnStmt *Return) override {
     Expr *RetValue = Return->getRetValue();
     if (RetValue != nullptr && RetValue->getType()->isRecordType() &&
         RetValue->isPRValue())
@@ -362,7 +362,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
     return true;
   }
 
-  bool VisitExpr(Expr *E) {
+  bool VisitExpr(Expr *E) override {
     // Clang's AST can have record-type prvalues without a result object -- for
     // example as full-expressions contained in a compound statement or as
     // arguments of call expressions. We notice this if we get here and a

>From 4bea1314df80bc8191a9226c4e5d8d774022cca8 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 1 Jul 2024 21:29:40 +0200
Subject: [PATCH 10/27] Migrate static analyser visitors

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 13 +++++++
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  4 +++
 clang/lib/Analysis/CalledOnceCheck.cpp        |  8 ++---
 clang/lib/Analysis/ReachableCode.cpp          | 14 ++++----
 .../Checkers/CastToStructChecker.cpp          |  8 ++---
 .../Checkers/DeadStoresChecker.cpp            | 16 ++++-----
 .../Checkers/DynamicTypePropagation.cpp       |  6 ++--
 .../Checkers/IdenticalExprChecker.cpp         | 17 +++++----
 .../Checkers/LocalizationChecker.cpp          | 28 +++++++--------
 .../Checkers/ObjCMissingSuperCallChecker.cpp  |  6 ++--
 .../Checkers/PaddingChecker.cpp               | 15 ++++----
 .../WebKit/NoUncountedMembersChecker.cpp      | 11 +++---
 .../WebKit/RefCntblBaseVirtualDtorChecker.cpp | 11 +++---
 .../WebKit/UncountedCallArgsChecker.cpp       | 16 ++++-----
 .../WebKit/UncountedLambdaCapturesChecker.cpp | 11 +++---
 .../WebKit/UncountedLocalVarsChecker.cpp      | 35 +++++++++----------
 .../StaticAnalyzer/Core/BugSuppression.cpp    |  8 ++---
 .../Frontend/AnalysisConsumer.cpp             | 20 +++++------
 18 files changed, 129 insertions(+), 118 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index cb7fe93a5b76b5..a0c7aa2736a7b7 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -19,6 +19,7 @@ class ASTContext;
 ///   - Visiting attributes
 ///   - Post-order traversal
 ///   - Overriding WalkUpFromX
+///   - Overriding dataTraverseStmtPre/Post()
 ///
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
@@ -181,6 +182,18 @@ class DynamicRecursiveASTVisitor {
   bool WalkUpFromType(Type *T) { return VisitType(T); }
   bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
 
+  /*/// Invoked before visiting a statement or expression via data recursion.
+  ///
+  /// \returns false to skip visiting the node, true otherwise.
+  virtual bool dataTraverseStmtPre(Stmt *S) { return true; }
+
+  /// Invoked after visiting a statement or expression via data recursion.
+  /// This is not invoked if the previously invoked \c dataTraverseStmtPre
+  /// returned false.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  virtual bool dataTraverseStmtPost(Stmt *S) { return true; }*/
+
   /*// Declare Traverse*() and friends for attributes.
 #define DYNAMIC_ATTR_VISITOR_DECLS
 #include "clang/AST/AttrVisitor.inc"
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index b4ac4517f72096..86986e94b9a3cd 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -102,6 +102,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseNestedNameSpecifierLoc(NNS);
   }
 
+
+  /*bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
+  bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }*/
+
   /// Visit a node.
   bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }
   bool VisitDecl(Decl *D) { return Visitor.VisitDecl(D); }
diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index 30cbd257b65e8f..73dc6bbe154b2b 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -15,7 +15,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -426,7 +426,7 @@ const Expr *getCondition(const Stmt *S) {
 /// of the AST will end up in the results.
 /// Results might have duplicate names, if this is a problem, convert to
 /// string sets afterwards.
-class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
+class NamesCollector : public DynamicRecursiveASTVisitor {
 public:
   static constexpr unsigned EXPECTED_NUMBER_OF_NAMES = 5;
   using NameCollection =
@@ -438,12 +438,12 @@ class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
     return Impl.Result;
   }
 
-  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     Result.push_back(E->getDecl()->getName());
     return true;
   }
 
-  bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) override {
     llvm::StringRef Name;
 
     if (E->isImplicitProperty()) {
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index acbe1470b38991..905192c7edd226 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
@@ -476,17 +476,19 @@ static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) {
     }
   if (!CoroStmt)
     return false;
-  struct Checker : RecursiveASTVisitor<Checker> {
+  struct Checker : DynamicRecursiveASTVisitor {
     const Stmt *DeadStmt;
     bool CoroutineSubStmt = false;
-    Checker(const Stmt *S) : DeadStmt(S) {}
-    bool VisitStmt(const Stmt *S) {
+    Checker(const Stmt *S) : DeadStmt(S) {
+      // Statements captured in the CFG can be implicit.
+      ShouldVisitImplicitCode = true;
+    }
+
+    bool VisitStmt(Stmt *S) override {
       if (S == DeadStmt)
         CoroutineSubStmt = true;
       return true;
     }
-    // Statements captured in the CFG can be implicit.
-    bool shouldVisitImplicitCode() const { return true; }
   };
   Checker checker(DeadStmt);
   checker.TraverseStmt(const_cast<Stmt *>(CoroStmt));
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index e674ec43bcd9df..aa0bd78c1472f5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -23,7 +23,7 @@ using namespace clang;
 using namespace ento;
 
 namespace {
-class CastToStructVisitor : public RecursiveASTVisitor<CastToStructVisitor> {
+class CastToStructVisitor : public DynamicRecursiveASTVisitor {
   BugReporter &BR;
   const CheckerBase *Checker;
   AnalysisDeclContext *AC;
@@ -32,11 +32,11 @@ class CastToStructVisitor : public RecursiveASTVisitor<CastToStructVisitor> {
   explicit CastToStructVisitor(BugReporter &B, const CheckerBase *Checker,
                                AnalysisDeclContext *A)
       : BR(B), Checker(Checker), AC(A) {}
-  bool VisitCastExpr(const CastExpr *CE);
+  bool VisitCastExpr(CastExpr *CE) override;
 };
 }
 
-bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) {
+bool CastToStructVisitor::VisitCastExpr(CastExpr *CE) {
   const Expr *E = CE->getSubExpr();
   ASTContext &Ctx = AC->getASTContext();
   QualType OrigTy = Ctx.getCanonicalType(E->getType());
diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 86f446fc411ca2..f7dba536b524f3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -14,7 +14,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
@@ -32,27 +32,27 @@ using namespace ento;
 namespace {
 
 /// A simple visitor to record what VarDecls occur in EH-handling code.
-class EHCodeVisitor : public RecursiveASTVisitor<EHCodeVisitor> {
+class EHCodeVisitor : public DynamicRecursiveASTVisitor {
 public:
   bool inEH;
   llvm::DenseSet<const VarDecl *> &S;
 
-  bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) override {
     SaveAndRestore inFinally(inEH, true);
-    return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtFinallyStmt(S);
+    return DynamicRecursiveASTVisitor::TraverseObjCAtFinallyStmt(S);
   }
 
-  bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) override {
     SaveAndRestore inCatch(inEH, true);
-    return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtCatchStmt(S);
+    return DynamicRecursiveASTVisitor::TraverseObjCAtCatchStmt(S);
   }
 
-  bool TraverseCXXCatchStmt(CXXCatchStmt *S) {
+  bool TraverseCXXCatchStmt(CXXCatchStmt *S) override {
     SaveAndRestore inCatch(inEH, true);
     return TraverseStmt(S->getHandlerBlock());
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *DR) {
+  bool VisitDeclRefExpr(DeclRefExpr *DR) override {
     if (inEH)
       if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
         S.insert(D);
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 034774a252b118..cdda319924563a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -21,7 +21,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -711,10 +711,10 @@ static bool isObjCTypeParamDependent(QualType Type) {
   // an Objective-C type can only be dependent on a type parameter when the type
   // parameter structurally present in the type itself.
   class IsObjCTypeParamDependentTypeVisitor
-      : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> {
+      : public DynamicRecursiveASTVisitor  {
   public:
     IsObjCTypeParamDependentTypeVisitor() = default;
-    bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) {
+    bool VisitObjCTypeParamType(ObjCTypeParamType *Type) override {
       if (isa<ObjCTypeParamDecl>(Type->getDecl())) {
         Result = true;
         return false;
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index 7ac34ef8164e4c..fa20766b639dcf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -16,7 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -32,8 +32,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
 //===----------------------------------------------------------------------===//
 
 namespace {
-class FindIdenticalExprVisitor
-    : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
+class FindIdenticalExprVisitor : public DynamicRecursiveASTVisitor {
   BugReporter &BR;
   const CheckerBase *Checker;
   AnalysisDeclContext *AC;
@@ -45,9 +44,9 @@ class FindIdenticalExprVisitor
   // FindIdenticalExprVisitor only visits nodes
   // that are binary operators, if statements or
   // conditional operators.
-  bool VisitBinaryOperator(const BinaryOperator *B);
-  bool VisitIfStmt(const IfStmt *I);
-  bool VisitConditionalOperator(const ConditionalOperator *C);
+  bool VisitBinaryOperator(BinaryOperator *B) override;
+  bool VisitIfStmt(IfStmt *I) override;
+  bool VisitConditionalOperator(ConditionalOperator *C) override;
 
 private:
   void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise,
@@ -103,7 +102,7 @@ void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B,
   }
 }
 
-bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
+bool FindIdenticalExprVisitor::VisitIfStmt(IfStmt *I) {
   const Stmt *Stmt1 = I->getThen();
   const Stmt *Stmt2 = I->getElse();
 
@@ -178,7 +177,7 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
   return true;
 }
 
-bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) {
+bool FindIdenticalExprVisitor::VisitBinaryOperator(BinaryOperator *B) {
   BinaryOperator::Opcode Op = B->getOpcode();
 
   if (BinaryOperator::isBitwiseOp(Op))
@@ -268,7 +267,7 @@ void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) {
 }
 
 bool FindIdenticalExprVisitor::VisitConditionalOperator(
-    const ConditionalOperator *C) {
+    ConditionalOperator *C) {
 
   // Check if expressions in conditional expression are identical
   // from a symbolic point of view.
diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index f524c4c067c8c3..342ff7fd6d817a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
@@ -1191,7 +1191,7 @@ namespace {
 class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
 
   // A helper class, which walks the AST
-  class MethodCrawler : public RecursiveASTVisitor<MethodCrawler> {
+  class MethodCrawler : public DynamicRecursiveASTVisitor {
     BugReporter &BR;
     const CheckerBase *Checker;
     AnalysisDeclContext *AC;
@@ -1209,13 +1209,13 @@ class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
                            AnalysisDeclContext *InAC)
         : BR(InBR), Checker(Checker), AC(InAC) {}
 
-    bool VisitIfStmt(const IfStmt *I);
+    bool VisitIfStmt(IfStmt *I) override;
     bool EndVisitIfStmt(IfStmt *I);
-    bool TraverseIfStmt(IfStmt *x);
-    bool VisitConditionalOperator(const ConditionalOperator *C);
-    bool TraverseConditionalOperator(ConditionalOperator *C);
-    bool VisitCallExpr(const CallExpr *CE);
-    bool VisitObjCMessageExpr(const ObjCMessageExpr *ME);
+    bool TraverseIfStmt(IfStmt *x) override;
+    bool VisitConditionalOperator(ConditionalOperator *C) override;
+    bool TraverseConditionalOperator(ConditionalOperator *C) override;
+    bool VisitCallExpr(CallExpr *CE) override;
+    bool VisitObjCMessageExpr(ObjCMessageExpr *ME) override;
 
   private:
     void reportPluralMisuseError(const Stmt *S) const;
@@ -1274,7 +1274,7 @@ bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
 // has been shown to almost always be a function that returns a localized
 // string. Raise a diagnostic when this is in a statement that matches
 // the condition.
-bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) {
+bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(CallExpr *CE) {
   if (InMatchingStatement) {
     if (const FunctionDecl *FD = CE->getDirectCallee()) {
       std::string NormalizedName =
@@ -1296,7 +1296,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) {
 // diagnostic when this is in a statement that matches
 // the condition.
 bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
-    const ObjCMessageExpr *ME) {
+    ObjCMessageExpr *ME) {
   const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
   if (!OD)
     return true;
@@ -1314,7 +1314,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
 
 /// Override TraverseIfStmt so we know when we are done traversing an IfStmt
 bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(IfStmt *I) {
-  RecursiveASTVisitor<MethodCrawler>::TraverseIfStmt(I);
+  DynamicRecursiveASTVisitor::TraverseIfStmt(I);
   return EndVisitIfStmt(I);
 }
 
@@ -1333,7 +1333,7 @@ bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(IfStmt *I) {
   return true;
 }
 
-bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) {
+bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(IfStmt *I) {
   const Expr *Condition = I->getCond();
   if (!Condition)
     return true;
@@ -1352,7 +1352,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) {
 // Preliminary support for conditional operators.
 bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
     ConditionalOperator *C) {
-  RecursiveASTVisitor<MethodCrawler>::TraverseConditionalOperator(C);
+  DynamicRecursiveASTVisitor::TraverseConditionalOperator(C);
   MatchingStatements.pop_back();
   if (!MatchingStatements.empty()) {
     if (MatchingStatements.back() != nullptr)
@@ -1366,7 +1366,7 @@ bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
 }
 
 bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
-    const ConditionalOperator *C) {
+    ConditionalOperator *C) {
   const Expr *Condition = C->getCond()->IgnoreParenImpCasts();
   if (isCheckingPlurality(Condition)) {
     MatchingStatements.push_back(C);
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index 03dab4f7ada7ae..dea1b1aea016bf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
@@ -38,11 +38,11 @@ struct SelectorDescriptor {
 // FindSuperCallVisitor - Identify specific calls to the superclass.
 //===----------------------------------------------------------------------===//
 
-class FindSuperCallVisitor : public RecursiveASTVisitor<FindSuperCallVisitor> {
+class FindSuperCallVisitor : public DynamicRecursiveASTVisitor {
 public:
   explicit FindSuperCallVisitor(Selector S) : DoesCallSuper(false), Sel(S) {}
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     if (E->getSelector() == Sel)
       if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance)
         DoesCallSuper = true;
diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 4f35d9442ad988..4354f36b397977 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -15,7 +15,7 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -45,16 +45,17 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const PaddingChecker *Checker;
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return true; }
-      explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {}
-      bool VisitRecordDecl(const RecordDecl *RD) {
+      explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = true;
+      }
+      bool VisitRecordDecl(RecordDecl *RD) override {
         Checker->visitRecord(RD);
         return true;
       }
-      bool VisitVarDecl(const VarDecl *VD) {
+      bool VisitVarDecl(VarDecl *VD) override {
         Checker->visitVariable(VD);
         return true;
       }
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
index 69a0eb3086ab72..2c30c7825b51e3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
@@ -12,7 +12,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -45,17 +45,16 @@ class NoUncountedMemberChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const NoUncountedMemberChecker *Checker;
       explicit LocalVisitor(const NoUncountedMemberChecker *Checker)
           : Checker(Checker) {
         assert(Checker);
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = true;
       }
 
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return false; }
-
-      bool VisitRecordDecl(const RecordDecl *RD) {
+      bool VisitRecordDecl(RecordDecl *RD) override {
         Checker->visitRecordDecl(RD);
         return true;
       }
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index 9df108e28ecdbb..c5e1af6e3ce082 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
@@ -10,7 +10,7 @@
 #include "DiagOutputUtils.h"
 #include "PtrTypesSemantics.h"
 #include "clang/AST/CXXInheritance.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -140,17 +140,16 @@ class RefCntblBaseVirtualDtorChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const RefCntblBaseVirtualDtorChecker *Checker;
       explicit LocalVisitor(const RefCntblBaseVirtualDtorChecker *Checker)
           : Checker(Checker) {
         assert(Checker);
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = false;
       }
 
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return false; }
-
-      bool VisitCXXRecordDecl(const CXXRecordDecl *RD) {
+      bool VisitCXXRecordDecl(CXXRecordDecl *RD) override {
         if (!RD->hasDefinition())
           return true;
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
index 704c082a4d1d63..a71027d0acb936 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
@@ -12,7 +12,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -43,24 +43,22 @@ class UncountedCallArgsChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const UncountedCallArgsChecker *Checker;
       explicit LocalVisitor(const UncountedCallArgsChecker *Checker)
           : Checker(Checker) {
         assert(Checker);
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = false;
       }
 
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return false; }
-
-      bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) {
+      bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) override {
         if (isRefType(safeGetName(Decl)))
           return true;
-        return RecursiveASTVisitor<LocalVisitor>::TraverseClassTemplateDecl(
-            Decl);
+        return DynamicRecursiveASTVisitor::TraverseClassTemplateDecl(Decl);
       }
 
-      bool VisitCallExpr(const CallExpr *CE) {
+      bool VisitCallExpr(CallExpr *CE) override {
         Checker->visitCallExpr(CE);
         return true;
       }
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index a226a01ec0a579..917c7670c3790e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
@@ -9,7 +9,7 @@
 #include "DiagOutputUtils.h"
 #include "PtrTypesSemantics.h"
 #include "clang/AST/CXXInheritance.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -35,17 +35,16 @@ class UncountedLambdaCapturesChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const UncountedLambdaCapturesChecker *Checker;
       explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker)
           : Checker(Checker) {
         assert(Checker);
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = false;
       }
 
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return false; }
-
-      bool VisitLambdaExpr(LambdaExpr *L) {
+      bool VisitLambdaExpr(LambdaExpr *L) override {
         Checker->visitLambdaExpr(L);
         return true;
       }
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
index 274da0baf2ce5c..e24c67c4d788ea 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
@@ -13,7 +13,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -119,29 +119,26 @@ class UncountedLocalVarsChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+    struct LocalVisitor : DynamicRecursiveASTVisitor {
       const UncountedLocalVarsChecker *Checker;
 
       TrivialFunctionAnalysis TFA;
 
-      using Base = RecursiveASTVisitor<LocalVisitor>;
-
       explicit LocalVisitor(const UncountedLocalVarsChecker *Checker)
           : Checker(Checker) {
         assert(Checker);
+        ShouldVisitTemplateInstantiations = true;
+        ShouldVisitImplicitCode = false;
       }
 
-      bool shouldVisitTemplateInstantiations() const { return true; }
-      bool shouldVisitImplicitCode() const { return false; }
-
-      bool VisitVarDecl(VarDecl *V) {
+      bool VisitVarDecl(VarDecl *V) override {
         auto *Init = V->getInit();
         if (Init && V->isLocalVarDecl())
           Checker->visitVarDecl(V, Init);
         return true;
       }
 
-      bool VisitBinaryOperator(const BinaryOperator *BO) {
+      bool VisitBinaryOperator(BinaryOperator *BO) override {
         if (BO->isAssignmentOp()) {
           if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) {
             if (auto *V = dyn_cast<VarDecl>(VarRef->getDecl()))
@@ -151,33 +148,33 @@ class UncountedLocalVarsChecker
         return true;
       }
 
-      bool TraverseIfStmt(IfStmt *IS) {
+      bool TraverseIfStmt(IfStmt *IS) override {
         if (!TFA.isTrivial(IS))
-          return Base::TraverseIfStmt(IS);
+          return DynamicRecursiveASTVisitor::TraverseIfStmt(IS);
         return true;
       }
 
-      bool TraverseForStmt(ForStmt *FS) {
+      bool TraverseForStmt(ForStmt *FS) override {
         if (!TFA.isTrivial(FS))
-          return Base::TraverseForStmt(FS);
+          return DynamicRecursiveASTVisitor::TraverseForStmt(FS);
         return true;
       }
 
-      bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) {
+      bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) override {
         if (!TFA.isTrivial(FRS))
-          return Base::TraverseCXXForRangeStmt(FRS);
+          return DynamicRecursiveASTVisitor::TraverseCXXForRangeStmt(FRS);
         return true;
       }
 
-      bool TraverseWhileStmt(WhileStmt *WS) {
+      bool TraverseWhileStmt(WhileStmt *WS) override {
         if (!TFA.isTrivial(WS))
-          return Base::TraverseWhileStmt(WS);
+          return DynamicRecursiveASTVisitor::TraverseWhileStmt(WS);
         return true;
       }
 
-      bool TraverseCompoundStmt(CompoundStmt *CS) {
+      bool TraverseCompoundStmt(CompoundStmt *CS) override {
         if (!TFA.isTrivial(CS))
-          return Base::TraverseCompoundStmt(CS);
+          return DynamicRecursiveASTVisitor::TraverseCompoundStmt(CS);
         return true;
       }
     };
diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
index 84004b8e5c1cdb..05c99c4a844e9e 100644
--- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 
 using namespace clang;
@@ -76,13 +76,13 @@ inline bool fullyContains(SourceRange Larger, SourceRange Smaller,
          isLessOrEqual(Smaller.getEnd(), Larger.getEnd(), SM);
 }
 
-class CacheInitializer : public RecursiveASTVisitor<CacheInitializer> {
+class CacheInitializer : public DynamicRecursiveASTVisitor {
 public:
   static void initialize(const Decl *D, Ranges &ToInit) {
     CacheInitializer(ToInit).TraverseDecl(const_cast<Decl *>(D));
   }
 
-  bool VisitDecl(Decl *D) {
+  bool VisitDecl(Decl *D) override {
     // Bug location could be somewhere in the init value of
     // a freshly declared variable.  Even though it looks like the
     // user applied attribute to a statement, it will apply to a
@@ -90,7 +90,7 @@ class CacheInitializer : public RecursiveASTVisitor<CacheInitializer> {
     return VisitAttributedNode(D);
   }
 
-  bool VisitAttributedStmt(AttributedStmt *AS) {
+  bool VisitAttributedStmt(AttributedStmt *AS) override {
     // When we apply attributes to statements, it actually creates
     // a wrapper statement that only contains attributes and the wrapped
     // statement.
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 03bc40804d7328..91c9b085f68292 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -15,7 +15,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CallGraph.h"
@@ -68,7 +68,7 @@ STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
 namespace {
 
 class AnalysisConsumer : public AnalysisASTConsumer,
-                         public RecursiveASTVisitor<AnalysisConsumer> {
+                         public DynamicRecursiveASTVisitor {
   enum {
     AM_None = 0,
     AM_Syntax = 0x1,
@@ -147,6 +147,9 @@ class AnalysisConsumer : public AnalysisASTConsumer,
 
     if (Opts.ShouldDisplayMacroExpansions)
       MacroExpansions.registerForPreprocessor(PP);
+
+    // Visitor options.
+    ShouldWalkTypesOfTypeLocs = false;
   }
 
   ~AnalysisConsumer() override {
@@ -261,11 +264,8 @@ class AnalysisConsumer : public AnalysisASTConsumer,
                               ExprEngine::InliningModes IMode,
                               SetOfConstDecls *VisitedCallees);
 
-  /// Visitors for the RecursiveASTVisitor.
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
   /// Handle callbacks for arbitrary Decls.
-  bool VisitDecl(Decl *D) {
+  bool VisitDecl(Decl *D) override {
     AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
     if (Mode & AM_Syntax) {
       if (SyntaxCheckTimer)
@@ -277,7 +277,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
     return true;
   }
 
-  bool VisitVarDecl(VarDecl *VD) {
+  bool VisitVarDecl(VarDecl *VD) override {
     if (!Opts.IsNaiveCTUEnabled)
       return true;
 
@@ -306,7 +306,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
     return true;
   }
 
-  bool VisitFunctionDecl(FunctionDecl *FD) {
+  bool VisitFunctionDecl(FunctionDecl *FD) override {
     IdentifierInfo *II = FD->getIdentifier();
     if (II && II->getName().starts_with("__inline"))
       return true;
@@ -321,7 +321,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
     return true;
   }
 
-  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override {
     if (MD->isThisDeclarationADefinition()) {
       assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
       HandleCode(MD, RecVisitorMode);
@@ -329,7 +329,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
     return true;
   }
 
-  bool VisitBlockDecl(BlockDecl *BD) {
+  bool VisitBlockDecl(BlockDecl *BD) override {
     if (BD->hasBody()) {
       assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
       // Since we skip function template definitions, we should skip blocks

>From 3c16260454b27d98fa6e81e56b9b05100231424f Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 2 Jul 2024 23:55:50 +0200
Subject: [PATCH 11/27] Actually override Visit for abstract nodes

---
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index 86986e94b9a3cd..fb846792f1e6e6 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -117,16 +117,21 @@ struct Impl : RecursiveASTVisitor<Impl> {
   #include "clang/AST/AttrVisitor.inc"
   #undef ATTR_VISITOR_DECLS*/
 
+  // Declarations.
 #define ABSTRACT_DECL(DECL)
 #define DECL(CLASS, BASE)                                                      \
   bool Traverse##CLASS##Decl(CLASS##Decl *D) {                                 \
     return Visitor.Traverse##CLASS##Decl(D);                                   \
-  }                                                                            \
+  }
+#include "clang/AST/DeclNodes.inc"
+
+#define DECL(CLASS, BASE)                                                      \
   bool Visit##CLASS##Decl(CLASS##Decl *D) {                                    \
     return Visitor.Visit##CLASS##Decl(D);                                      \
   }
 #include "clang/AST/DeclNodes.inc"
 
+  // Statements.
 #define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                                                    \
   bool Traverse##CLASS(CLASS *S) { return Visitor.Traverse##CLASS(S); }
@@ -136,17 +141,21 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool Visit##CLASS(CLASS *S) { return Visitor.Visit##CLASS(S); }
 #include "clang/AST/StmtNodes.inc"
 
-  // Declare Traverse*() and friends for all concrete Typeclasses.
+  // Types.
 #define ABSTRACT_TYPE(CLASS, BASE)
 #define TYPE(CLASS, BASE)                                                      \
   bool Traverse##CLASS##Type(CLASS##Type *T) {                                 \
     return Visitor.Traverse##CLASS##Type(T);                                   \
-  }                                                                            \
+  }
+#include "clang/AST/TypeNodes.inc"
+
+#define TYPE(CLASS, BASE)                                                      \
   bool Visit##CLASS##Type(CLASS##Type *T) {                                    \
     return Visitor.Visit##CLASS##Type(T);                                      \
   }
 #include "clang/AST/TypeNodes.inc"
 
+  // TypeLocs.
 #define ABSTRACT_TYPELOC(CLASS, BASE)
 #define TYPELOC(CLASS, BASE)                                                   \
   bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL) {                           \

>From e542efa7636105f4ee6784a208cc50ad87f9d680 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Wed, 3 Jul 2024 00:22:00 +0200
Subject: [PATCH 12/27] Migrate even more visitors

---
 clang/include/clang/InstallAPI/Visitor.h      | 20 ++++----
 .../Refactoring/RecursiveSymbolVisitor.h      | 31 +++++-------
 clang/lib/AST/ASTImporterLookupTable.cpp      | 22 ++++----
 clang/lib/Analysis/UnsafeBufferUsage.cpp      | 50 ++++++++-----------
 .../ObjectFilePCHContainerOperations.cpp      | 14 +++---
 clang/lib/Frontend/ASTConsumers.cpp           | 26 +++++-----
 clang/lib/Index/IndexTypeSourceInfo.cpp       | 41 ++++++++-------
 clang/lib/InstallAPI/Visitor.cpp              | 10 ++--
 clang/lib/Tooling/ASTDiff/ASTDiff.cpp         | 19 +++----
 .../Tooling/Refactoring/Rename/USRFinder.cpp  | 12 ++---
 .../Refactoring/Rename/USRFindingAction.cpp   | 11 ++--
 .../Refactoring/Rename/USRLocFinder.cpp       | 23 ++++-----
 12 files changed, 132 insertions(+), 147 deletions(-)

diff --git a/clang/include/clang/InstallAPI/Visitor.h b/clang/include/clang/InstallAPI/Visitor.h
index 3680ee566ca875..ab8b5588b62c92 100644
--- a/clang/include/clang/InstallAPI/Visitor.h
+++ b/clang/include/clang/InstallAPI/Visitor.h
@@ -14,7 +14,7 @@
 #define LLVM_CLANG_INSTALLAPI_VISITOR_H
 
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/InstallAPI/Context.h"
@@ -26,35 +26,37 @@ namespace installapi {
 
 /// ASTVisitor for collecting declarations that represent global symbols.
 class InstallAPIVisitor final : public ASTConsumer,
-                                public RecursiveASTVisitor<InstallAPIVisitor> {
+                                public DynamicRecursiveASTVisitor {
 public:
   InstallAPIVisitor(ASTContext &ASTCtx, InstallAPIContext &Ctx,
                     SourceManager &SrcMgr, Preprocessor &PP)
       : Ctx(Ctx), SrcMgr(SrcMgr), PP(PP),
         MC(ItaniumMangleContext::create(ASTCtx, ASTCtx.getDiagnostics())),
-        Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {}
+        Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {
+    ShouldVisitTemplateInstantiations = true;
+  }
+
   void HandleTranslationUnit(ASTContext &ASTCtx) override;
-  bool shouldVisitTemplateInstantiations() const { return true; }
 
   /// Collect global variables.
-  bool VisitVarDecl(const VarDecl *D);
+  bool VisitVarDecl(VarDecl *D) override;
 
   /// Collect global functions.
-  bool VisitFunctionDecl(const FunctionDecl *D);
+  bool VisitFunctionDecl(FunctionDecl *D) override;
 
   /// Collect Objective-C Interface declarations.
   /// Every Objective-C class has an interface declaration that lists all the
   /// ivars, properties, and methods of the class.
-  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
+  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) override;
 
   /// Collect Objective-C Category/Extension declarations.
   ///
   /// The class that is being extended might come from a different library and
   /// is therefore itself not collected.
-  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
+  bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) override;
 
   /// Collect global c++ declarations.
-  bool VisitCXXRecordDecl(const CXXRecordDecl *D);
+  bool VisitCXXRecordDecl(CXXRecordDecl *D) override;
 
 private:
   std::string getMangledName(const NamedDecl *D) const;
diff --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index 015dbba26f6887..aeea0c1b2df7f0 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -24,27 +24,23 @@ namespace tooling {
 
 /// Traverses the AST and visits the occurrence of each named symbol in the
 /// given nodes.
-template <typename T>
-class RecursiveSymbolVisitor
-    : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
-  using BaseType = RecursiveASTVisitor<RecursiveSymbolVisitor<T>>;
-
+class RecursiveSymbolVisitor : public DynamicRecursiveASTVisitor {
 public:
   RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
       : SM(SM), LangOpts(LangOpts) {}
 
-  bool visitSymbolOccurrence(const NamedDecl *ND,
+  virtual bool visitSymbolOccurrence(const NamedDecl *ND,
                              ArrayRef<SourceRange> NameRanges) {
     return true;
   }
 
   // Declaration visitors:
 
-  bool VisitNamedDecl(const NamedDecl *D) {
+  bool VisitNamedDecl(NamedDecl *D) override {
     return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
   }
 
-  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
+  bool VisitCXXConstructorDecl(CXXConstructorDecl *CD) override {
     for (const auto *Initializer : CD->inits()) {
       // Ignore implicit initializers.
       if (!Initializer->isWritten())
@@ -61,15 +57,15 @@ class RecursiveSymbolVisitor
 
   // Expression visitors:
 
-  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+  bool VisitDeclRefExpr(DeclRefExpr *Expr) override {
     return visit(Expr->getFoundDecl(), Expr->getLocation());
   }
 
-  bool VisitMemberExpr(const MemberExpr *Expr) {
+  bool VisitMemberExpr(MemberExpr *Expr) override {
     return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
   }
 
-  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
+  bool VisitOffsetOfExpr(OffsetOfExpr *S) override {
     for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
       const OffsetOfNode &Component = S->getComponent(I);
       if (Component.getKind() == OffsetOfNode::Field) {
@@ -83,7 +79,7 @@ class RecursiveSymbolVisitor
 
   // Other visitors:
 
-  bool VisitTypeLoc(const TypeLoc Loc) {
+  bool VisitTypeLoc(TypeLoc Loc) override {
     const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
     const SourceLocation TypeEndLoc =
         Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
@@ -105,13 +101,13 @@ class RecursiveSymbolVisitor
     return true;
   }
 
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) override {
     const SourceLocation TypeEndLoc =
         Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
     return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
   }
 
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
     // The base visitor will visit NNSL prefixes, so we should only look at
     // the current NNS.
     if (NNS) {
@@ -119,10 +115,10 @@ class RecursiveSymbolVisitor
       if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
         return false;
     }
-    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
+    return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
   }
 
-  bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
+  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) override {
     for (const DesignatedInitExpr::Designator &D : E->designators()) {
       if (D.isFieldDesignator()) {
         if (const FieldDecl *Decl = D.getFieldDecl()) {
@@ -140,8 +136,7 @@ class RecursiveSymbolVisitor
 
   bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
              SourceLocation EndLoc) {
-    return static_cast<T *>(this)->visitSymbolOccurrence(
-        ND, SourceRange(BeginLoc, EndLoc));
+    return visitSymbolOccurrence(ND, SourceRange(BeginLoc, EndLoc));
   }
   bool visit(const NamedDecl *ND, SourceLocation Loc) {
     return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp
index 307c03404e0121..b7c112540c1c60 100644
--- a/clang/lib/AST/ASTImporterLookupTable.cpp
+++ b/clang/lib/AST/ASTImporterLookupTable.cpp
@@ -13,20 +13,22 @@
 
 #include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "llvm/Support/FormatVariadic.h"
 
 namespace clang {
 
 namespace {
 
-// FIXME: This breaks if we try to use a dynamic visitor,
-// and I have no idea why.
-struct Builder : RecursiveASTVisitor<Builder> {
+struct Builder : DynamicRecursiveASTVisitor {
   ASTImporterLookupTable <
-  Builder(ASTImporterLookupTable &LT) : LT(LT) {}
+  Builder(ASTImporterLookupTable &LT) : LT(LT) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = true;
+  }
 
-  bool VisitTypedefNameDecl(TypedefNameDecl *D) {
+  bool VisitTypedefNameDecl(TypedefNameDecl *D) override {
     QualType Ty = D->getUnderlyingType();
     Ty = Ty.getCanonicalType();
     if (const auto *RTy = dyn_cast<RecordType>(Ty)) {
@@ -39,7 +41,7 @@ struct Builder : RecursiveASTVisitor<Builder> {
     return true;
   }
 
-  bool VisitNamedDecl(NamedDecl *D) {
+  bool VisitNamedDecl(NamedDecl *D) override {
     LT.add(D);
     return true;
   }
@@ -48,7 +50,7 @@ struct Builder : RecursiveASTVisitor<Builder> {
   // visitation. However, there are cases when the befriended class is not a
   // child, thus it must be fetched explicitly from the FriendDecl, and only
   // then can we add it to the lookup table.
-  bool VisitFriendDecl(FriendDecl *D) {
+  bool VisitFriendDecl(FriendDecl *D) override {
     if (D->getFriendType()) {
       QualType Ty = D->getFriendType()->getType();
       if (isa<ElaboratedType>(Ty))
@@ -78,10 +80,6 @@ struct Builder : RecursiveASTVisitor<Builder> {
     }
     return true;
   }
-
-  // Override default settings of base.
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const { return true; }
 };
 
 } // anonymous namespace
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 866222380974b6..a412d951bb0fbb 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -10,7 +10,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -81,11 +81,8 @@ static std::string getDREAncestorString(const DeclRefExpr *DRE,
 namespace clang::ast_matchers {
 // A `RecursiveASTVisitor` that traverses all descendants of a given node "n"
 // except for those belonging to a different callable of "n".
-class MatchDescendantVisitor
-    : public RecursiveASTVisitor<MatchDescendantVisitor> {
+class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
 public:
-  typedef RecursiveASTVisitor<MatchDescendantVisitor> VisitorBase;
-
   // Creates an AST visitor that matches `Matcher` on all
   // descendants of a given node "n" except for the ones
   // belonging to a different callable of "n".
@@ -95,7 +92,10 @@ class MatchDescendantVisitor
                          internal::ASTMatchFinder::BindKind Bind,
                          const bool ignoreUnevaluatedContext)
       : Matcher(Matcher), Finder(Finder), Builder(Builder), Bind(Bind),
-        Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) {}
+        Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = false; // TODO: let's ignore implicit code for now
+  }
 
   // Returns true if a match is found in a subtree of `DynNode`, which belongs
   // to the same callable of `DynNode`.
@@ -116,7 +116,7 @@ class MatchDescendantVisitor
   // For the matchers so far used in safe buffers, we only need to match
   // `Stmt`s.  To override more as needed.
 
-  bool TraverseDecl(Decl *Node) {
+  bool TraverseDecl(Decl *Node) override {
     if (!Node)
       return true;
     if (!match(*Node))
@@ -125,63 +125,57 @@ class MatchDescendantVisitor
     if (isa<FunctionDecl, BlockDecl, ObjCMethodDecl>(Node))
       return true;
     // Traverse descendants
-    return VisitorBase::TraverseDecl(Node);
+    return DynamicRecursiveASTVisitor::TraverseDecl(Node);
   }
 
-  bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) {
+  bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
     // These are unevaluated, except the result expression.
     if (ignoreUnevaluatedContext)
       return TraverseStmt(Node->getResultExpr());
-    return VisitorBase::TraverseGenericSelectionExpr(Node);
+    return DynamicRecursiveASTVisitor::TraverseGenericSelectionExpr(Node);
   }
 
-  bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
+  bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
-    return VisitorBase::TraverseUnaryExprOrTypeTraitExpr(Node);
+    return DynamicRecursiveASTVisitor::TraverseUnaryExprOrTypeTraitExpr(Node);
   }
 
-  bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) {
+  bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
-    return VisitorBase::TraverseTypeOfExprTypeLoc(Node);
+    return DynamicRecursiveASTVisitor::TraverseTypeOfExprTypeLoc(Node);
   }
 
-  bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) {
+  bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
-    return VisitorBase::TraverseDecltypeTypeLoc(Node);
+    return DynamicRecursiveASTVisitor::TraverseDecltypeTypeLoc(Node);
   }
 
-  bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) {
+  bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
-    return VisitorBase::TraverseCXXNoexceptExpr(Node);
+    return DynamicRecursiveASTVisitor::TraverseCXXNoexceptExpr(Node);
   }
 
-  bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) {
+  bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
-    return VisitorBase::TraverseCXXTypeidExpr(Node);
+    return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(Node);
   }
 
-  bool TraverseStmt(Stmt *Node, DataRecursionQueue *Queue = nullptr) {
+  bool TraverseStmt(Stmt *Node, DataRecursionQueue *Queue = nullptr) override {
     if (!Node)
       return true;
     if (!match(*Node))
       return false;
-    return VisitorBase::TraverseStmt(Node);
-  }
-
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const {
-    // TODO: let's ignore implicit code for now
-    return false;
+    return DynamicRecursiveASTVisitor::TraverseStmt(Node);
   }
 
 private:
diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index ee543e40b46099..c598c33a458ec6 100644
--- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -12,7 +12,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
@@ -58,7 +58,7 @@ class PCHContainerGenerator : public ASTConsumer {
   std::shared_ptr<PCHBuffer> Buffer;
 
   /// Visit every type and emit debug info for it.
-  struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
+  struct DebugTypeVisitor : DynamicRecursiveASTVisitor {
     clang::CodeGen::CGDebugInfo &DI;
     ASTContext &Ctx;
     DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
@@ -69,13 +69,13 @@ class PCHContainerGenerator : public ASTConsumer {
       return !Ty->isDependentType() && !Ty->isUndeducedType();
     }
 
-    bool VisitImportDecl(ImportDecl *D) {
+    bool VisitImportDecl(ImportDecl *D) override {
       if (!D->getImportedOwningModule())
         DI.EmitImportDecl(*D);
       return true;
     }
 
-    bool VisitTypeDecl(TypeDecl *D) {
+    bool VisitTypeDecl(TypeDecl *D) override {
       // TagDecls may be deferred until after all decls have been merged and we
       // know the complete type. Pure forward declarations will be skipped, but
       // they don't need to be emitted into the module anyway.
@@ -89,14 +89,14 @@ class PCHContainerGenerator : public ASTConsumer {
       return true;
     }
 
-    bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+    bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) override {
       QualType QualTy(D->getTypeForDecl(), 0);
       if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
         DI.getOrCreateStandaloneType(QualTy, D->getLocation());
       return true;
     }
 
-    bool VisitFunctionDecl(FunctionDecl *D) {
+    bool VisitFunctionDecl(FunctionDecl *D) override {
       // Skip deduction guides.
       if (isa<CXXDeductionGuideDecl>(D))
         return true;
@@ -117,7 +117,7 @@ class PCHContainerGenerator : public ASTConsumer {
       return true;
     }
 
-    bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    bool VisitObjCMethodDecl(ObjCMethodDecl *D) override {
       if (!D->getClassInterface())
         return true;
 
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index 7b58eaa04df95a..5ecd17ad36ada8 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -16,7 +16,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Path.h"
@@ -29,9 +29,7 @@ using namespace clang;
 
 namespace {
   class ASTPrinter : public ASTConsumer,
-                     public RecursiveASTVisitor<ASTPrinter> {
-    typedef RecursiveASTVisitor<ASTPrinter> base;
-
+                     public DynamicRecursiveASTVisitor {
   public:
     enum Kind { DumpFull, Dump, Print, None };
     ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
@@ -39,7 +37,9 @@ namespace {
                bool DumpLookups = false, bool DumpDeclTypes = false)
         : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
           OutputKind(K), OutputFormat(Format), FilterString(FilterString),
-          DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
+          DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {
+      ShouldWalkTypesOfTypeLocs = false;
+    }
 
     void HandleTranslationUnit(ASTContext &Context) override {
       TranslationUnitDecl *D = Context.getTranslationUnitDecl();
@@ -50,9 +50,7 @@ namespace {
       TraverseDecl(D);
     }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-    bool TraverseDecl(Decl *D) {
+    bool TraverseDecl(Decl *D) override {
       if (D && filterMatches(D)) {
         bool ShowColors = Out.has_colors();
         if (ShowColors)
@@ -69,7 +67,7 @@ namespace {
         // Don't traverse child nodes to avoid output duplication.
         return true;
       }
-      return base::TraverseDecl(D);
+      return DynamicRecursiveASTVisitor::TraverseDecl(D);
     }
 
   private:
@@ -134,18 +132,18 @@ namespace {
   };
 
   class ASTDeclNodeLister : public ASTConsumer,
-                     public RecursiveASTVisitor<ASTDeclNodeLister> {
+                     public DynamicRecursiveASTVisitor {
   public:
     ASTDeclNodeLister(raw_ostream *Out = nullptr)
-        : Out(Out ? *Out : llvm::outs()) {}
+        : Out(Out ? *Out : llvm::outs()) {
+      ShouldWalkTypesOfTypeLocs = false;
+    }
 
     void HandleTranslationUnit(ASTContext &Context) override {
       TraverseDecl(Context.getTranslationUnitDecl());
     }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-    bool VisitNamedDecl(NamedDecl *D) {
+    bool VisitNamedDecl(NamedDecl *D) override {
       D->printQualifiedName(Out);
       Out << '\n';
       return true;
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index b986ccde574525..4f09d0d7a16e8e 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -8,8 +8,9 @@
 
 #include "IndexingContext.h"
 #include "clang/AST/ASTConcept.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "llvm/ADT/ScopeExit.h"
 
@@ -18,15 +19,13 @@ using namespace index;
 
 namespace {
 
-class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
+class TypeIndexer : public DynamicRecursiveASTVisitor {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
   bool IsBase;
   SmallVector<SymbolRelation, 3> Relations;
 
-  typedef RecursiveASTVisitor<TypeIndexer> base;
-
 public:
   TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
               const DeclContext *DC, bool isBase, bool isIBType)
@@ -39,9 +38,9 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
       assert(Parent);
       Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
     }
-  }
 
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
@@ -49,14 +48,14 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
       return false;                                                            \
   } while (0)
 
-  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) {
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) override {
     SourceLocation Loc = TTPL.getNameLoc();
     TemplateTypeParmDecl *TTPD = TTPL.getDecl();
     return IndexCtx.handleReference(TTPD, Loc, Parent, ParentDC,
                                     SymbolRoleSet());
   }
 
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) override {
     SourceLocation Loc = TL.getNameLoc();
     TypedefNameDecl *ND = TL.getTypedefNameDecl();
     if (ND->isTransparentTag()) {
@@ -80,7 +79,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     return true;
   }
 
-  bool VisitAutoTypeLoc(AutoTypeLoc TL) {
+  bool VisitAutoTypeLoc(AutoTypeLoc TL) override {
     if (auto *C = TL.getNamedConcept())
       return IndexCtx.handleReference(C, TL.getConceptNameLoc(), Parent,
                                       ParentDC);
@@ -94,7 +93,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     return true;
   }
 
-  bool TraverseParmVarDecl(ParmVarDecl *D) {
+  bool TraverseParmVarDecl(ParmVarDecl *D) override {
     // Avoid visiting default arguments from the definition that were already
     // visited in the declaration.
     // FIXME: A free function definition can have default arguments.
@@ -107,15 +106,15 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
       }
     }
 
-    return base::TraverseParmVarDecl(D);
+    return DynamicRecursiveASTVisitor::TraverseParmVarDecl(D);
   }
 
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
     IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
     return true;
   }
 
-  bool VisitTagTypeLoc(TagTypeLoc TL) {
+  bool VisitTagTypeLoc(TagTypeLoc TL) override {
     TagDecl *D = TL.getDecl();
     if (!IndexCtx.shouldIndexFunctionLocalSymbols() &&
         D->getParentFunctionOrMethod())
@@ -131,12 +130,12 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
                                     Relations);
   }
 
-  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) override {
     return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
                                     Parent, ParentDC, SymbolRoleSet(), Relations);
   }
 
-  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) override {
     for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
       IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
                                Parent, ParentDC, SymbolRoleSet(), Relations);
@@ -161,7 +160,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     }
   }
 
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) override {
     auto *T = TL.getTypePtr();
     if (!T)
       return true;
@@ -171,7 +170,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     return true;
   }
 
-  bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+  bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) override {
     if (!WalkUpFromTemplateSpecializationTypeLoc(TL))
       return false;
     if (!TraverseTemplateName(TL.getTypePtr()->getTemplateName()))
@@ -191,7 +190,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     return true;
   }
 
-  bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) {
+  bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) override {
     auto *T = TL.getTypePtr();
     if (!T)
       return true;
@@ -201,12 +200,12 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     return true;
   }
 
-  bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) override {
     return IndexCtx.handleReference(TL.getDecl(), TL.getNameLoc(), Parent,
                                     ParentDC, SymbolRoleSet(), Relations);
   }
 
-  bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) override {
     const DependentNameType *DNT = TL.getTypePtr();
     const NestedNameSpecifier *NNS = DNT->getQualifier();
     const Type *T = NNS->getAsType();
@@ -234,7 +233,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
                                     ParentDC, SymbolRoleSet(), Relations);
   }
 
-  bool TraverseStmt(Stmt *S) {
+  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
     IndexCtx.indexBody(S, Parent, ParentDC);
     return true;
   }
diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp
index a73ea0b0d124c2..6b1951c54fe17c 100644
--- a/clang/lib/InstallAPI/Visitor.cpp
+++ b/clang/lib/InstallAPI/Visitor.cpp
@@ -163,7 +163,7 @@ void InstallAPIVisitor::recordObjCInstanceVariables(
   }
 }
 
-bool InstallAPIVisitor::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
+bool InstallAPIVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
   // Skip forward declaration for classes (@class)
   if (!D->isThisDeclarationADefinition())
     return true;
@@ -195,7 +195,7 @@ bool InstallAPIVisitor::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
   return true;
 }
 
-bool InstallAPIVisitor::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+bool InstallAPIVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
   StringRef CategoryName = D->getName();
   // Skip over declarations that access could not be collected for.
   auto Access = getAccessForDecl(D);
@@ -213,7 +213,7 @@ bool InstallAPIVisitor::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
   return true;
 }
 
-bool InstallAPIVisitor::VisitVarDecl(const VarDecl *D) {
+bool InstallAPIVisitor::VisitVarDecl(VarDecl *D) {
   // Skip function parameters.
   if (isa<ParmVarDecl>(D))
     return true;
@@ -248,7 +248,7 @@ bool InstallAPIVisitor::VisitVarDecl(const VarDecl *D) {
   return true;
 }
 
-bool InstallAPIVisitor::VisitFunctionDecl(const FunctionDecl *D) {
+bool InstallAPIVisitor::VisitFunctionDecl(FunctionDecl *D) {
   if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(D)) {
     // Skip member function in class templates.
     if (M->getParent()->getDescribedClassTemplate() != nullptr)
@@ -554,7 +554,7 @@ void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D,
   }
 }
 
-bool InstallAPIVisitor::VisitCXXRecordDecl(const CXXRecordDecl *D) {
+bool InstallAPIVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
   if (!D->isCompleteDefinition())
     return true;
 
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
index 5f7153cd53ac21..ee5c69ef55e598 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -11,8 +11,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/PriorityQueue.h"
@@ -186,7 +187,7 @@ static bool isNodeExcluded(const SourceManager &SrcMgr, T *N) {
 
 namespace {
 // Sets Height, Parent and Children for each node.
-struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
+struct PreorderVisitor : DynamicRecursiveASTVisitor {
   int Id = 0, Depth = 0;
   NodeId Parent;
   SyntaxTree::Impl &Tree;
@@ -228,30 +229,30 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
     for (NodeId Child : N.Children)
       N.Height = std::max(N.Height, 1 + Tree.getNode(Child).Height);
   }
-  bool TraverseDecl(Decl *D) {
+  bool TraverseDecl(Decl *D) override {
     if (isNodeExcluded(Tree.AST.getSourceManager(), D))
       return true;
     auto SavedState = PreTraverse(D);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseDecl(D);
+    DynamicRecursiveASTVisitor::TraverseDecl(D);
     PostTraverse(SavedState);
     return true;
   }
-  bool TraverseStmt(Stmt *S) {
+  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
     if (auto *E = dyn_cast_or_null<Expr>(S))
       S = E->IgnoreImplicit();
     if (isNodeExcluded(Tree.AST.getSourceManager(), S))
       return true;
     auto SavedState = PreTraverse(S);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseStmt(S);
+    DynamicRecursiveASTVisitor::TraverseStmt(S);
     PostTraverse(SavedState);
     return true;
   }
-  bool TraverseType(QualType T) { return true; }
-  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+  bool TraverseType(QualType T) override { return true; }
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
     if (isNodeExcluded(Tree.AST.getSourceManager(), Init))
       return true;
     auto SavedState = PreTraverse(Init);
-    RecursiveASTVisitor<PreorderVisitor>::TraverseConstructorInitializer(Init);
+    DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
     PostTraverse(SavedState);
     return true;
   }
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
index ac8ad344623cc3..a726990d8ff5f2 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -14,7 +14,7 @@
 #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
@@ -29,8 +29,7 @@ namespace tooling {
 namespace {
 
 /// Recursively visits each AST node to find the symbol underneath the cursor.
-class NamedDeclOccurrenceFindingVisitor
-    : public RecursiveSymbolVisitor<NamedDeclOccurrenceFindingVisitor> {
+class NamedDeclOccurrenceFindingVisitor : public RecursiveSymbolVisitor {
 public:
   // Finds the NamedDecl at a point in the source.
   // \param Point the location in the source to search for the NamedDecl.
@@ -41,7 +40,7 @@ class NamedDeclOccurrenceFindingVisitor
         Point(Point), Context(Context) {}
 
   bool visitSymbolOccurrence(const NamedDecl *ND,
-                             ArrayRef<SourceRange> NameRanges) {
+                             ArrayRef<SourceRange> NameRanges) override {
     if (!ND)
       return true;
     for (const auto &Range : NameRanges) {
@@ -98,14 +97,13 @@ namespace {
 
 /// Recursively visits each NamedDecl node to find the declaration with a
 /// specific name.
-class NamedDeclFindingVisitor
-    : public RecursiveASTVisitor<NamedDeclFindingVisitor> {
+class NamedDeclFindingVisitor : public DynamicRecursiveASTVisitor {
 public:
   explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}
 
   // We don't have to traverse the uses to find some declaration with a
   // specific name, so just visit the named declarations.
-  bool VisitNamedDecl(const NamedDecl *ND) {
+  bool VisitNamedDecl(NamedDecl *ND) override {
     if (!ND)
       return true;
     // Fully qualified name is used to find the declaration.
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
index 7708fea53d014c..d7a1f761fc3030 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendAction.h"
@@ -60,10 +60,12 @@ namespace {
 // AdditionalUSRFinder. AdditionalUSRFinder adds USRs of ctor and dtor if given
 // Decl refers to class and adds USRs of all overridden methods if Decl refers
 // to virtual method.
-class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
+class AdditionalUSRFinder : public DynamicRecursiveASTVisitor {
 public:
   AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
-      : FoundDecl(FoundDecl), Context(Context) {}
+      : FoundDecl(FoundDecl), Context(Context) {
+    ShouldVisitTemplateInstantiations = true;
+  }
 
   std::vector<std::string> Find() {
     // Fill OverriddenMethods and PartialSpecs storages.
@@ -102,9 +104,8 @@ class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
     return std::vector<std::string>(USRSet.begin(), USRSet.end());
   }
 
-  bool shouldVisitTemplateInstantiations() const { return true; }
 
-  bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
+  bool VisitCXXMethodDecl(CXXMethodDecl *MethodDecl) override {
     if (MethodDecl->isVirtual())
       OverriddenMethods.push_back(MethodDecl);
     if (MethodDecl->getInstantiatedFromMemberFunction())
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index c18f9290471fe4..8b60134017724f 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -16,7 +16,7 @@
 #include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -52,8 +52,7 @@ bool IsValidEditLoc(const clang::SourceManager& SM, clang::SourceLocation Loc) {
 
 // This visitor recursively searches for all instances of a USR in a
 // translation unit and stores them for later usage.
-class USRLocFindingASTVisitor
-    : public RecursiveSymbolVisitor<USRLocFindingASTVisitor> {
+class USRLocFindingASTVisitor : public RecursiveSymbolVisitor {
 public:
   explicit USRLocFindingASTVisitor(const std::vector<std::string> &USRs,
                                    StringRef PrevName,
@@ -64,7 +63,7 @@ class USRLocFindingASTVisitor
   }
 
   bool visitSymbolOccurrence(const NamedDecl *ND,
-                             ArrayRef<SourceRange> NameRanges) {
+                             ArrayRef<SourceRange> NameRanges) override {
     if (USRSet.find(getUSRForDecl(ND)) != USRSet.end()) {
       assert(NameRanges.size() == 1 &&
              "Multiple name pieces are not supported yet!");
@@ -153,7 +152,7 @@ NestedNameSpecifier *GetNestedNameForType(TypeLoc TL) {
 //
 // This class will traverse the AST and find every AST node whose USR is in the
 // given USRs' set.
-class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
+class RenameLocFinder : public DynamicRecursiveASTVisitor {
 public:
   RenameLocFinder(llvm::ArrayRef<std::string> USRs, ASTContext &Context)
       : USRSet(USRs.begin(), USRs.end()), Context(Context) {}
@@ -179,7 +178,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     bool IgnorePrefixQualifers;
   };
 
-  bool VisitNamedDecl(const NamedDecl *Decl) {
+  bool VisitNamedDecl(NamedDecl *Decl) override {
     // UsingDecl has been handled in other place.
     if (llvm::isa<UsingDecl>(Decl))
       return true;
@@ -212,7 +211,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitMemberExpr(const MemberExpr *Expr) {
+  bool VisitMemberExpr(MemberExpr *Expr) override {
     const NamedDecl *Decl = Expr->getFoundDecl();
     auto StartLoc = Expr->getMemberLoc();
     auto EndLoc = Expr->getMemberLoc();
@@ -226,7 +225,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
+  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) override {
     for (const DesignatedInitExpr::Designator &D : E->designators()) {
       if (D.isFieldDesignator()) {
         if (const FieldDecl *Decl = D.getFieldDecl()) {
@@ -245,7 +244,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
+  bool VisitCXXConstructorDecl(CXXConstructorDecl *CD) override {
     // Fix the constructor initializer when renaming class members.
     for (const auto *Initializer : CD->inits()) {
       // Ignore implicit initializers.
@@ -266,7 +265,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+  bool VisitDeclRefExpr(DeclRefExpr *Expr) override {
     const NamedDecl *Decl = Expr->getFoundDecl();
     // Get the underlying declaration of the shadow declaration introduced by a
     // using declaration.
@@ -340,7 +339,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitUsingDecl(const UsingDecl *Using) {
+  bool VisitUsingDecl(UsingDecl *Using) override {
     for (const auto *UsingShadow : Using->shadows()) {
       if (isInUSRSet(UsingShadow->getTargetDecl())) {
         UsingDecls.push_back(Using);
@@ -369,7 +368,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitTypeLoc(TypeLoc Loc) {
+  bool VisitTypeLoc(TypeLoc Loc) override {
     auto Parents = Context.getParents(Loc);
     TypeLoc ParentTypeLoc;
     if (!Parents.empty()) {

>From 73fba5085c13e2fe2d154ab552be7482265da311 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 15 Jul 2024 18:46:26 +0200
Subject: [PATCH 13/27] Enable overriding dataTraverseStmtPre/Post

---
 clang/include/clang/AST/DynamicRecursiveASTVisitor.h | 4 ++--
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp         | 5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index a0c7aa2736a7b7..208be2e924025b 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -182,7 +182,7 @@ class DynamicRecursiveASTVisitor {
   bool WalkUpFromType(Type *T) { return VisitType(T); }
   bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
 
-  /*/// Invoked before visiting a statement or expression via data recursion.
+  /// Invoked before visiting a statement or expression via data recursion.
   ///
   /// \returns false to skip visiting the node, true otherwise.
   virtual bool dataTraverseStmtPre(Stmt *S) { return true; }
@@ -192,7 +192,7 @@ class DynamicRecursiveASTVisitor {
   /// returned false.
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
-  virtual bool dataTraverseStmtPost(Stmt *S) { return true; }*/
+  virtual bool dataTraverseStmtPost(Stmt *S) { return true; }
 
   /*// Declare Traverse*() and friends for attributes.
 #define DYNAMIC_ATTR_VISITOR_DECLS
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index fb846792f1e6e6..f919067da7e759 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -102,9 +102,8 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseNestedNameSpecifierLoc(NNS);
   }
 
-
-  /*bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
-  bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }*/
+  bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
+  bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }
 
   /// Visit a node.
   bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }

>From 6f622712b477f76f926cb7846f19dac524aa18e8 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 23 Jul 2024 16:20:07 +0200
Subject: [PATCH 14/27] Migrate more visitors

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    |  21 ++-
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  27 +++
 clang/lib/ASTMatchers/ASTMatchFinder.cpp      | 156 +++++++++---------
 clang/lib/CodeGen/CodeGenPGO.cpp              |  52 +++---
 .../InterfaceStubFunctionsConsumer.cpp        |   6 +-
 5 files changed, 143 insertions(+), 119 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 208be2e924025b..e75433f7a8b704 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -19,7 +19,7 @@ class ASTContext;
 ///   - Visiting attributes
 ///   - Post-order traversal
 ///   - Overriding WalkUpFromX
-///   - Overriding dataTraverseStmtPre/Post()
+///   - Overriding getStmtChildren()
 ///
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
@@ -194,15 +194,24 @@ class DynamicRecursiveASTVisitor {
   /// \returns false if the visitation was terminated early, true otherwise.
   virtual bool dataTraverseStmtPost(Stmt *S) { return true; }
 
+  virtual bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue = nullptr);
+
   /*// Declare Traverse*() and friends for attributes.
 #define DYNAMIC_ATTR_VISITOR_DECLS
 #include "clang/AST/AttrVisitor.inc"
 #undef DYNAMIC_ATTR_VISITOR_DECLS*/
 
+  // Not virtual for now because no-one overrides them.
+#define DEF_TRAVERSE_TMPL_INST(kind)                                           \
+  virtual bool TraverseTemplateInstantiations(kind##TemplateDecl *D);
+  DEF_TRAVERSE_TMPL_INST(Class)
+  DEF_TRAVERSE_TMPL_INST(Var)
+  DEF_TRAVERSE_TMPL_INST(Function)
+#undef DEF_TRAVERSE_TMPL_INST
+
   // Declare Traverse*() for and friends all concrete Decl classes.
 #define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
-  virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#define DECL(CLASS, BASE) virtual bool Traverse##CLASS##Decl(CLASS##Decl *D);
 #include "clang/AST/DeclNodes.inc"
 
 #define DECL(CLASS, BASE)                                                      \
@@ -212,8 +221,7 @@ class DynamicRecursiveASTVisitor {
 
   // Declare Traverse*() and friends for all concrete Stmt classes.
 #define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT)                                                    \
-  virtual bool Traverse##CLASS(CLASS *S);
+#define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(CLASS *S);
 #include "clang/AST/StmtNodes.inc"
 
 #define STMT(CLASS, PARENT)                                                    \
@@ -223,8 +231,7 @@ class DynamicRecursiveASTVisitor {
 
   // Declare Traverse*() and friends for all concrete Type classes.
 #define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE)                                                      \
-  virtual bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) virtual bool Traverse##CLASS##Type(CLASS##Type *T);
 #include "clang/AST/TypeNodes.inc"
 
 #define TYPE(CLASS, BASE)                                                      \
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index f919067da7e759..e7f896f4bc56f5 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -104,6 +104,9 @@ struct Impl : RecursiveASTVisitor<Impl> {
 
   bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
   bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }
+  bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
+    return Visitor.dataTraverseNode(S, Queue);
+  }
 
   /// Visit a node.
   bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }
@@ -116,6 +119,15 @@ struct Impl : RecursiveASTVisitor<Impl> {
   #include "clang/AST/AttrVisitor.inc"
   #undef ATTR_VISITOR_DECLS*/
 
+#define DEF_TRAVERSE_TMPL_INST(kind)                                           \
+  bool TraverseTemplateInstantiations(kind##TemplateDecl *D) {                 \
+    return Visitor.TraverseTemplateInstantiations(D);                          \
+  }
+  DEF_TRAVERSE_TMPL_INST(Class)
+  DEF_TRAVERSE_TMPL_INST(Var)
+  DEF_TRAVERSE_TMPL_INST(Function)
+#undef DEF_TRAVERSE_TMPL_INST
+
   // Declarations.
 #define ABSTRACT_DECL(DECL)
 #define DECL(CLASS, BASE)                                                      \
@@ -282,12 +294,27 @@ bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
       NNS);
 }
 
+bool DynamicRecursiveASTVisitor::dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::dataTraverseNode(S, Queue);
+}
+
 /*
 #define DYNAMIC_ATTR_VISITOR_IMPL
 #include "clang/AST/AttrVisitor.inc"
 #undef DYNAMIC_ATTR_VISITOR_IMPL
 */
 
+#define DEF_TRAVERSE_TMPL_INST(kind)                                           \
+  bool DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(             \
+      kind##TemplateDecl *D) {                                                 \
+    return Impl(*this)                                                         \
+        .RecursiveASTVisitor<Impl>::TraverseTemplateInstantiations(D);         \
+  }
+DEF_TRAVERSE_TMPL_INST(Class)
+DEF_TRAVERSE_TMPL_INST(Var)
+DEF_TRAVERSE_TMPL_INST(Function)
+#undef DEF_TRAVERSE_TMPL_INST
+
 // Declare Traverse*() for and friends all concrete Decl classes.
 #define ABSTRACT_DECL(DECL)
 #define DECL(CLASS, BASE)                                                      \
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 0bac2ed63a927e..e9c8779972f475 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -19,7 +19,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringMap.h"
@@ -87,11 +87,8 @@ struct MemoizedMatchResult {
 
 // A RecursiveASTVisitor that traverses all children or all descendants of
 // a node.
-class MatchChildASTVisitor
-    : public RecursiveASTVisitor<MatchChildASTVisitor> {
+class MatchChildASTVisitor : public DynamicRecursiveASTVisitor {
 public:
-  typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
-
   // Creates an AST visitor that matches 'matcher' on all children or
   // descendants of a traversed node. max_depth is the maximum depth
   // to traverse: use 1 for matching the children and INT_MAX for
@@ -101,8 +98,10 @@ class MatchChildASTVisitor
                        bool IgnoreImplicitChildren,
                        ASTMatchFinder::BindKind Bind)
       : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0),
-        MaxDepth(MaxDepth), IgnoreImplicitChildren(IgnoreImplicitChildren),
-        Bind(Bind), Matches(false) {}
+        MaxDepth(MaxDepth), Bind(Bind), Matches(false) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = !IgnoreImplicitChildren;
+  }
 
   // Returns true if a match is found in the subtree rooted at the
   // given AST node. This is done via a set of mutually recursive
@@ -111,7 +110,7 @@ class MatchChildASTVisitor
   //
   //   - Traverse(node) calls BaseTraverse(node) when it needs
   //     to visit the descendants of node.
-  //   - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
+  //   - BaseTraverse(node) then calls (via the DynamicRecursiveASTVisitor)
   //     Traverse*(c) for each child c of 'node'.
   //   - Traverse*(c) in turn calls Traverse(c), completing the
   //     recursion.
@@ -151,7 +150,7 @@ class MatchChildASTVisitor
   // The following are overriding methods from the base visitor class.
   // They are public only to allow CRTP to work. They are *not *part
   // of the public API of this class.
-  bool TraverseDecl(Decl *DeclNode) {
+  bool TraverseDecl(Decl *DeclNode) override {
 
     if (DeclNode && DeclNode->isImplicit() &&
         Finder->isTraversalIgnoringImplicitNodes())
@@ -175,7 +174,7 @@ class MatchChildASTVisitor
     return StmtToTraverse;
   }
 
-  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) {
+  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) override {
     // If we need to keep track of the depth, we can't perform data recursion.
     if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX))
       Queue = nullptr;
@@ -185,16 +184,16 @@ class MatchChildASTVisitor
     if (!StmtToTraverse)
       return true;
 
-    if (IgnoreImplicitChildren && isa<CXXDefaultArgExpr>(StmtNode))
+    if (!ShouldVisitImplicitCode && isa<CXXDefaultArgExpr>(StmtNode))
       return true;
 
     if (!match(*StmtToTraverse))
       return false;
-    return VisitorBase::TraverseStmt(StmtToTraverse, Queue);
+    return DynamicRecursiveASTVisitor::TraverseStmt(StmtToTraverse, Queue);
   }
   // We assume that the QualType and the contained type are on the same
   // hierarchy level. Thus, we try to match either of them.
-  bool TraverseType(QualType TypeNode) {
+  bool TraverseType(QualType TypeNode) override {
     if (TypeNode.isNull())
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -206,7 +205,7 @@ class MatchChildASTVisitor
   }
   // We assume that the TypeLoc, contained QualType and contained Type all are
   // on the same hierarchy level. Thus, we try to match all of them.
-  bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+  bool TraverseTypeLoc(TypeLoc TypeLocNode) override {
     if (TypeLocNode.isNull())
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -219,11 +218,11 @@ class MatchChildASTVisitor
     // The TypeLoc is matched inside traverse.
     return traverse(TypeLocNode);
   }
-  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) override {
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return (NNS == nullptr) || traverse(*NNS);
   }
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
     if (!NNS)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -231,19 +230,19 @@ class MatchChildASTVisitor
       return false;
     return traverse(NNS);
   }
-  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) {
+  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) override {
     if (!CtorInit)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return traverse(*CtorInit);
   }
-  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) {
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc& TAL) override {
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return traverse(TAL);
   }
-  bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) {
+  bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) override {
     if (!Finder->isTraversalIgnoringImplicitNodes())
-      return VisitorBase::TraverseCXXForRangeStmt(Node);
+      return DynamicRecursiveASTVisitor::TraverseCXXForRangeStmt(Node);
     if (!Node)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -253,22 +252,22 @@ class MatchChildASTVisitor
     if (!match(*Node->getLoopVariable()))
       return false;
     if (match(*Node->getRangeInit()))
-      if (!VisitorBase::TraverseStmt(Node->getRangeInit()))
+      if (!DynamicRecursiveASTVisitor::TraverseStmt(Node->getRangeInit()))
         return false;
     if (!match(*Node->getBody()))
       return false;
-    return VisitorBase::TraverseStmt(Node->getBody());
+    return DynamicRecursiveASTVisitor::TraverseStmt(Node->getBody());
   }
-  bool TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *Node) {
+  bool TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *Node) override {
     if (!Finder->isTraversalIgnoringImplicitNodes())
-      return VisitorBase::TraverseCXXRewrittenBinaryOperator(Node);
+      return DynamicRecursiveASTVisitor::TraverseCXXRewrittenBinaryOperator(Node);
     if (!Node)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
 
     return match(*Node->getLHS()) && match(*Node->getRHS());
   }
-  bool TraverseAttr(Attr *A) {
+  bool TraverseAttr(Attr *A) override {
     if (A == nullptr ||
         (A->isImplicit() &&
          Finder->getASTContext().getParentMapContext().getTraversalKind() ==
@@ -277,9 +276,9 @@ class MatchChildASTVisitor
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return traverse(*A);
   }
-  bool TraverseLambdaExpr(LambdaExpr *Node) {
+  bool TraverseLambdaExpr(LambdaExpr *Node) override {
     if (!Finder->isTraversalIgnoringImplicitNodes())
-      return VisitorBase::TraverseLambdaExpr(Node);
+      return DynamicRecursiveASTVisitor::TraverseLambdaExpr(Node);
     if (!Node)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -309,12 +308,9 @@ class MatchChildASTVisitor
     if (!match(*Node->getBody()))
       return false;
 
-    return VisitorBase::TraverseStmt(Node->getBody());
+    return DynamicRecursiveASTVisitor::TraverseStmt(Node->getBody());
   }
 
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const { return !IgnoreImplicitChildren; }
-
 private:
   // Used for updating the depth during traversal.
   struct ScopedIncrement {
@@ -334,33 +330,33 @@ class MatchChildASTVisitor
   // Forwards the call to the corresponding Traverse*() method in the
   // base visitor class.
   bool baseTraverse(const Decl &DeclNode) {
-    return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
+    return DynamicRecursiveASTVisitor::TraverseDecl(const_cast<Decl*>(&DeclNode));
   }
   bool baseTraverse(const Stmt &StmtNode) {
-    return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
+    return DynamicRecursiveASTVisitor::TraverseStmt(const_cast<Stmt*>(&StmtNode));
   }
   bool baseTraverse(QualType TypeNode) {
-    return VisitorBase::TraverseType(TypeNode);
+    return DynamicRecursiveASTVisitor::TraverseType(TypeNode);
   }
   bool baseTraverse(TypeLoc TypeLocNode) {
-    return VisitorBase::TraverseTypeLoc(TypeLocNode);
+    return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode);
   }
   bool baseTraverse(const NestedNameSpecifier &NNS) {
-    return VisitorBase::TraverseNestedNameSpecifier(
+    return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifier(
         const_cast<NestedNameSpecifier*>(&NNS));
   }
   bool baseTraverse(NestedNameSpecifierLoc NNS) {
-    return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
+    return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
   }
   bool baseTraverse(const CXXCtorInitializer &CtorInit) {
-    return VisitorBase::TraverseConstructorInitializer(
+    return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(
         const_cast<CXXCtorInitializer *>(&CtorInit));
   }
   bool baseTraverse(TemplateArgumentLoc TAL) {
-    return VisitorBase::TraverseTemplateArgumentLoc(TAL);
+    return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(TAL);
   }
   bool baseTraverse(const Attr &AttrNode) {
-    return VisitorBase::TraverseAttr(const_cast<Attr *>(&AttrNode));
+    return DynamicRecursiveASTVisitor::TraverseAttr(const_cast<Attr *>(&AttrNode));
   }
 
   // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
@@ -410,19 +406,25 @@ class MatchChildASTVisitor
   BoundNodesTreeBuilder ResultBindings;
   int CurrentDepth;
   const int MaxDepth;
-  const bool IgnoreImplicitChildren;
   const ASTMatchFinder::BindKind Bind;
   bool Matches;
 };
 
 // Controls the outermost traversal of the AST and allows to match multiple
 // matchers.
-class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
+class MatchASTVisitor : public DynamicRecursiveASTVisitor,
                         public ASTMatchFinder {
 public:
   MatchASTVisitor(const MatchFinder::MatchersByType *Matchers,
                   const MatchFinder::MatchFinderOptions &Options)
-      : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {}
+      : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = true;
+
+    // We visit the lambda body explicitly, so instruct the RAV
+    // to not visit it on our behalf too.
+    ShouldVisitLambdaBody = false;
+  }
 
   ~MatchASTVisitor() override {
     if (Options.CheckProfiling) {
@@ -454,10 +456,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
     ActiveASTContext = NewActiveASTContext;
   }
 
-  // The following Visit*() and Traverse*() functions "override"
-  // methods in RecursiveASTVisitor.
-
-  bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) {
+  bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) override {
     // When we see 'typedef A B', we add name 'B' to the set of names
     // A's canonical type maps to.  This is necessary for implementing
     // isDerivedFrom(x) properly, where x can be the name of the base
@@ -492,23 +491,23 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
     return true;
   }
 
-  bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
+  bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) override {
     const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface();
     CompatibleAliases[InterfaceDecl].insert(CAD);
     return true;
   }
 
-  bool TraverseDecl(Decl *DeclNode);
-  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr);
-  bool TraverseType(QualType TypeNode);
-  bool TraverseTypeLoc(TypeLoc TypeNode);
-  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
-  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
-  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);
-  bool TraverseAttr(Attr *AttrNode);
+  bool TraverseDecl(Decl *DeclNode) override;
+  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) override;
+  bool TraverseType(QualType TypeNode) override;
+  bool TraverseTypeLoc(TypeLoc TypeNode) override;
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) override;
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override;
+  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) override;
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc& TAL) override;
+  bool TraverseAttr(Attr *AttrNode) override;
 
-  bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
+  bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) override {
     if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) {
       {
         ASTNodeNotAsIsSourceScope RAII(this, true);
@@ -589,7 +588,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
       TraverseStmt(LE->getBody());
       return true;
     }
-    return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue);
+    return DynamicRecursiveASTVisitor::dataTraverseNode(S, Queue);
   }
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
@@ -733,13 +732,6 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
   // Implements ASTMatchFinder::getASTContext.
   ASTContext &getASTContext() const override { return *ActiveASTContext; }
 
-  bool shouldVisitTemplateInstantiations() const { return true; }
-  bool shouldVisitImplicitCode() const { return true; }
-
-  // We visit the lambda body explicitly, so instruct the RAV
-  // to not visit it on our behalf too.
-  bool shouldVisitLambdaBody() const { return false; }
-
   bool IsMatchingInASTNodeNotSpelledInSource() const override {
     return TraversingASTNodeNotSpelledInSource;
   }
@@ -754,21 +746,21 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
     return TraversingASTNodeNotAsIs;
   }
 
-  bool TraverseTemplateInstantiations(ClassTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(ClassTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
         D);
   }
 
-  bool TraverseTemplateInstantiations(VarTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(VarTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
         D);
   }
 
-  bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
         D);
   }
 
@@ -1468,7 +1460,7 @@ bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
   ASTChildrenNotSpelledInSourceScope RAII2(this, ScopedChildren);
 
   match(*DeclNode);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
+  return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode);
 }
 
 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
@@ -1480,12 +1472,12 @@ bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
 
   ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal);
   match(*StmtNode);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue);
+  return DynamicRecursiveASTVisitor::TraverseStmt(StmtNode, Queue);
 }
 
 bool MatchASTVisitor::TraverseType(QualType TypeNode) {
   match(TypeNode);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
+  return DynamicRecursiveASTVisitor::TraverseType(TypeNode);
 }
 
 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
@@ -1496,12 +1488,12 @@ bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
   // each TypeLoc.
   match(TypeLocNode);
   match(TypeLocNode.getType());
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode);
+  return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode);
 }
 
 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
   match(*NNS);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS);
+  return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifier(NNS);
 }
 
 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
@@ -1516,7 +1508,7 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
   if (NNS.hasQualifier())
     match(*NNS.getNestedNameSpecifier());
   return
-      RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
+      DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
 }
 
 bool MatchASTVisitor::TraverseConstructorInitializer(
@@ -1534,18 +1526,18 @@ bool MatchASTVisitor::TraverseConstructorInitializer(
 
   match(*CtorInit);
 
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer(
+  return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(
       CtorInit);
 }
 
-bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) {
+bool MatchASTVisitor::TraverseTemplateArgumentLoc(const TemplateArgumentLoc& Loc) {
   match(Loc);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateArgumentLoc(Loc);
+  return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(Loc);
 }
 
 bool MatchASTVisitor::TraverseAttr(Attr *AttrNode) {
   match(*AttrNode);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseAttr(AttrNode);
+  return DynamicRecursiveASTVisitor::TraverseAttr(AttrNode);
 }
 
 class MatchASTConsumer : public ASTConsumer {
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index ea726b5708a4a1..91aea219e8b6ff 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -13,7 +13,7 @@
 #include "CodeGenPGO.h"
 #include "CodeGenFunction.h"
 #include "CoverageMappingGen.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
@@ -158,9 +158,7 @@ static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
 }
 
 /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
-struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
-  using Base = RecursiveASTVisitor<MapRegionCounters>;
-
+struct MapRegionCounters : DynamicRecursiveASTVisitor {
   /// The next counter value to assign.
   unsigned NextCounter;
   /// The function hash.
@@ -186,16 +184,16 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
 
   // Blocks and lambdas are handled as separate functions, so we need not
   // traverse them in the parent context.
-  bool TraverseBlockExpr(BlockExpr *BE) { return true; }
-  bool TraverseLambdaExpr(LambdaExpr *LE) {
+  bool TraverseBlockExpr(BlockExpr *BE) override { return true; }
+  bool TraverseLambdaExpr(LambdaExpr *LE) override {
     // Traverse the captures, but not the body.
     for (auto C : zip(LE->captures(), LE->capture_inits()))
       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
     return true;
   }
-  bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
+  bool TraverseCapturedStmt(CapturedStmt *CS) override { return true; }
 
-  bool VisitDecl(const Decl *D) {
+  bool VisitDecl(Decl *D) override {
     switch (D->getKind()) {
     default:
       break;
@@ -237,7 +235,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
   SmallVector<const BinaryOperator *, 16> LogOpStack;
 
   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
-  bool dataTraverseStmtPre(Stmt *S) {
+  bool dataTraverseStmtPre(Stmt *S) override {
     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
     if (MCDCMaxCond == 0)
       return true;
@@ -277,7 +275,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
   // Hook: dataTraverseStmtPost() is invoked by the AST visitor after visiting
   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
   // logical operation (boolean expression) nest is encountered.
-  bool dataTraverseStmtPost(Stmt *S) {
+  bool dataTraverseStmtPost(Stmt *S) override {
     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
     if (MCDCMaxCond == 0)
       return true;
@@ -330,7 +328,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
   /// semantics of the operator. This is only valid for ">= v7" of the profile
   /// version so that we facilitate backward compatibility. In addition, in
   /// order to use MC/DC, count the number of total LHS and RHS conditions.
-  bool VisitBinaryOperator(BinaryOperator *S) {
+  bool VisitBinaryOperator(BinaryOperator *S) override {
     if (S->isLogicalOp()) {
       if (CodeGenFunction::isInstrumentedCondition(S->getLHS()))
         NumCond++;
@@ -342,19 +340,19 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
         NumCond++;
       }
     }
-    return Base::VisitBinaryOperator(S);
+    return DynamicRecursiveASTVisitor::VisitBinaryOperator(S);
   }
 
-  bool VisitConditionalOperator(ConditionalOperator *S) {
+  bool VisitConditionalOperator(ConditionalOperator *S) override {
     if (llvm::EnableSingleByteCoverage && S->getTrueExpr())
       CounterMap[S->getTrueExpr()] = NextCounter++;
     if (llvm::EnableSingleByteCoverage && S->getFalseExpr())
       CounterMap[S->getFalseExpr()] = NextCounter++;
-    return Base::VisitConditionalOperator(S);
+    return DynamicRecursiveASTVisitor::VisitConditionalOperator(S);
   }
 
   /// Include \p S in the function hash.
-  bool VisitStmt(Stmt *S) {
+  bool VisitStmt(Stmt *S) override {
     auto Type = updateCounterMappings(S);
     if (Hash.getHashVersion() != PGO_HASH_V1)
       Type = getHashType(Hash.getHashVersion(), S);
@@ -363,10 +361,10 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
     return true;
   }
 
-  bool TraverseIfStmt(IfStmt *If) {
+  bool TraverseIfStmt(IfStmt *If) override {
     // If we used the V1 hash, use the default traversal.
     if (Hash.getHashVersion() == PGO_HASH_V1)
-      return Base::TraverseIfStmt(If);
+      return DynamicRecursiveASTVisitor::TraverseIfStmt(If);
 
     // When single byte coverage mode is enabled, add a counter to then and
     // else.
@@ -396,7 +394,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
     return true;
   }
 
-  bool TraverseWhileStmt(WhileStmt *While) {
+  bool TraverseWhileStmt(WhileStmt *While) override {
     // When single byte coverage mode is enabled, add a counter to condition and
     // body.
     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
@@ -409,13 +407,13 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
         CounterMap[While->getBody()] = NextCounter++;
     }
 
-    Base::TraverseWhileStmt(While);
+    DynamicRecursiveASTVisitor::TraverseWhileStmt(While);
     if (Hash.getHashVersion() != PGO_HASH_V1)
       Hash.combine(PGOHash::EndOfScope);
     return true;
   }
 
-  bool TraverseDoStmt(DoStmt *Do) {
+  bool TraverseDoStmt(DoStmt *Do) override {
     // When single byte coverage mode is enabled, add a counter to condition and
     // body.
     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
@@ -428,13 +426,13 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
         CounterMap[Do->getBody()] = NextCounter++;
     }
 
-    Base::TraverseDoStmt(Do);
+    DynamicRecursiveASTVisitor::TraverseDoStmt(Do);
     if (Hash.getHashVersion() != PGO_HASH_V1)
       Hash.combine(PGOHash::EndOfScope);
     return true;
   }
 
-  bool TraverseForStmt(ForStmt *For) {
+  bool TraverseForStmt(ForStmt *For) override {
     // When single byte coverage mode is enabled, add a counter to condition,
     // increment and body.
     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
@@ -449,13 +447,13 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
         CounterMap[For->getBody()] = NextCounter++;
     }
 
-    Base::TraverseForStmt(For);
+    DynamicRecursiveASTVisitor::TraverseForStmt(For);
     if (Hash.getHashVersion() != PGO_HASH_V1)
       Hash.combine(PGOHash::EndOfScope);
     return true;
   }
 
-  bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) {
+  bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) override {
     // When single byte coverage mode is enabled, add a counter to body.
     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
     for (Stmt *CS : ForRange->children()) {
@@ -465,7 +463,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
         CounterMap[ForRange->getBody()] = NextCounter++;
     }
 
-    Base::TraverseCXXForRangeStmt(ForRange);
+    DynamicRecursiveASTVisitor::TraverseCXXForRangeStmt(ForRange);
     if (Hash.getHashVersion() != PGO_HASH_V1)
       Hash.combine(PGOHash::EndOfScope);
     return true;
@@ -475,8 +473,8 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
 // stability, define a custom traversal which tracks the end of the statement
 // in the hash (provided we're not using the V1 hash).
 #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
-  bool Traverse##N(N *S) {                                                     \
-    Base::Traverse##N(S);                                                      \
+  bool Traverse##N(N *S) override {                                            \
+    DynamicRecursiveASTVisitor::Traverse##N(S);                                \
     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
       Hash.combine(PGOHash::EndOfScope);                                       \
     return true;                                                               \
diff --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
index d7cfd23bb0a7a6..616f0c9a8241f6 100644
--- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -242,8 +242,8 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer {
       : Instance(Instance), InFile(InFile), Format(Format) {}
 
   void HandleTranslationUnit(ASTContext &context) override {
-    struct Visitor : public RecursiveASTVisitor<Visitor> {
-      bool VisitNamedDecl(NamedDecl *ND) {
+    struct Visitor : DynamicRecursiveASTVisitor {
+      bool VisitNamedDecl(NamedDecl *ND) override {
         if (const auto *FD = dyn_cast<FunctionDecl>(ND))
           if (FD->isLateTemplateParsed()) {
             LateParsedDecls.insert(FD);

>From c756a6599a18cb12f882f5f04737884c28bf8afb Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 23 Jul 2024 17:50:51 +0200
Subject: [PATCH 15/27] Migrate more visitors, again

---
 clang/docs/RAVFrontendAction.rst              | 17 ++--
 .../CallSuperAttribute/CallSuperAttrInfo.cpp  | 12 +--
 .../PrintFunctionNames/PrintFunctionNames.cpp |  7 +-
 .../clang/AST/DynamicRecursiveASTVisitor.h    |  4 +
 clang/lib/AST/ParentMapContext.cpp            | 42 +++++-----
 clang/lib/Index/IndexBody.cpp                 | 81 +++++++++----------
 6 files changed, 82 insertions(+), 81 deletions(-)

diff --git a/clang/docs/RAVFrontendAction.rst b/clang/docs/RAVFrontendAction.rst
index 2e387b4b339d6c..1e7d88a19f201a 100644
--- a/clang/docs/RAVFrontendAction.rst
+++ b/clang/docs/RAVFrontendAction.rst
@@ -70,10 +70,9 @@ CXXRecordDecl's.
 
 ::
 
-      class FindNamedClassVisitor
-        : public RecursiveASTVisitor<FindNamedClassVisitor> {
+      class FindNamedClassVisitor : public DynamicRecursiveASTVisitor {
       public:
-        bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
+        bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) override {
           // For debugging, dumping the AST nodes will show which nodes are already
           // being visited.
           Declaration->dump();
@@ -91,7 +90,7 @@ can check for a specific qualified name:
 
 ::
 
-      bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
+      bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) override {
         if (Declaration->getQualifiedNameAsString() == "n::m::C")
           Declaration->dump();
         return true;
@@ -122,7 +121,7 @@ locations:
 
 ::
 
-      bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
+      bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) override {
         if (Declaration->getQualifiedNameAsString() == "n::m::C") {
           // getFullLoc uses the ASTContext's SourceManager to resolve the source
           // location and break it up into its line and column parts.
@@ -143,20 +142,20 @@ Now we can combine all of the above into a small example program:
 ::
 
       #include "clang/AST/ASTConsumer.h"
-      #include "clang/AST/RecursiveASTVisitor.h"
+      #include "clang/AST/DynamicRecursiveASTVisitor.h"
+      #include "clang/AST/DeclCXX.h"
       #include "clang/Frontend/CompilerInstance.h"
       #include "clang/Frontend/FrontendAction.h"
       #include "clang/Tooling/Tooling.h"
 
       using namespace clang;
 
-      class FindNamedClassVisitor
-        : public RecursiveASTVisitor<FindNamedClassVisitor> {
+      class FindNamedClassVisitor : public DynamicRecursiveASTVisitor {
       public:
         explicit FindNamedClassVisitor(ASTContext *Context)
           : Context(Context) {}
 
-        bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
+        bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) override {
           if (Declaration->getQualifiedNameAsString() == "n::m::C") {
             FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getBeginLoc());
             if (FullLocation.isValid())
diff --git a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
index 12d4c311586e6f..451506b13ab313 100644
--- a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
+++ b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
@@ -25,7 +25,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Sema.h"
@@ -41,13 +41,14 @@ bool isMarkedAsCallSuper(const CXXMethodDecl *D) {
   return MarkedMethods.contains(D);
 }
 
-class MethodUsageVisitor : public RecursiveASTVisitor<MethodUsageVisitor> {
+class MethodUsageVisitor : public DynamicRecursiveASTVisitor {
 public:
   bool IsOverriddenUsed = false;
   explicit MethodUsageVisitor(
       llvm::SmallPtrSet<const CXXMethodDecl *, 16> &MustCalledMethods)
       : MustCalledMethods(MustCalledMethods) {}
-  bool VisitCallExpr(CallExpr *CallExpr) {
+
+  bool VisitCallExpr(CallExpr *CallExpr) override {
     const CXXMethodDecl *Callee = nullptr;
     for (const auto &MustCalled : MustCalledMethods) {
       if (CallExpr->getCalleeDecl() == MustCalled) {
@@ -67,7 +68,7 @@ class MethodUsageVisitor : public RecursiveASTVisitor<MethodUsageVisitor> {
   llvm::SmallPtrSet<const CXXMethodDecl *, 16> &MustCalledMethods;
 };
 
-class CallSuperVisitor : public RecursiveASTVisitor<CallSuperVisitor> {
+class CallSuperVisitor : public DynamicRecursiveASTVisitor {
 public:
   CallSuperVisitor(DiagnosticsEngine &Diags) : Diags(Diags) {
     WarningSuperNotCalled = Diags.getCustomDiagID(
@@ -77,7 +78,8 @@ class CallSuperVisitor : public RecursiveASTVisitor<CallSuperVisitor> {
     NotePreviousCallSuperDeclaration = Diags.getCustomDiagID(
         DiagnosticsEngine::Note, "function marked 'call_super' here");
   }
-  bool VisitCXXMethodDecl(CXXMethodDecl *MethodDecl) {
+
+  bool VisitCXXMethodDecl(CXXMethodDecl *MethodDecl) override {
     if (MethodDecl->isThisDeclarationADefinition() && MethodDecl->hasBody()) {
       // First find out which overridden methods are marked as 'call_super'
       llvm::SmallPtrSet<const CXXMethodDecl *, 16> OverriddenMarkedMethods;
diff --git a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
index b2b785b87c25cf..5100901f74d992 100644
--- a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
+++ b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -14,7 +14,7 @@
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/Support/raw_ostream.h"
@@ -52,11 +52,12 @@ class PrintFunctionsConsumer : public ASTConsumer {
     // The advantage of doing this in HandleTranslationUnit() is that all
     // codegen (when using -add-plugin) is completely finished and this can't
     // affect the compiler output.
-    struct Visitor : public RecursiveASTVisitor<Visitor> {
+    struct Visitor : DynamicRecursiveASTVisitor {
       const std::set<std::string> &ParsedTemplates;
       Visitor(const std::set<std::string> &ParsedTemplates)
           : ParsedTemplates(ParsedTemplates) {}
-      bool VisitFunctionDecl(FunctionDecl *FD) {
+
+      bool VisitFunctionDecl(FunctionDecl *FD) override {
         if (FD->isLateTemplateParsed() &&
             ParsedTemplates.count(FD->getNameAsString()))
           LateParsedDecls.insert(FD);
diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index e75433f7a8b704..8b89518863540d 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -24,6 +24,7 @@ class ASTContext;
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
 public:
+  // FIXME: I think we can just get rid of the Queue entirely.
   using DataRecursionQueue =
       SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>;
 
@@ -114,6 +115,8 @@ class DynamicRecursiveASTVisitor {
   ///
   /// \returns false if the visitation was terminated early, true
   /// otherwise (including when the argument is nullptr).
+  ///
+  // FIXME: I think we can just get rid of the Queue entirely.
   virtual bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
 
   /// Recursively visit a template argument and dispatch to the
@@ -194,6 +197,7 @@ class DynamicRecursiveASTVisitor {
   /// \returns false if the visitation was terminated early, true otherwise.
   virtual bool dataTraverseStmtPost(Stmt *S) { return true; }
 
+  // FIXME: I think we can just get rid of the Queue entirely.
   virtual bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue = nullptr);
 
   /*// Declare Traverse*() and friends for attributes.
diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index 9723c0cfa83bbe..eb8a2119afd795 100644
--- a/clang/lib/AST/ParentMapContext.cpp
+++ b/clang/lib/AST/ParentMapContext.cpp
@@ -12,9 +12,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/TemplateBase.h"
 
 using namespace clang;
@@ -352,19 +353,14 @@ template <> DynTypedNode createDynTypedNode(const ObjCProtocolLoc &Node) {
 /// traversal - there are other relationships (for example declaration context)
 /// in the AST that are better modeled by special matchers.
 class ParentMapContext::ParentMap::ASTVisitor
-    : public RecursiveASTVisitor<ASTVisitor> {
+    : public DynamicRecursiveASTVisitor {
 public:
-  ASTVisitor(ParentMap &Map) : Map(Map) {}
+  ASTVisitor(ParentMap &Map) : Map(Map) {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = true;
+  }
 
 private:
-  friend class RecursiveASTVisitor<ASTVisitor>;
-
-  using VisitorBase = RecursiveASTVisitor<ASTVisitor>;
-
-  bool shouldVisitTemplateInstantiations() const { return true; }
-
-  bool shouldVisitImplicitCode() const { return true; }
-
   /// Record the parent of the node we're visiting.
   /// MapNode is the child, the parent is on top of ParentStack.
   /// Parents is the parent storage (either PointerParents or OtherParents).
@@ -427,42 +423,42 @@ class ParentMapContext::ParentMap::ASTVisitor
     return Result;
   }
 
-  bool TraverseDecl(Decl *DeclNode) {
+  bool TraverseDecl(Decl *DeclNode) override {
     return TraverseNode(
-        DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
+        DeclNode, DeclNode, [&] { return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode); },
         &Map.PointerParents);
   }
-  bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+  bool TraverseTypeLoc(TypeLoc TypeLocNode) override {
     return TraverseNode(
         TypeLocNode, DynTypedNode::create(TypeLocNode),
-        [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
+        [&] { return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode); },
         &Map.OtherParents);
   }
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) override {
     return TraverseNode(
         NNSLocNode, DynTypedNode::create(NNSLocNode),
-        [&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
+        [&] { return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSLocNode); },
         &Map.OtherParents);
   }
-  bool TraverseAttr(Attr *AttrNode) {
+  bool TraverseAttr(Attr *AttrNode) override {
     return TraverseNode(
-        AttrNode, AttrNode, [&] { return VisitorBase::TraverseAttr(AttrNode); },
+        AttrNode, AttrNode, [&] { return DynamicRecursiveASTVisitor::TraverseAttr(AttrNode); },
         &Map.PointerParents);
   }
-  bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) {
+  bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) override {
     return TraverseNode(
         ProtocolLocNode, DynTypedNode::create(ProtocolLocNode),
-        [&] { return VisitorBase::TraverseObjCProtocolLoc(ProtocolLocNode); },
+        [&] { return DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(ProtocolLocNode); },
         &Map.OtherParents);
   }
 
   // Using generic TraverseNode for Stmt would prevent data-recursion.
-  bool dataTraverseStmtPre(Stmt *StmtNode) {
+  bool dataTraverseStmtPre(Stmt *StmtNode) override {
     addParent(StmtNode, &Map.PointerParents);
     ParentStack.push_back(DynTypedNode::create(*StmtNode));
     return true;
   }
-  bool dataTraverseStmtPost(Stmt *StmtNode) {
+  bool dataTraverseStmtPost(Stmt *StmtNode) override {
     ParentStack.pop_back();
     return true;
   }
diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index c18daf7faa7497..40f9deffa96292 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -10,8 +10,10 @@
 #include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprConcepts.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 
 using namespace clang;
@@ -19,41 +21,39 @@ using namespace clang::index;
 
 namespace {
 
-class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
+class BodyIndexer : public DynamicRecursiveASTVisitor {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
   SmallVector<Stmt*, 16> StmtStack;
 
-  typedef RecursiveASTVisitor<BodyIndexer> base;
-
   Stmt *getParentStmt() const {
     return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
   }
 public:
   BodyIndexer(IndexingContext &indexCtx,
               const NamedDecl *Parent, const DeclContext *DC)
-    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
+    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-  bool dataTraverseStmtPre(Stmt *S) {
+  bool dataTraverseStmtPre(Stmt *S) override {
     StmtStack.push_back(S);
     return true;
   }
 
-  bool dataTraverseStmtPost(Stmt *S) {
+  bool dataTraverseStmtPost(Stmt *S) override {
     assert(StmtStack.back() == S);
     StmtStack.pop_back();
     return true;
   }
 
-  bool TraverseTypeLoc(TypeLoc TL) {
+  bool TraverseTypeLoc(TypeLoc TL) override {
     IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
     return true;
   }
 
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
     IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
     return true;
   }
@@ -137,25 +137,25 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
       Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
+  bool VisitDeclRefExpr(DeclRefExpr *E) override {
     SmallVector<SymbolRelation, 4> Relations;
     SymbolRoleSet Roles = getRolesForRef(E, Relations);
     return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                     Parent, ParentDC, Roles, Relations, E);
   }
 
-  bool VisitGotoStmt(GotoStmt *S) {
+  bool VisitGotoStmt(GotoStmt *S) override {
     return IndexCtx.handleReference(S->getLabel(), S->getLabelLoc(), Parent,
                                     ParentDC);
   }
 
-  bool VisitLabelStmt(LabelStmt *S) {
+  bool VisitLabelStmt(LabelStmt *S) override {
     if (IndexCtx.shouldIndexFunctionLocalSymbols())
       return IndexCtx.handleDecl(S->getDecl());
     return true;
   }
 
-  bool VisitMemberExpr(MemberExpr *E) {
+  bool VisitMemberExpr(MemberExpr *E) override {
     SourceLocation Loc = E->getMemberLoc();
     if (Loc.isInvalid())
       Loc = E->getBeginLoc();
@@ -197,14 +197,14 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
                                     Relations, E);
   }
 
-  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
     const DeclarationNameInfo &Info = E->getMemberNameInfo();
     return indexDependentReference(
         E, E->getBaseType().getTypePtrOrNull(), Info,
         [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
   }
 
-  bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override {
     const DeclarationNameInfo &Info = E->getNameInfo();
     const NestedNameSpecifier *NNS = E->getQualifier();
     return indexDependentReference(
@@ -212,7 +212,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
         [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
   }
 
-  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) override {
     for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
       if (D.isFieldDesignator()) {
         if (const FieldDecl *FD = D.getFieldDecl()) {
@@ -224,14 +224,14 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) override {
     SmallVector<SymbolRelation, 4> Relations;
     SymbolRoleSet Roles = getRolesForRef(E, Relations);
     return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
                                     Parent, ParentDC, Roles, Relations, E);
   }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
     auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
       if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
         return false;
@@ -303,7 +303,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) override {
     if (E->isExplicitProperty()) {
       SmallVector<SymbolRelation, 2> Relations;
       SymbolRoleSet Roles = getRolesForRef(E, Relations);
@@ -328,12 +328,12 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
+  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) override {
     return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
                                     Parent, ParentDC, SymbolRoleSet(), {}, E);
   }
 
-  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) override {
     return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
                                     Parent, ParentDC, SymbolRoleSet(), {}, E);
   }
@@ -347,28 +347,28 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
                                     Roles, Relations, E);
   }
 
-  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
+  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) override {
     if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
       return passObjCLiteralMethodCall(MD, E);
     }
     return true;
   }
 
-  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
+  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override {
     if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
       return passObjCLiteralMethodCall(MD, E);
     }
     return true;
   }
 
-  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) override {
     if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
       return passObjCLiteralMethodCall(MD, E);
     }
     return true;
   }
 
-  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+  bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
     SymbolRoleSet Roles{};
     SmallVector<SymbolRelation, 2> Relations;
     addCallRole(Roles, Relations);
@@ -376,14 +376,13 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
                                     Parent, ParentDC, Roles, Relations, E);
   }
 
-  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
-                                   DataRecursionQueue *Q = nullptr) {
+  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) override {
     if (E->getOperatorLoc().isInvalid())
       return true; // implicit.
-    return base::TraverseCXXOperatorCallExpr(E, Q);
+    return DynamicRecursiveASTVisitor::TraverseCXXOperatorCallExpr(E);
   }
 
-  bool VisitDeclStmt(DeclStmt *S) {
+  bool VisitDeclStmt(DeclStmt *S) override {
     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
       IndexCtx.indexDeclGroupRef(S->getDeclGroup());
       return true;
@@ -402,11 +401,11 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
   }
 
   bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
-                             Expr *Init) {
+                             Expr *Init) override {
     if (C->capturesThis() || C->capturesVLAType())
       return true;
 
-    if (!base::TraverseStmt(Init))
+    if (!DynamicRecursiveASTVisitor::TraverseStmt(Init))
       return false;
 
     if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
@@ -420,10 +419,10 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
   // the things that we visit. Make sure to only visit the semantic form.
   // Also visit things that are in the syntactic form but not the semantic one,
   // for example the indices in DesignatedInitExprs.
-  bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
+  bool TraverseInitListExpr(InitListExpr *S) override {
     auto visitForm = [&](InitListExpr *Form) {
       for (Stmt *SubStmt : Form->children()) {
-        if (!TraverseStmt(SubStmt, Q))
+        if (!TraverseStmt(SubStmt))
           return false;
       }
       return true;
@@ -464,7 +463,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitOffsetOfExpr(OffsetOfExpr *S) {
+  bool VisitOffsetOfExpr(OffsetOfExpr *S) override {
     for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
       const OffsetOfNode &Component = S->getComponent(I);
       if (Component.getKind() == OffsetOfNode::Field)
@@ -475,7 +474,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitParmVarDecl(ParmVarDecl* D) {
+  bool VisitParmVarDecl(ParmVarDecl* D) override {
     // Index the parameters of lambda expression and requires expression.
     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
       const auto *DC = D->getDeclContext();
@@ -485,7 +484,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitOverloadExpr(OverloadExpr *E) {
+  bool VisitOverloadExpr(OverloadExpr *E) override {
     SmallVector<SymbolRelation, 4> Relations;
     SymbolRoleSet Roles = getRolesForRef(E, Relations);
     for (auto *D : E->decls())
@@ -494,16 +493,16 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     return true;
   }
 
-  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
+  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) override {
     IndexCtx.handleReference(R->getNamedConcept(), R->getConceptNameLoc(),
                              Parent, ParentDC);
     return true;
   }
 
-  bool TraverseTypeConstraint(const TypeConstraint *C) {
+  bool TraverseTypeConstraint(const TypeConstraint *C) override {
     IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
                              Parent, ParentDC);
-    return RecursiveASTVisitor::TraverseTypeConstraint(C);
+    return DynamicRecursiveASTVisitor::TraverseTypeConstraint(C);
   }
 };
 

>From 98350fba73bc17242190ab7322ea3d29bcd40f4f Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 17:46:53 +0200
Subject: [PATCH 16/27] [Tests] Refactor most tests to use the dynamic visitor

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    |   2 +
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  16 +-
 clang/unittests/AST/EvaluateAsRValueTest.cpp  |  10 +-
 .../unittests/Analysis/CloneDetectionTest.cpp |   7 +-
 .../unittests/Frontend/FrontendActionTest.cpp |   6 +-
 clang/unittests/Tooling/ASTSelectionTest.cpp  |   4 +-
 clang/unittests/Tooling/CRTPTestVisitor.h     |  42 +++++
 clang/unittests/Tooling/CastExprTest.cpp      |   6 +-
 .../unittests/Tooling/CommentHandlerTest.cpp  |   8 +-
 clang/unittests/Tooling/ExecutionTest.cpp     |  10 +-
 ...exicallyOrderedRecursiveASTVisitorTest.cpp |   5 +-
 clang/unittests/Tooling/LookupTest.cpp        |  10 +-
 clang/unittests/Tooling/QualTypeNamesTest.cpp |   4 +-
 .../RecursiveASTVisitorTestDeclVisitor.cpp    |  18 +--
 ...ecursiveASTVisitorTestPostOrderVisitor.cpp |  12 +-
 .../RecursiveASTVisitorTestTypeLocVisitor.cpp |   4 +-
 .../Tooling/RecursiveASTVisitorTests/Attr.cpp |   4 +-
 .../BitfieldInitializer.cpp                   |   5 +-
 .../CXXBoolLiteralExpr.cpp                    |   5 +-
 .../CXXMemberCall.cpp                         |   5 +-
 .../CXXMethodDecl.cpp                         |  18 +--
 .../CXXOperatorCallExprTraverser.cpp          |   8 +-
 .../CallbacksCommon.h                         |   4 +-
 .../RecursiveASTVisitorTests/Class.cpp        |   5 +-
 .../RecursiveASTVisitorTests/Concept.cpp      | 114 ++++++-------
 .../ConstructExpr.cpp                         |  20 +--
 .../RecursiveASTVisitorTests/DeclRefExpr.cpp  |  17 +-
 .../DeductionGuide.cpp                        |  17 +-
 .../RecursiveASTVisitorTests/ImplicitCtor.cpp |   7 +-
 .../ImplicitCtorInitializer.cpp               |  18 +--
 .../InitListExprPostOrder.cpp                 |   4 +-
 .../InitListExprPostOrderNoQueue.cpp          |   6 +-
 .../InitListExprPreOrder.cpp                  |  15 +-
 .../InitListExprPreOrderNoQueue.cpp           |   7 +-
 .../IntegerLiteral.cpp                        |   5 +-
 .../LambdaDefaultCapture.cpp                  |   5 +-
 .../RecursiveASTVisitorTests/LambdaExpr.cpp   |  19 +--
 .../LambdaTemplateParams.cpp                  |  13 +-
 .../MemberPointerTypeLoc.cpp                  |   7 +-
 .../NestedNameSpecifiers.cpp                  |   7 +-
 .../RecursiveASTVisitorTests/ParenExpr.cpp    |   4 +-
 .../TemplateArgumentLocTraverser.cpp          |   8 +-
 .../TraversalScope.cpp                        |   6 +-
 clang/unittests/Tooling/RefactoringTest.cpp   |  21 ++-
 clang/unittests/Tooling/SourceCodeTest.cpp    |  55 ++++---
 clang/unittests/Tooling/TestVisitor.h         | 150 ++++++++++--------
 46 files changed, 393 insertions(+), 350 deletions(-)
 create mode 100644 clang/unittests/Tooling/CRTPTestVisitor.h

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 8b89518863540d..75d7597c2b7497 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -171,6 +171,8 @@ class DynamicRecursiveASTVisitor {
   virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
   virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
   virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
+  virtual bool TraverseConceptReference(ConceptReference *CR);
+  virtual bool VisitConceptReference(ConceptReference *CR) { return true; }
 
   /// Visit a node.
   virtual bool VisitAttr(Attr *A) { return true; }
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index e7f896f4bc56f5..fe9b80df3e5477 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file implements an AST visitor that does not require any template
-// instantiation to allow users to override this behaviour.
+// instantiation to allow users to override its behaviour.
 //
 //===----------------------------------------------------------------------===//
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
@@ -81,6 +81,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseConceptNestedRequirement(R);
   }
 
+  bool TraverseConceptReference(ConceptReference *CR) {
+    return Visitor.TraverseConceptReference(CR);
+  }
+
   bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
     return Visitor.TraverseCXXBaseSpecifier(Base);
   }
@@ -102,6 +106,10 @@ struct Impl : RecursiveASTVisitor<Impl> {
     return Visitor.TraverseNestedNameSpecifierLoc(NNS);
   }
 
+  bool VisitConceptReference(ConceptReference *CR) {
+    return Visitor.VisitConceptReference(CR);
+  }
+
   bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
   bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }
   bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
@@ -271,6 +279,12 @@ bool DynamicRecursiveASTVisitor::TraverseConceptNestedRequirement(
       .RecursiveASTVisitor<Impl>::TraverseConceptNestedRequirement(R);
 }
 
+bool DynamicRecursiveASTVisitor::TraverseConceptReference(
+    ConceptReference *CR) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptReference(CR);
+}
+
+
 bool DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(
     const CXXBaseSpecifier &Base) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseCXXBaseSpecifier(Base);
diff --git a/clang/unittests/AST/EvaluateAsRValueTest.cpp b/clang/unittests/AST/EvaluateAsRValueTest.cpp
index f6261b827671bc..2645d3c8e05c6b 100644
--- a/clang/unittests/AST/EvaluateAsRValueTest.cpp
+++ b/clang/unittests/AST/EvaluateAsRValueTest.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
 #include <map>
@@ -28,7 +28,7 @@ typedef std::map<std::string, bool> VarInfoMap;
 
 /// \brief Records information on variable initializers to a map.
 class EvaluateConstantInitializersVisitor
-    : public clang::RecursiveASTVisitor<EvaluateConstantInitializersVisitor> {
+    : public clang::DynamicRecursiveASTVisitor {
  public:
   explicit EvaluateConstantInitializersVisitor(VarInfoMap &VarInfo)
       : VarInfo(VarInfo) {}
@@ -38,7 +38,7 @@ class EvaluateConstantInitializersVisitor
   ///
   /// For each VarDecl with an initializer this also records in VarInfo
   /// whether the initializer could be evaluated as a constant.
-  bool VisitVarDecl(const clang::VarDecl *VD) {
+  bool VisitVarDecl(clang::VarDecl *VD) override {
     if (const clang::Expr *Init = VD->getInit()) {
       clang::Expr::EvalResult Result;
       bool WasEvaluated = Init->EvaluateAsRValue(Result, VD->getASTContext());
@@ -109,9 +109,9 @@ TEST(EvaluateAsRValue, FailsGracefullyForUnknownTypes) {
 }
 
 class CheckLValueToRValueConversionVisitor
-    : public clang::RecursiveASTVisitor<CheckLValueToRValueConversionVisitor> {
+    : public clang::DynamicRecursiveASTVisitor {
 public:
-  bool VisitDeclRefExpr(const clang::DeclRefExpr *E) {
+  bool VisitDeclRefExpr(clang::DeclRefExpr *E) override {
     clang::Expr::EvalResult Result;
     E->EvaluateAsRValue(Result, E->getDecl()->getASTContext(), true);
 
diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp
index 738f6efd2018d7..1b34ee5d6dde1f 100644
--- a/clang/unittests/Analysis/CloneDetectionTest.cpp
+++ b/clang/unittests/Analysis/CloneDetectionTest.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Analysis/CloneDetection.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
@@ -15,15 +15,14 @@ namespace clang {
 namespace analysis {
 namespace {
 
-class CloneDetectionVisitor
-    : public RecursiveASTVisitor<CloneDetectionVisitor> {
+class CloneDetectionVisitor : public DynamicRecursiveASTVisitor {
 
   CloneDetector &Detector;
 
 public:
   explicit CloneDetectionVisitor(CloneDetector &D) : Detector(D) {}
 
-  bool VisitFunctionDecl(FunctionDecl *D) {
+  bool VisitFunctionDecl(FunctionDecl *D) override {
     Detector.analyzeCodeBody(D);
     return true;
   }
diff --git a/clang/unittests/Frontend/FrontendActionTest.cpp b/clang/unittests/Frontend/FrontendActionTest.cpp
index 818e8cef27e51b..6ce9ba6f6a0888 100644
--- a/clang/unittests/Frontend/FrontendActionTest.cpp
+++ b/clang/unittests/Frontend/FrontendActionTest.cpp
@@ -9,7 +9,7 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/LangStandard.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
@@ -53,7 +53,7 @@ class TestASTFrontendAction : public ASTFrontendAction {
   }
 
 private:
-  class Visitor : public ASTConsumer, public RecursiveASTVisitor<Visitor> {
+  class Visitor : public ASTConsumer, public DynamicRecursiveASTVisitor {
   public:
     Visitor(CompilerInstance &CI, bool ActOnEndOfTranslationUnit,
             std::vector<std::string> &decl_names) :
@@ -67,7 +67,7 @@ class TestASTFrontendAction : public ASTFrontendAction {
       TraverseDecl(context.getTranslationUnitDecl());
     }
 
-    virtual bool VisitNamedDecl(NamedDecl *Decl) {
+    bool VisitNamedDecl(NamedDecl *Decl) override {
       decl_names_.push_back(Decl->getQualifiedNameAsString());
       return true;
     }
diff --git a/clang/unittests/Tooling/ASTSelectionTest.cpp b/clang/unittests/Tooling/ASTSelectionTest.cpp
index 38b7df8fd564f9..eefbc8cca9029b 100644
--- a/clang/unittests/Tooling/ASTSelectionTest.cpp
+++ b/clang/unittests/Tooling/ASTSelectionTest.cpp
@@ -26,7 +26,7 @@ struct FileLocation {
 
 using FileRange = std::pair<FileLocation, FileLocation>;
 
-class SelectionFinderVisitor : public TestVisitor<SelectionFinderVisitor> {
+class SelectionFinderVisitor : public TestVisitor {
   FileLocation Location;
   std::optional<FileRange> SelectionRange;
   llvm::function_ref<void(SourceRange SelectionRange,
@@ -42,7 +42,7 @@ class SelectionFinderVisitor : public TestVisitor<SelectionFinderVisitor> {
       : Location(Location), SelectionRange(SelectionRange), Consumer(Consumer) {
   }
 
-  bool VisitTranslationUnitDecl(const TranslationUnitDecl *TU) {
+  bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) override {
     const ASTContext &Context = TU->getASTContext();
     const SourceManager &SM = Context.getSourceManager();
 
diff --git a/clang/unittests/Tooling/CRTPTestVisitor.h b/clang/unittests/Tooling/CRTPTestVisitor.h
new file mode 100644
index 00000000000000..67ae36b2e3ddd9
--- /dev/null
+++ b/clang/unittests/Tooling/CRTPTestVisitor.h
@@ -0,0 +1,42 @@
+//===--- TestVisitor.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines a CRTP-based RecursiveASTVisitor helper for tests.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H
+#define LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H
+
+#include "TestVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+// CRTP versions of the visitors in TestVisitor.h.
+namespace clang {
+template <typename T>
+class CRTPTestVisitor : public RecursiveASTVisitor<T>,
+                        public detail::TestVisitorHelper {
+public:
+  bool shouldVisitTemplateInstantiations() const { return true; }
+  bool shouldVisitImplicitCode() const { return true; }
+
+  void InvokeTraverseDecl(TranslationUnitDecl *D) override {
+    RecursiveASTVisitor<T>::TraverseDecl(D);
+  }
+};
+
+template <typename T>
+class CRTPExpectedLocationVisitor
+    : public CRTPTestVisitor<T>,
+      public detail::ExpectedLocationVisitorHelper {
+  ASTContext *getASTContext() override { return this->Context; }
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H
diff --git a/clang/unittests/Tooling/CastExprTest.cpp b/clang/unittests/Tooling/CastExprTest.cpp
index eab23a5a98e5d5..e5a8d994bf011b 100644
--- a/clang/unittests/Tooling/CastExprTest.cpp
+++ b/clang/unittests/Tooling/CastExprTest.cpp
@@ -12,17 +12,17 @@ using namespace clang;
 
 namespace {
 
-struct CastExprVisitor : TestVisitor<CastExprVisitor> {
+struct CastExprVisitor : TestVisitor {
   std::function<void(ExplicitCastExpr *)> OnExplicitCast;
   std::function<void(CastExpr *)> OnCast;
 
-  bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) {
+  bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) override {
     if (OnExplicitCast)
       OnExplicitCast(Expr);
     return true;
   }
 
-  bool VisitCastExpr(CastExpr *Expr) {
+  bool VisitCastExpr(CastExpr *Expr) override {
     if (OnCast)
       OnCast(Expr);
     return true;
diff --git a/clang/unittests/Tooling/CommentHandlerTest.cpp b/clang/unittests/Tooling/CommentHandlerTest.cpp
index 7eb11ccd6ee2d1..d7184b08076d80 100644
--- a/clang/unittests/Tooling/CommentHandlerTest.cpp
+++ b/clang/unittests/Tooling/CommentHandlerTest.cpp
@@ -22,12 +22,10 @@ struct Comment {
 class CommentVerifier;
 typedef std::vector<Comment> CommentList;
 
-class CommentHandlerVisitor : public TestVisitor<CommentHandlerVisitor>,
+class CommentHandlerVisitor : public TestVisitor,
                               public CommentHandler {
-  typedef TestVisitor<CommentHandlerVisitor> base;
-
 public:
-  CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {}
+  CommentHandlerVisitor() : PP(nullptr), Verified(false) {}
 
   ~CommentHandlerVisitor() override {
     EXPECT_TRUE(Verified) << "CommentVerifier not accessed";
@@ -64,7 +62,7 @@ class CommentHandlerVisitor : public TestVisitor<CommentHandlerVisitor>,
   CommentList Comments;
   bool Verified;
 
-  class CommentHandlerAction : public base::TestAction {
+  class CommentHandlerAction : public TestAction {
   public:
     CommentHandlerAction(CommentHandlerVisitor *Visitor)
         : TestAction(Visitor) { }
diff --git a/clang/unittests/Tooling/ExecutionTest.cpp b/clang/unittests/Tooling/ExecutionTest.cpp
index 91ab8594f6823d..1bfe6293f3f27b 100644
--- a/clang/unittests/Tooling/ExecutionTest.cpp
+++ b/clang/unittests/Tooling/ExecutionTest.cpp
@@ -9,7 +9,7 @@
 #include "clang/Tooling/Execution.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -32,10 +32,8 @@ namespace {
 // each function declaration.
 class ASTConsumerWithResult
     : public ASTConsumer,
-      public RecursiveASTVisitor<ASTConsumerWithResult> {
+      public DynamicRecursiveASTVisitor {
 public:
-  using ASTVisitor = RecursiveASTVisitor<ASTConsumerWithResult>;
-
   explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) {
     assert(Context != nullptr);
   }
@@ -44,12 +42,12 @@ class ASTConsumerWithResult
     TraverseDecl(Context.getTranslationUnitDecl());
   }
 
-  bool TraverseFunctionDecl(clang::FunctionDecl *Decl) {
+  bool TraverseFunctionDecl(clang::FunctionDecl *Decl) override {
     Context->reportResult(Decl->getNameAsString(),
                           Context->getRevision() + ":" + Context->getCorpus() +
                               ":" + Context->getCurrentCompilationUnit() +
                               "/1");
-    return ASTVisitor::TraverseFunctionDecl(Decl);
+    return DynamicRecursiveASTVisitor::TraverseFunctionDecl(Decl);
   }
 
 private:
diff --git a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
index 5d16595aec8014..b167eb4b811755 100644
--- a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
+++ b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
@@ -44,13 +44,14 @@ class LexicallyOrderedDeclVisitor
   llvm::SmallVector<Decl *, 8> TraversalStack;
 };
 
-class DummyMatchVisitor : public ExpectedLocationVisitor<DummyMatchVisitor> {
+class DummyMatchVisitor : public ExpectedLocationVisitor {
   bool EmitDeclIndices, EmitStmtIndices;
 
 public:
   DummyMatchVisitor(bool EmitDeclIndices = false, bool EmitStmtIndices = false)
       : EmitDeclIndices(EmitDeclIndices), EmitStmtIndices(EmitStmtIndices) {}
-  bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+
+  bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) override {
     const ASTContext &Context = TU->getASTContext();
     const SourceManager &SM = Context.getSourceManager();
     LexicallyOrderedDeclVisitor SubVisitor(*this, SM, EmitDeclIndices,
diff --git a/clang/unittests/Tooling/LookupTest.cpp b/clang/unittests/Tooling/LookupTest.cpp
index 2cf5ebb2a4cbd0..acd1714a26e071 100644
--- a/clang/unittests/Tooling/LookupTest.cpp
+++ b/clang/unittests/Tooling/LookupTest.cpp
@@ -13,31 +13,31 @@
 using namespace clang;
 
 namespace {
-struct GetDeclsVisitor : TestVisitor<GetDeclsVisitor> {
+struct GetDeclsVisitor : TestVisitor {
   std::function<void(CallExpr *)> OnCall;
   std::function<void(RecordTypeLoc)> OnRecordTypeLoc;
   std::function<void(UsingTypeLoc)> OnUsingTypeLoc;
   SmallVector<Decl *, 4> DeclStack;
 
-  bool VisitCallExpr(CallExpr *Expr) {
+  bool VisitCallExpr(CallExpr *Expr) override {
     if (OnCall)
       OnCall(Expr);
     return true;
   }
 
-  bool VisitRecordTypeLoc(RecordTypeLoc Loc) {
+  bool VisitRecordTypeLoc(RecordTypeLoc Loc) override {
     if (OnRecordTypeLoc)
       OnRecordTypeLoc(Loc);
     return true;
   }
 
-  bool VisitUsingTypeLoc(UsingTypeLoc Loc) {
+  bool VisitUsingTypeLoc(UsingTypeLoc Loc) override {
     if (OnUsingTypeLoc)
       OnUsingTypeLoc(Loc);
     return true;
   }
 
-  bool TraverseDecl(Decl *D) {
+  bool TraverseDecl(Decl *D) override {
     DeclStack.push_back(D);
     bool Ret = TestVisitor::TraverseDecl(D);
     DeclStack.pop_back();
diff --git a/clang/unittests/Tooling/QualTypeNamesTest.cpp b/clang/unittests/Tooling/QualTypeNamesTest.cpp
index 686d189cf69eb2..5ded64d4fcc8c5 100644
--- a/clang/unittests/Tooling/QualTypeNamesTest.cpp
+++ b/clang/unittests/Tooling/QualTypeNamesTest.cpp
@@ -11,12 +11,12 @@
 using namespace clang;
 
 namespace {
-struct TypeNameVisitor : TestVisitor<TypeNameVisitor> {
+struct TypeNameVisitor : TestVisitor {
   llvm::StringMap<std::string> ExpectedQualTypeNames;
   bool WithGlobalNsPrefix = false;
 
   // ValueDecls are the least-derived decl with both a qualtype and a name.
-  bool VisitValueDecl(const ValueDecl *VD) {
+  bool VisitValueDecl(ValueDecl *VD) override {
     std::string ExpectedName =
         ExpectedQualTypeNames.lookup(VD->getNameAsString());
     if (ExpectedName != "") {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
index e207f03971ad2f..ccd3048b820efd 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
@@ -12,9 +12,9 @@ using namespace clang;
 
 namespace {
 
-class VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
+class VarDeclVisitor : public ExpectedLocationVisitor {
 public:
- bool VisitVarDecl(VarDecl *Variable) {
+ bool VisitVarDecl(VarDecl *Variable) override {
    Match(Variable->getNameAsString(), Variable->getBeginLoc());
    return true;
  }
@@ -29,12 +29,13 @@ TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
     VarDeclVisitor::Lang_CXX11));
 }
 
-class ParmVarDeclVisitorForImplicitCode :
-  public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> {
+class ParmVarDeclVisitorForImplicitCode : public ExpectedLocationVisitor {
 public:
-  bool shouldVisitImplicitCode() const { return true; }
+  ParmVarDeclVisitorForImplicitCode() {
+    ShouldVisitImplicitCode = true;
+  }
 
-  bool VisitParmVarDecl(ParmVarDecl *ParamVar) {
+  bool VisitParmVarDecl(ParmVarDecl *ParamVar) override {
     Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc());
     return true;
   }
@@ -58,10 +59,9 @@ TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {
     "void bar(Y a) {Y b = a;}"));
 }
 
-class NamedDeclVisitor
-  : public ExpectedLocationVisitor<NamedDeclVisitor> {
+class NamedDeclVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitNamedDecl(NamedDecl *Decl) {
+  bool VisitNamedDecl(NamedDecl *Decl) override {
     std::string NameWithTemplateArgs;
     llvm::raw_string_ostream OS(NameWithTemplateArgs);
     Decl->getNameForDiagnostic(OS,
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
index 8ac0604c09110a..e2942bf8a11a51 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
@@ -11,14 +11,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TestVisitor.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+#include <CRTPTestVisitor.h>
 
 using namespace clang;
 
 namespace {
-
-class RecordingVisitor : public TestVisitor<RecordingVisitor> {
-
+class RecordingVisitor : public CRTPTestVisitor<RecordingVisitor> {
   bool VisitPostOrder;
 
 public:
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
index a21186265db6a9..eec628ca396417 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
@@ -12,9 +12,9 @@ using namespace clang;
 
 namespace {
 
-class TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
+class TypeLocVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitTypeLoc(TypeLoc TypeLocation) {
+  bool VisitTypeLoc(TypeLoc TypeLocation) override {
     Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc());
     return true;
   }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
index 022ef8b8322868..bbec767ae60896 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TestVisitor.h"
+#include "CRTPTestVisitor.h"
 
 using namespace clang;
 
@@ -14,7 +14,7 @@ namespace {
 
 // Check to ensure that attributes and expressions within them are being
 // visited.
-class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> {
+class AttrVisitor : public CRTPExpectedLocationVisitor<AttrVisitor> {
 public:
   bool VisitMemberExpr(MemberExpr *ME) {
     Match(ME->getMemberDecl()->getNameAsString(), ME->getBeginLoc());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
index c11e726fe85528..c1217179768ac2 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
@@ -14,10 +14,9 @@ using namespace clang;
 namespace {
 
 // Check to ensure that bitfield initializers are visited.
-class BitfieldInitializerVisitor
-    : public ExpectedLocationVisitor<BitfieldInitializerVisitor> {
+class BitfieldInitializerVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitIntegerLiteral(IntegerLiteral *IL) {
+  bool VisitIntegerLiteral(IntegerLiteral *IL) override {
     Match(std::to_string(IL->getValue().getSExtValue()), IL->getLocation());
     return true;
   }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
index 1fb192dcda0863..4b0c4c31f2dd2e 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
@@ -12,10 +12,9 @@ using namespace clang;
 
 namespace {
 
-class CXXBoolLiteralExprVisitor 
-  : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> {
+class CXXBoolLiteralExprVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) {
+  bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) override {
     if (BE->getValue())
       Match("true", BE->getLocation());
     else
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
index c7b31e06e0e8e9..fe95e8987a73a1 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
@@ -12,10 +12,9 @@ using namespace clang;
 
 namespace {
 
-class CXXMemberCallVisitor
-  : public ExpectedLocationVisitor<CXXMemberCallVisitor> {
+class CXXMemberCallVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) {
+  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) override {
     Match(Call->getMethodDecl()->getQualifiedNameAsString(),
           Call->getBeginLoc());
     return true;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
index 90fa84bd448124..1eeb3df81a3168 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp
@@ -13,25 +13,21 @@ using namespace clang;
 
 namespace {
 
-class CXXMethodDeclVisitor
-    : public ExpectedLocationVisitor<CXXMethodDeclVisitor> {
+class CXXMethodDeclVisitor : public ExpectedLocationVisitor {
 public:
-  CXXMethodDeclVisitor(bool VisitImplicitCode)
-      : VisitImplicitCode(VisitImplicitCode) {}
-
-  bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
+  CXXMethodDeclVisitor(bool VisitImplicitCode) {
+    ShouldVisitImplicitCode = VisitImplicitCode;
+  }
 
-  bool VisitDeclRefExpr(DeclRefExpr *D) {
+  bool VisitDeclRefExpr(DeclRefExpr *D) override {
     Match("declref", D->getLocation());
     return true;
   }
-  bool VisitParmVarDecl(ParmVarDecl *P) {
+
+  bool VisitParmVarDecl(ParmVarDecl *P) override {
     Match("parm", P->getLocation());
     return true;
   }
-
-private:
-  bool VisitImplicitCode;
 };
 
 TEST(RecursiveASTVisitor, CXXMethodDeclNoDefaultBodyVisited) {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
index 376874eb351de1..46686199c05d4e 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
@@ -12,15 +12,13 @@ using namespace clang;
 
 namespace {
 
-class CXXOperatorCallExprTraverser
-  : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> {
+class CXXOperatorCallExprTraverser : public ExpectedLocationVisitor {
 public:
   // Use Traverse, not Visit, to check that data recursion optimization isn't
   // bypassing the call of this function.
-  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
+  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) override {
     Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc());
-    return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>::
-        TraverseCXXOperatorCallExpr(CE);
+    return ExpectedLocationVisitor::TraverseCXXOperatorCallExpr(CE);
   }
 };
 
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
index 92e30c2d46e5fa..355ecfb452e7e8 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TestVisitor.h"
+#include "CRTPTestVisitor.h"
 
 using namespace clang;
 
@@ -21,7 +21,7 @@ enum class ShouldTraversePostOrder : bool {
 /// sequence of calls to user-defined callbacks like Traverse*(), WalkUp*(),
 /// Visit*().
 template <typename Derived>
-class RecordingVisitorBase : public TestVisitor<Derived> {
+class RecordingVisitorBase : public CRTPTestVisitor<Derived> {
   ShouldTraversePostOrder ShouldTraversePostOrderValue;
 
 public:
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
index 3ea5abd46a1eca..90953c66f6edf3 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
@@ -14,10 +14,11 @@ namespace {
 
 // Checks for lambda classes that are not marked as implicitly-generated.
 // (There should be none.)
-class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
+class ClassVisitor : public ExpectedLocationVisitor {
 public:
   ClassVisitor() : SawNonImplicitLambdaClass(false) {}
-  bool VisitCXXRecordDecl(CXXRecordDecl* record) {
+
+  bool VisitCXXRecordDecl(CXXRecordDecl* record) override {
     if (record->isLambda() && !record->isImplicit())
       SawNonImplicitLambdaClass = true;
     return true;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
index 6a8d91672f1d93..3c8781d28e54d3 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
@@ -16,78 +16,84 @@ using namespace clang;
 
 namespace {
 
-struct ConceptVisitor : ExpectedLocationVisitor<ConceptVisitor> {
-  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
+struct ConceptVisitor : ExpectedLocationVisitor {
+  ConceptVisitor(bool VisitImplicitCode = false) {
+    ShouldVisitImplicitCode = VisitImplicitCode;
+  }
+
+  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) override {
     ++ConceptSpecializationExprsVisited;
     return true;
   }
-  bool TraverseTypeConstraint(const TypeConstraint *C) {
+  bool TraverseTypeConstraint(const TypeConstraint *C) override {
     ++TypeConstraintsTraversed;
     return ExpectedLocationVisitor::TraverseTypeConstraint(C);
   }
-  bool TraverseConceptRequirement(concepts::Requirement *R) {
+  bool TraverseConceptRequirement(concepts::Requirement *R) override {
     ++ConceptRequirementsTraversed;
     return ExpectedLocationVisitor::TraverseConceptRequirement(R);
   }
-  bool TraverseConceptReference(ConceptReference *CR) {
+  bool TraverseConceptReference(ConceptReference *CR) override {
     ++ConceptReferencesTraversed;
     return ExpectedLocationVisitor::TraverseConceptReference(CR);
   }
-  bool VisitConceptReference(ConceptReference *CR) {
+  bool VisitConceptReference(ConceptReference *CR) override {
     ++ConceptReferencesVisited;
     return true;
   }
 
-  bool shouldVisitImplicitCode() { return ShouldVisitImplicitCode; }
-
   int ConceptSpecializationExprsVisited = 0;
   int TypeConstraintsTraversed = 0;
   int ConceptRequirementsTraversed = 0;
   int ConceptReferencesTraversed = 0;
   int ConceptReferencesVisited = 0;
-  bool ShouldVisitImplicitCode = false;
 };
 
 TEST(RecursiveASTVisitor, Concepts) {
-  ConceptVisitor Visitor;
-  Visitor.ShouldVisitImplicitCode = true;
-  EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
-                              "template <Fooable T> void bar(T);",
-                              ConceptVisitor::Lang_CXX2a));
-  // Check that we traverse the "Fooable T" template parameter's
-  // TypeConstraint's ImmediatelyDeclaredConstraint, which is a
-  // ConceptSpecializationExpr.
-  EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited);
-  // Also check we traversed the TypeConstraint that produced the expr.
-  EXPECT_EQ(1, Visitor.TypeConstraintsTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  {
+    ConceptVisitor Visitor{true};
+    EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
+                                "template <Fooable T> void bar(T);",
+                                ConceptVisitor::Lang_CXX2a));
+    // Check that we traverse the "Fooable T" template parameter's
+    // TypeConstraint's ImmediatelyDeclaredConstraint, which is a
+    // ConceptSpecializationExpr.
+    EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited);
+    // Also check we traversed the TypeConstraint that produced the expr.
+    EXPECT_EQ(1, Visitor.TypeConstraintsTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  }
 
-  Visitor = {}; // Don't visit implicit code now.
-  EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
-                              "template <Fooable T> void bar(T);",
-                              ConceptVisitor::Lang_CXX2a));
-  // Check that we only visit the TypeConstraint, but not the implicitly
-  // generated immediately declared expression.
-  EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited);
-  EXPECT_EQ(1, Visitor.TypeConstraintsTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  {
+    ConceptVisitor Visitor; // Don't visit implicit code now.
+    EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
+                                "template <Fooable T> void bar(T);",
+                                ConceptVisitor::Lang_CXX2a));
+    // Check that we only visit the TypeConstraint, but not the implicitly
+    // generated immediately declared expression.
+    EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited);
+    EXPECT_EQ(1, Visitor.TypeConstraintsTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  }
 
-  Visitor = {};
-  EXPECT_TRUE(Visitor.runOver("template <class T> concept A = true;\n"
-                              "template <class T> struct vector {};\n"
-                              "template <class T> concept B = requires(T x) {\n"
-                              "  typename vector<T*>;\n"
-                              "  {x} -> A;\n"
-                              "  requires true;\n"
-                              "};",
-                              ConceptVisitor::Lang_CXX2a));
-  EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
-  EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  {
+    ConceptVisitor Visitor;
+    EXPECT_TRUE(Visitor.runOver("template <class T> concept A = true;\n"
+                                "template <class T> struct vector {};\n"
+                                "template <class T> concept B = requires(T x) {\n"
+                                "  typename vector<T*>;\n"
+                                "  {x} -> A;\n"
+                                "  requires true;\n"
+                                "};",
+                                ConceptVisitor::Lang_CXX2a));
+    EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
+    EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
+  }
 
-  Visitor = {};
+  ConceptVisitor Visitor;
   llvm::StringRef Code =
       R"cpp(
 template<typename T> concept True = false;
@@ -107,34 +113,36 @@ struct Foo<F>  {};
   EXPECT_EQ(2, Visitor.ConceptReferencesVisited);
 }
 
-struct VisitDeclOnlyOnce : ExpectedLocationVisitor<VisitDeclOnlyOnce> {
-  bool VisitConceptDecl(ConceptDecl *D) {
+struct VisitDeclOnlyOnce : ExpectedLocationVisitor {
+  VisitDeclOnlyOnce() {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
+
+  bool VisitConceptDecl(ConceptDecl *D) override {
     ++ConceptDeclsVisited;
     return true;
   }
 
-  bool VisitAutoType(AutoType *) {
+  bool VisitAutoType(AutoType *) override {
     ++AutoTypeVisited;
     return true;
   }
-  bool VisitAutoTypeLoc(AutoTypeLoc) {
+  bool VisitAutoTypeLoc(AutoTypeLoc) override {
     ++AutoTypeLocVisited;
     return true;
   }
-  bool VisitConceptReference(ConceptReference *) {
+  bool VisitConceptReference(ConceptReference *) override {
     ++ConceptReferencesVisited;
     return true;
   }
 
-  bool TraverseVarDecl(VarDecl *V) {
+  bool TraverseVarDecl(VarDecl *V) override {
     // The base traversal visits only the `TypeLoc`.
     // However, in the test we also validate the underlying `QualType`.
     TraverseType(V->getType());
     return ExpectedLocationVisitor::TraverseVarDecl(V);
   }
 
-  bool shouldWalkTypesOfTypeLocs() { return false; }
-
   int ConceptDeclsVisited = 0;
   int AutoTypeVisited = 0;
   int AutoTypeLocVisited = 0;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
index b4f4f54dc7e2f9..6e295be5a2956f 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
@@ -18,18 +18,13 @@ namespace {
 /// The name recorded for the match is the name of the class whose constructor
 /// is invoked by the CXXConstructExpr, not the name of the class whose
 /// constructor the CXXConstructExpr is contained in.
-class ConstructExprVisitor
-    : public ExpectedLocationVisitor<ConstructExprVisitor> {
+class ConstructExprVisitor : public ExpectedLocationVisitor  {
 public:
-  ConstructExprVisitor() : ShouldVisitImplicitCode(false) {}
-
-  bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
-
-  void setShouldVisitImplicitCode(bool NewValue) {
-    ShouldVisitImplicitCode = NewValue;
+  ConstructExprVisitor() {
+    ShouldVisitImplicitCode = false;
   }
 
-  bool VisitCXXConstructExpr(CXXConstructExpr* Expr) {
+  bool VisitCXXConstructExpr(CXXConstructExpr* Expr) override {
     if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
       if (const CXXRecordDecl* Class = Ctor->getParent()) {
         Match(Class->getName(), Expr->getLocation());
@@ -37,14 +32,11 @@ class ConstructExprVisitor
     }
     return true;
   }
-
- private:
-  bool ShouldVisitImplicitCode;
 };
 
 TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
   ConstructExprVisitor Visitor;
-  Visitor.setShouldVisitImplicitCode(true);
+  Visitor.ShouldVisitImplicitCode = true;
   Visitor.ExpectMatch("WithCtor", 2, 8);
   // Simple has a constructor that implicitly initializes 'w'.  Test
   // that a visitor that visits implicit code visits that initialization.
@@ -60,7 +52,7 @@ TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
 // visits are omitted when the visitor does not include implicit code.
 TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) {
   ConstructExprVisitor Visitor;
-  Visitor.setShouldVisitImplicitCode(false);
+  Visitor.ShouldVisitImplicitCode = false;
   Visitor.DisallowMatch("WithCtor", 2, 8);
   // Simple has a constructor that implicitly initializes 'w'.  Test
   // that a visitor that skips implicit code skips that initialization.
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
index adc972e1c3d913..653e9c8bdf8ec6 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
@@ -12,23 +12,16 @@ using namespace clang;
 
 namespace {
 
-class DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> {
+class DeclRefExprVisitor : public ExpectedLocationVisitor {
 public:
-  DeclRefExprVisitor() : ShouldVisitImplicitCode(false) {}
-
-  bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
-
-  void setShouldVisitImplicitCode(bool NewValue) {
-    ShouldVisitImplicitCode = NewValue;
+  DeclRefExprVisitor() {
+    ShouldVisitImplicitCode = false;
   }
 
-  bool VisitDeclRefExpr(DeclRefExpr *Reference) {
+  bool VisitDeclRefExpr(DeclRefExpr *Reference) override {
     Match(Reference->getNameInfo().getAsString(), Reference->getLocation());
     return true;
   }
-
-private:
-  bool ShouldVisitImplicitCode;
 };
 
 TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) {
@@ -73,7 +66,7 @@ TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) {
 
 TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) {
   DeclRefExprVisitor Visitor;
-  Visitor.setShouldVisitImplicitCode(true);
+  Visitor.ShouldVisitImplicitCode = true;
   // We're expecting "i" to be visited twice: once for the initialization expr
   // for the captured variable "i" outside of the lambda body, and again for
   // the use of "i" inside the lambda.
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
index df878bfc113e57..7d03b283947993 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
@@ -13,23 +13,20 @@ using namespace clang;
 
 namespace {
 
-class DeductionGuideVisitor
-    : public ExpectedLocationVisitor<DeductionGuideVisitor> {
+class DeductionGuideVisitor : public ExpectedLocationVisitor {
 public:
-  DeductionGuideVisitor(bool ShouldVisitImplicitCode)
-      : ShouldVisitImplicitCode(ShouldVisitImplicitCode) {}
-  bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+  DeductionGuideVisitor(bool VisitImplicitCode) {
+    ShouldVisitImplicitCode = VisitImplicitCode;
+    ShouldVisitTemplateInstantiations = false;
+  }
+
+  bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) override {
     std::string Storage;
     llvm::raw_string_ostream Stream(Storage);
     D->print(Stream);
     Match(Storage, D->getLocation());
     return true;
   }
-
-  bool shouldVisitTemplateInstantiations() const { return false; }
-
-  bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
-  bool ShouldVisitImplicitCode;
 };
 
 TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
index 27999e5ef8efcb..f67cff2586aa15 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
@@ -13,12 +13,9 @@ using namespace clang;
 namespace {
 
 // A visitor that visits implicit declarations and matches constructors.
-class ImplicitCtorVisitor
-    : public ExpectedLocationVisitor<ImplicitCtorVisitor> {
+class ImplicitCtorVisitor : public ExpectedLocationVisitor {
 public:
-  bool shouldVisitImplicitCode() const { return true; }
-
-  bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) {
+    bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) override {
     if (Ctor->isImplicit()) {  // Was not written in source code
       if (const CXXRecordDecl* Class = Ctor->getParent()) {
         Match(Class->getName(), Ctor->getLocation());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp
index c762e1cffc3686..ae952c33bfe78b 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp
@@ -12,26 +12,20 @@ using namespace clang;
 
 namespace {
 
-class CXXCtorInitializerVisitor
-    : public ExpectedLocationVisitor<CXXCtorInitializerVisitor> {
+class CXXCtorInitializerVisitor : public ExpectedLocationVisitor {
 public:
-  CXXCtorInitializerVisitor(bool VisitImplicitCode)
-      : VisitImplicitCode(VisitImplicitCode) {}
-
-  bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
+  CXXCtorInitializerVisitor(bool VisitImplicitCode) {
+    ShouldVisitImplicitCode = VisitImplicitCode;
+  }
 
-  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
     if (!Init->isWritten())
       VisitedImplicitInitializer = true;
     Match("initializer", Init->getSourceLocation());
-    return ExpectedLocationVisitor<
-        CXXCtorInitializerVisitor>::TraverseConstructorInitializer(Init);
+    return ExpectedLocationVisitor::TraverseConstructorInitializer(Init);
   }
 
   bool VisitedImplicitInitializer = false;
-
-private:
-  bool VisitImplicitCode;
 };
 
 // Check to ensure that CXXCtorInitializer is not visited when implicit code
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
index 80d9c9873505b4..5836fc1b2e8de5 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
@@ -6,14 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TestVisitor.h"
+#include "CRTPTestVisitor.h"
 
 using namespace clang;
 
 namespace {
 
 class InitListExprPostOrderVisitor
-    : public ExpectedLocationVisitor<InitListExprPostOrderVisitor> {
+    : public CRTPExpectedLocationVisitor<InitListExprPostOrderVisitor> {
 public:
   bool shouldTraversePostOrder() const { return true; }
 
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
index 8750f78349443e..20140d2dcbf9e4 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
@@ -6,19 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TestVisitor.h"
+#include "CRTPTestVisitor.h"
 
 using namespace clang;
 
 namespace {
 
 class InitListExprPostOrderNoQueueVisitor
-    : public ExpectedLocationVisitor<InitListExprPostOrderNoQueueVisitor> {
+    : public CRTPExpectedLocationVisitor<InitListExprPostOrderNoQueueVisitor> {
 public:
   bool shouldTraversePostOrder() const { return true; }
 
   bool TraverseInitListExpr(InitListExpr *ILE) {
-    return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
+    return CRTPExpectedLocationVisitor::TraverseInitListExpr(ILE);
   }
 
   bool VisitInitListExpr(InitListExpr *ILE) {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
index 3fa1529ea0eefe..933d25898390dd 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
@@ -14,21 +14,16 @@ namespace {
 
 // Check to ensure that InitListExpr is visited twice, once each for the
 // syntactic and semantic form.
-class InitListExprPreOrderVisitor
-    : public ExpectedLocationVisitor<InitListExprPreOrderVisitor> {
+class InitListExprPreOrderVisitor : public ExpectedLocationVisitor {
 public:
-  InitListExprPreOrderVisitor(bool VisitImplicitCode)
-      : VisitImplicitCode(VisitImplicitCode) {}
-
-  bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
+  InitListExprPreOrderVisitor(bool VisitImplicitCode) {
+    ShouldVisitImplicitCode = VisitImplicitCode;
+  }
 
-  bool VisitInitListExpr(InitListExpr *ILE) {
+  bool VisitInitListExpr(InitListExpr *ILE) override {
     Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc());
     return true;
   }
-
-private:
-  bool VisitImplicitCode;
 };
 
 TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
index 8db88e1e063975..0dcd11b8027f04 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
@@ -12,14 +12,13 @@ using namespace clang;
 
 namespace {
 
-class InitListExprPreOrderNoQueueVisitor
-    : public ExpectedLocationVisitor<InitListExprPreOrderNoQueueVisitor> {
+class InitListExprPreOrderNoQueueVisitor : public ExpectedLocationVisitor {
 public:
-  bool TraverseInitListExpr(InitListExpr *ILE) {
+  bool TraverseInitListExpr(InitListExpr *ILE) override {
     return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
   }
 
-  bool VisitInitListExpr(InitListExpr *ILE) {
+  bool VisitInitListExpr(InitListExpr *ILE) override {
     Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc());
     return true;
   }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
index 3fc3cb1a99a744..83136fc11edb2c 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
@@ -13,10 +13,9 @@ using namespace clang;
 namespace {
 
 // Check to ensure that implicit default argument expressions are visited.
-class IntegerLiteralVisitor
-    : public ExpectedLocationVisitor<IntegerLiteralVisitor> {
+class IntegerLiteralVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitIntegerLiteral(const IntegerLiteral *IL) {
+  bool VisitIntegerLiteral(IntegerLiteral *IL) override {
     Match("literal", IL->getLocation());
     return true;
   }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
index b1d6d593e733a9..4a9175ed2dda24 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
@@ -13,10 +13,9 @@ using namespace clang;
 namespace {
 
 // Matches the (optional) capture-default of a lambda-introducer.
-class LambdaDefaultCaptureVisitor
-  : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
+class LambdaDefaultCaptureVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitLambdaExpr(LambdaExpr *Lambda) {
+  bool VisitLambdaExpr(LambdaExpr *Lambda) override {
     if (Lambda->getCaptureDefault() != LCD_None) {
       Match("", Lambda->getCaptureDefaultLoc());
     }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
index 337dace5fd2274..af84c6ef9ad832 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
@@ -14,9 +14,13 @@ using namespace clang;
 
 namespace {
 
-class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> {
+class LambdaExprVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitLambdaExpr(LambdaExpr *Lambda) {
+  LambdaExprVisitor() {
+    ShouldVisitImplicitCode = false;
+  }
+
+  bool VisitLambdaExpr(LambdaExpr *Lambda) override {
     PendingBodies.push(Lambda->getBody());
     PendingClasses.push(Lambda->getLambdaClass());
     Match("", Lambda->getIntroducerRange().getBegin());
@@ -24,12 +28,12 @@ class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> {
   }
   /// For each call to VisitLambdaExpr, we expect a subsequent call to visit
   /// the body (and maybe the lambda class, which is implicit).
-  bool VisitStmt(Stmt *S) {
+  bool VisitStmt(Stmt *S) override {
     if (!PendingBodies.empty() && S == PendingBodies.top())
       PendingBodies.pop();
     return true;
   }
-  bool VisitDecl(Decl *D) {
+  bool VisitDecl(Decl *D) override {
     if (!PendingClasses.empty() && D == PendingClasses.top())
       PendingClasses.pop();
     return true;
@@ -38,9 +42,6 @@ class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> {
   bool allBodiesHaveBeenTraversed() const { return PendingBodies.empty(); }
   bool allClassesHaveBeenTraversed() const { return PendingClasses.empty(); }
 
-  bool VisitImplicitCode = false;
-  bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
-
 private:
   std::stack<Stmt *> PendingBodies;
   std::stack<Decl *> PendingClasses;
@@ -67,7 +68,7 @@ TEST(RecursiveASTVisitor, LambdaInLambda) {
 
 TEST(RecursiveASTVisitor, TopLevelLambda) {
   LambdaExprVisitor Visitor;
-  Visitor.VisitImplicitCode = true;
+  Visitor.ShouldVisitImplicitCode = true;
   Visitor.ExpectMatch("", 1, 10);
   Visitor.ExpectMatch("", 1, 14);
   EXPECT_TRUE(Visitor.runOver("auto x = []{ [] {}; };",
@@ -78,7 +79,7 @@ TEST(RecursiveASTVisitor, TopLevelLambda) {
 
 TEST(RecursiveASTVisitor, VisitsLambdaExprAndImplicitClass) {
   LambdaExprVisitor Visitor;
-  Visitor.VisitImplicitCode = true;
+  Visitor.ShouldVisitImplicitCode = true;
   Visitor.ExpectMatch("", 1, 12);
   EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }",
                               LambdaExprVisitor::Lang_CXX11));
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
index c355e3f1083f96..77194b04de0369 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
@@ -13,24 +13,25 @@ using namespace clang;
 namespace {
 
 // Matches (optional) explicit template parameters.
-class LambdaTemplateParametersVisitor
-  : public ExpectedLocationVisitor<LambdaTemplateParametersVisitor> {
+class LambdaTemplateParametersVisitor : public ExpectedLocationVisitor {
 public:
-  bool shouldVisitImplicitCode() const { return false; }
+  LambdaTemplateParametersVisitor() {
+    ShouldVisitImplicitCode = false;
+  }
 
-  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) override {
     EXPECT_FALSE(D->isImplicit());
     Match(D->getName(), D->getBeginLoc());
     return true;
   }
 
-  bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) override {
     EXPECT_FALSE(D->isImplicit());
     Match(D->getName(), D->getBeginLoc());
     return true;
   }
 
-  bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) override {
     EXPECT_FALSE(D->isImplicit());
     Match(D->getName(), D->getBeginLoc());
     return true;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
index d67bd0395a670e..587a00dd270511 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
@@ -13,16 +13,15 @@ using namespace clang;
 
 namespace {
 
-class MemberPointerTypeLocVisitor
-    : public ExpectedLocationVisitor<MemberPointerTypeLocVisitor> {
+class MemberPointerTypeLocVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
     if (!TL)
       return true;
     Match(TL.getDecl()->getName(), TL.getNameLoc());
     return true;
   }
-  bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
+  bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
     if (!RTL)
       return true;
     Match(RTL.getDecl()->getName(), RTL.getNameLoc());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
index 868a3988c756d2..ddc663e2b6fd3f 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
@@ -13,17 +13,16 @@ using namespace clang;
 namespace {
 
 // Check to ensure that nested name specifiers are visited.
-class NestedNameSpecifiersVisitor
-    : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> {
+class NestedNameSpecifiersVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
+  bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
     if (!RTL)
       return true;
     Match(RTL.getDecl()->getName(), RTL.getNameLoc());
     return true;
   }
 
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
     if (!NNS)
       return true;
     if (const NamespaceDecl *ND =
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
index c316f98f40ce0f..89ccf20587ad06 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
@@ -12,9 +12,9 @@ using namespace clang;
 
 namespace {
 
-class ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> {
+class ParenExprVisitor : public ExpectedLocationVisitor {
 public:
-  bool VisitParenExpr(ParenExpr *Parens) {
+  bool VisitParenExpr(ParenExpr *Parens) override {
     Match("", Parens->getExprLoc());
     return true;
   }
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
index f068e53ae9c288..3af2b13dc5daf3 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
@@ -12,18 +12,16 @@ using namespace clang;
 
 namespace {
 
-class TemplateArgumentLocTraverser
-  : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> {
+class TemplateArgumentLocTraverser : public ExpectedLocationVisitor {
 public:
-  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override {
     std::string ArgStr;
     llvm::raw_string_ostream Stream(ArgStr);
     const TemplateArgument &Arg = ArgLoc.getArgument();
 
     Arg.print(Context->getPrintingPolicy(), Stream, /*IncludeType*/ true);
     Match(Stream.str(), ArgLoc.getLocation());
-    return ExpectedLocationVisitor<TemplateArgumentLocTraverser>::
-      TraverseTemplateArgumentLoc(ArgLoc);
+    return ExpectedLocationVisitor::TraverseTemplateArgumentLoc(ArgLoc);
   }
 };
 
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
index 9e71f9554e5951..2feddf58cac7b2 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
@@ -12,17 +12,17 @@ using namespace clang;
 
 namespace {
 
-class Visitor : public ExpectedLocationVisitor<Visitor, clang::TestVisitor> {
+class Visitor : public ExpectedLocationVisitor {
 public:
   Visitor(ASTContext *Context) { this->Context = Context; }
 
-  bool VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  bool VisitTranslationUnitDecl(TranslationUnitDecl *D) override {
     auto &SM = D->getParentASTContext().getSourceManager();
     Match("TU", SM.getLocForStartOfFile(SM.getMainFileID()));
     return true;
   }
 
-  bool VisitNamedDecl(NamedDecl *D) {
+  bool VisitNamedDecl(NamedDecl *D) override {
     if (!D->isImplicit())
       Match(D->getName(), D->getLocation());
     return true;
diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp
index 77d410f5d3b604..9df8c1b94c6a45 100644
--- a/clang/unittests/Tooling/RefactoringTest.cpp
+++ b/clang/unittests/Tooling/RefactoringTest.cpp
@@ -13,7 +13,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclGroup.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -648,8 +648,7 @@ TEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) {
 }
 
 namespace {
-template <typename T>
-class TestVisitor : public clang::RecursiveASTVisitor<T> {
+class TestVisitor : public DynamicRecursiveASTVisitor {
 public:
   bool runOver(StringRef Code) {
     return runToolOnCode(std::make_unique<TestAction>(this), Code);
@@ -699,9 +698,9 @@ void expectReplacementAt(const Replacement &Replace,
   EXPECT_EQ(Length, Replace.getLength());
 }
 
-class ClassDeclXVisitor : public TestVisitor<ClassDeclXVisitor> {
+class ClassDeclXVisitor : public TestVisitor {
 public:
-  bool VisitCXXRecordDecl(CXXRecordDecl *Record) {
+  bool VisitCXXRecordDecl(CXXRecordDecl *Record) override {
     if (Record->getName() == "X") {
       Replace = Replacement(*SM, Record, "");
     }
@@ -722,9 +721,9 @@ TEST(Replacement, ReplacesAtSpellingLocation) {
   expectReplacementAt(ClassDeclX.Replace, "input.cc", 17, 7);
 }
 
-class CallToFVisitor : public TestVisitor<CallToFVisitor> {
+class CallToFVisitor : public TestVisitor {
 public:
-  bool VisitCallExpr(CallExpr *Call) {
+  bool VisitCallExpr(CallExpr *Call) override {
     if (Call->getDirectCallee()->getName() == "F") {
       Replace = Replacement(*SM, Call, "");
     }
@@ -746,10 +745,9 @@ TEST(Replacement, TemplatedFunctionCall) {
   expectReplacementAt(CallToF.Replace, "input.cc", 43, 8);
 }
 
-class NestedNameSpecifierAVisitor
-    : public TestVisitor<NestedNameSpecifierAVisitor> {
+class NestedNameSpecifierAVisitor : public TestVisitor {
 public:
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) {
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) override {
     if (NNSLoc.getNestedNameSpecifier()) {
       if (const NamespaceDecl* NS = NNSLoc.getNestedNameSpecifier()->getAsNamespace()) {
         if (NS->getName() == "a") {
@@ -757,8 +755,7 @@ class NestedNameSpecifierAVisitor
         }
       }
     }
-    return TestVisitor<NestedNameSpecifierAVisitor>::TraverseNestedNameSpecifierLoc(
-        NNSLoc);
+    return TestVisitor::TraverseNestedNameSpecifierLoc(NNSLoc);
   }
   Replacement Replace;
 };
diff --git a/clang/unittests/Tooling/SourceCodeTest.cpp b/clang/unittests/Tooling/SourceCodeTest.cpp
index 3c24b6220a224a..549b77752f1c21 100644
--- a/clang/unittests/Tooling/SourceCodeTest.cpp
+++ b/clang/unittests/Tooling/SourceCodeTest.cpp
@@ -35,8 +35,8 @@ using tooling::validateEditRange;
 
 namespace {
 
-struct IntLitVisitor : TestVisitor<IntLitVisitor> {
-  bool VisitIntegerLiteral(IntegerLiteral *Expr) {
+struct IntLitVisitor : TestVisitor {
+  bool VisitIntegerLiteral(IntegerLiteral *Expr) override {
     OnIntLit(Expr, Context);
     return true;
   }
@@ -44,8 +44,8 @@ struct IntLitVisitor : TestVisitor<IntLitVisitor> {
   std::function<void(IntegerLiteral *, ASTContext *Context)> OnIntLit;
 };
 
-struct CallsVisitor : TestVisitor<CallsVisitor> {
-  bool VisitCallExpr(CallExpr *Expr) {
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) override {
     OnCall(Expr, Context);
     return true;
   }
@@ -53,8 +53,8 @@ struct CallsVisitor : TestVisitor<CallsVisitor> {
   std::function<void(CallExpr *, ASTContext *Context)> OnCall;
 };
 
-struct TypeLocVisitor : TestVisitor<TypeLocVisitor> {
-  bool VisitTypeLoc(TypeLoc TL) {
+struct TypeLocVisitor : TestVisitor {
+  bool VisitTypeLoc(TypeLoc TL) override {
     OnTypeLoc(TL, Context);
     return true;
   }
@@ -97,7 +97,7 @@ static ::testing::Matcher<CharSourceRange> AsRange(const SourceManager &SM,
 
 // Base class for visitors that expect a single match corresponding to a
 // specific annotated range.
-template <typename T> class AnnotatedCodeVisitor : public TestVisitor<T> {
+class AnnotatedCodeVisitor : public TestVisitor {
 protected:
   int MatchCount = 0;
   llvm::Annotations Code;
@@ -199,9 +199,8 @@ TEST(SourceCodeTest, getExtendedText) {
 }
 
 TEST(SourceCodeTest, maybeExtendRange_TokenRange) {
-  struct ExtendTokenRangeVisitor
-      : AnnotatedCodeVisitor<ExtendTokenRangeVisitor> {
-    bool VisitCallExpr(CallExpr *CE) {
+  struct ExtendTokenRangeVisitor : AnnotatedCodeVisitor {
+    bool VisitCallExpr(CallExpr *CE) override {
       ++MatchCount;
       EXPECT_THAT(getExtendedRange(*CE, tok::TokenKind::semi, *Context),
                   EqualsAnnotatedRange(Context, Code.range("r")));
@@ -218,8 +217,8 @@ TEST(SourceCodeTest, maybeExtendRange_TokenRange) {
 }
 
 TEST(SourceCodeTest, maybeExtendRange_CharRange) {
-  struct ExtendCharRangeVisitor : AnnotatedCodeVisitor<ExtendCharRangeVisitor> {
-    bool VisitCallExpr(CallExpr *CE) {
+  struct ExtendCharRangeVisitor : AnnotatedCodeVisitor {
+    bool VisitCallExpr(CallExpr *CE) override {
       ++MatchCount;
       CharSourceRange Call = Lexer::getAsCharRange(CE->getSourceRange(),
                                                    Context->getSourceManager(),
@@ -238,8 +237,8 @@ TEST(SourceCodeTest, maybeExtendRange_CharRange) {
 }
 
 TEST(SourceCodeTest, getAssociatedRange) {
-  struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> {
-    bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); }
+  struct VarDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitVarDecl(VarDecl *Decl) override { return VisitDeclHelper(Decl); }
   };
   VarDeclsVisitor Visitor;
 
@@ -283,8 +282,10 @@ TEST(SourceCodeTest, getAssociatedRange) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeClasses) {
-  struct RecordDeclsVisitor : AnnotatedCodeVisitor<RecordDeclsVisitor> {
-    bool VisitRecordDecl(RecordDecl *Decl) { return VisitDeclHelper(Decl); }
+  struct RecordDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitRecordDecl(RecordDecl *Decl) override {
+      return VisitDeclHelper(Decl);
+    }
   };
   RecordDeclsVisitor Visitor;
 
@@ -297,8 +298,8 @@ TEST(SourceCodeTest, getAssociatedRangeClasses) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) {
-  struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor<CXXRecordDeclsVisitor> {
-    bool VisitCXXRecordDecl(CXXRecordDecl *Decl) {
+  struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitCXXRecordDecl(CXXRecordDecl *Decl) override {
       return Decl->getTemplateSpecializationKind() !=
                  TSK_ExplicitSpecialization ||
              VisitDeclHelper(Decl);
@@ -315,8 +316,10 @@ TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeFunctions) {
-  struct FunctionDeclsVisitor : AnnotatedCodeVisitor<FunctionDeclsVisitor> {
-    bool VisitFunctionDecl(FunctionDecl *Decl) { return VisitDeclHelper(Decl); }
+  struct FunctionDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitFunctionDecl(FunctionDecl *Decl) override {
+      return VisitDeclHelper(Decl);
+    }
   };
   FunctionDeclsVisitor Visitor;
 
@@ -328,8 +331,8 @@ TEST(SourceCodeTest, getAssociatedRangeFunctions) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) {
-  struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor<CXXMethodDeclsVisitor> {
-    bool VisitCXXMethodDecl(CXXMethodDecl *Decl) {
+  struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitCXXMethodDecl(CXXMethodDecl *Decl) override {
       // Only consider the definition of the template.
       return !Decl->doesThisDeclarationHaveABody() || VisitDeclHelper(Decl);
     }
@@ -346,8 +349,8 @@ TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeWithComments) {
-  struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> {
-    bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); }
+  struct VarDeclsVisitor : AnnotatedCodeVisitor {
+    bool VisitVarDecl(VarDecl *Decl) override { return VisitDeclHelper(Decl); }
   };
 
   VarDeclsVisitor Visitor;
@@ -447,9 +450,9 @@ TEST(SourceCodeTest, getAssociatedRangeWithComments) {
 }
 
 TEST(SourceCodeTest, getAssociatedRangeInvalidForPartialExpansions) {
-  struct FailingVarDeclsVisitor : TestVisitor<FailingVarDeclsVisitor> {
+  struct FailingVarDeclsVisitor : TestVisitor {
     FailingVarDeclsVisitor() {}
-    bool VisitVarDecl(VarDecl *Decl) {
+    bool VisitVarDecl(VarDecl *Decl) override {
       EXPECT_TRUE(getAssociatedRange(*Decl, *Context).isInvalid());
       return true;
     }
diff --git a/clang/unittests/Tooling/TestVisitor.h b/clang/unittests/Tooling/TestVisitor.h
index 751ca74d1a881c..cf39fc143507ce 100644
--- a/clang/unittests/Tooling/TestVisitor.h
+++ b/clang/unittests/Tooling/TestVisitor.h
@@ -16,7 +16,7 @@
 
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Tooling/Tooling.h"
@@ -24,20 +24,11 @@
 #include <vector>
 
 namespace clang {
-
-/// \brief Base class for simple RecursiveASTVisitor based tests.
-///
-/// This is a drop-in replacement for RecursiveASTVisitor itself, with the
-/// additional capability of running it over a snippet of code.
-///
-/// Visits template instantiations and implicit code by default.
-template <typename T>
-class TestVisitor : public RecursiveASTVisitor<T> {
+namespace detail {
+// Use 'TestVisitor' or include 'CRTPTestVisitor.h' and use 'CRTPTestVisitor'
+// instead of using this directly.
+class TestVisitorHelper {
 public:
-  TestVisitor() { }
-
-  virtual ~TestVisitor() { }
-
   enum Language {
     Lang_C,
     Lang_CXX98,
@@ -54,57 +45,53 @@ class TestVisitor : public RecursiveASTVisitor<T> {
   bool runOver(StringRef Code, Language L = Lang_CXX) {
     std::vector<std::string> Args;
     switch (L) {
-      case Lang_C:
-        Args.push_back("-x");
-        Args.push_back("c");
-        break;
-      case Lang_CXX98: Args.push_back("-std=c++98"); break;
-      case Lang_CXX11: Args.push_back("-std=c++11"); break;
-      case Lang_CXX14: Args.push_back("-std=c++14"); break;
-      case Lang_CXX17: Args.push_back("-std=c++17"); break;
-      case Lang_CXX2a: Args.push_back("-std=c++2a"); break;
-      case Lang_OBJC:
-        Args.push_back("-ObjC");
-        Args.push_back("-fobjc-runtime=macosx-10.12.0");
-        break;
-      case Lang_OBJCXX11:
-        Args.push_back("-ObjC++");
-        Args.push_back("-std=c++11");
-        Args.push_back("-fblocks");
-        break;
+    case Lang_C:
+      Args.push_back("-x");
+      Args.push_back("c");
+      break;
+    case Lang_CXX98: Args.push_back("-std=c++98"); break;
+    case Lang_CXX11: Args.push_back("-std=c++11"); break;
+    case Lang_CXX14: Args.push_back("-std=c++14"); break;
+    case Lang_CXX17: Args.push_back("-std=c++17"); break;
+    case Lang_CXX2a: Args.push_back("-std=c++2a"); break;
+    case Lang_OBJC:
+      Args.push_back("-ObjC");
+      Args.push_back("-fobjc-runtime=macosx-10.12.0");
+      break;
+    case Lang_OBJCXX11:
+      Args.push_back("-ObjC++");
+      Args.push_back("-std=c++11");
+      Args.push_back("-fblocks");
+      break;
     }
     return tooling::runToolOnCodeWithArgs(CreateTestAction(), Code, Args);
   }
 
-  bool shouldVisitTemplateInstantiations() const {
-    return true;
-  }
-
-  bool shouldVisitImplicitCode() const {
-    return true;
-  }
-
 protected:
+  TestVisitorHelper() = default;
+  virtual ~TestVisitorHelper() = default;
+  virtual void InvokeTraverseDecl(TranslationUnitDecl* D) = 0;
+
   virtual std::unique_ptr<ASTFrontendAction> CreateTestAction() {
     return std::make_unique<TestAction>(this);
   }
 
   class FindConsumer : public ASTConsumer {
   public:
-    FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {}
+    FindConsumer(TestVisitorHelper *Visitor) : Visitor(Visitor) {}
 
     void HandleTranslationUnit(clang::ASTContext &Context) override {
       Visitor->Context = &Context;
-      Visitor->TraverseDecl(Context.getTranslationUnitDecl());
+      Visitor->InvokeTraverseDecl(Context.getTranslationUnitDecl());
     }
 
   private:
-    TestVisitor *Visitor;
+    TestVisitorHelper *Visitor;
   };
 
   class TestAction : public ASTFrontendAction {
   public:
-    TestAction(TestVisitor *Visitor) : Visitor(Visitor) {}
+    TestAction(TestVisitorHelper *Visitor) : Visitor(Visitor) {}
 
     std::unique_ptr<clang::ASTConsumer>
     CreateASTConsumer(CompilerInstance &, llvm::StringRef dummy) override {
@@ -113,20 +100,13 @@ class TestVisitor : public RecursiveASTVisitor<T> {
     }
 
   protected:
-    TestVisitor *Visitor;
+    TestVisitorHelper *Visitor;
   };
 
   ASTContext *Context;
 };
 
-/// \brief A RecursiveASTVisitor to check that certain matches are (or are
-/// not) observed during visitation.
-///
-/// This is a RecursiveASTVisitor for testing the RecursiveASTVisitor itself,
-/// and allows simple creation of test visitors running matches on only a small
-/// subset of the Visit* methods.
-template <typename T, template <typename> class Visitor = TestVisitor>
-class ExpectedLocationVisitor : public Visitor<T> {
+class ExpectedLocationVisitorHelper {
 public:
   /// \brief Expect 'Match' *not* to occur at the given 'Line' and 'Column'.
   ///
@@ -147,37 +127,42 @@ class ExpectedLocationVisitor : public Visitor<T> {
   }
 
   /// \brief Checks that all expected matches have been found.
-  ~ExpectedLocationVisitor() override {
-    for (typename std::vector<ExpectedMatch>::const_iterator
+  virtual ~ExpectedLocationVisitorHelper() {
+    // FIXME: Range-based for loop.
+    for (std::vector<ExpectedMatch>::const_iterator
              It = ExpectedMatches.begin(), End = ExpectedMatches.end();
          It != End; ++It) {
       It->ExpectFound();
-    }
+         }
   }
 
 protected:
+  virtual ASTContext* getASTContext() = 0;
+
   /// \brief Checks an actual match against expected and disallowed matches.
   ///
   /// Implementations are required to call this with appropriate values
   /// for 'Name' during visitation.
   void Match(StringRef Name, SourceLocation Location) {
-    const FullSourceLoc FullLocation = this->Context->getFullLoc(Location);
+    const FullSourceLoc FullLocation = getASTContext()->getFullLoc(Location);
 
-    for (typename std::vector<MatchCandidate>::const_iterator
+    // FIXME: Range-based for loop.
+    for (std::vector<MatchCandidate>::const_iterator
              It = DisallowedMatches.begin(), End = DisallowedMatches.end();
          It != End; ++It) {
       EXPECT_FALSE(It->Matches(Name, FullLocation))
           << "Matched disallowed " << *It;
-    }
+         }
 
-    for (typename std::vector<ExpectedMatch>::iterator
+    // FIXME: Range-based for loop.
+    for (std::vector<ExpectedMatch>::iterator
              It = ExpectedMatches.begin(), End = ExpectedMatches.end();
          It != End; ++It) {
-      It->UpdateFor(Name, FullLocation, this->Context->getSourceManager());
-    }
+      It->UpdateFor(Name, FullLocation, getASTContext()->getSourceManager());
+         }
   }
 
- private:
+private:
   struct MatchCandidate {
     std::string ExpectedName;
     unsigned LineNumber;
@@ -228,7 +213,7 @@ class ExpectedLocationVisitor : public Visitor<T> {
         llvm::raw_string_ostream Stream(PartialMatches);
         Stream << ", partial match: \"" << Name << "\" at ";
         Location.print(Stream, SM);
-      }
+                 }
     }
 
     void ExpectFound() const {
@@ -249,4 +234,41 @@ class ExpectedLocationVisitor : public Visitor<T> {
 };
 }
 
+/// \brief Base class for simple (Dynamic)RecursiveASTVisitor based tests.
+///
+/// This is a drop-in replacement for DynamicRecursiveASTVisitor itself, with
+/// the additional capability of running it over a snippet of code.
+///
+/// Visits template instantiations and implicit code by default.
+///
+/// For post-order traversal etc. use CTRPTestVisitor from
+/// CTRPTestVisitor.h instead.
+class TestVisitor : public DynamicRecursiveASTVisitor,
+                    public detail::TestVisitorHelper {
+public:
+  TestVisitor() {
+    ShouldVisitTemplateInstantiations = true;
+    ShouldVisitImplicitCode = true;
+  }
+
+  void InvokeTraverseDecl(TranslationUnitDecl* D) override {
+    TraverseDecl(D);
+  }
+};
+
+/// \brief A RecursiveASTVisitor to check that certain matches are (or are
+/// not) observed during visitation.
+///
+/// This is a RecursiveASTVisitor for testing the RecursiveASTVisitor itself,
+/// and allows simple creation of test visitors running matches on only a small
+/// subset of the Visit* methods.
+///
+/// For post-order traversal etc. use CTRPExpectedLocationVisitor from
+/// CTRPTestVisitor.h instead.
+class ExpectedLocationVisitor : public TestVisitor,
+                                public detail::ExpectedLocationVisitorHelper {
+  ASTContext *getASTContext() override { return Context; }
+};
+}
+
 #endif

>From 676a069b35f45cd8578c2db67cf9b46042ec627a Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 18:03:14 +0200
Subject: [PATCH 17/27] So long, DataRecursionQueue

---
 .../clang/AST/DynamicRecursiveASTVisitor.h    | 12 ++--------
 clang/include/clang/Analysis/CallGraph.h      |  2 +-
 clang/lib/ARCMigrate/ObjCMT.cpp               |  2 +-
 clang/lib/ARCMigrate/Transforms.cpp           |  2 +-
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  | 23 +++++++++++--------
 clang/lib/ASTMatchers/ASTMatchFinder.cpp      | 20 +++++++---------
 clang/lib/Analysis/UnsafeBufferUsage.cpp      |  2 +-
 clang/lib/Index/IndexTypeSourceInfo.cpp       |  2 +-
 clang/lib/Sema/SemaAvailability.cpp           |  2 +-
 clang/lib/Sema/SemaTemplate.cpp               |  4 ++--
 clang/lib/Sema/SemaTemplateVariadic.cpp       |  4 ++--
 clang/lib/Tooling/ASTDiff/ASTDiff.cpp         |  2 +-
 12 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 75d7597c2b7497..14b60ee0dc3192 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -24,10 +24,6 @@ class ASTContext;
 /// \see RecursiveASTVisitor
 class DynamicRecursiveASTVisitor {
 public:
-  // FIXME: I think we can just get rid of the Queue entirely.
-  using DataRecursionQueue =
-      SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>;
-
   /// Whether this visitor should recurse into template instantiations.
   bool ShouldVisitTemplateInstantiations = false;
 
@@ -115,9 +111,7 @@ class DynamicRecursiveASTVisitor {
   ///
   /// \returns false if the visitation was terminated early, true
   /// otherwise (including when the argument is nullptr).
-  ///
-  // FIXME: I think we can just get rid of the Queue entirely.
-  virtual bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
+  virtual bool TraverseStmt(Stmt *S);
 
   /// Recursively visit a template argument and dispatch to the
   /// appropriate method for the argument type.
@@ -198,9 +192,7 @@ class DynamicRecursiveASTVisitor {
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
   virtual bool dataTraverseStmtPost(Stmt *S) { return true; }
-
-  // FIXME: I think we can just get rid of the Queue entirely.
-  virtual bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue = nullptr);
+  virtual bool dataTraverseNode(Stmt *S);
 
   /*// Declare Traverse*() and friends for attributes.
 #define DYNAMIC_ATTR_VISITOR_DECLS
diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h
index 891c4c750011d2..c11d163f8fe20d 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -134,7 +134,7 @@ class CallGraph : public DynamicRecursiveASTVisitor {
   }
 
   // We are only collecting the declarations, so do not step into the bodies.
-  bool TraverseStmt(Stmt *S, DataRecursionQueue*) override { return true; }
+  bool TraverseStmt(Stmt *S) override { return true; }
 
 private:
   /// Add the given declaration to the call graph.
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 4164e452059307..62402646009e12 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -364,7 +364,7 @@ namespace {
       ShouldWalkTypesOfTypeLocs = false;
     }
 
-    bool TraverseStmt(Stmt *S, DataRecursionQueue * = nullptr) override {
+    bool TraverseStmt(Stmt *S) override {
       PMap.reset(new ParentMap(S));
       ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
       return true;
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index 4c35bcda2c15da..8b429bcdd1e7a8 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -335,7 +335,7 @@ class ASTTransform : public DynamicRecursiveASTVisitor {
     return DynamicRecursiveASTVisitor::TraverseObjCImplementationDecl(D);
   }
 
-  bool TraverseStmt(Stmt *rootS, DataRecursionQueue * = nullptr) override {
+  bool TraverseStmt(Stmt *rootS) override {
     if (!rootS)
       return true;
 
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index fe9b80df3e5477..7c39c6c58c02f4 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -41,8 +41,8 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool TraverseDecl(Decl *D) { return Visitor.TraverseDecl(D); }
   bool TraverseType(QualType T) { return Visitor.TraverseType(T); }
   bool TraverseTypeLoc(TypeLoc TL) { return Visitor.TraverseTypeLoc(TL); }
-  bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr) {
-    return Visitor.TraverseStmt(S, Queue);
+  bool TraverseStmt(Stmt *S) {
+    return Visitor.TraverseStmt(S);
   }
 
   bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
@@ -112,8 +112,14 @@ struct Impl : RecursiveASTVisitor<Impl> {
 
   bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
   bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }
-  bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
-    return Visitor.dataTraverseNode(S, Queue);
+
+  // TraverseStmt() always passes in a queue, so we have no choice but to
+  // accept it as a parameter here.
+  bool dataTraverseNode(Stmt *S, DataRecursionQueue* = nullptr) {
+    // But since don't support postorder traversal, we don't need it, so
+    // simply discard it here. This way, derived classes don't need to worry
+    // about including it as a parameter that they never use.
+    return Visitor.dataTraverseNode(S);
   }
 
   /// Visit a node.
@@ -218,9 +224,8 @@ bool DynamicRecursiveASTVisitor::TraverseLambdaCapture(LambdaExpr *LE,
                                                                       Init);
 }
 
-bool DynamicRecursiveASTVisitor::TraverseStmt(Stmt *S,
-                                              DataRecursionQueue *Queue) {
-  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseStmt(S, Queue);
+bool DynamicRecursiveASTVisitor::TraverseStmt(Stmt *S) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseStmt(S);
 }
 
 bool DynamicRecursiveASTVisitor::TraverseTemplateArgument(
@@ -308,8 +313,8 @@ bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
       NNS);
 }
 
-bool DynamicRecursiveASTVisitor::dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
-  return Impl(*this).RecursiveASTVisitor<Impl>::dataTraverseNode(S, Queue);
+bool DynamicRecursiveASTVisitor::dataTraverseNode(Stmt *S) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::dataTraverseNode(S, nullptr);
 }
 
 /*
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index e9c8779972f475..2c2399b1951b89 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -174,11 +174,7 @@ class MatchChildASTVisitor : public DynamicRecursiveASTVisitor {
     return StmtToTraverse;
   }
 
-  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) override {
-    // If we need to keep track of the depth, we can't perform data recursion.
-    if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX))
-      Queue = nullptr;
-
+  bool TraverseStmt(Stmt *StmtNode) override {
     ScopedIncrement ScopedDepth(&CurrentDepth);
     Stmt *StmtToTraverse = getStmtToTraverse(StmtNode);
     if (!StmtToTraverse)
@@ -189,7 +185,7 @@ class MatchChildASTVisitor : public DynamicRecursiveASTVisitor {
 
     if (!match(*StmtToTraverse))
       return false;
-    return DynamicRecursiveASTVisitor::TraverseStmt(StmtToTraverse, Queue);
+    return DynamicRecursiveASTVisitor::TraverseStmt(StmtToTraverse);
   }
   // We assume that the QualType and the contained type are on the same
   // hierarchy level. Thus, we try to match either of them.
@@ -498,7 +494,7 @@ class MatchASTVisitor : public DynamicRecursiveASTVisitor,
   }
 
   bool TraverseDecl(Decl *DeclNode) override;
-  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) override;
+  bool TraverseStmt(Stmt *StmtNode) override;
   bool TraverseType(QualType TypeNode) override;
   bool TraverseTypeLoc(TypeLoc TypeNode) override;
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) override;
@@ -507,7 +503,7 @@ class MatchASTVisitor : public DynamicRecursiveASTVisitor,
   bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc& TAL) override;
   bool TraverseAttr(Attr *AttrNode) override;
 
-  bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) override {
+  bool dataTraverseNode(Stmt *S) override {
     if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) {
       {
         ASTNodeNotAsIsSourceScope RAII(this, true);
@@ -578,7 +574,7 @@ class MatchASTVisitor : public DynamicRecursiveASTVisitor,
           TraverseType(E);
 
         if (Expr *NE = T->getNoexceptExpr())
-          TraverseStmt(NE, Queue);
+          TraverseStmt(NE);
 
         if (LE->hasExplicitResultType())
           TraverseTypeLoc(Proto.getReturnLoc());
@@ -588,7 +584,7 @@ class MatchASTVisitor : public DynamicRecursiveASTVisitor,
       TraverseStmt(LE->getBody());
       return true;
     }
-    return DynamicRecursiveASTVisitor::dataTraverseNode(S, Queue);
+    return DynamicRecursiveASTVisitor::dataTraverseNode(S);
   }
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
@@ -1463,7 +1459,7 @@ bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
   return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode);
 }
 
-bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
+bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
   if (!StmtNode) {
     return true;
   }
@@ -1472,7 +1468,7 @@ bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
 
   ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal);
   match(*StmtNode);
-  return DynamicRecursiveASTVisitor::TraverseStmt(StmtNode, Queue);
+  return DynamicRecursiveASTVisitor::TraverseStmt(StmtNode);
 }
 
 bool MatchASTVisitor::TraverseType(QualType TypeNode) {
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index e1f214c1c582a7..912bcb6f353f96 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -170,7 +170,7 @@ class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
     return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(Node);
   }
 
-  bool TraverseStmt(Stmt *Node, DataRecursionQueue *Queue = nullptr) override {
+  bool TraverseStmt(Stmt *Node) override {
     if (!Node)
       return true;
     if (!match(*Node))
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 4f09d0d7a16e8e..cf7da0893cafb8 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -233,7 +233,7 @@ class TypeIndexer : public DynamicRecursiveASTVisitor {
                                     ParentDC, SymbolRoleSet(), Relations);
   }
 
-  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
+  bool TraverseStmt(Stmt *S) override {
     IndexCtx.indexBody(S, Parent, ParentDC);
     return true;
   }
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index 80f42f6cf4990f..ed78199015165d 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -779,7 +779,7 @@ class DiagnoseUnguardedAvailability : public DynamicRecursiveASTVisitor {
         SemaRef.Context.getTargetInfo().getPlatformMinVersion());
   }
 
-  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
+  bool TraverseStmt(Stmt *S) override {
     if (!S)
       return true;
     StmtStack.push_back(S);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6526548685c390..ce62cb417e1db2 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2584,7 +2584,7 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
     return false;
   }
 
-  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) override {
+  bool TraverseStmt(Stmt *S) override {
     // Prune out non-type-dependent expressions if requested. This can
     // sometimes result in us failing to find a template parameter reference
     // (if a value-dependent expression creates a dependent type), but this
@@ -2592,7 +2592,7 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
     if (auto *E = dyn_cast_or_null<Expr>(S))
       if (IgnoreNonTypeDependent && !E->isTypeDependent())
         return true;
-    return DynamicRecursiveASTVisitor::TraverseStmt(S, Q);
+    return DynamicRecursiveASTVisitor::TraverseStmt(S);
   }
 
   bool TraverseTypeLoc(TypeLoc TL) override {
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index e88d41208bdee0..11462fb362721e 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -128,10 +128,10 @@ class CollectUnexpandedParameterPacksVisitor
 
   /// Suppress traversal into statements and expressions that
   /// do not contain unexpanded parameter packs.
-  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) override {
+  bool TraverseStmt(Stmt *S) override {
     Expr *E = dyn_cast_or_null<Expr>(S);
     if ((E && E->containsUnexpandedParameterPack()) || InLambda)
-      return DynamicRecursiveASTVisitor::TraverseStmt(S, Q);
+      return DynamicRecursiveASTVisitor::TraverseStmt(S);
 
     return true;
   }
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
index ee5c69ef55e598..0440e47ddb4ae4 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -237,7 +237,7 @@ struct PreorderVisitor : DynamicRecursiveASTVisitor {
     PostTraverse(SavedState);
     return true;
   }
-  bool TraverseStmt(Stmt *S, DataRecursionQueue* = nullptr) override {
+  bool TraverseStmt(Stmt *S) override {
     if (auto *E = dyn_cast_or_null<Expr>(S))
       S = E->IgnoreImplicit();
     if (isNodeExcluded(Tree.AST.getSourceManager(), S))

>From c60376418407188af2017652114baae90c586be5 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 18:11:39 +0200
Subject: [PATCH 18/27] Make a bunch of visitors 'final' to see if that makes a
 difference

---
 clang/docs/RAVFrontendAction.rst                          | 2 +-
 clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp   | 4 ++--
 clang/examples/PrintFunctionNames/PrintFunctionNames.cpp  | 2 +-
 clang/include/clang/Analysis/CallGraph.h                  | 2 +-
 clang/lib/ARCMigrate/ObjCMT.cpp                           | 6 +++---
 clang/lib/ARCMigrate/TransAPIUses.cpp                     | 2 +-
 clang/lib/ARCMigrate/TransARCAssign.cpp                   | 2 +-
 clang/lib/ARCMigrate/TransAutoreleasePool.cpp             | 4 ++--
 clang/lib/ARCMigrate/TransBlockObjCVariable.cpp           | 6 +++---
 clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp   | 2 +-
 clang/lib/ARCMigrate/TransGCAttrs.cpp                     | 2 +-
 clang/lib/ARCMigrate/TransGCCalls.cpp                     | 2 +-
 clang/lib/ARCMigrate/TransProtectedScope.cpp              | 4 ++--
 clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp       | 2 +-
 clang/lib/ARCMigrate/Transforms.cpp                       | 8 ++++----
 clang/lib/AST/ASTImporterLookupTable.cpp                  | 2 +-
 clang/lib/AST/StmtOpenACC.cpp                             | 2 +-
 clang/lib/ASTMatchers/ASTMatchFinder.cpp                  | 6 +++---
 clang/lib/Analysis/CalledOnceCheck.cpp                    | 2 +-
 clang/lib/Analysis/ReachableCode.cpp                      | 2 +-
 clang/lib/Analysis/UnsafeBufferUsage.cpp                  | 2 +-
 clang/lib/CodeGen/CGDebugInfo.cpp                         | 4 ++--
 clang/lib/CodeGen/CodeGenModule.cpp                       | 2 +-
 clang/lib/CodeGen/CodeGenPGO.cpp                          | 2 +-
 clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp        | 2 +-
 clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp     | 2 +-
 clang/lib/Index/IndexBody.cpp                             | 2 +-
 clang/lib/Index/IndexTypeSourceInfo.cpp                   | 2 +-
 clang/lib/Sema/AnalysisBasedWarnings.cpp                  | 4 ++--
 clang/lib/Sema/SemaAvailability.cpp                       | 6 +++---
 clang/lib/Sema/SemaCodeComplete.cpp                       | 2 +-
 clang/lib/Sema/SemaDeclAttr.cpp                           | 2 +-
 clang/lib/Sema/SemaDeclCXX.cpp                            | 4 ++--
 clang/lib/Sema/SemaDeclObjC.cpp                           | 2 +-
 clang/lib/Sema/SemaExpr.cpp                               | 6 +++---
 clang/lib/Sema/SemaExprCXX.cpp                            | 2 +-
 clang/lib/Sema/SemaHLSL.cpp                               | 4 ++--
 clang/lib/Sema/SemaStmt.cpp                               | 2 +-
 clang/lib/Sema/SemaTemplate.cpp                           | 2 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp                  | 2 +-
 clang/lib/Sema/SemaTemplateVariadic.cpp                   | 2 +-
 clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp | 2 +-
 clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp   | 2 +-
 .../StaticAnalyzer/Checkers/DynamicTypePropagation.cpp    | 2 +-
 .../lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp  | 2 +-
 clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp | 2 +-
 .../Checkers/ObjCMissingSuperCallChecker.cpp              | 2 +-
 clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp      | 2 +-
 .../Checkers/WebKit/NoUncountedMembersChecker.cpp         | 2 +-
 .../Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp    | 2 +-
 .../Checkers/WebKit/UncountedCallArgsChecker.cpp          | 2 +-
 .../Checkers/WebKit/UncountedLambdaCapturesChecker.cpp    | 2 +-
 .../Checkers/WebKit/UncountedLocalVarsChecker.cpp         | 2 +-
 clang/lib/StaticAnalyzer/Core/BugSuppression.cpp          | 2 +-
 clang/lib/Tooling/ASTDiff/ASTDiff.cpp                     | 2 +-
 clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp        | 2 +-
 clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp | 2 +-
 clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp     | 2 +-
 clang/unittests/Analysis/CloneDetectionTest.cpp           | 2 +-
 59 files changed, 79 insertions(+), 79 deletions(-)

diff --git a/clang/docs/RAVFrontendAction.rst b/clang/docs/RAVFrontendAction.rst
index 1e7d88a19f201a..28a99d1744b7b5 100644
--- a/clang/docs/RAVFrontendAction.rst
+++ b/clang/docs/RAVFrontendAction.rst
@@ -150,7 +150,7 @@ Now we can combine all of the above into a small example program:
 
       using namespace clang;
 
-      class FindNamedClassVisitor : public DynamicRecursiveASTVisitor {
+      class FindNamedClassVisitor final : public DynamicRecursiveASTVisitor {
       public:
         explicit FindNamedClassVisitor(ASTContext *Context)
           : Context(Context) {}
diff --git a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
index 451506b13ab313..036c54e593dab4 100644
--- a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
+++ b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
@@ -41,7 +41,7 @@ bool isMarkedAsCallSuper(const CXXMethodDecl *D) {
   return MarkedMethods.contains(D);
 }
 
-class MethodUsageVisitor : public DynamicRecursiveASTVisitor {
+class MethodUsageVisitor final : public DynamicRecursiveASTVisitor {
 public:
   bool IsOverriddenUsed = false;
   explicit MethodUsageVisitor(
@@ -68,7 +68,7 @@ class MethodUsageVisitor : public DynamicRecursiveASTVisitor {
   llvm::SmallPtrSet<const CXXMethodDecl *, 16> &MustCalledMethods;
 };
 
-class CallSuperVisitor : public DynamicRecursiveASTVisitor {
+class CallSuperVisitor final : public DynamicRecursiveASTVisitor {
 public:
   CallSuperVisitor(DiagnosticsEngine &Diags) : Diags(Diags) {
     WarningSuperNotCalled = Diags.getCustomDiagID(
diff --git a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
index 5100901f74d992..248e3e159b329a 100644
--- a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
+++ b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -52,7 +52,7 @@ class PrintFunctionsConsumer : public ASTConsumer {
     // The advantage of doing this in HandleTranslationUnit() is that all
     // codegen (when using -add-plugin) is completely finished and this can't
     // affect the compiler output.
-    struct Visitor : DynamicRecursiveASTVisitor {
+    struct Visitor final : DynamicRecursiveASTVisitor {
       const std::set<std::string> &ParsedTemplates;
       Visitor(const std::set<std::string> &ParsedTemplates)
           : ParsedTemplates(ParsedTemplates) {}
diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h
index c11d163f8fe20d..4266ebfd2f7829 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -40,7 +40,7 @@ class Stmt;
 /// The call graph extends itself with the given declarations by implementing
 /// the recursive AST visitor, which constructs the graph by visiting the given
 /// declarations.
-class CallGraph : public DynamicRecursiveASTVisitor {
+class CallGraph final : public DynamicRecursiveASTVisitor {
   friend class CallGraphNode;
 
   using FunctionMapTy =
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 62402646009e12..f99dcaabd4adb3 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -308,7 +308,7 @@ namespace {
     return true;
   }
 
-  class ObjCMigrator : public DynamicRecursiveASTVisitor {
+  class ObjCMigrator final : public DynamicRecursiveASTVisitor {
     ObjCMigrateASTConsumer &Consumer;
     ParentMap &PMap;
 
@@ -354,7 +354,7 @@ namespace {
     }
   };
 
-  class BodyMigrator : public DynamicRecursiveASTVisitor {
+  class BodyMigrator final : public DynamicRecursiveASTVisitor {
     ObjCMigrateASTConsumer &Consumer;
     std::unique_ptr<ParentMap> PMap;
 
@@ -1672,7 +1672,7 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
 }
 
 namespace {
-class SuperInitChecker : public DynamicRecursiveASTVisitor {
+class SuperInitChecker final : public DynamicRecursiveASTVisitor {
 public:
   SuperInitChecker() {
     ShouldVisitTemplateInstantiations = false;
diff --git a/clang/lib/ARCMigrate/TransAPIUses.cpp b/clang/lib/ARCMigrate/TransAPIUses.cpp
index 4525aa8718d890..1ec65d730a81e0 100644
--- a/clang/lib/ARCMigrate/TransAPIUses.cpp
+++ b/clang/lib/ARCMigrate/TransAPIUses.cpp
@@ -27,7 +27,7 @@ using namespace trans;
 
 namespace {
 
-class APIChecker : public DynamicRecursiveASTVisitor {
+class APIChecker final : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
   Selector getReturnValueSel, setReturnValueSel;
diff --git a/clang/lib/ARCMigrate/TransARCAssign.cpp b/clang/lib/ARCMigrate/TransARCAssign.cpp
index 672d9b7865d805..8d93b10414ce63 100644
--- a/clang/lib/ARCMigrate/TransARCAssign.cpp
+++ b/clang/lib/ARCMigrate/TransARCAssign.cpp
@@ -31,7 +31,7 @@ using namespace trans;
 
 namespace {
 
-class ARCAssignChecker : public DynamicRecursiveASTVisitor {
+class ARCAssignChecker final : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
   llvm::DenseSet<VarDecl *> ModifiedVars;
 
diff --git a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
index 03dba2b20f95e9..6a00bb1cbc5ed1 100644
--- a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -39,7 +39,7 @@ using namespace trans;
 
 namespace {
 
-class ReleaseCollector : public DynamicRecursiveASTVisitor {
+class ReleaseCollector final : public DynamicRecursiveASTVisitor {
   Decl *Dcl;
   SmallVectorImpl<ObjCMessageExpr *> &Releases;
 
@@ -244,7 +244,7 @@ class AutoreleasePoolRewriter
     }
   };
 
-  class NameReferenceChecker : public DynamicRecursiveASTVisitor {
+  class NameReferenceChecker final : public DynamicRecursiveASTVisitor {
     ASTContext &Ctx;
     SourceRange ScopeRange;
     SourceLocation &referenceLoc, &declarationLoc;
diff --git a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 3d4e34952a1798..2d3cec91b96aa6 100644
--- a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -36,10 +36,10 @@ using namespace trans;
 
 namespace {
 
-class RootBlockObjCVarRewriter : public DynamicRecursiveASTVisitor {
+class RootBlockObjCVarRewriter final : public DynamicRecursiveASTVisitor {
   llvm::DenseSet<VarDecl *> &VarsToChange;
 
-  class BlockVarChecker : public DynamicRecursiveASTVisitor {
+  class BlockVarChecker final : public DynamicRecursiveASTVisitor {
     VarDecl *Var;
 
   public:
@@ -106,7 +106,7 @@ class RootBlockObjCVarRewriter : public DynamicRecursiveASTVisitor {
   }
 };
 
-class BlockObjCVarRewriter : public DynamicRecursiveASTVisitor {
+class BlockObjCVarRewriter final : public DynamicRecursiveASTVisitor {
   llvm::DenseSet<VarDecl *> &VarsToChange;
 
 public:
diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index 51c07a1d4fc4ab..a63e1750b95da5 100644
--- a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -143,7 +143,7 @@ class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
   }
 };
 
-class EmptyStatementsRemover : public DynamicRecursiveASTVisitor {
+class EmptyStatementsRemover final : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
 public:
diff --git a/clang/lib/ARCMigrate/TransGCAttrs.cpp b/clang/lib/ARCMigrate/TransGCAttrs.cpp
index f4cc0d839e495e..bcf874c0fd56d2 100644
--- a/clang/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/clang/lib/ARCMigrate/TransGCAttrs.cpp
@@ -23,7 +23,7 @@ using namespace trans;
 namespace {
 
 /// Collects all the places where GC attributes __strong/__weak occur.
-class GCAttrsCollector : public DynamicRecursiveASTVisitor {
+class GCAttrsCollector final : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
   bool FullyMigratable;
   std::vector<ObjCPropertyDecl *> &AllProps;
diff --git a/clang/lib/ARCMigrate/TransGCCalls.cpp b/clang/lib/ARCMigrate/TransGCCalls.cpp
index 1da686cd7ec8c2..de758f33fdcd69 100644
--- a/clang/lib/ARCMigrate/TransGCCalls.cpp
+++ b/clang/lib/ARCMigrate/TransGCCalls.cpp
@@ -17,7 +17,7 @@ using namespace trans;
 
 namespace {
 
-class GCCollectableCallsChecker : public DynamicRecursiveASTVisitor {
+class GCCollectableCallsChecker final : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
   IdentifierInfo *NSMakeCollectableII;
   IdentifierInfo *CFMakeCollectableII;
diff --git a/clang/lib/ARCMigrate/TransProtectedScope.cpp b/clang/lib/ARCMigrate/TransProtectedScope.cpp
index b6d4b1b7c771ae..ef526f7edcaa94 100644
--- a/clang/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/clang/lib/ARCMigrate/TransProtectedScope.cpp
@@ -23,7 +23,7 @@ using namespace trans;
 
 namespace {
 
-class LocalRefsCollector : public DynamicRecursiveASTVisitor {
+class LocalRefsCollector final : public DynamicRecursiveASTVisitor {
   SmallVectorImpl<DeclRefExpr *> &Refs;
 
 public:
@@ -52,7 +52,7 @@ struct CaseInfo {
     : SC(S), Range(Range), State(St_Unchecked) {}
 };
 
-class CaseCollector : public DynamicRecursiveASTVisitor {
+class CaseCollector final : public DynamicRecursiveASTVisitor {
   ParentMap &PMap;
   SmallVectorImpl<CaseInfo> &Cases;
 
diff --git a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index ea87b9288de13e..a606a52b826614 100644
--- a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -22,7 +22,7 @@ using namespace trans;
 
 namespace {
 
-class ZeroOutInDeallocRemover : public DynamicRecursiveASTVisitor {
+class ZeroOutInDeallocRemover final : public DynamicRecursiveASTVisitor {
   MigrationPass &Pass;
 
   llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties;
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index 8b429bcdd1e7a8..7363427580c83b 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -211,7 +211,7 @@ StringRef trans::getNilString(MigrationPass &Pass) {
 
 namespace {
 
-class ReferenceClear : public DynamicRecursiveASTVisitor {
+class ReferenceClear final : public DynamicRecursiveASTVisitor {
   ExprSet &Refs;
 public:
   ReferenceClear(ExprSet &refs) : Refs(refs) { }
@@ -221,7 +221,7 @@ class ReferenceClear : public DynamicRecursiveASTVisitor {
   }
 };
 
-class ReferenceCollector : public DynamicRecursiveASTVisitor {
+class ReferenceCollector final : public DynamicRecursiveASTVisitor {
   ValueDecl *Dcl;
   ExprSet &Refs;
 
@@ -236,7 +236,7 @@ class ReferenceCollector : public DynamicRecursiveASTVisitor {
   }
 };
 
-class RemovablesCollector : public DynamicRecursiveASTVisitor {
+class RemovablesCollector final : public DynamicRecursiveASTVisitor {
   ExprSet &Removables;
 
 public:
@@ -317,7 +317,7 @@ void trans::collectRemovables(Stmt *S, ExprSet &exprs) {
 
 namespace {
 
-class ASTTransform : public DynamicRecursiveASTVisitor {
+class ASTTransform final : public DynamicRecursiveASTVisitor {
   MigrationContext &MigrateCtx;
 
 public:
diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp
index b7c112540c1c60..37807de07e7593 100644
--- a/clang/lib/AST/ASTImporterLookupTable.cpp
+++ b/clang/lib/AST/ASTImporterLookupTable.cpp
@@ -21,7 +21,7 @@ namespace clang {
 
 namespace {
 
-struct Builder : DynamicRecursiveASTVisitor {
+struct Builder final : DynamicRecursiveASTVisitor {
   ASTImporterLookupTable <
   Builder(ASTImporterLookupTable &LT) : LT(LT) {
     ShouldVisitTemplateInstantiations = true;
diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp
index fbf0ef540eb685..366f4e8df0885a 100644
--- a/clang/lib/AST/StmtOpenACC.cpp
+++ b/clang/lib/AST/StmtOpenACC.cpp
@@ -44,7 +44,7 @@ OpenACCComputeConstruct *OpenACCComputeConstruct::Create(
 }
 
 void OpenACCComputeConstruct::findAndSetChildLoops() {
-  struct LoopConstructFinder : DynamicRecursiveASTVisitor {
+  struct LoopConstructFinder final : DynamicRecursiveASTVisitor {
     OpenACCComputeConstruct *Construct = nullptr;
 
     LoopConstructFinder(OpenACCComputeConstruct *Construct)
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 2c2399b1951b89..e0aecb1d1ccad4 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -87,7 +87,7 @@ struct MemoizedMatchResult {
 
 // A RecursiveASTVisitor that traverses all children or all descendants of
 // a node.
-class MatchChildASTVisitor : public DynamicRecursiveASTVisitor {
+class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
 public:
   // Creates an AST visitor that matches 'matcher' on all children or
   // descendants of a traversed node. max_depth is the maximum depth
@@ -408,8 +408,8 @@ class MatchChildASTVisitor : public DynamicRecursiveASTVisitor {
 
 // Controls the outermost traversal of the AST and allows to match multiple
 // matchers.
-class MatchASTVisitor : public DynamicRecursiveASTVisitor,
-                        public ASTMatchFinder {
+class MatchASTVisitor final : public DynamicRecursiveASTVisitor,
+                              public ASTMatchFinder {
 public:
   MatchASTVisitor(const MatchFinder::MatchersByType *Matchers,
                   const MatchFinder::MatchFinderOptions &Options)
diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index 73dc6bbe154b2b..cada4add01d9a5 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -426,7 +426,7 @@ const Expr *getCondition(const Stmt *S) {
 /// of the AST will end up in the results.
 /// Results might have duplicate names, if this is a problem, convert to
 /// string sets afterwards.
-class NamesCollector : public DynamicRecursiveASTVisitor {
+class NamesCollector final : public DynamicRecursiveASTVisitor {
 public:
   static constexpr unsigned EXPECTED_NUMBER_OF_NAMES = 5;
   using NameCollection =
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 905192c7edd226..02948479faae35 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -476,7 +476,7 @@ static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) {
     }
   if (!CoroStmt)
     return false;
-  struct Checker : DynamicRecursiveASTVisitor {
+  struct Checker final : DynamicRecursiveASTVisitor {
     const Stmt *DeadStmt;
     bool CoroutineSubStmt = false;
     Checker(const Stmt *S) : DeadStmt(S) {
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 912bcb6f353f96..22b628d230b907 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -81,7 +81,7 @@ static std::string getDREAncestorString(const DeclRefExpr *DRE,
 namespace clang::ast_matchers {
 // A `RecursiveASTVisitor` that traverses all descendants of a given node "n"
 // except for those belonging to a different callable of "n".
-class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
+class MatchDescendantVisitor final : public DynamicRecursiveASTVisitor {
 public:
   // Creates an AST visitor that matches `Matcher` on all
   // descendants of a given node "n" except for the ones
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 23a9ba18844a4a..2aff23aa271583 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5446,7 +5446,7 @@ static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args) {
     case TemplateArgument::Pack:
       return ReferencesAnonymousEntity(TA.getPackAsArray());
     case TemplateArgument::Type: {
-      struct ReferencesAnonymous : DynamicRecursiveASTVisitor {
+      struct ReferencesAnonymous final : DynamicRecursiveASTVisitor {
         bool RefAnon = false;
         bool VisitRecordType(RecordType *RT) override {
           if (ReferencesAnonymousEntity(RT)) {
@@ -5469,7 +5469,7 @@ static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args) {
   });
 }
 namespace {
-struct ReconstitutableType : DynamicRecursiveASTVisitor {
+struct ReconstitutableType final : DynamicRecursiveASTVisitor {
   bool Reconstitutable = true;
   bool VisitVectorType(VectorType *FT) override {
     Reconstitutable = false;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d8e851dee474d5..690f0fece72975 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3951,7 +3951,7 @@ namespace {
   };
 
   // Make sure we're not referencing non-imported vars or functions.
-  struct DLLImportFunctionVisitor : DynamicRecursiveASTVisitor {
+  struct DLLImportFunctionVisitor final : DynamicRecursiveASTVisitor {
     bool SafeToInline = true;
 
     DLLImportFunctionVisitor() { ShouldVisitImplicitCode = true; }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 0bfa3eb93eab09..833c491d2c5934 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -156,7 +156,7 @@ static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
 }
 
 /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
-struct MapRegionCounters : DynamicRecursiveASTVisitor {
+struct MapRegionCounters final : DynamicRecursiveASTVisitor {
   /// The next counter value to assign.
   unsigned NextCounter;
   /// The function hash.
diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
index bfddb885b392e4..c3bc1641e542c4 100644
--- a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
+++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
@@ -58,7 +58,7 @@ class PCHContainerGenerator : public ASTConsumer {
   std::shared_ptr<PCHBuffer> Buffer;
 
   /// Visit every type and emit debug info for it.
-  struct DebugTypeVisitor : DynamicRecursiveASTVisitor {
+  struct DebugTypeVisitor final : DynamicRecursiveASTVisitor {
     clang::CodeGen::CGDebugInfo &DI;
     ASTContext &Ctx;
     DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
diff --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
index 616f0c9a8241f6..2473ad50ab4872 100644
--- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -242,7 +242,7 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer {
       : Instance(Instance), InFile(InFile), Format(Format) {}
 
   void HandleTranslationUnit(ASTContext &context) override {
-    struct Visitor : DynamicRecursiveASTVisitor {
+    struct Visitor final : DynamicRecursiveASTVisitor {
       bool VisitNamedDecl(NamedDecl *ND) override {
         if (const auto *FD = dyn_cast<FunctionDecl>(ND))
           if (FD->isLateTemplateParsed()) {
diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index 40f9deffa96292..8628a2dcdac90a 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -21,7 +21,7 @@ using namespace clang::index;
 
 namespace {
 
-class BodyIndexer : public DynamicRecursiveASTVisitor {
+class BodyIndexer final : public DynamicRecursiveASTVisitor {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index cf7da0893cafb8..9c44847688f9ee 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -19,7 +19,7 @@ using namespace index;
 
 namespace {
 
-class TypeIndexer : public DynamicRecursiveASTVisitor {
+class TypeIndexer final : public DynamicRecursiveASTVisitor {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 62ed9d2c44a9bd..c894b358bf7c26 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1067,7 +1067,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
 }
 
 namespace {
-  class FallthroughMapper : public DynamicRecursiveASTVisitor {
+  class FallthroughMapper final : public DynamicRecursiveASTVisitor {
   public:
     FallthroughMapper(Sema &S)
       : FoundSwitchStatements(false),
@@ -2473,7 +2473,7 @@ static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
 
 // An AST Visitor that calls a callback function on each callable DEFINITION
 // that is NOT in a dependent context:
-class CallableVisitor : public DynamicRecursiveASTVisitor {
+class CallableVisitor final : public DynamicRecursiveASTVisitor {
 private:
   llvm::function_ref<void(const Decl *)> Callback;
 
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index ed78199015165d..d78cb406043e38 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -717,7 +717,7 @@ bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) {
   }
 }
 
-class StmtUSEFinder : public DynamicRecursiveASTVisitor {
+class StmtUSEFinder final : public DynamicRecursiveASTVisitor {
   const Stmt *Target;
 
 public:
@@ -733,7 +733,7 @@ class StmtUSEFinder : public DynamicRecursiveASTVisitor {
 
 /// Traverses the AST and finds the last statement that used a given
 /// declaration.
-class LastDeclUSEFinder : public DynamicRecursiveASTVisitor {
+class LastDeclUSEFinder final : public DynamicRecursiveASTVisitor {
   const Decl *D;
 
 public:
@@ -761,7 +761,7 @@ class LastDeclUSEFinder : public DynamicRecursiveASTVisitor {
 /// to a partially available declaration. Whenever we encounter an \c if of the
 /// form: \c if(@available(...)), we use the version from the condition to visit
 /// the then statement.
-class DiagnoseUnguardedAvailability : public DynamicRecursiveASTVisitor {
+class DiagnoseUnguardedAvailability final : public DynamicRecursiveASTVisitor {
   Sema &SemaRef;
   Decl *Ctx;
 
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 03a8915a68e933..3a7819a924b8d6 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5424,7 +5424,7 @@ class ConceptInfo {
 
   // This visitor infers members of T based on traversing expressions/types
   // that involve T. It is invoked with code known to be valid for T.
-  class ValidVisitor : public DynamicRecursiveASTVisitor {
+  class ValidVisitor final : public DynamicRecursiveASTVisitor {
     ConceptInfo *Outer;
     const TemplateTypeParmType *T;
 
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f85425a4cfa47d..0b45f7a8197d71 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -723,7 +723,7 @@ static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
 namespace {
 /// Determines if a given Expr references any of the given function's
 /// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
-class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor {
+class ArgumentDependenceChecker final : public DynamicRecursiveASTVisitor {
 #ifndef NDEBUG
   const CXXRecordDecl *ClassType;
 #endif
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bb9a2ab12f2f87..53ac48a07358bd 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2499,7 +2499,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
   assert(FD->isImmediateEscalating() && !FD->isConsteval() &&
          "expected an immediate function");
   assert(FD->hasBody() && "expected the function to have a body");
-  struct ImmediateEscalatingExpressionsVisitor : DynamicRecursiveASTVisitor {
+  struct ImmediateEscalatingExpressionsVisitor final : DynamicRecursiveASTVisitor {
     Sema &SemaRef;
 
     const FunctionDecl *ImmediateFn;
@@ -18742,7 +18742,7 @@ void Sema::CheckDelegatingCtorCycles() {
 
 namespace {
   /// AST visitor that finds references to the 'this' expression.
-class FindCXXThisExpr : public DynamicRecursiveASTVisitor {
+class FindCXXThisExpr final : public DynamicRecursiveASTVisitor {
   Sema &S;
 
 public:
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 4d0be8ff41daca..3dfe5d3d33ea41 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -5320,7 +5320,7 @@ SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
 namespace {
 /// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property
 /// accessor references the backing ivar.
-class UnusedBackingIvarChecker : public DynamicRecursiveASTVisitor {
+class UnusedBackingIvarChecker final : public DynamicRecursiveASTVisitor {
 public:
   Sema &S;
   const ObjCMethodDecl *Method;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a4b37ad571b3c7..29c17093889d5c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5368,7 +5368,7 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
   return false;
 }
 
-struct ImmediateCallVisitor : DynamicRecursiveASTVisitor {
+struct ImmediateCallVisitor final : DynamicRecursiveASTVisitor {
   const ASTContext &Context;
   ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {
     ShouldVisitImplicitCode = true;
@@ -17533,7 +17533,7 @@ HandleImmediateInvocations(Sema &SemaRef,
         RemoveNestedImmediateInvocation(SemaRef, Rec, It);
   } else if (Rec.ImmediateInvocationCandidates.size() == 1 &&
              Rec.ReferenceToConsteval.size()) {
-    struct SimpleRemove : DynamicRecursiveASTVisitor {
+    struct SimpleRemove final : DynamicRecursiveASTVisitor {
       llvm::SmallPtrSetImpl<DeclRefExpr *> &DRSet;
       SimpleRemove(llvm::SmallPtrSetImpl<DeclRefExpr *> &S) : DRSet(S) {}
       bool VisitDeclRefExpr(DeclRefExpr *E) override {
@@ -19826,7 +19826,7 @@ namespace {
   // TreeTransforms rebuilding the type in a new context. Rather than
   // duplicating the TreeTransform logic, we should consider reusing it here.
   // Currently that causes problems when rebuilding LambdaExprs.
-class MarkReferencedDecls : public DynamicRecursiveASTVisitor {
+class MarkReferencedDecls final : public DynamicRecursiveASTVisitor {
   Sema &S;
   SourceLocation Loc;
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index bbdb534aa9dc9e..8931945b07f4ee 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -8762,7 +8762,7 @@ static ExprResult attemptRecovery(Sema &SemaRef,
 }
 
 namespace {
-class FindTypoExprs : public DynamicRecursiveASTVisitor {
+class FindTypoExprs final : public DynamicRecursiveASTVisitor {
   llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
 
 public:
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index fa24644541fc87..356840878585f6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -356,7 +356,7 @@ static bool isLegalTypeForHLSLSV_DispatchThreadID(QualType T) {
   return true;
 }
 
-void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) {  
+void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) {
   auto *VD = cast<ValueDecl>(D);
   if (!isLegalTypeForHLSLSV_DispatchThreadID(VD->getType())) {
     Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
@@ -552,7 +552,7 @@ namespace {
 /// and of all exported functions, and any functions that are referenced
 /// from this AST. In other words, any functions that are reachable from
 /// the entry points.
-class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
+class DiagnoseHLSLAvailability final : public DynamicRecursiveASTVisitor {
 
   Sema &SemaRef;
 
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 3e8057e30e3855..76a40626342dea 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3594,7 +3594,7 @@ namespace {
 /// others. Pretend that all local typedefs are always referenced, to not warn
 /// on this. This isn't necessary if f has internal linkage, or the typedef
 /// is private.
-class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor {
+class LocalTypedefNameReferencer final : public DynamicRecursiveASTVisitor {
 public:
   LocalTypedefNameReferencer(Sema &S) : S(S) {}
   bool VisitRecordType(RecordType *RT) override;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ce62cb417e1db2..d06fa749610f00 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2546,7 +2546,7 @@ namespace {
 
 /// A class which looks for a use of a certain level of template
 /// parameter.
-struct DependencyChecker : DynamicRecursiveASTVisitor {
+struct DependencyChecker final : DynamicRecursiveASTVisitor {
   unsigned Depth;
 
   // Whether we're looking for a use of a template parameter that makes the
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 0c302e53b62612..dc4045d010075b 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -6228,7 +6228,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
 }
 
 namespace {
-struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
+struct MarkUsedTemplateParameterVisitor final : DynamicRecursiveASTVisitor {
   llvm::SmallBitVector &Used;
   unsigned Depth;
 
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 11462fb362721e..12fe3a660109a1 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -28,7 +28,7 @@ using namespace clang;
 
 namespace {
   /// A class that collects unexpanded parameter packs.
-class CollectUnexpandedParameterPacksVisitor
+class CollectUnexpandedParameterPacksVisitor final
     : public DynamicRecursiveASTVisitor {
   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index aa0bd78c1472f5..275442973559e1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -23,7 +23,7 @@ using namespace clang;
 using namespace ento;
 
 namespace {
-class CastToStructVisitor : public DynamicRecursiveASTVisitor {
+class CastToStructVisitor final : public DynamicRecursiveASTVisitor {
   BugReporter &BR;
   const CheckerBase *Checker;
   AnalysisDeclContext *AC;
diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index f7dba536b524f3..3ec46f055563d3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -32,7 +32,7 @@ using namespace ento;
 namespace {
 
 /// A simple visitor to record what VarDecls occur in EH-handling code.
-class EHCodeVisitor : public DynamicRecursiveASTVisitor {
+class EHCodeVisitor final : public DynamicRecursiveASTVisitor {
 public:
   bool inEH;
   llvm::DenseSet<const VarDecl *> &S;
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index cdda319924563a..a540bc43695a4e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -710,7 +710,7 @@ static bool isObjCTypeParamDependent(QualType Type) {
   // It is illegal to typedef parameterized types inside an interface. Therefore
   // an Objective-C type can only be dependent on a type parameter when the type
   // parameter structurally present in the type itself.
-  class IsObjCTypeParamDependentTypeVisitor
+  class IsObjCTypeParamDependentTypeVisitor final
       : public DynamicRecursiveASTVisitor  {
   public:
     IsObjCTypeParamDependentTypeVisitor() = default;
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index fa20766b639dcf..be98a3e58a83f9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -32,7 +32,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
 //===----------------------------------------------------------------------===//
 
 namespace {
-class FindIdenticalExprVisitor : public DynamicRecursiveASTVisitor {
+class FindIdenticalExprVisitor final : public DynamicRecursiveASTVisitor {
   BugReporter &BR;
   const CheckerBase *Checker;
   AnalysisDeclContext *AC;
diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index 342ff7fd6d817a..1dd0fb7b8fbfce 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -1191,7 +1191,7 @@ namespace {
 class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
 
   // A helper class, which walks the AST
-  class MethodCrawler : public DynamicRecursiveASTVisitor {
+  class MethodCrawler final : public DynamicRecursiveASTVisitor {
     BugReporter &BR;
     const CheckerBase *Checker;
     AnalysisDeclContext *AC;
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index dea1b1aea016bf..55e4dcddfdcd88 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -38,7 +38,7 @@ struct SelectorDescriptor {
 // FindSuperCallVisitor - Identify specific calls to the superclass.
 //===----------------------------------------------------------------------===//
 
-class FindSuperCallVisitor : public DynamicRecursiveASTVisitor {
+class FindSuperCallVisitor final : public DynamicRecursiveASTVisitor {
 public:
   explicit FindSuperCallVisitor(Selector S) : DoesCallSuper(false), Sel(S) {}
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 4354f36b397977..9dbf63079e355f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -45,7 +45,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const PaddingChecker *Checker;
       explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {
         ShouldVisitTemplateInstantiations = true;
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
index 2c30c7825b51e3..62a42234cba130 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp
@@ -45,7 +45,7 @@ class NoUncountedMemberChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const NoUncountedMemberChecker *Checker;
       explicit LocalVisitor(const NoUncountedMemberChecker *Checker)
           : Checker(Checker) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index c5e1af6e3ce082..9455bad3377505 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
@@ -140,7 +140,7 @@ class RefCntblBaseVirtualDtorChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const RefCntblBaseVirtualDtorChecker *Checker;
       explicit LocalVisitor(const RefCntblBaseVirtualDtorChecker *Checker)
           : Checker(Checker) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
index a71027d0acb936..0acdcf8de519cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
@@ -43,7 +43,7 @@ class UncountedCallArgsChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const UncountedCallArgsChecker *Checker;
       explicit LocalVisitor(const UncountedCallArgsChecker *Checker)
           : Checker(Checker) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index 917c7670c3790e..d2ae43cedff09e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
@@ -35,7 +35,7 @@ class UncountedLambdaCapturesChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const UncountedLambdaCapturesChecker *Checker;
       explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker)
           : Checker(Checker) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
index e24c67c4d788ea..3748cf15901e9b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
@@ -119,7 +119,7 @@ class UncountedLocalVarsChecker
     // The calls to checkAST* from AnalysisConsumer don't
     // visit template instantiations or lambda classes. We
     // want to visit those, so we make our own RecursiveASTVisitor.
-    struct LocalVisitor : DynamicRecursiveASTVisitor {
+    struct LocalVisitor final : DynamicRecursiveASTVisitor {
       const UncountedLocalVarsChecker *Checker;
 
       TrivialFunctionAnalysis TFA;
diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
index 05c99c4a844e9e..319b3f01a41549 100644
--- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
@@ -76,7 +76,7 @@ inline bool fullyContains(SourceRange Larger, SourceRange Smaller,
          isLessOrEqual(Smaller.getEnd(), Larger.getEnd(), SM);
 }
 
-class CacheInitializer : public DynamicRecursiveASTVisitor {
+class CacheInitializer final : public DynamicRecursiveASTVisitor {
 public:
   static void initialize(const Decl *D, Ranges &ToInit) {
     CacheInitializer(ToInit).TraverseDecl(const_cast<Decl *>(D));
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
index 0440e47ddb4ae4..ec4f5b94832807 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -187,7 +187,7 @@ static bool isNodeExcluded(const SourceManager &SrcMgr, T *N) {
 
 namespace {
 // Sets Height, Parent and Children for each node.
-struct PreorderVisitor : DynamicRecursiveASTVisitor {
+struct PreorderVisitor final : DynamicRecursiveASTVisitor {
   int Id = 0, Depth = 0;
   NodeId Parent;
   SyntaxTree::Impl &Tree;
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
index a726990d8ff5f2..aa6a571a820007 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -97,7 +97,7 @@ namespace {
 
 /// Recursively visits each NamedDecl node to find the declaration with a
 /// specific name.
-class NamedDeclFindingVisitor : public DynamicRecursiveASTVisitor {
+class NamedDeclFindingVisitor final : public DynamicRecursiveASTVisitor {
 public:
   explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}
 
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
index d7a1f761fc3030..f0f27c005bf9a5 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -60,7 +60,7 @@ namespace {
 // AdditionalUSRFinder. AdditionalUSRFinder adds USRs of ctor and dtor if given
 // Decl refers to class and adds USRs of all overridden methods if Decl refers
 // to virtual method.
-class AdditionalUSRFinder : public DynamicRecursiveASTVisitor {
+class AdditionalUSRFinder final : public DynamicRecursiveASTVisitor {
 public:
   AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
       : FoundDecl(FoundDecl), Context(Context) {
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 8b60134017724f..8e8271648ad08d 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -152,7 +152,7 @@ NestedNameSpecifier *GetNestedNameForType(TypeLoc TL) {
 //
 // This class will traverse the AST and find every AST node whose USR is in the
 // given USRs' set.
-class RenameLocFinder : public DynamicRecursiveASTVisitor {
+class RenameLocFinder final : public DynamicRecursiveASTVisitor {
 public:
   RenameLocFinder(llvm::ArrayRef<std::string> USRs, ASTContext &Context)
       : USRSet(USRs.begin(), USRs.end()), Context(Context) {}
diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp
index 1b34ee5d6dde1f..a07bbc780ad6a7 100644
--- a/clang/unittests/Analysis/CloneDetectionTest.cpp
+++ b/clang/unittests/Analysis/CloneDetectionTest.cpp
@@ -15,7 +15,7 @@ namespace clang {
 namespace analysis {
 namespace {
 
-class CloneDetectionVisitor : public DynamicRecursiveASTVisitor {
+class CloneDetectionVisitor final : public DynamicRecursiveASTVisitor {
 
   CloneDetector &Detector;
 

>From 19cd49458b3e11086956c59811d3b609acc2c5c8 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 18:18:43 +0200
Subject: [PATCH 19/27] Avoid including RecursiveASTVisitor.h wherever possible

---
 clang/lib/ARCMigrate/Transforms.cpp                 |  1 -
 clang/lib/ASTMatchers/GtestMatchers.cpp             |  1 -
 .../Analysis/FlowSensitive/DataflowEnvironment.cpp  |  1 -
 clang/lib/Sema/SemaConcept.cpp                      |  1 -
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp       | 13 ++++++-------
 5 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index 7363427580c83b..ca24b512b4d9e1 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -10,7 +10,6 @@
 #include "Internals.h"
 #include "clang/ARCMigrate/ARCMT.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
diff --git a/clang/lib/ASTMatchers/GtestMatchers.cpp b/clang/lib/ASTMatchers/GtestMatchers.cpp
index a556d8ef2da066..d2a672535f2c5d 100644
--- a/clang/lib/ASTMatchers/GtestMatchers.cpp
+++ b/clang/lib/ASTMatchers/GtestMatchers.cpp
@@ -18,7 +18,6 @@
 #include "clang/ASTMatchers/GtestMatchers.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringRef.h"
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 295493944ac918..ff2a213f5d753a 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -16,7 +16,6 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
 #include "clang/Analysis/FlowSensitive/ASTOps.h"
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index de24bbe7eb99ce..4873acc82b8251 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -15,7 +15,6 @@
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprConcepts.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/OperatorPrecedence.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 545da21183c3c4..533be539c446de 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -21,10 +21,10 @@
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/OperationKinds.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
@@ -637,8 +637,7 @@ struct ConvertConstructorToDeductionGuideTransform {
 SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
     const TemplateParameterList *TemplateParamsList,
     ArrayRef<TemplateArgument> DeducedArgs) {
-  struct TemplateParamsReferencedFinder
-      : public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
+  struct TemplateParamsReferencedFinder final : DynamicRecursiveASTVisitor {
     const TemplateParameterList *TemplateParamList;
     llvm::BitVector ReferencedTemplateParams;
 
@@ -647,22 +646,22 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
         : TemplateParamList(TemplateParamList),
           ReferencedTemplateParams(TemplateParamList->size()) {}
 
-    bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
+    bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) override {
       // We use the index and depth to retrieve the corresponding template
       // parameter from the parameter list, which is more robost.
       Mark(TTP->getDepth(), TTP->getIndex());
       return true;
     }
 
-    bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+    bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
       MarkAppeared(DRE->getFoundDecl());
       return true;
     }
 
-    bool TraverseTemplateName(TemplateName Template) {
+    bool TraverseTemplateName(TemplateName Template) override {
       if (auto *TD = Template.getAsTemplateDecl())
         MarkAppeared(TD);
-      return RecursiveASTVisitor::TraverseTemplateName(Template);
+      return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
     }
 
     void MarkAppeared(NamedDecl *ND) {

>From ad000269b099edec690575128feea2e0f36d05bb Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 18:26:11 +0200
Subject: [PATCH 20/27] Make destructor = default

---
 clang/include/clang/AST/DynamicRecursiveASTVisitor.h | 6 +++---
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp         | 3 +--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 14b60ee0dc3192..1390977c09ea79 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -41,15 +41,15 @@ class DynamicRecursiveASTVisitor {
   DynamicRecursiveASTVisitor() = default;
 
 public:
+  virtual void anchor();
+
   // Copying/moving a polymorphic type is a bad idea.
   DynamicRecursiveASTVisitor(DynamicRecursiveASTVisitor &&) = delete;
   DynamicRecursiveASTVisitor(const DynamicRecursiveASTVisitor &) = delete;
   DynamicRecursiveASTVisitor &operator=(DynamicRecursiveASTVisitor &&) = delete;
   DynamicRecursiveASTVisitor &
   operator=(const DynamicRecursiveASTVisitor &) = delete;
-
-  // Declared out of line as a vtable anchor.
-  virtual ~DynamicRecursiveASTVisitor();
+  virtual ~DynamicRecursiveASTVisitor() = default;
 
   /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
   /// \returns false if visitation was terminated early.
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index 7c39c6c58c02f4..133e2762061286 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -196,8 +196,7 @@ struct Impl : RecursiveASTVisitor<Impl> {
 };
 } // namespace
 
-// Declared out of line to serve as a vtable anchor.
-DynamicRecursiveASTVisitor::~DynamicRecursiveASTVisitor() = default;
+void DynamicRecursiveASTVisitor::anchor() { }
 
 bool DynamicRecursiveASTVisitor::TraverseAST(ASTContext &AST) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAST(AST);

>From 1d2fdbabf39799370eeae4ea1c482cc55409788f Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 22:16:50 +0200
Subject: [PATCH 21/27] Revert FallthroughMapper to use CRTP

---
 clang/lib/Sema/AnalysisBasedWarnings.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index c894b358bf7c26..f5ce8202547680 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -16,13 +16,14 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -1067,14 +1068,18 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
 }
 
 namespace {
-  class FallthroughMapper final : public DynamicRecursiveASTVisitor {
+  // This is not a dynamic visitor because it ends up traversing an
+  // order of magnitude more statements than every other visitor combined.
+  class FallthroughMapper final
+    : public RecursiveASTVisitor<FallthroughMapper> {
   public:
     FallthroughMapper(Sema &S)
       : FoundSwitchStatements(false),
         S(S) {
-      ShouldWalkTypesOfTypeLocs = false;
     }
 
+    bool shouldWalkTypesOfTypeLocs() const { return false; }
+
     bool foundSwitchStatements() const { return FoundSwitchStatements; }
 
     void markFallthroughVisited(const AttributedStmt *Stmt) {
@@ -1187,23 +1192,23 @@ namespace {
       return !!UnannotatedCnt;
     }
 
-    bool VisitAttributedStmt(AttributedStmt *S) override {
+    bool VisitAttributedStmt(AttributedStmt *S) {
       if (asFallThroughAttr(S))
         FallthroughStmts.insert(S);
       return true;
     }
 
-    bool VisitSwitchStmt(SwitchStmt *S) override {
+    bool VisitSwitchStmt(SwitchStmt *S) {
       FoundSwitchStatements = true;
       return true;
     }
 
     // We don't want to traverse local type declarations. We analyze their
     // methods separately.
-    bool TraverseDecl(Decl *D) override { return true; }
+    bool TraverseDecl(Decl *D) { return true; }
 
     // We analyze lambda bodies separately. Skip them here.
-    bool TraverseLambdaExpr(LambdaExpr *LE) override {
+    bool TraverseLambdaExpr(LambdaExpr *LE) {
       // Traverse the captures, but not the body.
       for (const auto C : zip(LE->captures(), LE->capture_inits()))
         TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));

>From 979eba07448d94966a061ee0323fe152fe6d6f02 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 23:45:49 +0200
Subject: [PATCH 22/27] Revert "Revert FallthroughMapper to use CRTP"

This reverts commit 1d2fdbabf39799370eeae4ea1c482cc55409788f.
---
 clang/lib/Sema/AnalysisBasedWarnings.cpp | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index f5ce8202547680..c894b358bf7c26 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -16,14 +16,13 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -1068,18 +1067,14 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
 }
 
 namespace {
-  // This is not a dynamic visitor because it ends up traversing an
-  // order of magnitude more statements than every other visitor combined.
-  class FallthroughMapper final
-    : public RecursiveASTVisitor<FallthroughMapper> {
+  class FallthroughMapper final : public DynamicRecursiveASTVisitor {
   public:
     FallthroughMapper(Sema &S)
       : FoundSwitchStatements(false),
         S(S) {
+      ShouldWalkTypesOfTypeLocs = false;
     }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
-
     bool foundSwitchStatements() const { return FoundSwitchStatements; }
 
     void markFallthroughVisited(const AttributedStmt *Stmt) {
@@ -1192,23 +1187,23 @@ namespace {
       return !!UnannotatedCnt;
     }
 
-    bool VisitAttributedStmt(AttributedStmt *S) {
+    bool VisitAttributedStmt(AttributedStmt *S) override {
       if (asFallThroughAttr(S))
         FallthroughStmts.insert(S);
       return true;
     }
 
-    bool VisitSwitchStmt(SwitchStmt *S) {
+    bool VisitSwitchStmt(SwitchStmt *S) override {
       FoundSwitchStatements = true;
       return true;
     }
 
     // We don't want to traverse local type declarations. We analyze their
     // methods separately.
-    bool TraverseDecl(Decl *D) { return true; }
+    bool TraverseDecl(Decl *D) override { return true; }
 
     // We analyze lambda bodies separately. Skip them here.
-    bool TraverseLambdaExpr(LambdaExpr *LE) {
+    bool TraverseLambdaExpr(LambdaExpr *LE) override {
       // Traverse the captures, but not the body.
       for (const auto C : zip(LE->captures(), LE->capture_inits()))
         TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));

>From c50f8d1fcffdfc128e18391fee3142d361a8a376 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 19 Aug 2024 23:51:07 +0200
Subject: [PATCH 23/27] Revert MarkReferencedDecls visitor to use CRTP

---
 clang/lib/Sema/SemaExpr.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 29c17093889d5c..70aac27f9ce876 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -28,6 +28,7 @@
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMapContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Builtins.h"
@@ -19826,14 +19827,15 @@ namespace {
   // TreeTransforms rebuilding the type in a new context. Rather than
   // duplicating the TreeTransform logic, we should consider reusing it here.
   // Currently that causes problems when rebuilding LambdaExprs.
-class MarkReferencedDecls final : public DynamicRecursiveASTVisitor {
+class MarkReferencedDecls final
+  : public RecursiveASTVisitor<MarkReferencedDecls> {
   Sema &S;
   SourceLocation Loc;
 
 public:
   MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) {}
 
-  bool TraverseTemplateArgument(const TemplateArgument &Arg) override;
+  bool TraverseTemplateArgument(const TemplateArgument &Arg);
 };
 }
 
@@ -19851,7 +19853,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument(
     }
   }
 
-  return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
+  return RecursiveASTVisitor::TraverseTemplateArgument(Arg);
 }
 
 void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {

>From 42f415f162e9aef704806220233d71076c066ff7 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 20 Aug 2024 16:10:29 +0200
Subject: [PATCH 24/27] Revert "Revert MarkReferencedDecls visitor to use CRTP"

This reverts commit c50f8d1fcffdfc128e18391fee3142d361a8a376.
---
 clang/lib/Sema/SemaExpr.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 70aac27f9ce876..29c17093889d5c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -28,7 +28,6 @@
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Builtins.h"
@@ -19827,15 +19826,14 @@ namespace {
   // TreeTransforms rebuilding the type in a new context. Rather than
   // duplicating the TreeTransform logic, we should consider reusing it here.
   // Currently that causes problems when rebuilding LambdaExprs.
-class MarkReferencedDecls final
-  : public RecursiveASTVisitor<MarkReferencedDecls> {
+class MarkReferencedDecls final : public DynamicRecursiveASTVisitor {
   Sema &S;
   SourceLocation Loc;
 
 public:
   MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) {}
 
-  bool TraverseTemplateArgument(const TemplateArgument &Arg);
+  bool TraverseTemplateArgument(const TemplateArgument &Arg) override;
 };
 }
 
@@ -19853,7 +19851,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument(
     }
   }
 
-  return RecursiveASTVisitor::TraverseTemplateArgument(Arg);
+  return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
 }
 
 void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {

>From 8f7d61923b414085d5d1e419cebd46500cef2662 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 20 Aug 2024 18:23:30 +0200
Subject: [PATCH 25/27] Add missing ObjC includes

---
 clang/lib/Sema/SemaAvailability.cpp     | 4 +++-
 clang/lib/Sema/SemaTemplateVariadic.cpp | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index d78cb406043e38..f23cd73037e04c 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -12,9 +12,11 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/StmtObjC.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtObjC.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 12fe3a660109a1..00e31f137c5662 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -11,6 +11,7 @@
 #include "TypeLocBuilder.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"

>From f200083f8821f411d9ea7b5dbeaa1394a1fbf784 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 20 Aug 2024 20:33:36 +0200
Subject: [PATCH 26/27] clang-format everything (I hope)

---
 .../clang/Analysis/FlowSensitive/ASTOps.h     |   2 +-
 clang/include/clang/InstallAPI/Visitor.h      |   2 +-
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  |  15 +-
 clang/lib/AST/ParentMapContext.cpp            |  25 +-
 clang/lib/ASTMatchers/ASTMatchFinder.cpp      |  39 ++--
 clang/lib/Analysis/CalledOnceCheck.cpp        |   2 +-
 clang/lib/Analysis/ReachableCode.cpp          |   2 +-
 clang/lib/Analysis/UnsafeBufferUsage.cpp      |   5 +-
 .../CodeGen/ObjectFilePCHContainerWriter.cpp  |   2 +-
 clang/lib/Frontend/ASTConsumers.cpp           | 213 +++++++++---------
 .../InterfaceStubFunctionsConsumer.cpp        |   2 +-
 clang/lib/Index/IndexBody.cpp                 |  15 +-
 clang/lib/Index/IndexTypeSourceInfo.cpp       |  11 +-
 clang/lib/Sema/AnalysisBasedWarnings.cpp      | 121 +++++-----
 clang/lib/Sema/SemaCodeComplete.cpp           |   5 +-
 clang/lib/Sema/SemaDeclAttr.cpp               |   2 +-
 clang/lib/Sema/SemaDeclCXX.cpp                |   3 +-
 clang/lib/Sema/SemaDeclObjC.cpp               |   2 +-
 clang/lib/Sema/SemaHLSL.cpp                   |   2 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp      |   2 +-
 .../Checkers/CastToStructChecker.cpp          |   2 +-
 .../Checkers/DeadStoresChecker.cpp            |   2 +-
 .../Checkers/DynamicTypePropagation.cpp       |   4 +-
 .../Checkers/IdenticalExprChecker.cpp         |   2 +-
 .../Checkers/ObjCMissingSuperCallChecker.cpp  |   6 +-
 .../Checkers/PaddingChecker.cpp               |   4 +-
 .../WebKit/UncountedLocalVarsChecker.cpp      |   2 +-
 clang/lib/Tooling/ASTDiff/ASTDiff.cpp         |   2 +-
 .../Refactoring/Rename/USRFindingAction.cpp   |   1 -
 .../Refactoring/Rename/USRLocFinder.cpp       |   2 +-
 clang/unittests/AST/EvaluateAsRValueTest.cpp  |   2 +-
 .../unittests/Analysis/CloneDetectionTest.cpp |   2 +-
 .../unittests/Tooling/CommentHandlerTest.cpp  |   3 +-
 clang/unittests/Tooling/ExecutionTest.cpp     |   5 +-
 .../RecursiveASTVisitorTestDeclVisitor.cpp    |  12 +-
 .../Tooling/RecursiveASTVisitorTests/Attr.cpp |   1 -
 .../RecursiveASTVisitorTests/Class.cpp        |   2 +-
 .../RecursiveASTVisitorTests/Concept.cpp      |  35 +--
 .../ConstructExpr.cpp                         |   8 +-
 .../RecursiveASTVisitorTests/DeclRefExpr.cpp  |   4 +-
 .../RecursiveASTVisitorTests/ImplicitCtor.cpp |   2 +-
 .../RecursiveASTVisitorTests/LambdaExpr.cpp   |   4 +-
 .../LambdaTemplateParams.cpp                  |   4 +-
 clang/unittests/Tooling/TestVisitor.h         |  50 ++--
 44 files changed, 322 insertions(+), 311 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index 7a9ea1c25e4e07..6294c810626a70 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -14,9 +14,9 @@
 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Analysis/FlowSensitive/StorageLocation.h"
 #include "llvm/ADT/DenseSet.h"
diff --git a/clang/include/clang/InstallAPI/Visitor.h b/clang/include/clang/InstallAPI/Visitor.h
index ab8b5588b62c92..a04100b7b147b3 100644
--- a/clang/include/clang/InstallAPI/Visitor.h
+++ b/clang/include/clang/InstallAPI/Visitor.h
@@ -13,8 +13,8 @@
 #ifndef LLVM_CLANG_INSTALLAPI_VISITOR_H
 #define LLVM_CLANG_INSTALLAPI_VISITOR_H
 
-#include "clang/AST/Mangle.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Mangle.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/InstallAPI/Context.h"
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index 133e2762061286..b5dc7915413cb1 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -41,9 +41,7 @@ struct Impl : RecursiveASTVisitor<Impl> {
   bool TraverseDecl(Decl *D) { return Visitor.TraverseDecl(D); }
   bool TraverseType(QualType T) { return Visitor.TraverseType(T); }
   bool TraverseTypeLoc(TypeLoc TL) { return Visitor.TraverseTypeLoc(TL); }
-  bool TraverseStmt(Stmt *S) {
-    return Visitor.TraverseStmt(S);
-  }
+  bool TraverseStmt(Stmt *S) { return Visitor.TraverseStmt(S); }
 
   bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
     return Visitor.TraverseConstructorInitializer(Init);
@@ -115,7 +113,7 @@ struct Impl : RecursiveASTVisitor<Impl> {
 
   // TraverseStmt() always passes in a queue, so we have no choice but to
   // accept it as a parameter here.
-  bool dataTraverseNode(Stmt *S, DataRecursionQueue* = nullptr) {
+  bool dataTraverseNode(Stmt *S, DataRecursionQueue * = nullptr) {
     // But since don't support postorder traversal, we don't need it, so
     // simply discard it here. This way, derived classes don't need to worry
     // about including it as a parameter that they never use.
@@ -196,7 +194,7 @@ struct Impl : RecursiveASTVisitor<Impl> {
 };
 } // namespace
 
-void DynamicRecursiveASTVisitor::anchor() { }
+void DynamicRecursiveASTVisitor::anchor() {}
 
 bool DynamicRecursiveASTVisitor::TraverseAST(ASTContext &AST) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAST(AST);
@@ -259,8 +257,10 @@ bool DynamicRecursiveASTVisitor::TraverseTypeConstraint(
     const TypeConstraint *C) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeConstraint(C);
 }
-bool DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
-  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseObjCProtocolLoc(ProtocolLoc);
+bool DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(
+    ObjCProtocolLoc ProtocolLoc) {
+  return Impl(*this).RecursiveASTVisitor<Impl>::TraverseObjCProtocolLoc(
+      ProtocolLoc);
 }
 
 bool DynamicRecursiveASTVisitor::TraverseConceptRequirement(
@@ -288,7 +288,6 @@ bool DynamicRecursiveASTVisitor::TraverseConceptReference(
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptReference(CR);
 }
 
-
 bool DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(
     const CXXBaseSpecifier &Base) {
   return Impl(*this).RecursiveASTVisitor<Impl>::TraverseCXXBaseSpecifier(Base);
diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index eb8a2119afd795..a5420f28750956 100644
--- a/clang/lib/AST/ParentMapContext.cpp
+++ b/clang/lib/AST/ParentMapContext.cpp
@@ -12,8 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TemplateBase.h"
@@ -425,30 +425,41 @@ class ParentMapContext::ParentMap::ASTVisitor
 
   bool TraverseDecl(Decl *DeclNode) override {
     return TraverseNode(
-        DeclNode, DeclNode, [&] { return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode); },
+        DeclNode, DeclNode,
+        [&] { return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode); },
         &Map.PointerParents);
   }
   bool TraverseTypeLoc(TypeLoc TypeLocNode) override {
     return TraverseNode(
         TypeLocNode, DynTypedNode::create(TypeLocNode),
-        [&] { return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode); },
+        [&] {
+          return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode);
+        },
         &Map.OtherParents);
   }
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) override {
+  bool
+  TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) override {
     return TraverseNode(
         NNSLocNode, DynTypedNode::create(NNSLocNode),
-        [&] { return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSLocNode); },
+        [&] {
+          return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
+              NNSLocNode);
+        },
         &Map.OtherParents);
   }
   bool TraverseAttr(Attr *AttrNode) override {
     return TraverseNode(
-        AttrNode, AttrNode, [&] { return DynamicRecursiveASTVisitor::TraverseAttr(AttrNode); },
+        AttrNode, AttrNode,
+        [&] { return DynamicRecursiveASTVisitor::TraverseAttr(AttrNode); },
         &Map.PointerParents);
   }
   bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) override {
     return TraverseNode(
         ProtocolLocNode, DynTypedNode::create(ProtocolLocNode),
-        [&] { return DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(ProtocolLocNode); },
+        [&] {
+          return DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(
+              ProtocolLocNode);
+        },
         &Map.OtherParents);
   }
 
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index e0aecb1d1ccad4..1840bf021e1741 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -232,7 +232,7 @@ class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return traverse(*CtorInit);
   }
-  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc& TAL) override {
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &TAL) override {
     ScopedIncrement ScopedDepth(&CurrentDepth);
     return traverse(TAL);
   }
@@ -254,9 +254,11 @@ class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
       return false;
     return DynamicRecursiveASTVisitor::TraverseStmt(Node->getBody());
   }
-  bool TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *Node) override {
+  bool TraverseCXXRewrittenBinaryOperator(
+      CXXRewrittenBinaryOperator *Node) override {
     if (!Finder->isTraversalIgnoringImplicitNodes())
-      return DynamicRecursiveASTVisitor::TraverseCXXRewrittenBinaryOperator(Node);
+      return DynamicRecursiveASTVisitor::TraverseCXXRewrittenBinaryOperator(
+          Node);
     if (!Node)
       return true;
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -326,10 +328,12 @@ class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
   // Forwards the call to the corresponding Traverse*() method in the
   // base visitor class.
   bool baseTraverse(const Decl &DeclNode) {
-    return DynamicRecursiveASTVisitor::TraverseDecl(const_cast<Decl*>(&DeclNode));
+    return DynamicRecursiveASTVisitor::TraverseDecl(
+        const_cast<Decl *>(&DeclNode));
   }
   bool baseTraverse(const Stmt &StmtNode) {
-    return DynamicRecursiveASTVisitor::TraverseStmt(const_cast<Stmt*>(&StmtNode));
+    return DynamicRecursiveASTVisitor::TraverseStmt(
+        const_cast<Stmt *>(&StmtNode));
   }
   bool baseTraverse(QualType TypeNode) {
     return DynamicRecursiveASTVisitor::TraverseType(TypeNode);
@@ -339,7 +343,7 @@ class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
   }
   bool baseTraverse(const NestedNameSpecifier &NNS) {
     return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifier(
-        const_cast<NestedNameSpecifier*>(&NNS));
+        const_cast<NestedNameSpecifier *>(&NNS));
   }
   bool baseTraverse(NestedNameSpecifierLoc NNS) {
     return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
@@ -352,7 +356,8 @@ class MatchChildASTVisitor final : public DynamicRecursiveASTVisitor {
     return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(TAL);
   }
   bool baseTraverse(const Attr &AttrNode) {
-    return DynamicRecursiveASTVisitor::TraverseAttr(const_cast<Attr *>(&AttrNode));
+    return DynamicRecursiveASTVisitor::TraverseAttr(
+        const_cast<Attr *>(&AttrNode));
   }
 
   // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
@@ -500,7 +505,7 @@ class MatchASTVisitor final : public DynamicRecursiveASTVisitor,
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) override;
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override;
   bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) override;
-  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc& TAL) override;
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &TAL) override;
   bool TraverseAttr(Attr *AttrNode) override;
 
   bool dataTraverseNode(Stmt *S) override {
@@ -744,20 +749,17 @@ class MatchASTVisitor final : public DynamicRecursiveASTVisitor,
 
   bool TraverseTemplateInstantiations(ClassTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
   bool TraverseTemplateInstantiations(VarTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
   bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
 private:
@@ -1503,8 +1505,7 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
   // because the traversal is already done in the parallel "Loc"-hierarchy.
   if (NNS.hasQualifier())
     match(*NNS.getNestedNameSpecifier());
-  return
-      DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
+  return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
 }
 
 bool MatchASTVisitor::TraverseConstructorInitializer(
@@ -1522,11 +1523,11 @@ bool MatchASTVisitor::TraverseConstructorInitializer(
 
   match(*CtorInit);
 
-  return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(
-      CtorInit);
+  return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(CtorInit);
 }
 
-bool MatchASTVisitor::TraverseTemplateArgumentLoc(const TemplateArgumentLoc& Loc) {
+bool MatchASTVisitor::TraverseTemplateArgumentLoc(
+    const TemplateArgumentLoc &Loc) {
   match(Loc);
   return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(Loc);
 }
diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index cada4add01d9a5..f97339bc9381ea 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -11,11 +11,11 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 02948479faae35..344047beaac72e 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -13,11 +13,11 @@
 
 #include "clang/Analysis/Analyses/ReachableCode.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 22b628d230b907..0fc99dc9fb5b74 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -9,8 +9,8 @@
 #include "clang/Analysis/Analyses/UnsafeBufferUsage.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -135,7 +135,8 @@ class MatchDescendantVisitor final : public DynamicRecursiveASTVisitor {
     return DynamicRecursiveASTVisitor::TraverseGenericSelectionExpr(Node);
   }
 
-  bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
+  bool
+  TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
     // Unevaluated context.
     if (ignoreUnevaluatedContext)
       return true;
diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
index c3bc1641e542c4..848030dd30006f 100644
--- a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
+++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
@@ -11,8 +11,8 @@
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index 5ecd17ad36ada8..180075119db0c2 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -14,9 +14,9 @@
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Path.h"
@@ -28,130 +28,129 @@ using namespace clang;
 /// ASTPrinter - Pretty-printer and dumper of ASTs
 
 namespace {
-  class ASTPrinter : public ASTConsumer,
-                     public DynamicRecursiveASTVisitor {
-  public:
-    enum Kind { DumpFull, Dump, Print, None };
-    ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
-               ASTDumpOutputFormat Format, StringRef FilterString,
-               bool DumpLookups = false, bool DumpDeclTypes = false)
-        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
-          OutputKind(K), OutputFormat(Format), FilterString(FilterString),
-          DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {
-      ShouldWalkTypesOfTypeLocs = false;
-    }
+class ASTPrinter : public ASTConsumer, public DynamicRecursiveASTVisitor {
+public:
+  enum Kind { DumpFull, Dump, Print, None };
+  ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
+             ASTDumpOutputFormat Format, StringRef FilterString,
+             bool DumpLookups = false, bool DumpDeclTypes = false)
+      : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), OutputKind(K),
+        OutputFormat(Format), FilterString(FilterString),
+        DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-    void HandleTranslationUnit(ASTContext &Context) override {
-      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
+  void HandleTranslationUnit(ASTContext &Context) override {
+    TranslationUnitDecl *D = Context.getTranslationUnitDecl();
 
-      if (FilterString.empty())
-        return print(D);
+    if (FilterString.empty())
+      return print(D);
 
-      TraverseDecl(D);
-    }
+    TraverseDecl(D);
+  }
 
-    bool TraverseDecl(Decl *D) override {
-      if (D && filterMatches(D)) {
-        bool ShowColors = Out.has_colors();
-        if (ShowColors)
-          Out.changeColor(raw_ostream::BLUE);
-
-        if (OutputFormat == ADOF_Default)
-          Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
-              << ":\n";
-
-        if (ShowColors)
-          Out.resetColor();
-        print(D);
-        Out << "\n";
-        // Don't traverse child nodes to avoid output duplication.
-        return true;
-      }
-      return DynamicRecursiveASTVisitor::TraverseDecl(D);
+  bool TraverseDecl(Decl *D) override {
+    if (D && filterMatches(D)) {
+      bool ShowColors = Out.has_colors();
+      if (ShowColors)
+        Out.changeColor(raw_ostream::BLUE);
+
+      if (OutputFormat == ADOF_Default)
+        Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
+            << ":\n";
+
+      if (ShowColors)
+        Out.resetColor();
+      print(D);
+      Out << "\n";
+      // Don't traverse child nodes to avoid output duplication.
+      return true;
     }
+    return DynamicRecursiveASTVisitor::TraverseDecl(D);
+  }
 
-  private:
-    std::string getName(Decl *D) {
-      if (isa<NamedDecl>(D))
-        return cast<NamedDecl>(D)->getQualifiedNameAsString();
-      return "";
-    }
-    bool filterMatches(Decl *D) {
-      return getName(D).find(FilterString) != std::string::npos;
+private:
+  std::string getName(Decl *D) {
+    if (isa<NamedDecl>(D))
+      return cast<NamedDecl>(D)->getQualifiedNameAsString();
+    return "";
+  }
+  bool filterMatches(Decl *D) {
+    return getName(D).find(FilterString) != std::string::npos;
+  }
+  void print(Decl *D) {
+    if (DumpLookups) {
+      if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+        if (DC == DC->getPrimaryContext())
+          DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
+        else
+          Out << "Lookup map is in primary DeclContext "
+              << DC->getPrimaryContext() << "\n";
+      } else
+        Out << "Not a DeclContext\n";
+    } else if (OutputKind == Print) {
+      PrintingPolicy Policy(D->getASTContext().getLangOpts());
+      D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
+    } else if (OutputKind != None) {
+      D->dump(Out, OutputKind == DumpFull, OutputFormat);
     }
-    void print(Decl *D) {
-      if (DumpLookups) {
-        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
-          if (DC == DC->getPrimaryContext())
-            DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
-          else
-            Out << "Lookup map is in primary DeclContext "
-                << DC->getPrimaryContext() << "\n";
-        } else
-          Out << "Not a DeclContext\n";
-      } else if (OutputKind == Print) {
-        PrintingPolicy Policy(D->getASTContext().getLangOpts());
-        D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
-      } else if (OutputKind != None) {
-        D->dump(Out, OutputKind == DumpFull, OutputFormat);
-      }
-
-      if (DumpDeclTypes) {
-        Decl *InnerD = D;
-        if (auto *TD = dyn_cast<TemplateDecl>(D))
-          InnerD = TD->getTemplatedDecl();
-
-        // FIXME: Support OutputFormat in type dumping.
-        // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
-        if (auto *VD = dyn_cast<ValueDecl>(InnerD))
-          VD->getType().dump(Out, VD->getASTContext());
-        if (auto *TD = dyn_cast<TypeDecl>(InnerD))
-          TD->getTypeForDecl()->dump(Out, TD->getASTContext());
-      }
+
+    if (DumpDeclTypes) {
+      Decl *InnerD = D;
+      if (auto *TD = dyn_cast<TemplateDecl>(D))
+        InnerD = TD->getTemplatedDecl();
+
+      // FIXME: Support OutputFormat in type dumping.
+      // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
+      if (auto *VD = dyn_cast<ValueDecl>(InnerD))
+        VD->getType().dump(Out, VD->getASTContext());
+      if (auto *TD = dyn_cast<TypeDecl>(InnerD))
+        TD->getTypeForDecl()->dump(Out, TD->getASTContext());
     }
+  }
 
-    raw_ostream &Out;
-    std::unique_ptr<raw_ostream> OwnedOut;
+  raw_ostream &Out;
+  std::unique_ptr<raw_ostream> OwnedOut;
 
-    /// How to output individual declarations.
-    Kind OutputKind;
+  /// How to output individual declarations.
+  Kind OutputKind;
 
-    /// What format should the output take?
-    ASTDumpOutputFormat OutputFormat;
+  /// What format should the output take?
+  ASTDumpOutputFormat OutputFormat;
 
-    /// Which declarations or DeclContexts to display.
-    std::string FilterString;
+  /// Which declarations or DeclContexts to display.
+  std::string FilterString;
 
-    /// Whether the primary output is lookup results or declarations. Individual
-    /// results will be output with a format determined by OutputKind. This is
-    /// incompatible with OutputKind == Print.
-    bool DumpLookups;
+  /// Whether the primary output is lookup results or declarations. Individual
+  /// results will be output with a format determined by OutputKind. This is
+  /// incompatible with OutputKind == Print.
+  bool DumpLookups;
 
-    /// Whether to dump the type for each declaration dumped.
-    bool DumpDeclTypes;
-  };
+  /// Whether to dump the type for each declaration dumped.
+  bool DumpDeclTypes;
+};
 
-  class ASTDeclNodeLister : public ASTConsumer,
-                     public DynamicRecursiveASTVisitor {
-  public:
-    ASTDeclNodeLister(raw_ostream *Out = nullptr)
-        : Out(Out ? *Out : llvm::outs()) {
-      ShouldWalkTypesOfTypeLocs = false;
-    }
+class ASTDeclNodeLister : public ASTConsumer,
+                          public DynamicRecursiveASTVisitor {
+public:
+  ASTDeclNodeLister(raw_ostream *Out = nullptr)
+      : Out(Out ? *Out : llvm::outs()) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-    void HandleTranslationUnit(ASTContext &Context) override {
-      TraverseDecl(Context.getTranslationUnitDecl());
-    }
+  void HandleTranslationUnit(ASTContext &Context) override {
+    TraverseDecl(Context.getTranslationUnitDecl());
+  }
 
-    bool VisitNamedDecl(NamedDecl *D) override {
-      D->printQualifiedName(Out);
-      Out << '\n';
-      return true;
-    }
+  bool VisitNamedDecl(NamedDecl *D) override {
+    D->printQualifiedName(Out);
+    Out << '\n';
+    return true;
+  }
 
-  private:
-    raw_ostream &Out;
-  };
+private:
+  raw_ostream &Out;
+};
 } // end anonymous namespace
 
 std::unique_ptr<ASTConsumer>
diff --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
index 2473ad50ab4872..9644fe732889f5 100644
--- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/Mangle.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Mangle.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index 8628a2dcdac90a..215605b45c411a 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -10,10 +10,10 @@
 #include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprConcepts.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/AST/Type.h"
 
 using namespace clang;
@@ -31,9 +31,9 @@ class BodyIndexer final : public DynamicRecursiveASTVisitor {
     return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
   }
 public:
-  BodyIndexer(IndexingContext &indexCtx,
-              const NamedDecl *Parent, const DeclContext *DC)
-    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) {
+  BodyIndexer(IndexingContext &indexCtx, const NamedDecl *Parent,
+              const DeclContext *DC)
+      : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) {
     ShouldWalkTypesOfTypeLocs = false;
   }
 
@@ -197,7 +197,8 @@ class BodyIndexer final : public DynamicRecursiveASTVisitor {
                                     Relations, E);
   }
 
-  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
+  bool
+  VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
     const DeclarationNameInfo &Info = E->getMemberNameInfo();
     return indexDependentReference(
         E, E->getBaseType().getTypePtrOrNull(), Info,
@@ -474,7 +475,7 @@ class BodyIndexer final : public DynamicRecursiveASTVisitor {
     return true;
   }
 
-  bool VisitParmVarDecl(ParmVarDecl* D) override {
+  bool VisitParmVarDecl(ParmVarDecl *D) override {
     // Index the parameters of lambda expression and requires expression.
     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
       const auto *DC = D->getDeclContext();
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 9c44847688f9ee..0abcc2e343a883 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -9,8 +9,8 @@
 #include "IndexingContext.h"
 #include "clang/AST/ASTConcept.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TypeLoc.h"
 #include "llvm/ADT/ScopeExit.h"
 
@@ -160,7 +160,8 @@ class TypeIndexer final : public DynamicRecursiveASTVisitor {
     }
   }
 
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) override {
+  bool VisitTemplateSpecializationTypeLoc(
+      TemplateSpecializationTypeLoc TL) override {
     auto *T = TL.getTypePtr();
     if (!T)
       return true;
@@ -170,7 +171,8 @@ class TypeIndexer final : public DynamicRecursiveASTVisitor {
     return true;
   }
 
-  bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) override {
+  bool TraverseTemplateSpecializationTypeLoc(
+      TemplateSpecializationTypeLoc TL) override {
     if (!WalkUpFromTemplateSpecializationTypeLoc(TL))
       return false;
     if (!TraverseTemplateName(TL.getTypePtr()->getTemplateName()))
@@ -190,7 +192,8 @@ class TypeIndexer final : public DynamicRecursiveASTVisitor {
     return true;
   }
 
-  bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) override {
+  bool VisitDeducedTemplateSpecializationTypeLoc(
+      DeducedTemplateSpecializationTypeLoc TL) override {
     auto *T = TL.getTypePtr();
     if (!T)
       return true;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index c894b358bf7c26..647c257cadfe1a 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -16,13 +16,13 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -1067,82 +1067,79 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
 }
 
 namespace {
-  class FallthroughMapper final : public DynamicRecursiveASTVisitor {
-  public:
-    FallthroughMapper(Sema &S)
-      : FoundSwitchStatements(false),
-        S(S) {
-      ShouldWalkTypesOfTypeLocs = false;
-    }
+class FallthroughMapper final : public DynamicRecursiveASTVisitor {
+public:
+  FallthroughMapper(Sema &S) : FoundSwitchStatements(false), S(S) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-    bool foundSwitchStatements() const { return FoundSwitchStatements; }
+  bool foundSwitchStatements() const { return FoundSwitchStatements; }
 
-    void markFallthroughVisited(const AttributedStmt *Stmt) {
-      bool Found = FallthroughStmts.erase(Stmt);
-      assert(Found);
-      (void)Found;
-    }
+  void markFallthroughVisited(const AttributedStmt *Stmt) {
+    bool Found = FallthroughStmts.erase(Stmt);
+    assert(Found);
+    (void)Found;
+  }
+
+  typedef llvm::SmallPtrSet<const AttributedStmt *, 8> AttrStmts;
 
-    typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
+  const AttrStmts &getFallthroughStmts() const { return FallthroughStmts; }
 
-    const AttrStmts &getFallthroughStmts() const {
-      return FallthroughStmts;
+  void fillReachableBlocks(CFG *Cfg) {
+    assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
+    std::deque<const CFGBlock *> BlockQueue;
+
+    ReachableBlocks.insert(&Cfg->getEntry());
+    BlockQueue.push_back(&Cfg->getEntry());
+    // Mark all case blocks reachable to avoid problems with switching on
+    // constants, covered enums, etc.
+    // These blocks can contain fall-through annotations, and we don't want to
+    // issue a warn_fallthrough_attr_unreachable for them.
+    for (const auto *B : *Cfg) {
+      const Stmt *L = B->getLabel();
+      if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second)
+        BlockQueue.push_back(B);
     }
 
-    void fillReachableBlocks(CFG *Cfg) {
-      assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
-      std::deque<const CFGBlock *> BlockQueue;
-
-      ReachableBlocks.insert(&Cfg->getEntry());
-      BlockQueue.push_back(&Cfg->getEntry());
-      // Mark all case blocks reachable to avoid problems with switching on
-      // constants, covered enums, etc.
-      // These blocks can contain fall-through annotations, and we don't want to
-      // issue a warn_fallthrough_attr_unreachable for them.
-      for (const auto *B : *Cfg) {
-        const Stmt *L = B->getLabel();
-        if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second)
+    while (!BlockQueue.empty()) {
+      const CFGBlock *P = BlockQueue.front();
+      BlockQueue.pop_front();
+      for (const CFGBlock *B : P->succs()) {
+        if (B && ReachableBlocks.insert(B).second)
           BlockQueue.push_back(B);
       }
-
-      while (!BlockQueue.empty()) {
-        const CFGBlock *P = BlockQueue.front();
-        BlockQueue.pop_front();
-        for (const CFGBlock *B : P->succs()) {
-          if (B && ReachableBlocks.insert(B).second)
-            BlockQueue.push_back(B);
-        }
-      }
     }
+  }
 
-    bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
-                                   bool IsTemplateInstantiation) {
-      assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
+  bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
+                                 bool IsTemplateInstantiation) {
+    assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
 
-      int UnannotatedCnt = 0;
-      AnnotatedCnt = 0;
+    int UnannotatedCnt = 0;
+    AnnotatedCnt = 0;
 
-      std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end());
-      while (!BlockQueue.empty()) {
-        const CFGBlock *P = BlockQueue.front();
-        BlockQueue.pop_front();
-        if (!P) continue;
+    std::deque<const CFGBlock *> BlockQueue(B.pred_begin(), B.pred_end());
+    while (!BlockQueue.empty()) {
+      const CFGBlock *P = BlockQueue.front();
+      BlockQueue.pop_front();
+      if (!P)
+        continue;
 
-        const Stmt *Term = P->getTerminatorStmt();
-        if (isa_and_nonnull<SwitchStmt>(Term))
-          continue; // Switch statement, good.
+      const Stmt *Term = P->getTerminatorStmt();
+      if (isa_and_nonnull<SwitchStmt>(Term))
+        continue; // Switch statement, good.
 
-        const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
-        if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
-          continue; // Previous case label has no statements, good.
+      const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
+      if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
+        continue; // Previous case label has no statements, good.
 
-        const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
-        if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
-          continue; // Case label is preceded with a normal label, good.
+      const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
+      if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
+        continue; // Case label is preceded with a normal label, good.
 
-        if (!ReachableBlocks.count(P)) {
-          for (const CFGElement &Elem : llvm::reverse(*P)) {
-            if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
+      if (!ReachableBlocks.count(P)) {
+        for (const CFGElement &Elem : llvm::reverse(*P)) {
+          if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
             if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
               // Don't issue a warning for an unreachable fallthrough
               // attribute in template instantiations as it may not be
@@ -1240,7 +1237,7 @@ namespace {
     AttrStmts FallthroughStmts;
     Sema &S;
     llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
-  };
+};
 } // anonymous namespace
 
 static StringRef getFallthroughAttrSpelling(Preprocessor &PP,
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 3a7819a924b8d6..21dfa10e46652a 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprConcepts.h"
@@ -22,7 +23,6 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/QualTypeNames.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/AttributeCommonInfo.h"
 #include "clang/Basic/CharInfo.h"
@@ -5442,7 +5442,8 @@ class ConceptInfo {
     }
 
     // In T.foo or T->foo, `foo` is a member function/variable.
-    bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
+    bool
+    VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
       const Type *Base = E->getBaseType().getTypePtr();
       bool IsArrow = E->isArrow();
       if (Base->isPointerType() && IsArrow) {
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index afe83780a77262..3f767a1e2cf52a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -17,10 +17,10 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Mangle.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Cuda.h"
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5c79c0d5e4a147..9b745716b3be8e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2499,7 +2499,8 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
   assert(FD->isImmediateEscalating() && !FD->isConsteval() &&
          "expected an immediate function");
   assert(FD->hasBody() && "expected the function to have a body");
-  struct ImmediateEscalatingExpressionsVisitor final : DynamicRecursiveASTVisitor {
+  struct ImmediateEscalatingExpressionsVisitor final
+      : DynamicRecursiveASTVisitor {
     Sema &SemaRef;
 
     const FunctionDecl *ImmediateFn;
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 3dfe5d3d33ea41..42909dbe0fdf9a 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -15,9 +15,9 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 356840878585f6..a78bf785fd47b1 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -10,8 +10,8 @@
 
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TargetInfo.h"
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index dc767f53a223ae..890810888cfbfa 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -20,10 +20,10 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index 275442973559e1..582bcfaec80f43 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -12,8 +12,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 3ec46f055563d3..d51b42bcb92d94 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -13,8 +13,8 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
-#include "clang/AST/ParentMap.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ParentMap.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index a540bc43695a4e..2c48c6156384f5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -20,8 +20,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/ParentMap.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ParentMap.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -711,7 +711,7 @@ static bool isObjCTypeParamDependent(QualType Type) {
   // an Objective-C type can only be dependent on a type parameter when the type
   // parameter structurally present in the type itself.
   class IsObjCTypeParamDependentTypeVisitor final
-      : public DynamicRecursiveASTVisitor  {
+      : public DynamicRecursiveASTVisitor {
   public:
     IsObjCTypeParamDependentTypeVisitor() = default;
     bool VisitObjCTypeParamType(ObjCTypeParamType *Type) override {
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index be98a3e58a83f9..dba3260bc80cf1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -15,8 +15,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index 55e4dcddfdcd88..4135a374dfb898 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -12,12 +12,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/Analysis/PathDiagnostic.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 9dbf63079e355f..d64469bb09b24f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -11,12 +11,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/AST/RecordLayout.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/RecordLayout.h"
 #include "clang/Driver/DriverDiagnostic.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
index 3748cf15901e9b..720fda57141675 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp
@@ -12,8 +12,8 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
index ec4f5b94832807..74e225a95f17af 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -11,9 +11,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/PriorityQueue.h"
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
index f0f27c005bf9a5..2b530a3b623647 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -104,7 +104,6 @@ class AdditionalUSRFinder final : public DynamicRecursiveASTVisitor {
     return std::vector<std::string>(USRSet.begin(), USRSet.end());
   }
 
-
   bool VisitCXXMethodDecl(CXXMethodDecl *MethodDecl) override {
     if (MethodDecl->isVirtual())
       OverriddenMethods.push_back(MethodDecl);
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 8e8271648ad08d..9caa818bdef397 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -15,8 +15,8 @@
 
 #include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
diff --git a/clang/unittests/AST/EvaluateAsRValueTest.cpp b/clang/unittests/AST/EvaluateAsRValueTest.cpp
index 2645d3c8e05c6b..1e17330863f264 100644
--- a/clang/unittests/AST/EvaluateAsRValueTest.cpp
+++ b/clang/unittests/AST/EvaluateAsRValueTest.cpp
@@ -29,7 +29,7 @@ typedef std::map<std::string, bool> VarInfoMap;
 /// \brief Records information on variable initializers to a map.
 class EvaluateConstantInitializersVisitor
     : public clang::DynamicRecursiveASTVisitor {
- public:
+public:
   explicit EvaluateConstantInitializersVisitor(VarInfoMap &VarInfo)
       : VarInfo(VarInfo) {}
 
diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp
index a07bbc780ad6a7..f6b2eb18979564 100644
--- a/clang/unittests/Analysis/CloneDetectionTest.cpp
+++ b/clang/unittests/Analysis/CloneDetectionTest.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Analysis/CloneDetection.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
 
diff --git a/clang/unittests/Tooling/CommentHandlerTest.cpp b/clang/unittests/Tooling/CommentHandlerTest.cpp
index d7184b08076d80..edfb72e2ec599b 100644
--- a/clang/unittests/Tooling/CommentHandlerTest.cpp
+++ b/clang/unittests/Tooling/CommentHandlerTest.cpp
@@ -22,8 +22,7 @@ struct Comment {
 class CommentVerifier;
 typedef std::vector<Comment> CommentList;
 
-class CommentHandlerVisitor : public TestVisitor,
-                              public CommentHandler {
+class CommentHandlerVisitor : public TestVisitor, public CommentHandler {
 public:
   CommentHandlerVisitor() : PP(nullptr), Verified(false) {}
 
diff --git a/clang/unittests/Tooling/ExecutionTest.cpp b/clang/unittests/Tooling/ExecutionTest.cpp
index 1bfe6293f3f27b..b0fd7ccb950ff4 100644
--- a/clang/unittests/Tooling/ExecutionTest.cpp
+++ b/clang/unittests/Tooling/ExecutionTest.cpp
@@ -30,9 +30,8 @@ namespace {
 
 // This traverses the AST and outputs function name as key and "1" as value for
 // each function declaration.
-class ASTConsumerWithResult
-    : public ASTConsumer,
-      public DynamicRecursiveASTVisitor {
+class ASTConsumerWithResult : public ASTConsumer,
+                              public DynamicRecursiveASTVisitor {
 public:
   explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) {
     assert(Context != nullptr);
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
index ccd3048b820efd..6712138b23ba64 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
@@ -14,10 +14,10 @@ namespace {
 
 class VarDeclVisitor : public ExpectedLocationVisitor {
 public:
- bool VisitVarDecl(VarDecl *Variable) override {
-   Match(Variable->getNameAsString(), Variable->getBeginLoc());
-   return true;
- }
+  bool VisitVarDecl(VarDecl *Variable) override {
+    Match(Variable->getNameAsString(), Variable->getBeginLoc());
+    return true;
+  }
 };
 
 TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
@@ -31,9 +31,7 @@ TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
 
 class ParmVarDeclVisitorForImplicitCode : public ExpectedLocationVisitor {
 public:
-  ParmVarDeclVisitorForImplicitCode() {
-    ShouldVisitImplicitCode = true;
-  }
+  ParmVarDeclVisitorForImplicitCode() { ShouldVisitImplicitCode = true; }
 
   bool VisitParmVarDecl(ParmVarDecl *ParamVar) override {
     Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
index bbec767ae60896..7693e77236b0c4 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
@@ -30,7 +30,6 @@ class AttrVisitor : public CRTPExpectedLocationVisitor<AttrVisitor> {
   }
 };
 
-
 TEST(RecursiveASTVisitor, AttributesAreVisited) {
   AttrVisitor Visitor;
   Visitor.ExpectMatch("Attr", 4, 24);
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
index 90953c66f6edf3..79dc84b2fdb7b9 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
@@ -18,7 +18,7 @@ class ClassVisitor : public ExpectedLocationVisitor {
 public:
   ClassVisitor() : SawNonImplicitLambdaClass(false) {}
 
-  bool VisitCXXRecordDecl(CXXRecordDecl* record) override {
+  bool VisitCXXRecordDecl(CXXRecordDecl *record) override {
     if (record->isLambda() && !record->isImplicit())
       SawNonImplicitLambdaClass = true;
     return true;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
index 3c8781d28e54d3..6dd28e27d7ec2c 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
@@ -52,9 +52,10 @@ struct ConceptVisitor : ExpectedLocationVisitor {
 TEST(RecursiveASTVisitor, Concepts) {
   {
     ConceptVisitor Visitor{true};
-    EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
-                                "template <Fooable T> void bar(T);",
-                                ConceptVisitor::Lang_CXX2a));
+    EXPECT_TRUE(
+        Visitor.runOver("template <typename T> concept Fooable = true;\n"
+                        "template <Fooable T> void bar(T);",
+                        ConceptVisitor::Lang_CXX2a));
     // Check that we traverse the "Fooable T" template parameter's
     // TypeConstraint's ImmediatelyDeclaredConstraint, which is a
     // ConceptSpecializationExpr.
@@ -67,9 +68,10 @@ TEST(RecursiveASTVisitor, Concepts) {
 
   {
     ConceptVisitor Visitor; // Don't visit implicit code now.
-    EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
-                                "template <Fooable T> void bar(T);",
-                                ConceptVisitor::Lang_CXX2a));
+    EXPECT_TRUE(
+        Visitor.runOver("template <typename T> concept Fooable = true;\n"
+                        "template <Fooable T> void bar(T);",
+                        ConceptVisitor::Lang_CXX2a));
     // Check that we only visit the TypeConstraint, but not the implicitly
     // generated immediately declared expression.
     EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited);
@@ -80,14 +82,15 @@ TEST(RecursiveASTVisitor, Concepts) {
 
   {
     ConceptVisitor Visitor;
-    EXPECT_TRUE(Visitor.runOver("template <class T> concept A = true;\n"
-                                "template <class T> struct vector {};\n"
-                                "template <class T> concept B = requires(T x) {\n"
-                                "  typename vector<T*>;\n"
-                                "  {x} -> A;\n"
-                                "  requires true;\n"
-                                "};",
-                                ConceptVisitor::Lang_CXX2a));
+    EXPECT_TRUE(
+        Visitor.runOver("template <class T> concept A = true;\n"
+                        "template <class T> struct vector {};\n"
+                        "template <class T> concept B = requires(T x) {\n"
+                        "  typename vector<T*>;\n"
+                        "  {x} -> A;\n"
+                        "  requires true;\n"
+                        "};",
+                        ConceptVisitor::Lang_CXX2a));
     EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed);
     EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
     EXPECT_EQ(1, Visitor.ConceptReferencesVisited);
@@ -114,9 +117,7 @@ struct Foo<F>  {};
 }
 
 struct VisitDeclOnlyOnce : ExpectedLocationVisitor {
-  VisitDeclOnlyOnce() {
-    ShouldWalkTypesOfTypeLocs = false;
-  }
+  VisitDeclOnlyOnce() { ShouldWalkTypesOfTypeLocs = false; }
 
   bool VisitConceptDecl(ConceptDecl *D) override {
     ++ConceptDeclsVisited;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
index 6e295be5a2956f..7b2ed9715aa80d 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
@@ -18,13 +18,11 @@ namespace {
 /// The name recorded for the match is the name of the class whose constructor
 /// is invoked by the CXXConstructExpr, not the name of the class whose
 /// constructor the CXXConstructExpr is contained in.
-class ConstructExprVisitor : public ExpectedLocationVisitor  {
+class ConstructExprVisitor : public ExpectedLocationVisitor {
 public:
-  ConstructExprVisitor() {
-    ShouldVisitImplicitCode = false;
-  }
+  ConstructExprVisitor() { ShouldVisitImplicitCode = false; }
 
-  bool VisitCXXConstructExpr(CXXConstructExpr* Expr) override {
+  bool VisitCXXConstructExpr(CXXConstructExpr *Expr) override {
     if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
       if (const CXXRecordDecl* Class = Ctor->getParent()) {
         Match(Class->getName(), Expr->getLocation());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
index 653e9c8bdf8ec6..6ed986c187eb52 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
@@ -14,9 +14,7 @@ namespace {
 
 class DeclRefExprVisitor : public ExpectedLocationVisitor {
 public:
-  DeclRefExprVisitor() {
-    ShouldVisitImplicitCode = false;
-  }
+  DeclRefExprVisitor() { ShouldVisitImplicitCode = false; }
 
   bool VisitDeclRefExpr(DeclRefExpr *Reference) override {
     Match(Reference->getNameInfo().getAsString(), Reference->getLocation());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
index f67cff2586aa15..dc9455a01e4882 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
@@ -15,7 +15,7 @@ namespace {
 // A visitor that visits implicit declarations and matches constructors.
 class ImplicitCtorVisitor : public ExpectedLocationVisitor {
 public:
-    bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) override {
+  bool VisitCXXConstructorDecl(CXXConstructorDecl *Ctor) override {
     if (Ctor->isImplicit()) {  // Was not written in source code
       if (const CXXRecordDecl* Class = Ctor->getParent()) {
         Match(Class->getName(), Ctor->getLocation());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
index af84c6ef9ad832..0ce7f4b18762f2 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
@@ -16,9 +16,7 @@ namespace {
 
 class LambdaExprVisitor : public ExpectedLocationVisitor {
 public:
-  LambdaExprVisitor() {
-    ShouldVisitImplicitCode = false;
-  }
+  LambdaExprVisitor() { ShouldVisitImplicitCode = false; }
 
   bool VisitLambdaExpr(LambdaExpr *Lambda) override {
     PendingBodies.push(Lambda->getBody());
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
index 77194b04de0369..cfac3a3c5ad988 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
@@ -15,9 +15,7 @@ namespace {
 // Matches (optional) explicit template parameters.
 class LambdaTemplateParametersVisitor : public ExpectedLocationVisitor {
 public:
-  LambdaTemplateParametersVisitor() {
-    ShouldVisitImplicitCode = false;
-  }
+  LambdaTemplateParametersVisitor() { ShouldVisitImplicitCode = false; }
 
   bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) override {
     EXPECT_FALSE(D->isImplicit());
diff --git a/clang/unittests/Tooling/TestVisitor.h b/clang/unittests/Tooling/TestVisitor.h
index cf39fc143507ce..fdf57a946a6e2d 100644
--- a/clang/unittests/Tooling/TestVisitor.h
+++ b/clang/unittests/Tooling/TestVisitor.h
@@ -49,11 +49,21 @@ class TestVisitorHelper {
       Args.push_back("-x");
       Args.push_back("c");
       break;
-    case Lang_CXX98: Args.push_back("-std=c++98"); break;
-    case Lang_CXX11: Args.push_back("-std=c++11"); break;
-    case Lang_CXX14: Args.push_back("-std=c++14"); break;
-    case Lang_CXX17: Args.push_back("-std=c++17"); break;
-    case Lang_CXX2a: Args.push_back("-std=c++2a"); break;
+    case Lang_CXX98:
+      Args.push_back("-std=c++98");
+      break;
+    case Lang_CXX11:
+      Args.push_back("-std=c++11");
+      break;
+    case Lang_CXX14:
+      Args.push_back("-std=c++14");
+      break;
+    case Lang_CXX17:
+      Args.push_back("-std=c++17");
+      break;
+    case Lang_CXX2a:
+      Args.push_back("-std=c++2a");
+      break;
     case Lang_OBJC:
       Args.push_back("-ObjC");
       Args.push_back("-fobjc-runtime=macosx-10.12.0");
@@ -70,7 +80,7 @@ class TestVisitorHelper {
 protected:
   TestVisitorHelper() = default;
   virtual ~TestVisitorHelper() = default;
-  virtual void InvokeTraverseDecl(TranslationUnitDecl* D) = 0;
+  virtual void InvokeTraverseDecl(TranslationUnitDecl *D) = 0;
 
   virtual std::unique_ptr<ASTFrontendAction> CreateTestAction() {
     return std::make_unique<TestAction>(this);
@@ -130,14 +140,15 @@ class ExpectedLocationVisitorHelper {
   virtual ~ExpectedLocationVisitorHelper() {
     // FIXME: Range-based for loop.
     for (std::vector<ExpectedMatch>::const_iterator
-             It = ExpectedMatches.begin(), End = ExpectedMatches.end();
+             It = ExpectedMatches.begin(),
+             End = ExpectedMatches.end();
          It != End; ++It) {
       It->ExpectFound();
-         }
+    }
   }
 
 protected:
-  virtual ASTContext* getASTContext() = 0;
+  virtual ASTContext *getASTContext() = 0;
 
   /// \brief Checks an actual match against expected and disallowed matches.
   ///
@@ -148,18 +159,19 @@ class ExpectedLocationVisitorHelper {
 
     // FIXME: Range-based for loop.
     for (std::vector<MatchCandidate>::const_iterator
-             It = DisallowedMatches.begin(), End = DisallowedMatches.end();
+             It = DisallowedMatches.begin(),
+             End = DisallowedMatches.end();
          It != End; ++It) {
       EXPECT_FALSE(It->Matches(Name, FullLocation))
           << "Matched disallowed " << *It;
-         }
+    }
 
     // FIXME: Range-based for loop.
-    for (std::vector<ExpectedMatch>::iterator
-             It = ExpectedMatches.begin(), End = ExpectedMatches.end();
+    for (std::vector<ExpectedMatch>::iterator It = ExpectedMatches.begin(),
+                                              End = ExpectedMatches.end();
          It != End; ++It) {
       It->UpdateFor(Name, FullLocation, getASTContext()->getSourceManager());
-         }
+    }
   }
 
 private:
@@ -213,7 +225,7 @@ class ExpectedLocationVisitorHelper {
         llvm::raw_string_ostream Stream(PartialMatches);
         Stream << ", partial match: \"" << Name << "\" at ";
         Location.print(Stream, SM);
-                 }
+      }
     }
 
     void ExpectFound() const {
@@ -232,7 +244,7 @@ class ExpectedLocationVisitorHelper {
   std::vector<MatchCandidate> DisallowedMatches;
   std::vector<ExpectedMatch> ExpectedMatches;
 };
-}
+} // namespace detail
 
 /// \brief Base class for simple (Dynamic)RecursiveASTVisitor based tests.
 ///
@@ -251,9 +263,7 @@ class TestVisitor : public DynamicRecursiveASTVisitor,
     ShouldVisitImplicitCode = true;
   }
 
-  void InvokeTraverseDecl(TranslationUnitDecl* D) override {
-    TraverseDecl(D);
-  }
+  void InvokeTraverseDecl(TranslationUnitDecl *D) override { TraverseDecl(D); }
 };
 
 /// \brief A RecursiveASTVisitor to check that certain matches are (or are
@@ -269,6 +279,6 @@ class ExpectedLocationVisitor : public TestVisitor,
                                 public detail::ExpectedLocationVisitorHelper {
   ASTContext *getASTContext() override { return Context; }
 };
-}
+} // namespace clang
 
 #endif

>From 1340c27e4679e60b2ef3140ad6897fd769178dd9 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 20 Aug 2024 20:42:24 +0200
Subject: [PATCH 27/27] clang-format, again

---
 .../Refactoring/RecursiveSymbolVisitor.h      |   2 +-
 clang/lib/Sema/AnalysisBasedWarnings.cpp      | 139 +++++++++---------
 2 files changed, 70 insertions(+), 71 deletions(-)

diff --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index aeea0c1b2df7f0..09c58ee02fea1a 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -30,7 +30,7 @@ class RecursiveSymbolVisitor : public DynamicRecursiveASTVisitor {
       : SM(SM), LangOpts(LangOpts) {}
 
   virtual bool visitSymbolOccurrence(const NamedDecl *ND,
-                             ArrayRef<SourceRange> NameRanges) {
+                                     ArrayRef<SourceRange> NameRanges) {
     return true;
   }
 
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 647c257cadfe1a..3b3f3f21986bae 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1152,91 +1152,90 @@ class FallthroughMapper final : public DynamicRecursiveASTVisitor {
               break;
             }
             // Don't care about other unreachable statements.
-            }
           }
-          // If there are no unreachable statements, this may be a special
-          // case in CFG:
-          // case X: {
-          //    A a;  // A has a destructor.
-          //    break;
-          // }
-          // // <<<< This place is represented by a 'hanging' CFG block.
-          // case Y:
-          continue;
-        }
-
-        const Stmt *LastStmt = getLastStmt(*P);
-        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
-          markFallthroughVisited(AS);
-          ++AnnotatedCnt;
-          continue; // Fallthrough annotation, good.
         }
+        // If there are no unreachable statements, this may be a special
+        // case in CFG:
+        // case X: {
+        //    A a;  // A has a destructor.
+        //    break;
+        // }
+        // // <<<< This place is represented by a 'hanging' CFG block.
+        // case Y:
+        continue;
+      }
 
-        if (!LastStmt) { // This block contains no executable statements.
-          // Traverse its predecessors.
-          std::copy(P->pred_begin(), P->pred_end(),
-                    std::back_inserter(BlockQueue));
-          continue;
-        }
+      const Stmt *LastStmt = getLastStmt(*P);
+      if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
+        markFallthroughVisited(AS);
+        ++AnnotatedCnt;
+        continue; // Fallthrough annotation, good.
+      }
 
-        ++UnannotatedCnt;
+      if (!LastStmt) { // This block contains no executable statements.
+        // Traverse its predecessors.
+        std::copy(P->pred_begin(), P->pred_end(),
+                  std::back_inserter(BlockQueue));
+        continue;
       }
-      return !!UnannotatedCnt;
-    }
 
-    bool VisitAttributedStmt(AttributedStmt *S) override {
-      if (asFallThroughAttr(S))
-        FallthroughStmts.insert(S);
-      return true;
+      ++UnannotatedCnt;
     }
+    return !!UnannotatedCnt;
+  }
 
-    bool VisitSwitchStmt(SwitchStmt *S) override {
-      FoundSwitchStatements = true;
-      return true;
-    }
+  bool VisitAttributedStmt(AttributedStmt *S) override {
+    if (asFallThroughAttr(S))
+      FallthroughStmts.insert(S);
+    return true;
+  }
 
-    // We don't want to traverse local type declarations. We analyze their
-    // methods separately.
-    bool TraverseDecl(Decl *D) override { return true; }
+  bool VisitSwitchStmt(SwitchStmt *S) override {
+    FoundSwitchStatements = true;
+    return true;
+  }
 
-    // We analyze lambda bodies separately. Skip them here.
-    bool TraverseLambdaExpr(LambdaExpr *LE) override {
-      // Traverse the captures, but not the body.
-      for (const auto C : zip(LE->captures(), LE->capture_inits()))
-        TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
-      return true;
-    }
+  // We don't want to traverse local type declarations. We analyze their
+  // methods separately.
+  bool TraverseDecl(Decl *D) override { return true; }
 
-  private:
+  // We analyze lambda bodies separately. Skip them here.
+  bool TraverseLambdaExpr(LambdaExpr *LE) override {
+    // Traverse the captures, but not the body.
+    for (const auto C : zip(LE->captures(), LE->capture_inits()))
+      TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
+    return true;
+  }
 
-    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
-      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
-        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
-          return AS;
-      }
-      return nullptr;
+private:
+  static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
+    if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
+      if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
+        return AS;
     }
+    return nullptr;
+  }
 
-    static const Stmt *getLastStmt(const CFGBlock &B) {
-      if (const Stmt *Term = B.getTerminatorStmt())
-        return Term;
-      for (const CFGElement &Elem : llvm::reverse(B))
-        if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
-          return CS->getStmt();
-      // Workaround to detect a statement thrown out by CFGBuilder:
-      //   case X: {} case Y:
-      //   case X: ; case Y:
-      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
-        if (!isa<SwitchCase>(SW->getSubStmt()))
-          return SW->getSubStmt();
-
-      return nullptr;
-    }
+  static const Stmt *getLastStmt(const CFGBlock &B) {
+    if (const Stmt *Term = B.getTerminatorStmt())
+      return Term;
+    for (const CFGElement &Elem : llvm::reverse(B))
+      if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
+        return CS->getStmt();
+    // Workaround to detect a statement thrown out by CFGBuilder:
+    //   case X: {} case Y:
+    //   case X: ; case Y:
+    if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
+      if (!isa<SwitchCase>(SW->getSubStmt()))
+        return SW->getSubStmt();
 
-    bool FoundSwitchStatements;
-    AttrStmts FallthroughStmts;
-    Sema &S;
-    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
+    return nullptr;
+  }
+
+  bool FoundSwitchStatements;
+  AttrStmts FallthroughStmts;
+  Sema &S;
+  llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
 };
 } // anonymous namespace
 



More information about the cfe-commits mailing list