[clang] [Clang] [NFC] Refactor more AST visitors (PR #116823)

via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 06:49:52 PST 2024


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

>From 2b29d679a6c232387bd7e307ff579f9271222c1c Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 19 Nov 2024 13:28:10 +0100
Subject: [PATCH 1/4] [Clang] [NFC] Migrate visitors in AST

---
 clang/lib/AST/ASTImporterLookupTable.cpp | 20 ++++-----
 clang/lib/AST/ParentMapContext.cpp       | 53 ++++++++++++++----------
 2 files changed, 40 insertions(+), 33 deletions(-)

diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp
index 07d39dcee2583a..b7c112540c1c60 100644
--- a/clang/lib/AST/ASTImporterLookupTable.cpp
+++ b/clang/lib/AST/ASTImporterLookupTable.cpp
@@ -13,18 +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 {
 
-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)) {
@@ -37,7 +41,7 @@ struct Builder : RecursiveASTVisitor<Builder> {
     return true;
   }
 
-  bool VisitNamedDecl(NamedDecl *D) {
+  bool VisitNamedDecl(NamedDecl *D) override {
     LT.add(D);
     return true;
   }
@@ -46,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))
@@ -76,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/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index 9723c0cfa83bbe..a5420f28750956 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/Decl.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.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,53 @@ 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;
   }

>From 0dc08083ed513686b7bf397755f347ceb9423418 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 19 Nov 2024 13:37:43 +0100
Subject: [PATCH 2/4] Migrate ASTMatcher visitor

---
 clang/lib/ASTMatchers/ASTMatchFinder.cpp | 178 +++++++++++------------
 1 file changed, 84 insertions(+), 94 deletions(-)

diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 3d01a70395a9bb..d18a7e90c59e36 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,8 @@ 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
+  //   DynamicRecursiveASTVisitor::Traverse*(node))
   //     Traverse*(c) for each child c of 'node'.
   //   - Traverse*(c) in turn calls Traverse(c), completing the
   //     recursion.
@@ -151,7 +151,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,26 +175,22 @@ class MatchChildASTVisitor
     return StmtToTraverse;
   }
 
-  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) {
-    // 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)
       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);
   }
   // 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 +202,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 +215,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 +227,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 +249,24 @@ 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 +275,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);
@@ -310,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 {
@@ -335,33 +330,36 @@ 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(
-        const_cast<NestedNameSpecifier*>(&NNS));
+    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:
@@ -411,19 +409,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) {
@@ -455,10 +459,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
@@ -493,23 +494,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) 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) override {
     if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) {
       {
         ASTNodeNotAsIsSourceScope RAII(this, true);
@@ -580,7 +581,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
           TraverseType(E);
 
         if (Expr *NE = T->getNoexceptExpr())
-          TraverseStmt(NE, Queue);
+          TraverseStmt(NE);
 
         if (LE->hasExplicitResultType())
           TraverseTypeLoc(Proto.getReturnLoc());
@@ -590,7 +591,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
       TraverseStmt(LE->getBody());
       return true;
     }
-    return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue);
+    return DynamicRecursiveASTVisitor::dataTraverseNode(S);
   }
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
@@ -734,13 +735,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;
   }
@@ -755,22 +749,19 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
     return TraversingASTNodeNotAsIs;
   }
 
-  bool TraverseTemplateInstantiations(ClassTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(ClassTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
-  bool TraverseTemplateInstantiations(VarTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(VarTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
-  bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) {
+  bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) override {
     ASTNodeNotSpelledInSourceScope RAII(this, true);
-    return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(
-        D);
+    return DynamicRecursiveASTVisitor::TraverseTemplateInstantiations(D);
   }
 
 private:
@@ -1469,10 +1460,10 @@ 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) {
+bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
   if (!StmtNode) {
     return true;
   }
@@ -1481,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);
 }
 
 bool MatchASTVisitor::TraverseType(QualType TypeNode) {
   match(TypeNode);
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
+  return DynamicRecursiveASTVisitor::TraverseType(TypeNode);
 }
 
 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
@@ -1497,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,8 +1507,7 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
   // because the traversal is already done in the parallel "Loc"-hierarchy.
   if (NNS.hasQualifier())
     match(*NNS.getNestedNameSpecifier());
-  return
-      RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
+  return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
 }
 
 bool MatchASTVisitor::TraverseConstructorInitializer(
@@ -1535,18 +1525,18 @@ bool MatchASTVisitor::TraverseConstructorInitializer(
 
   match(*CtorInit);
 
-  return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer(
-      CtorInit);
+  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 {

>From 1f71d147575b262de1fba1e35e9fd08c360db8ac Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 19 Nov 2024 14:24:43 +0100
Subject: [PATCH 3/4] Migrate visitors in CodeGen

---
 clang/lib/CodeGen/CGDebugInfo.cpp             | 21 ++++----
 clang/lib/CodeGen/CodeGenModule.cpp           | 21 ++++----
 clang/lib/CodeGen/CodeGenPGO.cpp              | 52 +++++++++----------
 .../CodeGen/ObjectFilePCHContainerWriter.cpp  | 14 ++---
 4 files changed, 52 insertions(+), 56 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 60f32f76109e9a..0ed010c7f12477 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -25,9 +25,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/SourceManager.h"
@@ -5452,10 +5452,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;
@@ -5476,17 +5475,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()) {
@@ -5495,7 +5494,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())) {
@@ -5510,13 +5509,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 508f53482d4e1f..5c78dc07529e08 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/CodeGenOptions.h"
@@ -3984,13 +3984,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;
@@ -4004,13 +4003,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>();
@@ -4019,12 +4018,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.
@@ -4035,12 +4034,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;
     }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 17d7902f0cfbc7..9e59bb1df3c6d3 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"
@@ -155,9 +155,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.
@@ -183,16 +181,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;
@@ -234,7 +232,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;
@@ -274,7 +272,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;
@@ -327,7 +325,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++;
@@ -339,19 +337,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);
@@ -360,10 +358,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.
@@ -393,7 +391,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;
@@ -406,13 +404,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;
@@ -425,13 +423,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;
@@ -446,13 +444,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()) {
@@ -462,7 +460,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;
@@ -472,8 +470,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/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
index 71745480706ed6..4147c0a97f4119 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/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
@@ -55,7 +55,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)
@@ -66,13 +66,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.
@@ -86,14 +86,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;
@@ -114,7 +114,7 @@ class PCHContainerGenerator : public ASTConsumer {
       return true;
     }
 
-    bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    bool VisitObjCMethodDecl(ObjCMethodDecl *D) override {
       if (!D->getClassInterface())
         return true;
 

>From e2fefce211617e09fbdd455c8d69137203424498 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 19 Nov 2024 15:15:53 +0100
Subject: [PATCH 4/4] Migrate yet more visitors

---
 clang/include/clang/InstallAPI/Visitor.h      |  20 +-
 .../Refactoring/RecursiveSymbolVisitor.h      |  35 ++-
 clang/lib/Frontend/ASTConsumers.cpp           | 223 +++++++++---------
 .../InterfaceStubFunctionsConsumer.cpp        |   6 +-
 clang/lib/Index/IndexBody.cpp                 |  86 +++----
 clang/lib/Index/IndexTypeSourceInfo.cpp       |  43 ++--
 clang/lib/InstallAPI/Visitor.cpp              |  10 +-
 clang/lib/Tooling/ASTDiff/ASTDiff.cpp         |  21 +-
 .../Tooling/Refactoring/Rename/USRFinder.cpp  |  11 +-
 .../Refactoring/Rename/USRFindingAction.cpp   |  12 +-
 .../Refactoring/Rename/USRLocFinder.cpp       |  25 +-
 11 files changed, 242 insertions(+), 250 deletions(-)

diff --git a/clang/include/clang/InstallAPI/Visitor.h b/clang/include/clang/InstallAPI/Visitor.h
index 3680ee566ca875..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/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.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..ab1d770046d827 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -16,7 +16,7 @@
 #define LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H
 
 #include "clang/AST/AST.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/Lex/Lexer.h"
 
 namespace clang {
@@ -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,
-                             ArrayRef<SourceRange> NameRanges) {
+  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/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index a6e35452b4fbe6..e519ee5c34b9f7 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/RecursiveASTVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Path.h"
@@ -28,133 +28,130 @@ using namespace clang;
 /// ASTPrinter - Pretty-printer and dumper of ASTs
 
 namespace {
-  class ASTPrinter : public ASTConsumer,
-                     public RecursiveASTVisitor<ASTPrinter> {
-    typedef RecursiveASTVisitor<ASTPrinter> base;
-
-  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) {}
-
-    void HandleTranslationUnit(ASTContext &Context) override {
-      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
-
-      if (FilterString.empty())
-        return print(D);
-
-      TraverseDecl(D);
-    }
+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;
+  }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-    bool TraverseDecl(Decl *D) {
-      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 base::TraverseDecl(D);
-    }
+  void HandleTranslationUnit(ASTContext &Context) override {
+    TranslationUnitDecl *D = Context.getTranslationUnitDecl();
 
-  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;
+    if (FilterString.empty())
+      return print(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;
     }
-    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))
-          if (Decl *TempD = TD->getTemplatedDecl())
-            InnerD = TempD;
-
-        // 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());
-      }
+    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;
+  }
+  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);
     }
 
-    raw_ostream &Out;
-    std::unique_ptr<raw_ostream> OwnedOut;
+    if (DumpDeclTypes) {
+      Decl *InnerD = D;
+      if (auto *TD = dyn_cast<TemplateDecl>(D))
+        if (Decl *TempD = TD->getTemplatedDecl())
+          InnerD = TempD;
+
+      // 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());
+    }
+  }
 
-    /// How to output individual declarations.
-    Kind OutputKind;
+  raw_ostream &Out;
+  std::unique_ptr<raw_ostream> OwnedOut;
 
-    /// What format should the output take?
-    ASTDumpOutputFormat OutputFormat;
+  /// How to output individual declarations.
+  Kind OutputKind;
 
-    /// Which declarations or DeclContexts to display.
-    std::string FilterString;
+  /// What format should the output take?
+  ASTDumpOutputFormat OutputFormat;
 
-    /// 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;
+  /// Which declarations or DeclContexts to display.
+  std::string FilterString;
 
-    /// Whether to dump the type for each declaration dumped.
-    bool DumpDeclTypes;
-  };
+  /// 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;
 
-  class ASTDeclNodeLister : public ASTConsumer,
-                     public RecursiveASTVisitor<ASTDeclNodeLister> {
-  public:
-    ASTDeclNodeLister(raw_ostream *Out = nullptr)
-        : Out(Out ? *Out : llvm::outs()) {}
+  /// Whether to dump the type for each declaration dumped.
+  bool DumpDeclTypes;
+};
 
-    void HandleTranslationUnit(ASTContext &Context) override {
-      TraverseDecl(Context.getTranslationUnitDecl());
-    }
+class ASTDeclNodeLister : public ASTConsumer,
+                          public DynamicRecursiveASTVisitor {
+public:
+  ASTDeclNodeLister(raw_ostream *Out = nullptr)
+      : Out(Out ? *Out : llvm::outs()) {
+    ShouldWalkTypesOfTypeLocs = false;
+  }
 
-    bool shouldWalkTypesOfTypeLocs() const { return false; }
+  void HandleTranslationUnit(ASTContext &Context) override {
+    TraverseDecl(Context.getTranslationUnitDecl());
+  }
 
-    bool VisitNamedDecl(NamedDecl *D) {
-      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 d7cfd23bb0a7a6..4d99e728b5e65d 100644
--- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.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);
diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index c18daf7faa7497..2d32201f3aeb12 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/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprConcepts.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.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; }
+  BodyIndexer(IndexingContext &indexCtx, const NamedDecl *Parent,
+              const DeclContext *DC)
+      : 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,15 @@ 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 +213,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 +225,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 +304,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 +329,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 +348,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 +377,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 +402,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 +420,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 +464,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 +475,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 +485,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 +494,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);
   }
 };
 
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index b986ccde574525..9f3b4aee41ad25 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/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "llvm/ADT/ScopeExit.h"
 
@@ -18,19 +19,18 @@ 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)
     : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
+    ShouldWalkTypesOfTypeLocs = false;
     if (IsBase) {
       assert(Parent);
       Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
@@ -41,22 +41,20 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
     }
   }
 
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
     if (!CALL_EXPR)                                                            \
       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 +78,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 +92,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 +105,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 +129,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 +159,8 @@ 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,8 @@ 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 +191,8 @@ 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 +202,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 +235,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
                                     ParentDC, SymbolRoleSet(), Relations);
   }
 
-  bool TraverseStmt(Stmt *S) {
+  bool TraverseStmt(Stmt *S) 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..76089d0a61b42f 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -6,13 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file contains definitons for the AST differencing interface.
+// This file contains definitions for the AST differencing interface.
 //
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.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) 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..713a8830dd20ca 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -14,7 +14,6 @@
 #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
@@ -29,8 +28,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 +39,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 +96,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..d898e46872291c 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,7 @@ 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..7021d766cee35f 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -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);
@@ -350,7 +349,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
     return true;
   }
 
-  bool VisitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
+  bool visitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
     if (!NestedLoc.getNestedNameSpecifier()->getAsType())
       return true;
 
@@ -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()) {
@@ -378,7 +377,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
       // The VisitNestedNameSpecifierLoc interface is not impelmented in
       // RecursiveASTVisitor, we have to handle it explicitly.
       if (const auto *NSL = Parents[0].get<NestedNameSpecifierLoc>()) {
-        VisitNestedNameSpecifierLocations(*NSL);
+        visitNestedNameSpecifierLocations(*NSL);
         return true;
       }
 



More information about the cfe-commits mailing list