[clang] [Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use DRAV (PR #115144)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 14 21:20:22 PST 2024
https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/115144
>From 80856d18460f139a39766393ce391d8ef2293e63 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Wed, 6 Nov 2024 09:51:46 +0100
Subject: [PATCH 1/5] [Clang] [NFC] Migrate AST visitors in Sema
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 149 +++++++++---------
clang/lib/Sema/SemaAvailability.cpp | 41 +++--
clang/lib/Sema/SemaCodeComplete.cpp | 17 +-
clang/lib/Sema/SemaDeclAttr.cpp | 9 +-
clang/lib/Sema/SemaDeclCXX.cpp | 53 +++----
clang/lib/Sema/SemaDeclObjC.cpp | 9 +-
clang/lib/Sema/SemaExpr.cpp | 49 +++---
clang/lib/Sema/SemaExprCXX.cpp | 6 +-
clang/lib/Sema/SemaFunctionEffects.cpp | 85 +++++-----
clang/lib/Sema/SemaHLSL.cpp | 10 +-
clang/lib/Sema/SemaOpenMP.cpp | 24 +--
clang/lib/Sema/SemaStmt.cpp | 10 +-
clang/lib/Sema/SemaTemplate.cpp | 34 ++--
clang/lib/Sema/SemaTemplateDeduction.cpp | 14 +-
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 13 +-
clang/lib/Sema/SemaTemplateInstantiate.cpp | 6 +-
clang/lib/Sema/SemaTemplateVariadic.cpp | 139 ++++++++--------
17 files changed, 332 insertions(+), 336 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index c76733e9a774b6..abee6b1075b25c 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -16,13 +16,13 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
@@ -1067,81 +1067,79 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
}
namespace {
- class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
- public:
- FallthroughMapper(Sema &S)
- : FoundSwitchStatements(false),
- S(S) {
- }
+class FallthroughMapper : public DynamicRecursiveASTVisitor {
+public:
+ FallthroughMapper(Sema &S) : FoundSwitchStatements(false), S(S) {
+ ShouldWalkTypesOfTypeLocs = false;
+ }
- bool foundSwitchStatements() const { return FoundSwitchStatements; }
+ bool foundSwitchStatements() const { return FoundSwitchStatements; }
- void markFallthroughVisited(const AttributedStmt *Stmt) {
- bool Found = FallthroughStmts.erase(Stmt);
- assert(Found);
- (void)Found;
- }
+ void markFallthroughVisited(const AttributedStmt *Stmt) {
+ bool Found = FallthroughStmts.erase(Stmt);
+ assert(Found);
+ (void)Found;
+ }
+
+ typedef llvm::SmallPtrSet<const AttributedStmt *, 8> AttrStmts;
- typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
+ const AttrStmts &getFallthroughStmts() const { return FallthroughStmts; }
- const AttrStmts &getFallthroughStmts() const {
- return FallthroughStmts;
+ void fillReachableBlocks(CFG *Cfg) {
+ assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
+ std::deque<const CFGBlock *> BlockQueue;
+
+ ReachableBlocks.insert(&Cfg->getEntry());
+ BlockQueue.push_back(&Cfg->getEntry());
+ // Mark all case blocks reachable to avoid problems with switching on
+ // constants, covered enums, etc.
+ // These blocks can contain fall-through annotations, and we don't want to
+ // issue a warn_fallthrough_attr_unreachable for them.
+ for (const auto *B : *Cfg) {
+ const Stmt *L = B->getLabel();
+ if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second)
+ BlockQueue.push_back(B);
}
- void fillReachableBlocks(CFG *Cfg) {
- assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
- std::deque<const CFGBlock *> BlockQueue;
-
- ReachableBlocks.insert(&Cfg->getEntry());
- BlockQueue.push_back(&Cfg->getEntry());
- // Mark all case blocks reachable to avoid problems with switching on
- // constants, covered enums, etc.
- // These blocks can contain fall-through annotations, and we don't want to
- // issue a warn_fallthrough_attr_unreachable for them.
- for (const auto *B : *Cfg) {
- const Stmt *L = B->getLabel();
- if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second)
+ while (!BlockQueue.empty()) {
+ const CFGBlock *P = BlockQueue.front();
+ BlockQueue.pop_front();
+ for (const CFGBlock *B : P->succs()) {
+ if (B && ReachableBlocks.insert(B).second)
BlockQueue.push_back(B);
}
-
- while (!BlockQueue.empty()) {
- const CFGBlock *P = BlockQueue.front();
- BlockQueue.pop_front();
- for (const CFGBlock *B : P->succs()) {
- if (B && ReachableBlocks.insert(B).second)
- BlockQueue.push_back(B);
- }
- }
}
+ }
- bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
- bool IsTemplateInstantiation) {
- assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
+ bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
+ bool IsTemplateInstantiation) {
+ assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
- int UnannotatedCnt = 0;
- AnnotatedCnt = 0;
+ int UnannotatedCnt = 0;
+ AnnotatedCnt = 0;
- std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end());
- while (!BlockQueue.empty()) {
- const CFGBlock *P = BlockQueue.front();
- BlockQueue.pop_front();
- if (!P) continue;
+ std::deque<const CFGBlock *> BlockQueue(B.pred_begin(), B.pred_end());
+ while (!BlockQueue.empty()) {
+ const CFGBlock *P = BlockQueue.front();
+ BlockQueue.pop_front();
+ if (!P)
+ continue;
- const Stmt *Term = P->getTerminatorStmt();
- if (isa_and_nonnull<SwitchStmt>(Term))
- continue; // Switch statement, good.
+ const Stmt *Term = P->getTerminatorStmt();
+ if (isa_and_nonnull<SwitchStmt>(Term))
+ continue; // Switch statement, good.
- const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
- if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
- continue; // Previous case label has no statements, good.
+ const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
+ if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
+ continue; // Previous case label has no statements, good.
- const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
- if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
- continue; // Case label is preceded with a normal label, good.
+ const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
+ if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
+ continue; // Case label is preceded with a normal label, good.
- if (!ReachableBlocks.count(P)) {
- for (const CFGElement &Elem : llvm::reverse(*P)) {
- if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
+ if (!ReachableBlocks.count(P)) {
+ for (const CFGElement &Elem : llvm::reverse(*P)) {
+ if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
// Don't issue a warning for an unreachable fallthrough
// attribute in template instantiations as it may not be
@@ -1186,26 +1184,23 @@ namespace {
return !!UnannotatedCnt;
}
- // RecursiveASTVisitor setup.
- bool shouldWalkTypesOfTypeLocs() const { return false; }
-
- bool VisitAttributedStmt(AttributedStmt *S) {
+ bool VisitAttributedStmt(AttributedStmt *S) override {
if (asFallThroughAttr(S))
FallthroughStmts.insert(S);
return true;
}
- bool VisitSwitchStmt(SwitchStmt *S) {
+ bool VisitSwitchStmt(SwitchStmt *S) override {
FoundSwitchStatements = true;
return true;
}
// We don't want to traverse local type declarations. We analyze their
// methods separately.
- bool TraverseDecl(Decl *D) { return true; }
+ bool TraverseDecl(Decl *D) override { return true; }
// We analyze lambda bodies separately. Skip them here.
- bool TraverseLambdaExpr(LambdaExpr *LE) {
+ bool TraverseLambdaExpr(LambdaExpr *LE) override {
// Traverse the captures, but not the body.
for (const auto C : zip(LE->captures(), LE->capture_inits()))
TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
@@ -1242,7 +1237,7 @@ namespace {
AttrStmts FallthroughStmts;
Sema &S;
llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
- };
+};
} // anonymous namespace
static StringRef getFallthroughAttrSpelling(Preprocessor &PP,
@@ -2502,15 +2497,18 @@ static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
// An AST Visitor that calls a callback function on each callable DEFINITION
// that is NOT in a dependent context:
-class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
+class CallableVisitor : public DynamicRecursiveASTVisitor {
private:
llvm::function_ref<void(const Decl *)> Callback;
public:
CallableVisitor(llvm::function_ref<void(const Decl *)> Callback)
- : Callback(Callback) {}
+ : Callback(Callback) {
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
+ }
- bool VisitFunctionDecl(FunctionDecl *Node) {
+ bool VisitFunctionDecl(FunctionDecl *Node) override {
if (cast<DeclContext>(Node)->isDependentContext())
return true; // Not to analyze dependent decl
// `FunctionDecl->hasBody()` returns true if the function has a body
@@ -2521,14 +2519,14 @@ class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
return true;
}
- bool VisitBlockDecl(BlockDecl *Node) {
+ bool VisitBlockDecl(BlockDecl *Node) override {
if (cast<DeclContext>(Node)->isDependentContext())
return true; // Not to analyze dependent decl
Callback(Node);
return true;
}
- bool VisitObjCMethodDecl(ObjCMethodDecl *Node) {
+ bool VisitObjCMethodDecl(ObjCMethodDecl *Node) override {
if (cast<DeclContext>(Node)->isDependentContext())
return true; // Not to analyze dependent decl
if (Node->hasBody())
@@ -2536,12 +2534,9 @@ class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> {
return true;
}
- bool VisitLambdaExpr(LambdaExpr *Node) {
+ bool VisitLambdaExpr(LambdaExpr *Node) override {
return VisitFunctionDecl(Node->getCallOperator());
}
-
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
};
void clang::sema::AnalysisBasedWarnings::IssueWarnings(
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index 076d3489fa9438..c806b832dec7a7 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -13,7 +13,9 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtObjC.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
@@ -741,11 +743,11 @@ bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) {
}
}
-class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
+class StmtUSEFinder : public DynamicRecursiveASTVisitor {
const Stmt *Target;
public:
- bool VisitStmt(Stmt *S) { return S != Target; }
+ bool VisitStmt(Stmt *S) override { return S != Target; }
/// Returns true if the given statement is present in the given declaration.
static bool isContained(const Stmt *Target, const Decl *D) {
@@ -757,11 +759,11 @@ class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
/// Traverses the AST and finds the last statement that used a given
/// declaration.
-class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
+class LastDeclUSEFinder : public DynamicRecursiveASTVisitor {
const Decl *D;
public:
- bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
if (DRE->getDecl() == D)
return false;
return true;
@@ -785,10 +787,7 @@ class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
/// to a partially available declaration. Whenever we encounter an \c if of the
/// form: \c if(@available(...)), we use the version from the condition to visit
/// the then statement.
-class DiagnoseUnguardedAvailability
- : public RecursiveASTVisitor<DiagnoseUnguardedAvailability> {
- typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base;
-
+class DiagnoseUnguardedAvailability : public DynamicRecursiveASTVisitor {
Sema &SemaRef;
Decl *Ctx;
@@ -806,26 +805,26 @@ class DiagnoseUnguardedAvailability
SemaRef.Context.getTargetInfo().getPlatformMinVersion());
}
- bool TraverseStmt(Stmt *S) {
+ bool TraverseStmt(Stmt *S) override {
if (!S)
return true;
StmtStack.push_back(S);
- bool Result = Base::TraverseStmt(S);
+ bool Result = DynamicRecursiveASTVisitor::TraverseStmt(S);
StmtStack.pop_back();
return Result;
}
void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
- bool TraverseIfStmt(IfStmt *If);
+ bool TraverseIfStmt(IfStmt *If) override;
// for 'case X:' statements, don't bother looking at the 'X'; it can't lead
// to any useful diagnostics.
- bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); }
-
- bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { return true; }
+ bool TraverseCaseStmt(CaseStmt *CS) override {
+ return TraverseStmt(CS->getSubStmt());
+ }
- bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
+ bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
if (ObjCMethodDecl *D = Msg->getMethodDecl()) {
ObjCInterfaceDecl *ID = nullptr;
QualType ReceiverTy = Msg->getClassReceiver();
@@ -838,25 +837,25 @@ class DiagnoseUnguardedAvailability
return true;
}
- bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
DiagnoseDeclAvailability(DRE->getDecl(),
SourceRange(DRE->getBeginLoc(), DRE->getEndLoc()));
return true;
}
- bool VisitMemberExpr(MemberExpr *ME) {
+ bool VisitMemberExpr(MemberExpr *ME) override {
DiagnoseDeclAvailability(ME->getMemberDecl(),
SourceRange(ME->getBeginLoc(), ME->getEndLoc()));
return true;
}
- bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+ bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) override {
SemaRef.Diag(E->getBeginLoc(), diag::warn_at_available_unchecked_use)
<< (!SemaRef.getLangOpts().ObjC);
return true;
}
- bool VisitTypeLoc(TypeLoc Ty);
+ bool VisitTypeLoc(TypeLoc Ty) override;
};
void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
@@ -1038,7 +1037,7 @@ bool DiagnoseUnguardedAvailability::TraverseIfStmt(IfStmt *If) {
ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(If->getCond());
if (!IfCond.E) {
// This isn't an availability checking 'if', we can just continue.
- return Base::TraverseIfStmt(If);
+ return DynamicRecursiveASTVisitor::TraverseIfStmt(If);
}
VersionTuple CondVersion = IfCond.E->getVersion();
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 16a76ff9b5c241..45fc8a6df52d8f 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
@@ -22,7 +23,6 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/QualTypeNames.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/CharInfo.h"
@@ -5422,7 +5422,7 @@ class ConceptInfo {
// This visitor infers members of T based on traversing expressions/types
// that involve T. It is invoked with code known to be valid for T.
- class ValidVisitor : public RecursiveASTVisitor<ValidVisitor> {
+ class ValidVisitor : public DynamicRecursiveASTVisitor {
ConceptInfo *Outer;
const TemplateTypeParmType *T;
@@ -5440,7 +5440,8 @@ class ConceptInfo {
}
// In T.foo or T->foo, `foo` is a member function/variable.
- bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+ bool
+ VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
const Type *Base = E->getBaseType().getTypePtr();
bool IsArrow = E->isArrow();
if (Base->isPointerType() && IsArrow) {
@@ -5453,14 +5454,14 @@ class ConceptInfo {
}
// In T::foo, `foo` is a static member function/variable.
- bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+ bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override {
if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T))
addValue(E, E->getDeclName(), Member::Colons);
return true;
}
// In T::typename foo, `foo` is a type.
- bool VisitDependentNameType(DependentNameType *DNT) {
+ bool VisitDependentNameType(DependentNameType *DNT) override {
const auto *Q = DNT->getQualifier();
if (Q && isApprox(Q->getAsType(), T))
addType(DNT->getIdentifier());
@@ -5469,7 +5470,7 @@ class ConceptInfo {
// In T::foo::bar, `foo` must be a type.
// VisitNNS() doesn't exist, and TraverseNNS isn't always called :-(
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) {
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) override {
if (NNSL) {
NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier();
const auto *Q = NNS->getPrefix();
@@ -5477,14 +5478,14 @@ class ConceptInfo {
addType(NNS->getAsIdentifier());
}
// FIXME: also handle T::foo<X>::bar
- return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
+ return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
}
// FIXME also handle T::foo<X>
// Track the innermost caller/callee relationship so we can tell if a
// nested expr is being called as a function.
- bool VisitCallExpr(CallExpr *CE) {
+ bool VisitCallExpr(CallExpr *CE) override {
Caller = CE;
Callee = CE->getCallee();
return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d05d326178e1b8..ec79b051c2d8a6 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -17,10 +17,10 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Mangle.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Cuda.h"
@@ -723,8 +723,7 @@ static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
namespace {
/// Determines if a given Expr references any of the given function's
/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
-class ArgumentDependenceChecker
- : public RecursiveASTVisitor<ArgumentDependenceChecker> {
+class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor {
#ifndef NDEBUG
const CXXRecordDecl *ClassType;
#endif
@@ -748,14 +747,14 @@ class ArgumentDependenceChecker
return Result;
}
- bool VisitCXXThisExpr(CXXThisExpr *E) {
+ bool VisitCXXThisExpr(CXXThisExpr *E) override {
assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
"`this` doesn't refer to the enclosing class?");
Result = true;
return false;
}
- bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
if (Parms.count(PVD)) {
Result = true;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1a691c0e1689d6..e2f3d5f2594d08 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -19,11 +19,11 @@
#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
@@ -2499,10 +2499,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
assert(FD->isImmediateEscalating() && !FD->isConsteval() &&
"expected an immediate function");
assert(FD->hasBody() && "expected the function to have a body");
- struct ImmediateEscalatingExpressionsVisitor
- : public RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor> {
-
- using Base = RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor>;
+ struct ImmediateEscalatingExpressionsVisitor : DynamicRecursiveASTVisitor {
Sema &SemaRef;
const FunctionDecl *ImmediateFn;
@@ -2512,10 +2509,10 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
ImmediateEscalatingExpressionsVisitor(Sema &SemaRef, FunctionDecl *FD)
: SemaRef(SemaRef), ImmediateFn(FD),
- ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) {}
-
- bool shouldVisitImplicitCode() const { return true; }
- bool shouldVisitLambdaBody() const { return false; }
+ ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) {
+ ShouldVisitImplicitCode = true;
+ ShouldVisitLambdaBody = false;
+ }
void Diag(const Expr *E, const FunctionDecl *Fn, bool IsCall) {
SourceLocation Loc = E->getBeginLoc();
@@ -2535,7 +2532,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
<< (CurrentInit && !CurrentInit->isWritten())
<< InitializedField << Range;
}
- bool TraverseCallExpr(CallExpr *E) {
+ bool TraverseCallExpr(CallExpr *E) override {
if (const auto *DR =
dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImplicit());
DR && DR->isImmediateEscalating()) {
@@ -2544,13 +2541,13 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
}
for (Expr *A : E->arguments())
- if (!getDerived().TraverseStmt(A))
+ if (!TraverseStmt(A))
return false;
return true;
}
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
if (const auto *ReferencedFn = dyn_cast<FunctionDecl>(E->getDecl());
ReferencedFn && E->isImmediateEscalating()) {
Diag(E, ReferencedFn, /*IsCall=*/false);
@@ -2560,7 +2557,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
return true;
}
- bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+ bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
CXXConstructorDecl *D = E->getConstructor();
if (E->isImmediateEscalating()) {
Diag(E, D, /*IsCall=*/true);
@@ -2569,18 +2566,18 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
return true;
}
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+ bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
llvm::SaveAndRestore RAII(CurrentInit, Init);
- return Base::TraverseConstructorInitializer(Init);
+ return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
}
- bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) {
+ bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) override {
llvm::SaveAndRestore RAII(CurrentConstructor, Ctr);
- return Base::TraverseCXXConstructorDecl(Ctr);
+ return DynamicRecursiveASTVisitor::TraverseCXXConstructorDecl(Ctr);
}
- bool TraverseType(QualType T) { return true; }
- bool VisitBlockExpr(BlockExpr *T) { return true; }
+ bool TraverseType(QualType T) override { return true; }
+ bool VisitBlockExpr(BlockExpr *T) override { return true; }
} Visitor(*this, FD);
Visitor.TraverseDecl(FD);
@@ -18750,18 +18747,18 @@ void Sema::CheckDelegatingCtorCycles() {
namespace {
/// AST visitor that finds references to the 'this' expression.
- class FindCXXThisExpr : public RecursiveASTVisitor<FindCXXThisExpr> {
- Sema &S;
+class FindCXXThisExpr : public DynamicRecursiveASTVisitor {
+ Sema &S;
- public:
- explicit FindCXXThisExpr(Sema &S) : S(S) { }
+public:
+ explicit FindCXXThisExpr(Sema &S) : S(S) {}
- bool VisitCXXThisExpr(CXXThisExpr *E) {
- S.Diag(E->getLocation(), diag::err_this_static_member_func)
+ bool VisitCXXThisExpr(CXXThisExpr *E) override {
+ S.Diag(E->getLocation(), diag::err_this_static_member_func)
<< E->isImplicit();
- return false;
- }
- };
+ return false;
+ }
+};
}
bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) {
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 431f267fd5be5c..10af06d4dfe496 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -15,9 +15,9 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
@@ -5317,8 +5317,7 @@ SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
namespace {
/// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property
/// accessor references the backing ivar.
-class UnusedBackingIvarChecker
- : public RecursiveASTVisitor<UnusedBackingIvarChecker> {
+class UnusedBackingIvarChecker : public DynamicRecursiveASTVisitor {
public:
Sema &S;
const ObjCMethodDecl *Method;
@@ -5333,7 +5332,7 @@ class UnusedBackingIvarChecker
assert(IvarD);
}
- bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+ bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) override {
if (E->getDecl() == IvarD) {
AccessedIvar = true;
return false;
@@ -5341,7 +5340,7 @@ class UnusedBackingIvarChecker
return true;
}
- bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
if (E->getReceiverKind() == ObjCMessageExpr::Instance &&
S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) {
InvokedSelfMethod = true;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 49fdb5b5ab43da..5c29f43bf1d8f8 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -29,7 +30,6 @@
#include "clang/AST/MangleNumberingContext.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
@@ -5395,32 +5395,33 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
return false;
}
-struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {
+struct ImmediateCallVisitor : DynamicRecursiveASTVisitor {
const ASTContext &Context;
- ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {}
+ ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {
+ ShouldVisitImplicitCode = true;
+ }
bool HasImmediateCalls = false;
- bool shouldVisitImplicitCode() const { return true; }
- bool VisitCallExpr(CallExpr *E) {
+ bool VisitCallExpr(CallExpr *E) override {
if (const FunctionDecl *FD = E->getDirectCallee())
HasImmediateCalls |= FD->isImmediateFunction();
- return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+ return DynamicRecursiveASTVisitor::VisitStmt(E);
}
- bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+ bool VisitCXXConstructExpr(CXXConstructExpr *E) override {
if (const FunctionDecl *FD = E->getConstructor())
HasImmediateCalls |= FD->isImmediateFunction();
- return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+ return DynamicRecursiveASTVisitor::VisitStmt(E);
}
// SourceLocExpr are not immediate invocations
// but CXXDefaultInitExpr/CXXDefaultArgExpr containing a SourceLocExpr
// need to be rebuilt so that they refer to the correct SourceLocation and
// DeclContext.
- bool VisitSourceLocExpr(SourceLocExpr *E) {
+ bool VisitSourceLocExpr(SourceLocExpr *E) override {
HasImmediateCalls = true;
- return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
+ return DynamicRecursiveASTVisitor::VisitStmt(E);
}
// A nested lambda might have parameters with immediate invocations
@@ -5429,15 +5430,15 @@ struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {
// subexpression).
// FIXME: We should consider visiting and transforming captures
// with init expressions.
- bool VisitLambdaExpr(LambdaExpr *E) {
+ bool VisitLambdaExpr(LambdaExpr *E) override {
return VisitCXXMethodDecl(E->getCallOperator());
}
- bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+ bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
return TraverseStmt(E->getExpr());
}
- bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
+ bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) override {
return TraverseStmt(E->getExpr());
}
};
@@ -17673,10 +17674,10 @@ HandleImmediateInvocations(Sema &SemaRef,
RemoveNestedImmediateInvocation(SemaRef, Rec, It);
} else if (Rec.ImmediateInvocationCandidates.size() == 1 &&
Rec.ReferenceToConsteval.size()) {
- struct SimpleRemove : RecursiveASTVisitor<SimpleRemove> {
+ struct SimpleRemove : DynamicRecursiveASTVisitor {
llvm::SmallPtrSetImpl<DeclRefExpr *> &DRSet;
SimpleRemove(llvm::SmallPtrSetImpl<DeclRefExpr *> &S) : DRSet(S) {}
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
DRSet.erase(E);
return DRSet.size();
}
@@ -19985,17 +19986,15 @@ namespace {
// TreeTransforms rebuilding the type in a new context. Rather than
// duplicating the TreeTransform logic, we should consider reusing it here.
// Currently that causes problems when rebuilding LambdaExprs.
- class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
- Sema &S;
- SourceLocation Loc;
-
- public:
- typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited;
+class MarkReferencedDecls : public DynamicRecursiveASTVisitor {
+ Sema &S;
+ SourceLocation Loc;
- MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
+public:
+ MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) {}
- bool TraverseTemplateArgument(const TemplateArgument &Arg);
- };
+ bool TraverseTemplateArgument(const TemplateArgument &Arg) override;
+};
}
bool MarkReferencedDecls::TraverseTemplateArgument(
@@ -20012,7 +20011,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument(
}
}
- return Inherited::TraverseTemplateArgument(Arg);
+ return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
}
void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ab9367f911cc51..4e3e9681890f58 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -18,10 +18,10 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/AlignedAllocation.h"
@@ -8821,13 +8821,13 @@ static ExprResult attemptRecovery(Sema &SemaRef,
}
namespace {
-class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> {
+class FindTypoExprs : public DynamicRecursiveASTVisitor {
llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
public:
explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs)
: TypoExprs(TypoExprs) {}
- bool VisitTypoExpr(TypoExpr *TE) {
+ bool VisitTypoExpr(TypoExpr *TE) override {
TypoExprs.insert(TE);
return true;
}
diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp
index ab728f24d8a271..61d13af5734502 100644
--- a/clang/lib/Sema/SemaFunctionEffects.cpp
+++ b/clang/lib/Sema/SemaFunctionEffects.cpp
@@ -12,8 +12,10 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtObjC.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Sema/SemaInternal.h"
@@ -964,9 +966,7 @@ class Analyzer {
// being checked for implicit conformance.
//
// Violations are always routed to a PendingFunctionAnalysis.
- struct FunctionBodyASTVisitor : RecursiveASTVisitor<FunctionBodyASTVisitor> {
- using Base = RecursiveASTVisitor<FunctionBodyASTVisitor>;
-
+ struct FunctionBodyASTVisitor : DynamicRecursiveASTVisitor {
Analyzer &Outer;
PendingFunctionAnalysis &CurrentFunction;
CallableInfo &CurrentCaller;
@@ -977,7 +977,10 @@ class Analyzer {
PendingFunctionAnalysis &CurrentFunction,
CallableInfo &CurrentCaller)
: Outer(Outer), CurrentFunction(CurrentFunction),
- CurrentCaller(CurrentCaller) {}
+ CurrentCaller(CurrentCaller) {
+ ShouldVisitImplicitCode = true;
+ ShouldWalkTypesOfTypeLocs = false;
+ }
// -- Entry point --
void run() {
@@ -1105,53 +1108,49 @@ class Analyzer {
// -- Methods for use of RecursiveASTVisitor --
- bool shouldVisitImplicitCode() const { return true; }
-
- bool shouldWalkTypesOfTypeLocs() const { return false; }
-
- bool VisitCXXThrowExpr(CXXThrowExpr *Throw) {
+ bool VisitCXXThrowExpr(CXXThrowExpr *Throw) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
ViolationID::ThrowsOrCatchesExceptions,
Throw->getThrowLoc());
return true;
}
- bool VisitCXXCatchStmt(CXXCatchStmt *Catch) {
+ bool VisitCXXCatchStmt(CXXCatchStmt *Catch) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Catch->getCatchLoc());
return true;
}
- bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) {
+ bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
ViolationID::ThrowsOrCatchesExceptions,
Throw->getThrowLoc());
return true;
}
- bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) {
+ bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Catch->getAtCatchLoc());
return true;
}
- bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) {
+ bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Finally->getAtFinallyLoc());
return true;
}
- bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
+ bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
ViolationID::AccessesObjCMethodOrProperty,
Msg->getBeginLoc());
return true;
}
- bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) {
+ bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) override {
// Under the hood, @autorelease (potentially?) allocates memory and
// invokes ObjC methods. We don't currently have memory allocation as
// a "language construct" but we do have ObjC messaging, so diagnose that.
@@ -1161,7 +1160,7 @@ class Analyzer {
return true;
}
- bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) {
+ bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) override {
// Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped
// in a @try/@finally block. Diagnose this generically as "ObjC
// messaging".
@@ -1171,14 +1170,14 @@ class Analyzer {
return true;
}
- bool VisitSEHExceptStmt(SEHExceptStmt *Exc) {
+ bool VisitSEHExceptStmt(SEHExceptStmt *Exc) override {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Exc->getExceptLoc());
return true;
}
- bool VisitCallExpr(CallExpr *Call) {
+ bool VisitCallExpr(CallExpr *Call) override {
LLVM_DEBUG(llvm::dbgs()
<< "VisitCallExpr : "
<< Call->getBeginLoc().printToString(Outer.S.SourceMgr)
@@ -1202,7 +1201,7 @@ class Analyzer {
return true;
}
- bool VisitVarDecl(VarDecl *Var) {
+ bool VisitVarDecl(VarDecl *Var) override {
LLVM_DEBUG(llvm::dbgs()
<< "VisitVarDecl : "
<< Var->getBeginLoc().printToString(Outer.S.SourceMgr)
@@ -1220,7 +1219,7 @@ class Analyzer {
return true;
}
- bool VisitCXXNewExpr(CXXNewExpr *New) {
+ bool VisitCXXNewExpr(CXXNewExpr *New) override {
// RecursiveASTVisitor does not visit the implicit call to operator new.
if (FunctionDecl *FD = New->getOperatorNew()) {
CallableInfo CI(*FD, SpecialFuncType::OperatorNew);
@@ -1235,7 +1234,7 @@ class Analyzer {
return true;
}
- bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) {
+ bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) override {
// RecursiveASTVisitor does not visit the implicit call to operator
// delete.
if (FunctionDecl *FD = Delete->getOperatorDelete()) {
@@ -1248,7 +1247,7 @@ class Analyzer {
return true;
}
- bool VisitCXXConstructExpr(CXXConstructExpr *Construct) {
+ bool VisitCXXConstructExpr(CXXConstructExpr *Construct) override {
LLVM_DEBUG(llvm::dbgs() << "VisitCXXConstructExpr : "
<< Construct->getBeginLoc().printToString(
Outer.S.SourceMgr)
@@ -1263,27 +1262,28 @@ class Analyzer {
return true;
}
- bool TraverseStmt(Stmt *Statement) {
+ bool TraverseStmt(Stmt *Statement) override {
// If this statement is a `requires` clause from the top-level function
// being traversed, ignore it, since it's not generating runtime code.
// We skip the traversal of lambdas (beyond their captures, see
// TraverseLambdaExpr below), so just caching this from our constructor
// should suffice.
if (Statement != TrailingRequiresClause)
- return Base::TraverseStmt(Statement);
+ return DynamicRecursiveASTVisitor::TraverseStmt(Statement);
return true;
}
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+ bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
ViolationSite PrevVS = VSite;
if (Init->isAnyMemberInitializer())
VSite.setKind(ViolationSite::Kind::MemberInitializer);
- bool Result = Base::TraverseConstructorInitializer(Init);
+ bool Result =
+ DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
VSite = PrevVS;
return Result;
}
- bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+ bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
LLVM_DEBUG(llvm::dbgs()
<< "TraverseCXXDefaultArgExpr : "
<< E->getUsedLocation().printToString(Outer.S.SourceMgr)
@@ -1293,12 +1293,12 @@ class Analyzer {
if (VSite.kind() == ViolationSite::Kind::Default)
VSite = ViolationSite{E};
- bool Result = Base::TraverseCXXDefaultArgExpr(E);
+ bool Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(E);
VSite = PrevVS;
return Result;
}
- bool TraverseLambdaExpr(LambdaExpr *Lambda) {
+ bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
// We override this so as to be able to skip traversal of the lambda's
// body. We have to explicitly traverse the captures. Why not return
// false from shouldVisitLambdaBody()? Because we need to visit a lambda's
@@ -1311,13 +1311,13 @@ class Analyzer {
return true;
}
- bool TraverseBlockExpr(BlockExpr * /*unused*/) {
+ bool TraverseBlockExpr(BlockExpr * /*unused*/) override {
// As with lambdas, don't traverse the block's body.
// TODO: are the capture expressions (ctor call?) safe?
return true;
}
- bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
const ValueDecl *Val = E->getDecl();
if (const auto *Var = dyn_cast<VarDecl>(Val)) {
if (Var->getTLSKind() != VarDecl::TLS_None) {
@@ -1331,23 +1331,30 @@ class Analyzer {
return true;
}
- bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) {
+ bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
return TraverseStmt(Node->getResultExpr());
}
- bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
+ bool
+ TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
return true;
}
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) { return true; }
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
+ return true;
+ }
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) { return true; }
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override { return true; }
- bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) { return true; }
+ bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
+ return true;
+ }
- bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) { return true; }
+ bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { return true; }
// Skip concept requirements since they don't generate code.
- bool TraverseConceptRequirement(concepts::Requirement *R) { return true; }
+ bool TraverseConceptRequirement(concepts::Requirement *R) override {
+ return true;
+ }
};
};
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 298b7ad4f9e687..5c3d1a4c2c2fe3 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -15,8 +15,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
@@ -1304,9 +1304,7 @@ namespace {
/// and of all exported functions, and any functions that are referenced
/// from this AST. In other words, any functions that are reachable from
/// the entry points.
-class DiagnoseHLSLAvailability
- : public RecursiveASTVisitor<DiagnoseHLSLAvailability> {
-
+class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
Sema &SemaRef;
// Stack of functions to be scaned
@@ -1409,14 +1407,14 @@ class DiagnoseHLSLAvailability
void RunOnTranslationUnit(const TranslationUnitDecl *TU);
void RunOnFunction(const FunctionDecl *FD);
- bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(DRE->getDecl());
if (FD)
HandleFunctionOrMethodRef(FD, DRE);
return true;
}
- bool VisitMemberExpr(MemberExpr *ME) {
+ bool VisitMemberExpr(MemberExpr *ME) override {
FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(ME->getMemberDecl());
if (FD)
HandleFunctionOrMethodRef(FD, ME);
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index fe8bb99d2db040..19d56759246d3e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -20,8 +20,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
@@ -7684,7 +7684,7 @@ struct LoopIterationSpace final {
/// Scan an AST subtree, checking that no decls in the CollapsedLoopVarDecls
/// set are referenced. Used for verifying loop nest structure before
/// performing a loop collapse operation.
-class ForSubExprChecker final : public RecursiveASTVisitor<ForSubExprChecker> {
+class ForSubExprChecker : public DynamicRecursiveASTVisitor {
const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls;
VarDecl *ForbiddenVar = nullptr;
SourceRange ErrLoc;
@@ -7692,13 +7692,13 @@ class ForSubExprChecker final : public RecursiveASTVisitor<ForSubExprChecker> {
public:
explicit ForSubExprChecker(
const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls)
- : CollapsedLoopVarDecls(CollapsedLoopVarDecls) {}
-
- // We want to visit implicit code, i.e. synthetic initialisation statements
- // created during range-for lowering.
- bool shouldVisitImplicitCode() const { return true; }
+ : CollapsedLoopVarDecls(CollapsedLoopVarDecls) {
+ // We want to visit implicit code, i.e. synthetic initialisation statements
+ // created during range-for lowering.
+ ShouldVisitImplicitCode = true;
+ }
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
ValueDecl *VD = E->getDecl();
if (!isa<VarDecl, BindingDecl>(VD))
return true;
@@ -9581,7 +9581,7 @@ static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
/// Look for variables declared in the body parts of a for-loop nest. Used
/// for verifying loop nest structure before performing a loop collapse
/// operation.
-class ForVarDeclFinder final : public RecursiveASTVisitor<ForVarDeclFinder> {
+class ForVarDeclFinder : public DynamicRecursiveASTVisitor {
int NestingDepth = 0;
llvm::SmallPtrSetImpl<const Decl *> &VarDecls;
@@ -9589,21 +9589,21 @@ class ForVarDeclFinder final : public RecursiveASTVisitor<ForVarDeclFinder> {
explicit ForVarDeclFinder(llvm::SmallPtrSetImpl<const Decl *> &VD)
: VarDecls(VD) {}
- bool VisitForStmt(ForStmt *F) {
+ bool VisitForStmt(ForStmt *F) override {
++NestingDepth;
TraverseStmt(F->getBody());
--NestingDepth;
return false;
}
- bool VisitCXXForRangeStmt(CXXForRangeStmt *RF) {
+ bool VisitCXXForRangeStmt(CXXForRangeStmt *RF) override {
++NestingDepth;
TraverseStmt(RF->getBody());
--NestingDepth;
return false;
}
- bool VisitVarDecl(VarDecl *D) {
+ bool VisitVarDecl(VarDecl *D) override {
Decl *C = D->getCanonicalDecl();
if (NestingDepth > 0)
VarDecls.insert(C);
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 38ae6d8116c3bb..23720591fbde2f 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -17,11 +17,11 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/IgnoreExpr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TypeLoc.h"
@@ -3606,15 +3606,15 @@ namespace {
/// others. Pretend that all local typedefs are always referenced, to not warn
/// on this. This isn't necessary if f has internal linkage, or the typedef
/// is private.
-class LocalTypedefNameReferencer
- : public RecursiveASTVisitor<LocalTypedefNameReferencer> {
+class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor {
public:
LocalTypedefNameReferencer(Sema &S) : S(S) {}
- bool VisitRecordType(const RecordType *RT);
+ bool VisitRecordType(RecordType *RT) override;
+
private:
Sema &S;
};
-bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) {
+bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());
if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
R->isDependentType())
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4503e60cff8c2f..c9c35553a4f77f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -14,9 +14,9 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
@@ -2559,9 +2559,7 @@ namespace {
/// A class which looks for a use of a certain level of template
/// parameter.
-struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
- typedef RecursiveASTVisitor<DependencyChecker> super;
-
+struct DependencyChecker : DynamicRecursiveASTVisitor {
unsigned Depth;
// Whether we're looking for a use of a template parameter that makes the
@@ -2599,7 +2597,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
return false;
}
- bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) {
+ bool TraverseStmt(Stmt *S) override {
// Prune out non-type-dependent expressions if requested. This can
// sometimes result in us failing to find a template parameter reference
// (if a value-dependent expression creates a dependent type), but this
@@ -2607,51 +2605,51 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
if (auto *E = dyn_cast_or_null<Expr>(S))
if (IgnoreNonTypeDependent && !E->isTypeDependent())
return true;
- return super::TraverseStmt(S, Q);
+ return DynamicRecursiveASTVisitor::TraverseStmt(S);
}
- bool TraverseTypeLoc(TypeLoc TL) {
+ bool TraverseTypeLoc(TypeLoc TL) override {
if (IgnoreNonTypeDependent && !TL.isNull() &&
!TL.getType()->isDependentType())
return true;
- return super::TraverseTypeLoc(TL);
+ return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
}
- bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+ bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc());
}
- bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
+ bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
// For a best-effort search, keep looking until we find a location.
return IgnoreNonTypeDependent || !Matches(T->getDepth());
}
- bool TraverseTemplateName(TemplateName N) {
+ bool TraverseTemplateName(TemplateName N) override {
if (TemplateTemplateParmDecl *PD =
dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl()))
if (Matches(PD->getDepth()))
return false;
- return super::TraverseTemplateName(N);
+ return DynamicRecursiveASTVisitor::TraverseTemplateName(N);
}
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
if (NonTypeTemplateParmDecl *PD =
dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
if (Matches(PD->getDepth(), E->getExprLoc()))
return false;
- return super::VisitDeclRefExpr(E);
+ return DynamicRecursiveASTVisitor::VisitDeclRefExpr(E);
}
- bool VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+ bool VisitSubstTemplateTypeParmType(SubstTemplateTypeParmType *T) override {
return TraverseType(T->getReplacementType());
}
- bool
- VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
+ bool VisitSubstTemplateTypeParmPackType(
+ SubstTemplateTypeParmPackType *T) override {
return TraverseTemplateArgument(T->getArgumentPack());
}
- bool TraverseInjectedClassNameType(const InjectedClassNameType *T) {
+ bool TraverseInjectedClassNameType(InjectedClassNameType *T) override {
return TraverseType(T->getInjectedSpecializationType());
}
};
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index b45f30fed49a64..db2d53956a933d 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -20,10 +20,10 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -6451,8 +6451,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
}
namespace {
-struct MarkUsedTemplateParameterVisitor :
- RecursiveASTVisitor<MarkUsedTemplateParameterVisitor> {
+struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
llvm::SmallBitVector &Used;
unsigned Depth;
@@ -6460,23 +6459,22 @@ struct MarkUsedTemplateParameterVisitor :
unsigned Depth)
: Used(Used), Depth(Depth) { }
- bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
+ bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
if (T->getDepth() == Depth)
Used[T->getIndex()] = true;
return true;
}
- bool TraverseTemplateName(TemplateName Template) {
+ bool TraverseTemplateName(TemplateName Template) override {
if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
Template.getAsTemplateDecl()))
if (TTP->getDepth() == Depth)
Used[TTP->getIndex()] = true;
- RecursiveASTVisitor<MarkUsedTemplateParameterVisitor>::
- TraverseTemplateName(Template);
+ DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
return true;
}
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
if (NTTP->getDepth() == Depth)
Used[NTTP->getIndex()] = true;
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 698e0760d808fe..b3ff244ede987b 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -21,10 +21,10 @@
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/OperationKinds.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -637,8 +637,7 @@ struct ConvertConstructorToDeductionGuideTransform {
SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
const TemplateParameterList *TemplateParamsList,
ArrayRef<TemplateArgument> DeducedArgs) {
- struct TemplateParamsReferencedFinder
- : public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
+ struct TemplateParamsReferencedFinder : DynamicRecursiveASTVisitor {
const TemplateParameterList *TemplateParamList;
llvm::BitVector ReferencedTemplateParams;
@@ -647,22 +646,22 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
: TemplateParamList(TemplateParamList),
ReferencedTemplateParams(TemplateParamList->size()) {}
- bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
+ bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) override {
// We use the index and depth to retrieve the corresponding template
// parameter from the parameter list, which is more robost.
Mark(TTP->getDepth(), TTP->getIndex());
return true;
}
- bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
MarkAppeared(DRE->getFoundDecl());
return true;
}
- bool TraverseTemplateName(TemplateName Template) {
+ bool TraverseTemplateName(TemplateName Template) override {
if (auto *TD = Template.getAsTemplateDecl())
MarkAppeared(TD);
- return RecursiveASTVisitor::TraverseTemplateName(Template);
+ return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
}
void MarkAppeared(NamedDecl *ND) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index de0ec0128905ff..3331c53db8fa9c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -17,10 +17,10 @@
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/PrettyDeclStackTrace.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeVisitor.h"
@@ -121,9 +121,9 @@ getEnclosingTypeAliasTemplateDecl(Sema &SemaRef) {
bool isLambdaEnclosedByTypeAliasDecl(
const FunctionDecl *LambdaCallOperator,
const TypeAliasTemplateDecl *PrimaryTypeAliasDecl) {
- struct Visitor : RecursiveASTVisitor<Visitor> {
+ struct Visitor : DynamicRecursiveASTVisitor {
Visitor(const FunctionDecl *CallOperator) : CallOperator(CallOperator) {}
- bool VisitLambdaExpr(const LambdaExpr *LE) {
+ bool VisitLambdaExpr(LambdaExpr *LE) override {
// Return true to bail out of the traversal, implying the Decl contains
// the lambda.
return getPrimaryTemplateOfGenericLambda(LE->getCallOperator()) !=
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 151b328872bd75..2ea2a368dd24cf 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -8,14 +8,15 @@
// This file implements semantic analysis for C++0x variadic templates.
//===----------------------------------------------------------------------===/
-#include "clang/Sema/Sema.h"
#include "TypeLocBuilder.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -29,16 +30,12 @@ using namespace clang;
namespace {
/// A class that collects unexpanded parameter packs.
- class CollectUnexpandedParameterPacksVisitor :
- public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
- {
- typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
- inherited;
+class CollectUnexpandedParameterPacksVisitor
+ : public DynamicRecursiveASTVisitor {
+ SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
-
- bool InLambdaOrBlock = false;
- unsigned DepthLimit = (unsigned)-1;
+ bool InLambdaOrBlock = false;
+ unsigned DepthLimit = (unsigned)-1;
#ifndef NDEBUG
bool ContainsIntermediatePacks = false;
@@ -67,19 +64,19 @@ namespace {
public:
explicit CollectUnexpandedParameterPacksVisitor(
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
- : Unexpanded(Unexpanded) {}
-
- bool shouldWalkTypesOfTypeLocs() const { return false; }
+ : Unexpanded(Unexpanded) {
+ ShouldWalkTypesOfTypeLocs = false;
- // We need this so we can find e.g. attributes on lambdas.
- bool shouldVisitImplicitCode() const { return true; }
+ // We need this so we can find e.g. attributes on lambdas.
+ ShouldVisitImplicitCode = true;
+ }
//------------------------------------------------------------------------
// Recording occurrences of (unexpanded) parameter packs.
//------------------------------------------------------------------------
/// Record occurrences of template type parameter packs.
- bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+ bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
if (TL.getTypePtr()->isParameterPack())
addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
return true;
@@ -90,7 +87,7 @@ namespace {
/// them.
///
/// Ideally, this routine would never be used.
- bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
+ bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
if (T->isParameterPack())
addUnexpanded(T);
@@ -99,7 +96,7 @@ namespace {
/// Record occurrences of function and non-type template
/// parameter packs in an expression.
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
if (E->getDecl()->isParameterPack())
addUnexpanded(E->getDecl(), E->getLocation());
@@ -107,7 +104,7 @@ namespace {
}
/// Record occurrences of template template parameter packs.
- bool TraverseTemplateName(TemplateName Template) {
+ bool TraverseTemplateName(TemplateName Template) override {
if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
Template.getAsTemplateDecl())) {
if (TTP->isParameterPack())
@@ -119,12 +116,12 @@ namespace {
(bool)Template.getAsSubstTemplateTemplateParmPack();
#endif
- return inherited::TraverseTemplateName(Template);
+ return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
}
/// Suppress traversal into Objective-C container literal
/// elements that are pack expansions.
- bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
+ bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override {
if (!E->containsUnexpandedParameterPack())
return true;
@@ -144,118 +141,127 @@ namespace {
/// Suppress traversal into statements and expressions that
/// do not contain unexpanded parameter packs.
- bool TraverseStmt(Stmt *S) {
+ bool TraverseStmt(Stmt *S) override {
Expr *E = dyn_cast_or_null<Expr>(S);
if ((E && E->containsUnexpandedParameterPack()) || InLambdaOrBlock)
- return inherited::TraverseStmt(S);
+ return DynamicRecursiveASTVisitor::TraverseStmt(S);
return true;
}
/// Suppress traversal into types that do not contain
/// unexpanded parameter packs.
- bool TraverseType(QualType T) {
+ bool TraverseType(QualType T) override {
if ((!T.isNull() && T->containsUnexpandedParameterPack()) ||
InLambdaOrBlock)
- return inherited::TraverseType(T);
+ return DynamicRecursiveASTVisitor::TraverseType(T);
return true;
}
/// Suppress traversal into types with location information
/// that do not contain unexpanded parameter packs.
- bool TraverseTypeLoc(TypeLoc TL) {
+ bool TraverseTypeLoc(TypeLoc TL) override {
if ((!TL.getType().isNull() &&
TL.getType()->containsUnexpandedParameterPack()) ||
InLambdaOrBlock)
- return inherited::TraverseTypeLoc(TL);
+ return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
return true;
}
/// Suppress traversal of parameter packs.
- bool TraverseDecl(Decl *D) {
+ bool TraverseDecl(Decl *D) override {
// A function parameter pack is a pack expansion, so cannot contain
// an unexpanded parameter pack. Likewise for a template parameter
// pack that contains any references to other packs.
if (D && D->isParameterPack())
return true;
- return inherited::TraverseDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseDecl(D);
}
/// Suppress traversal of pack-expanded attributes.
- bool TraverseAttr(Attr *A) {
+ bool TraverseAttr(Attr *A) override {
if (A->isPackExpansion())
return true;
- return inherited::TraverseAttr(A);
+ return DynamicRecursiveASTVisitor::TraverseAttr(A);
}
/// Suppress traversal of pack expansion expressions and types.
///@{
- bool TraversePackExpansionType(PackExpansionType *T) { return true; }
- bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
- bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
- bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
- bool TraversePackIndexingExpr(PackIndexingExpr *E) {
- return inherited::TraverseStmt(E->getIndexExpr());
+ bool TraversePackExpansionType(PackExpansionType *T) override {
+ return true;
}
- bool TraversePackIndexingType(PackIndexingType *E) {
- return inherited::TraverseStmt(E->getIndexExpr());
+ bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) override {
+ return true;
}
- bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) {
- return inherited::TraverseStmt(TL.getIndexExpr());
+ bool TraversePackExpansionExpr(PackExpansionExpr *E) override {
+ return true;
+ }
+ bool TraverseCXXFoldExpr(CXXFoldExpr *E) override { return true; }
+ bool TraversePackIndexingExpr(PackIndexingExpr *E) override {
+ return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
+ }
+ bool TraversePackIndexingType(PackIndexingType *E) override {
+ return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
+ }
+ bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) override {
+ return DynamicRecursiveASTVisitor::TraverseStmt(TL.getIndexExpr());
}
///@}
/// Suppress traversal of using-declaration pack expansion.
- bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+ bool
+ TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) override {
if (D->isPackExpansion())
return true;
- return inherited::TraverseUnresolvedUsingValueDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingValueDecl(D);
}
/// Suppress traversal of using-declaration pack expansion.
- bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ bool TraverseUnresolvedUsingTypenameDecl(
+ UnresolvedUsingTypenameDecl *D) override {
if (D->isPackExpansion())
return true;
- return inherited::TraverseUnresolvedUsingTypenameDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingTypenameDecl(D);
}
/// Suppress traversal of template argument pack expansions.
- bool TraverseTemplateArgument(const TemplateArgument &Arg) {
+ bool TraverseTemplateArgument(const TemplateArgument &Arg) override {
if (Arg.isPackExpansion())
return true;
- return inherited::TraverseTemplateArgument(Arg);
+ return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg);
}
/// Suppress traversal of template argument pack expansions.
- bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
+ bool
+ TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override {
if (ArgLoc.getArgument().isPackExpansion())
return true;
- return inherited::TraverseTemplateArgumentLoc(ArgLoc);
+ return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(ArgLoc);
}
/// Suppress traversal of base specifier pack expansions.
- bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
+ bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) override {
if (Base.isPackExpansion())
return true;
- return inherited::TraverseCXXBaseSpecifier(Base);
+ return DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(Base);
}
/// Suppress traversal of mem-initializer pack expansions.
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+ bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
if (Init->isPackExpansion())
return true;
- return inherited::TraverseConstructorInitializer(Init);
+ return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init);
}
/// Note whether we're traversing a lambda containing an unexpanded
@@ -263,7 +269,7 @@ namespace {
/// including all the places where we normally wouldn't look. Within a
/// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
/// outside an expression.
- bool TraverseLambdaExpr(LambdaExpr *Lambda) {
+ bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
// The ContainsUnexpandedParameterPack bit on a lambda is always correct,
// even if it's contained within another lambda.
if (!Lambda->containsUnexpandedParameterPack())
@@ -275,57 +281,58 @@ namespace {
if (auto *TPL = Lambda->getTemplateParameterList())
DepthLimit = TPL->getDepth();
- inherited::TraverseLambdaExpr(Lambda);
+ DynamicRecursiveASTVisitor::TraverseLambdaExpr(Lambda);
DepthLimit = OldDepthLimit;
return true;
}
/// Analogously for blocks.
- bool TraverseBlockExpr(BlockExpr *Block) {
+ bool TraverseBlockExpr(BlockExpr *Block) override {
if (!Block->containsUnexpandedParameterPack())
return true;
SaveAndRestore _(InLambdaOrBlock, true);
- inherited::TraverseBlockExpr(Block);
+ DynamicRecursiveASTVisitor::TraverseBlockExpr(Block);
return true;
}
/// Suppress traversal within pack expansions in lambda captures.
bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
- Expr *Init) {
+ Expr *Init) override {
if (C->isPackExpansion())
return true;
- return inherited::TraverseLambdaCapture(Lambda, C, Init);
+ return DynamicRecursiveASTVisitor::TraverseLambdaCapture(Lambda, C, Init);
}
#ifndef NDEBUG
- bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) {
+ bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) override {
ContainsIntermediatePacks = true;
return true;
}
bool TraverseSubstNonTypeTemplateParmPackExpr(
- SubstNonTypeTemplateParmPackExpr *) {
+ SubstNonTypeTemplateParmPackExpr *) override {
ContainsIntermediatePacks = true;
return true;
}
- bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *) {
+ bool VisitSubstTemplateTypeParmPackType(
+ SubstTemplateTypeParmPackType *) override {
ContainsIntermediatePacks = true;
return true;
}
- bool
- VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc) {
+ bool VisitSubstTemplateTypeParmPackTypeLoc(
+ SubstTemplateTypeParmPackTypeLoc) override {
ContainsIntermediatePacks = true;
return true;
}
bool containsIntermediatePacks() const { return ContainsIntermediatePacks; }
#endif
- };
+};
}
/// Determine whether it's possible for an unexpanded parameter pack to
>From 2074e8a732fbe04365d82ec8fcbff5635228be2d Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Mon, 1 Jul 2024 21:29:40 +0200
Subject: [PATCH 2/5] [Clang] [NFC] Migrate static analyser visitors
---
clang/include/clang/Analysis/CallGraph.h | 15 ++---
.../clang/Analysis/FlowSensitive/ASTOps.h | 31 ++++++-----
clang/lib/Analysis/CallGraph.cpp | 3 +
clang/lib/Analysis/CalledOnceCheck.cpp | 8 +--
clang/lib/Analysis/FlowSensitive/ASTOps.cpp | 19 +++----
.../FlowSensitive/DataflowEnvironment.cpp | 14 ++---
clang/lib/Analysis/ReachableCode.cpp | 14 +++--
clang/lib/Analysis/UnsafeBufferUsage.cpp | 55 +++++++++----------
.../Checkers/CastToStructChecker.cpp | 8 +--
.../Checkers/DeadStoresChecker.cpp | 16 +++---
.../Checkers/DynamicTypePropagation.cpp | 6 +-
.../Checkers/IdenticalExprChecker.cpp | 17 +++---
.../Checkers/LocalizationChecker.cpp | 28 +++++-----
.../Checkers/ObjCMissingSuperCallChecker.cpp | 10 ++--
.../Checkers/PaddingChecker.cpp | 17 +++---
.../WebKit/RawPtrRefLocalVarsChecker.cpp | 52 ++++++++----------
.../WebKit/RawPtrRefMemberChecker.cpp | 11 ++--
.../WebKit/RefCntblBaseVirtualDtorChecker.cpp | 11 ++--
.../WebKit/UncountedCallArgsChecker.cpp | 21 +++----
.../WebKit/UncountedLambdaCapturesChecker.cpp | 11 ++--
.../StaticAnalyzer/Core/BugSuppression.cpp | 8 +--
.../Frontend/AnalysisConsumer.cpp | 20 +++----
22 files changed, 190 insertions(+), 205 deletions(-)
diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h
index 78f8d115550178..c11d163f8fe20d 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -18,7 +18,8 @@
#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
#include "clang/AST/Decl.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
@@ -39,7 +40,7 @@ class Stmt;
/// The call graph extends itself with the given declarations by implementing
/// the recursive AST visitor, which constructs the graph by visiting the given
/// declarations.
-class CallGraph : public RecursiveASTVisitor<CallGraph> {
+class CallGraph : public DynamicRecursiveASTVisitor {
friend class CallGraphNode;
using FunctionMapTy =
@@ -109,7 +110,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
/// Part of recursive declaration visitation. We recursively visit all the
/// declarations to collect the root functions.
- bool VisitFunctionDecl(FunctionDecl *FD) {
+ bool VisitFunctionDecl(FunctionDecl *FD) override {
// We skip function template definitions, as their semantics is
// only determined when they are instantiated.
if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
@@ -124,7 +125,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
}
/// Part of recursive declaration visitation.
- bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+ bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override {
if (includeInGraph(MD)) {
addNodesForBlocks(MD);
addNodeForDecl(MD, true);
@@ -133,11 +134,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
}
// We are only collecting the declarations, so do not step into the bodies.
- bool TraverseStmt(Stmt *S) { return true; }
-
- bool shouldWalkTypesOfTypeLocs() const { return false; }
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return true; }
+ bool TraverseStmt(Stmt *S) override { return true; }
private:
/// Add the given declaration to the call graph.
diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index ec4d041254877f..6294c810626a70 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -14,8 +14,9 @@
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "llvm/ADT/DenseSet.h"
@@ -88,14 +89,14 @@ class RecordInitListHelper {
/// the function to analyze. Don't call `TraverseDecl()` on the function itself;
/// this won't work as `TraverseDecl()` contains code to avoid traversing nested
/// functions.
-template <class Derived>
-class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
+class AnalysisASTVisitor : public DynamicRecursiveASTVisitor {
public:
- bool shouldVisitImplicitCode() { return true; }
-
- bool shouldVisitLambdaBody() const { return false; }
+ AnalysisASTVisitor() {
+ ShouldVisitImplicitCode = true;
+ ShouldVisitLambdaBody = false;
+ }
- bool TraverseDecl(Decl *D) {
+ bool TraverseDecl(Decl *D) override {
// Don't traverse nested record or function declarations.
// - We won't be analyzing code contained in these anyway
// - We don't model fields that are used only in these nested declaration,
@@ -104,30 +105,30 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D))
return true;
- return RecursiveASTVisitor<Derived>::TraverseDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseDecl(D);
}
// Don't traverse expressions in unevaluated contexts, as we don't model
// fields that are only used in these.
// Note: The operand of the `noexcept` operator is an unevaluated operand, but
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
- bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) {
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; }
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; }
+ bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override {
if (TIE->isPotentiallyEvaluated())
- return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE);
+ return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE);
return true;
}
- bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
+ bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) override {
return true;
}
- bool TraverseBindingDecl(BindingDecl *BD) {
+ bool TraverseBindingDecl(BindingDecl *BD) override {
// `RecursiveASTVisitor` doesn't traverse holding variables for
// `BindingDecl`s by itself, so we need to tell it to.
if (VarDecl *HoldingVar = BD->getHoldingVar())
TraverseDecl(HoldingVar);
- return RecursiveASTVisitor<Derived>::TraverseBindingDecl(BD);
+ return DynamicRecursiveASTVisitor::TraverseBindingDecl(BD);
}
};
diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp
index f892980ed31386..d9da74d40efff6 100644
--- a/clang/lib/Analysis/CallGraph.cpp
+++ b/clang/lib/Analysis/CallGraph.cpp
@@ -147,6 +147,9 @@ void CallGraph::addNodesForBlocks(DeclContext *D) {
}
CallGraph::CallGraph() {
+ ShouldWalkTypesOfTypeLocs = false;
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = true;
Root = getOrInsertNode(nullptr);
}
diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index 30cbd257b65e8f..1554eab1860c15 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -11,11 +11,11 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
@@ -426,7 +426,7 @@ const Expr *getCondition(const Stmt *S) {
/// of the AST will end up in the results.
/// Results might have duplicate names, if this is a problem, convert to
/// string sets afterwards.
-class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
+class NamesCollector : public DynamicRecursiveASTVisitor {
public:
static constexpr unsigned EXPECTED_NUMBER_OF_NAMES = 5;
using NameCollection =
@@ -438,12 +438,12 @@ class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
return Impl.Result;
}
- bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
Result.push_back(E->getDecl()->getName());
return true;
}
- bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
+ bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) override {
llvm::StringRef Name;
if (E->isImplicitProperty()) {
diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
index fdba139628d8ff..9e7821bfc1e89e 100644
--- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
+++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
@@ -198,13 +198,12 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
return nullptr;
}
-class ReferencedDeclsVisitor
- : public AnalysisASTVisitor<ReferencedDeclsVisitor> {
+class ReferencedDeclsVisitor : public AnalysisASTVisitor {
public:
ReferencedDeclsVisitor(ReferencedDecls &Referenced)
: Referenced(Referenced) {}
- void TraverseConstructorInits(const CXXConstructorDecl *Ctor) {
+ void traverseConstructorInits(const CXXConstructorDecl *Ctor) {
for (const CXXCtorInitializer *Init : Ctor->inits()) {
if (Init->isMemberInitializer()) {
Referenced.Fields.insert(Init->getMember());
@@ -225,21 +224,21 @@ class ReferencedDeclsVisitor
}
}
- bool VisitDecl(Decl *D) {
+ bool VisitDecl(Decl *D) override {
insertIfGlobal(*D, Referenced.Globals);
insertIfLocal(*D, Referenced.Locals);
insertIfFunction(*D, Referenced.Functions);
return true;
}
- bool VisitDeclRefExpr(DeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) override {
insertIfGlobal(*E->getDecl(), Referenced.Globals);
insertIfLocal(*E->getDecl(), Referenced.Locals);
insertIfFunction(*E->getDecl(), Referenced.Functions);
return true;
}
- bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) {
+ bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) override {
// If this is a method that returns a member variable but does nothing else,
// model the field of the return value.
if (MemberExpr *E = getMemberForAccessor(*C))
@@ -248,7 +247,7 @@ class ReferencedDeclsVisitor
return true;
}
- bool VisitMemberExpr(MemberExpr *E) {
+ bool VisitMemberExpr(MemberExpr *E) override {
// FIXME: should we be using `E->getFoundDecl()`?
const ValueDecl *VD = E->getMemberDecl();
insertIfGlobal(*VD, Referenced.Globals);
@@ -258,14 +257,14 @@ class ReferencedDeclsVisitor
return true;
}
- bool VisitInitListExpr(InitListExpr *InitList) {
+ bool VisitInitListExpr(InitListExpr *InitList) override {
if (InitList->getType()->isRecordType())
for (const auto *FD : getFieldsForInitListExpr(InitList))
Referenced.Fields.insert(FD);
return true;
}
- bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) {
+ bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) override {
if (ParenInitList->getType()->isRecordType())
for (const auto *FD : getFieldsForInitListExpr(ParenInitList))
Referenced.Fields.insert(FD);
@@ -281,7 +280,7 @@ ReferencedDecls getReferencedDecls(const FunctionDecl &FD) {
ReferencedDeclsVisitor Visitor(Result);
Visitor.TraverseStmt(FD.getBody());
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&FD))
- Visitor.TraverseConstructorInits(CtorDecl);
+ Visitor.traverseConstructorInits(CtorDecl);
return Result;
}
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index e1f68e493f3553..c5c6e900b79766 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -298,7 +298,7 @@ namespace {
// Visitor that builds a map from record prvalues to result objects.
// For each result object that it encounters, it propagates the storage location
// of the result object to all record prvalues that can initialize it.
-class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
+class ResultObjectVisitor : public AnalysisASTVisitor {
public:
// `ResultObjectMap` will be filled with a map from record prvalues to result
// object. If this visitor will traverse a function that returns a record by
@@ -315,7 +315,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// called by `RecursiveASTVisitor`; it should be called manually if we are
// analyzing a constructor. `ThisPointeeLoc` is the storage location that
// `this` points to.
- void TraverseConstructorInits(const CXXConstructorDecl *Ctor,
+ void traverseConstructorInits(const CXXConstructorDecl *Ctor,
RecordStorageLocation *ThisPointeeLoc) {
assert(ThisPointeeLoc != nullptr);
for (const CXXCtorInitializer *Init : Ctor->inits()) {
@@ -339,7 +339,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
}
}
- bool VisitVarDecl(VarDecl *VD) {
+ bool VisitVarDecl(VarDecl *VD) override {
if (VD->getType()->isRecordType() && VD->hasInit())
PropagateResultObject(
VD->getInit(),
@@ -347,7 +347,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
return true;
}
- bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) {
+ bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) override {
if (MTE->getType()->isRecordType())
PropagateResultObject(
MTE->getSubExpr(),
@@ -355,7 +355,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
return true;
}
- bool VisitReturnStmt(ReturnStmt *Return) {
+ bool VisitReturnStmt(ReturnStmt *Return) override {
Expr *RetValue = Return->getRetValue();
if (RetValue != nullptr && RetValue->getType()->isRecordType() &&
RetValue->isPRValue())
@@ -363,7 +363,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
return true;
}
- bool VisitExpr(Expr *E) {
+ bool VisitExpr(Expr *E) override {
// Clang's AST can have record-type prvalues without a result object -- for
// example as full-expressions contained in a compound statement or as
// arguments of call expressions. We notice this if we get here and a
@@ -1211,7 +1211,7 @@ Environment::PrValueToResultObject Environment::buildResultObjectMap(
ResultObjectVisitor Visitor(Map, LocForRecordReturnVal, *DACtx);
if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FuncDecl))
- Visitor.TraverseConstructorInits(Ctor, ThisPointeeLoc);
+ Visitor.traverseConstructorInits(Ctor, ThisPointeeLoc);
return Map;
}
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index acbe1470b38991..dd81c8e0a3d543 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -13,11 +13,11 @@
#include "clang/Analysis/Analyses/ReachableCode.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
@@ -476,17 +476,19 @@ static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) {
}
if (!CoroStmt)
return false;
- struct Checker : RecursiveASTVisitor<Checker> {
+ struct Checker : DynamicRecursiveASTVisitor {
const Stmt *DeadStmt;
bool CoroutineSubStmt = false;
- Checker(const Stmt *S) : DeadStmt(S) {}
- bool VisitStmt(const Stmt *S) {
+ Checker(const Stmt *S) : DeadStmt(S) {
+ // Statements captured in the CFG can be implicit.
+ ShouldVisitImplicitCode = true;
+ }
+
+ bool VisitStmt(Stmt *S) override {
if (S == DeadStmt)
CoroutineSubStmt = true;
return true;
}
- // Statements captured in the CFG can be implicit.
- bool shouldVisitImplicitCode() const { return true; }
};
Checker checker(DeadStmt);
checker.TraverseStmt(const_cast<Stmt *>(CoroStmt));
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 2c68409b846bc8..248a70b0155f62 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -9,9 +9,9 @@
#include "clang/Analysis/Analyses/UnsafeBufferUsage.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/FormatString.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
@@ -82,11 +82,8 @@ static std::string getDREAncestorString(const DeclRefExpr *DRE,
namespace clang::ast_matchers {
// A `RecursiveASTVisitor` that traverses all descendants of a given node "n"
// except for those belonging to a different callable of "n".
-class MatchDescendantVisitor
- : public RecursiveASTVisitor<MatchDescendantVisitor> {
+class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
public:
- typedef RecursiveASTVisitor<MatchDescendantVisitor> VisitorBase;
-
// Creates an AST visitor that matches `Matcher` on all
// descendants of a given node "n" except for the ones
// belonging to a different callable of "n".
@@ -96,7 +93,10 @@ class MatchDescendantVisitor
internal::ASTMatchFinder::BindKind Bind,
const bool ignoreUnevaluatedContext)
: Matcher(Matcher), Finder(Finder), Builder(Builder), Bind(Bind),
- Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) {}
+ Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) {
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false; // TODO: let's ignore implicit code for now
+ }
// Returns true if a match is found in a subtree of `DynNode`, which belongs
// to the same callable of `DynNode`.
@@ -117,7 +117,7 @@ class MatchDescendantVisitor
// For the matchers so far used in safe buffers, we only need to match
// `Stmt`s. To override more as needed.
- bool TraverseDecl(Decl *Node) {
+ bool TraverseDecl(Decl *Node) override {
if (!Node)
return true;
if (!match(*Node))
@@ -126,69 +126,64 @@ class MatchDescendantVisitor
if (isa<FunctionDecl, BlockDecl, ObjCMethodDecl>(Node))
return true;
// Traverse descendants
- return VisitorBase::TraverseDecl(Node);
+ return DynamicRecursiveASTVisitor::TraverseDecl(Node);
}
- bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) {
+ bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
// These are unevaluated, except the result expression.
if (ignoreUnevaluatedContext)
return TraverseStmt(Node->getResultExpr());
- return VisitorBase::TraverseGenericSelectionExpr(Node);
+ return DynamicRecursiveASTVisitor::TraverseGenericSelectionExpr(Node);
}
- bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
+ bool
+ TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return VisitorBase::TraverseUnaryExprOrTypeTraitExpr(Node);
+ return DynamicRecursiveASTVisitor::TraverseUnaryExprOrTypeTraitExpr(Node);
}
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) {
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return VisitorBase::TraverseTypeOfExprTypeLoc(Node);
+ return DynamicRecursiveASTVisitor::TraverseTypeOfExprTypeLoc(Node);
}
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) {
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return VisitorBase::TraverseDecltypeTypeLoc(Node);
+ return DynamicRecursiveASTVisitor::TraverseDecltypeTypeLoc(Node);
}
- bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) {
+ bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return VisitorBase::TraverseCXXNoexceptExpr(Node);
+ return DynamicRecursiveASTVisitor::TraverseCXXNoexceptExpr(Node);
}
- bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) {
+ bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return VisitorBase::TraverseCXXTypeidExpr(Node);
+ return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(Node);
}
- bool TraverseCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
+ bool TraverseCXXDefaultInitExpr(CXXDefaultInitExpr *Node) override {
if (!TraverseStmt(Node->getExpr()))
return false;
- return VisitorBase::TraverseCXXDefaultInitExpr(Node);
+ return DynamicRecursiveASTVisitor::TraverseCXXDefaultInitExpr(Node);
}
- bool TraverseStmt(Stmt *Node, DataRecursionQueue *Queue = nullptr) {
+ bool TraverseStmt(Stmt *Node) override {
if (!Node)
return true;
if (!match(*Node))
return false;
- return VisitorBase::TraverseStmt(Node);
- }
-
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const {
- // TODO: let's ignore implicit code for now
- return false;
+ return DynamicRecursiveASTVisitor::TraverseStmt(Node);
}
private:
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index e674ec43bcd9df..3e87ad09b05ee2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -23,7 +23,7 @@ using namespace clang;
using namespace ento;
namespace {
-class CastToStructVisitor : public RecursiveASTVisitor<CastToStructVisitor> {
+class CastToStructVisitor : public DynamicRecursiveASTVisitor {
BugReporter &BR;
const CheckerBase *Checker;
AnalysisDeclContext *AC;
@@ -32,11 +32,11 @@ class CastToStructVisitor : public RecursiveASTVisitor<CastToStructVisitor> {
explicit CastToStructVisitor(BugReporter &B, const CheckerBase *Checker,
AnalysisDeclContext *A)
: BR(B), Checker(Checker), AC(A) {}
- bool VisitCastExpr(const CastExpr *CE);
+ bool VisitCastExpr(CastExpr *CE) override;
};
}
-bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) {
+bool CastToStructVisitor::VisitCastExpr(CastExpr *CE) {
const Expr *E = CE->getSubExpr();
ASTContext &Ctx = AC->getASTContext();
QualType OrigTy = Ctx.getCanonicalType(E->getType());
diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 86f446fc411ca2..4e3919ef016674 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -13,8 +13,8 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
@@ -32,27 +32,27 @@ using namespace ento;
namespace {
/// A simple visitor to record what VarDecls occur in EH-handling code.
-class EHCodeVisitor : public RecursiveASTVisitor<EHCodeVisitor> {
+class EHCodeVisitor : public DynamicRecursiveASTVisitor {
public:
bool inEH;
llvm::DenseSet<const VarDecl *> &S;
- bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+ bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) override {
SaveAndRestore inFinally(inEH, true);
- return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtFinallyStmt(S);
+ return DynamicRecursiveASTVisitor::TraverseObjCAtFinallyStmt(S);
}
- bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+ bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) override {
SaveAndRestore inCatch(inEH, true);
- return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtCatchStmt(S);
+ return DynamicRecursiveASTVisitor::TraverseObjCAtCatchStmt(S);
}
- bool TraverseCXXCatchStmt(CXXCatchStmt *S) {
+ bool TraverseCXXCatchStmt(CXXCatchStmt *S) override {
SaveAndRestore inCatch(inEH, true);
return TraverseStmt(S->getHandlerBlock());
}
- bool VisitDeclRefExpr(DeclRefExpr *DR) {
+ bool VisitDeclRefExpr(DeclRefExpr *DR) override {
if (inEH)
if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
S.insert(D);
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 034774a252b118..a0bf776b11f531 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -711,10 +711,10 @@ static bool isObjCTypeParamDependent(QualType Type) {
// an Objective-C type can only be dependent on a type parameter when the type
// parameter structurally present in the type itself.
class IsObjCTypeParamDependentTypeVisitor
- : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> {
+ : public DynamicRecursiveASTVisitor {
public:
IsObjCTypeParamDependentTypeVisitor() = default;
- bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) {
+ bool VisitObjCTypeParamType(ObjCTypeParamType *Type) override {
if (isa<ObjCTypeParamDecl>(Type->getDecl())) {
Result = true;
return false;
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index 7ac34ef8164e4c..45642483dd4578 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -15,8 +15,8 @@
///
//===----------------------------------------------------------------------===//
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -32,8 +32,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
//===----------------------------------------------------------------------===//
namespace {
-class FindIdenticalExprVisitor
- : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
+class FindIdenticalExprVisitor : public DynamicRecursiveASTVisitor {
BugReporter &BR;
const CheckerBase *Checker;
AnalysisDeclContext *AC;
@@ -45,9 +44,9 @@ class FindIdenticalExprVisitor
// FindIdenticalExprVisitor only visits nodes
// that are binary operators, if statements or
// conditional operators.
- bool VisitBinaryOperator(const BinaryOperator *B);
- bool VisitIfStmt(const IfStmt *I);
- bool VisitConditionalOperator(const ConditionalOperator *C);
+ bool VisitBinaryOperator(BinaryOperator *B) override;
+ bool VisitIfStmt(IfStmt *I) override;
+ bool VisitConditionalOperator(ConditionalOperator *C) override;
private:
void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise,
@@ -103,7 +102,7 @@ void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B,
}
}
-bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
+bool FindIdenticalExprVisitor::VisitIfStmt(IfStmt *I) {
const Stmt *Stmt1 = I->getThen();
const Stmt *Stmt2 = I->getElse();
@@ -178,7 +177,7 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
return true;
}
-bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) {
+bool FindIdenticalExprVisitor::VisitBinaryOperator(BinaryOperator *B) {
BinaryOperator::Opcode Op = B->getOpcode();
if (BinaryOperator::isBitwiseOp(Op))
@@ -268,7 +267,7 @@ void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) {
}
bool FindIdenticalExprVisitor::VisitConditionalOperator(
- const ConditionalOperator *C) {
+ ConditionalOperator *C) {
// Check if expressions in conditional expression are identical
// from a symbolic point of view.
diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index f524c4c067c8c3..342ff7fd6d817a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -17,7 +17,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
@@ -1191,7 +1191,7 @@ namespace {
class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
// A helper class, which walks the AST
- class MethodCrawler : public RecursiveASTVisitor<MethodCrawler> {
+ class MethodCrawler : public DynamicRecursiveASTVisitor {
BugReporter &BR;
const CheckerBase *Checker;
AnalysisDeclContext *AC;
@@ -1209,13 +1209,13 @@ class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
AnalysisDeclContext *InAC)
: BR(InBR), Checker(Checker), AC(InAC) {}
- bool VisitIfStmt(const IfStmt *I);
+ bool VisitIfStmt(IfStmt *I) override;
bool EndVisitIfStmt(IfStmt *I);
- bool TraverseIfStmt(IfStmt *x);
- bool VisitConditionalOperator(const ConditionalOperator *C);
- bool TraverseConditionalOperator(ConditionalOperator *C);
- bool VisitCallExpr(const CallExpr *CE);
- bool VisitObjCMessageExpr(const ObjCMessageExpr *ME);
+ bool TraverseIfStmt(IfStmt *x) override;
+ bool VisitConditionalOperator(ConditionalOperator *C) override;
+ bool TraverseConditionalOperator(ConditionalOperator *C) override;
+ bool VisitCallExpr(CallExpr *CE) override;
+ bool VisitObjCMessageExpr(ObjCMessageExpr *ME) override;
private:
void reportPluralMisuseError(const Stmt *S) const;
@@ -1274,7 +1274,7 @@ bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
// has been shown to almost always be a function that returns a localized
// string. Raise a diagnostic when this is in a statement that matches
// the condition.
-bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) {
+bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(CallExpr *CE) {
if (InMatchingStatement) {
if (const FunctionDecl *FD = CE->getDirectCallee()) {
std::string NormalizedName =
@@ -1296,7 +1296,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) {
// diagnostic when this is in a statement that matches
// the condition.
bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
- const ObjCMessageExpr *ME) {
+ ObjCMessageExpr *ME) {
const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
if (!OD)
return true;
@@ -1314,7 +1314,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
/// Override TraverseIfStmt so we know when we are done traversing an IfStmt
bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(IfStmt *I) {
- RecursiveASTVisitor<MethodCrawler>::TraverseIfStmt(I);
+ DynamicRecursiveASTVisitor::TraverseIfStmt(I);
return EndVisitIfStmt(I);
}
@@ -1333,7 +1333,7 @@ bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(IfStmt *I) {
return true;
}
-bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) {
+bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(IfStmt *I) {
const Expr *Condition = I->getCond();
if (!Condition)
return true;
@@ -1352,7 +1352,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) {
// Preliminary support for conditional operators.
bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
ConditionalOperator *C) {
- RecursiveASTVisitor<MethodCrawler>::TraverseConditionalOperator(C);
+ DynamicRecursiveASTVisitor::TraverseConditionalOperator(C);
MatchingStatements.pop_back();
if (!MatchingStatements.empty()) {
if (MatchingStatements.back() != nullptr)
@@ -1366,7 +1366,7 @@ bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
}
bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
- const ConditionalOperator *C) {
+ ConditionalOperator *C) {
const Expr *Condition = C->getCond()->IgnoreParenImpCasts();
if (isCheckingPlurality(Condition)) {
MatchingStatements.push_back(C);
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index 03dab4f7ada7ae..495502ecaed946 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -12,12 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/Analysis/PathDiagnostic.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
@@ -38,11 +38,11 @@ struct SelectorDescriptor {
// FindSuperCallVisitor - Identify specific calls to the superclass.
//===----------------------------------------------------------------------===//
-class FindSuperCallVisitor : public RecursiveASTVisitor<FindSuperCallVisitor> {
+class FindSuperCallVisitor : public DynamicRecursiveASTVisitor {
public:
explicit FindSuperCallVisitor(Selector S) : DoesCallSuper(false), Sel(S) {}
- bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
if (E->getSelector() == Sel)
if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance)
DoesCallSuper = true;
diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 4f35d9442ad988..bb882c9d199cea 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -45,16 +45,17 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const PaddingChecker *Checker;
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return true; }
- explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {}
- bool VisitRecordDecl(const RecordDecl *RD) {
+ explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = true;
+ }
+ bool VisitRecordDecl(RecordDecl *RD) override {
Checker->visitRecord(RD);
return true;
}
- bool VisitVarDecl(const VarDecl *VD) {
+ bool VisitVarDecl(VarDecl *VD) override {
Checker->visitVariable(VD);
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
index 06f8f43cee8151..d38f4693845bbf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
@@ -12,8 +12,8 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/ParentMapContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -48,17 +48,14 @@ bool isRefcountedStringsHack(const VarDecl *V) {
return false;
}
-struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> {
- using Base = RecursiveASTVisitor<GuardianVisitor>;
-
+struct GuardianVisitor : DynamicRecursiveASTVisitor {
const VarDecl *Guardian{nullptr};
-public:
explicit GuardianVisitor(const VarDecl *Guardian) : Guardian(Guardian) {
assert(Guardian);
}
- bool VisitBinaryOperator(const BinaryOperator *BO) {
+ bool VisitBinaryOperator(BinaryOperator *BO) override {
if (BO->isAssignmentOp()) {
if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) {
if (VarRef->getDecl() == Guardian)
@@ -68,7 +65,7 @@ struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> {
return true;
}
- bool VisitCXXConstructExpr(const CXXConstructExpr *CE) {
+ bool VisitCXXConstructExpr(CXXConstructExpr *CE) override {
if (auto *Ctor = CE->getConstructor()) {
if (Ctor->isMoveConstructor() && CE->getNumArgs() == 1) {
auto *Arg = CE->getArg(0)->IgnoreParenCasts();
@@ -81,7 +78,7 @@ struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> {
return true;
}
- bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE) {
+ bool VisitCXXMemberCallExpr(CXXMemberCallExpr *MCE) override {
auto MethodName = safeGetName(MCE->getMethodDecl());
if (MethodName == "swap" || MethodName == "leakRef" ||
MethodName == "releaseNonNull") {
@@ -94,7 +91,7 @@ struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> {
return true;
}
- bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) {
+ bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *OCE) override {
if (OCE->isAssignmentOp()) {
assert(OCE->getNumArgs() == 2);
auto *ThisArg = OCE->getArg(0)->IgnoreParenCasts();
@@ -184,37 +181,34 @@ class RawPtrRefLocalVarsChecker
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const RawPtrRefLocalVarsChecker *Checker;
Decl *DeclWithIssue{nullptr};
TrivialFunctionAnalysis TFA;
- using Base = RecursiveASTVisitor<LocalVisitor>;
-
explicit LocalVisitor(const RawPtrRefLocalVarsChecker *Checker)
: Checker(Checker) {
assert(Checker);
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
}
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
-
- bool TraverseDecl(Decl *D) {
+ bool TraverseDecl(Decl *D) override {
llvm::SaveAndRestore SavedDecl(DeclWithIssue);
if (D && (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)))
DeclWithIssue = D;
- return Base::TraverseDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseDecl(D);
}
- bool VisitVarDecl(VarDecl *V) {
+ bool VisitVarDecl(VarDecl *V) override {
auto *Init = V->getInit();
if (Init && V->isLocalVarDecl())
Checker->visitVarDecl(V, Init, DeclWithIssue);
return true;
}
- bool VisitBinaryOperator(const BinaryOperator *BO) {
+ bool VisitBinaryOperator(BinaryOperator *BO) override {
if (BO->isAssignmentOp()) {
if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) {
if (auto *V = dyn_cast<VarDecl>(VarRef->getDecl()))
@@ -224,33 +218,33 @@ class RawPtrRefLocalVarsChecker
return true;
}
- bool TraverseIfStmt(IfStmt *IS) {
+ bool TraverseIfStmt(IfStmt *IS) override {
if (!TFA.isTrivial(IS))
- return Base::TraverseIfStmt(IS);
+ return DynamicRecursiveASTVisitor::TraverseIfStmt(IS);
return true;
}
- bool TraverseForStmt(ForStmt *FS) {
+ bool TraverseForStmt(ForStmt *FS) override {
if (!TFA.isTrivial(FS))
- return Base::TraverseForStmt(FS);
+ return DynamicRecursiveASTVisitor::TraverseForStmt(FS);
return true;
}
- bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) {
+ bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) override {
if (!TFA.isTrivial(FRS))
- return Base::TraverseCXXForRangeStmt(FRS);
+ return DynamicRecursiveASTVisitor::TraverseCXXForRangeStmt(FRS);
return true;
}
- bool TraverseWhileStmt(WhileStmt *WS) {
+ bool TraverseWhileStmt(WhileStmt *WS) override {
if (!TFA.isTrivial(WS))
- return Base::TraverseWhileStmt(WS);
+ return DynamicRecursiveASTVisitor::TraverseWhileStmt(WS);
return true;
}
- bool TraverseCompoundStmt(CompoundStmt *CS) {
+ bool TraverseCompoundStmt(CompoundStmt *CS) override {
if (!TFA.isTrivial(CS))
- return Base::TraverseCompoundStmt(CS);
+ return DynamicRecursiveASTVisitor::TraverseCompoundStmt(CS);
return true;
}
};
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index 2ce6bc330e0ca1..d7e5ebee9a9b4f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -12,7 +12,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -48,17 +48,16 @@ class RawPtrRefMemberChecker
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const RawPtrRefMemberChecker *Checker;
explicit LocalVisitor(const RawPtrRefMemberChecker *Checker)
: Checker(Checker) {
assert(Checker);
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
}
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
-
- bool VisitRecordDecl(const RecordDecl *RD) {
+ bool VisitRecordDecl(RecordDecl *RD) override {
Checker->visitRecordDecl(RD);
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index e80246f49a3100..77520f1f731c1f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
@@ -10,7 +10,7 @@
#include "DiagOutputUtils.h"
#include "PtrTypesSemantics.h"
#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -173,17 +173,16 @@ class RefCntblBaseVirtualDtorChecker
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const RefCntblBaseVirtualDtorChecker *Checker;
explicit LocalVisitor(const RefCntblBaseVirtualDtorChecker *Checker)
: Checker(Checker) {
assert(Checker);
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
}
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
-
- bool VisitCXXRecordDecl(const CXXRecordDecl *RD) {
+ bool VisitCXXRecordDecl(CXXRecordDecl *RD) override {
if (!RD->hasDefinition())
return true;
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
index 177c196127c7f0..6ee3dbc08931c5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp
@@ -12,7 +12,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -45,34 +45,31 @@ class UncountedCallArgsChecker
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
- using Base = RecursiveASTVisitor<LocalVisitor>;
-
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const UncountedCallArgsChecker *Checker;
Decl *DeclWithIssue{nullptr};
explicit LocalVisitor(const UncountedCallArgsChecker *Checker)
: Checker(Checker) {
assert(Checker);
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
}
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
-
- bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) {
+ bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) override {
if (isRefType(safeGetName(Decl)))
return true;
- return Base::TraverseClassTemplateDecl(Decl);
+ return DynamicRecursiveASTVisitor::TraverseClassTemplateDecl(Decl);
}
- bool TraverseDecl(Decl *D) {
+ bool TraverseDecl(Decl *D) override {
llvm::SaveAndRestore SavedDecl(DeclWithIssue);
if (D && (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)))
DeclWithIssue = D;
- return Base::TraverseDecl(D);
+ return DynamicRecursiveASTVisitor::TraverseDecl(D);
}
- bool VisitCallExpr(const CallExpr *CE) {
+ bool VisitCallExpr(CallExpr *CE) override {
Checker->visitCallExpr(CE, DeclWithIssue);
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index 998bd4ccee07db..a0cad04cc6ff56 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
@@ -9,7 +9,7 @@
#include "DiagOutputUtils.h"
#include "PtrTypesSemantics.h"
#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -35,17 +35,16 @@ class UncountedLambdaCapturesChecker
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
// want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
+ struct LocalVisitor : DynamicRecursiveASTVisitor {
const UncountedLambdaCapturesChecker *Checker;
explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker)
: Checker(Checker) {
assert(Checker);
+ ShouldVisitTemplateInstantiations = true;
+ ShouldVisitImplicitCode = false;
}
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return false; }
-
- bool VisitLambdaExpr(LambdaExpr *L) {
+ bool VisitLambdaExpr(LambdaExpr *L) override {
Checker->visitLambdaExpr(L);
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
index 84004b8e5c1cdb..05c99c4a844e9e 100644
--- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
using namespace clang;
@@ -76,13 +76,13 @@ inline bool fullyContains(SourceRange Larger, SourceRange Smaller,
isLessOrEqual(Smaller.getEnd(), Larger.getEnd(), SM);
}
-class CacheInitializer : public RecursiveASTVisitor<CacheInitializer> {
+class CacheInitializer : public DynamicRecursiveASTVisitor {
public:
static void initialize(const Decl *D, Ranges &ToInit) {
CacheInitializer(ToInit).TraverseDecl(const_cast<Decl *>(D));
}
- bool VisitDecl(Decl *D) {
+ bool VisitDecl(Decl *D) override {
// Bug location could be somewhere in the init value of
// a freshly declared variable. Even though it looks like the
// user applied attribute to a statement, it will apply to a
@@ -90,7 +90,7 @@ class CacheInitializer : public RecursiveASTVisitor<CacheInitializer> {
return VisitAttributedNode(D);
}
- bool VisitAttributedStmt(AttributedStmt *AS) {
+ bool VisitAttributedStmt(AttributedStmt *AS) override {
// When we apply attributes to statements, it actually creates
// a wrapper statement that only contains attributes and the wrapped
// statement.
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 03bc40804d7328..91c9b085f68292 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -15,7 +15,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CallGraph.h"
@@ -68,7 +68,7 @@ STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
namespace {
class AnalysisConsumer : public AnalysisASTConsumer,
- public RecursiveASTVisitor<AnalysisConsumer> {
+ public DynamicRecursiveASTVisitor {
enum {
AM_None = 0,
AM_Syntax = 0x1,
@@ -147,6 +147,9 @@ class AnalysisConsumer : public AnalysisASTConsumer,
if (Opts.ShouldDisplayMacroExpansions)
MacroExpansions.registerForPreprocessor(PP);
+
+ // Visitor options.
+ ShouldWalkTypesOfTypeLocs = false;
}
~AnalysisConsumer() override {
@@ -261,11 +264,8 @@ class AnalysisConsumer : public AnalysisASTConsumer,
ExprEngine::InliningModes IMode,
SetOfConstDecls *VisitedCallees);
- /// Visitors for the RecursiveASTVisitor.
- bool shouldWalkTypesOfTypeLocs() const { return false; }
-
/// Handle callbacks for arbitrary Decls.
- bool VisitDecl(Decl *D) {
+ bool VisitDecl(Decl *D) override {
AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
if (Mode & AM_Syntax) {
if (SyntaxCheckTimer)
@@ -277,7 +277,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
}
- bool VisitVarDecl(VarDecl *VD) {
+ bool VisitVarDecl(VarDecl *VD) override {
if (!Opts.IsNaiveCTUEnabled)
return true;
@@ -306,7 +306,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
}
- bool VisitFunctionDecl(FunctionDecl *FD) {
+ bool VisitFunctionDecl(FunctionDecl *FD) override {
IdentifierInfo *II = FD->getIdentifier();
if (II && II->getName().starts_with("__inline"))
return true;
@@ -321,7 +321,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
}
- bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+ bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override {
if (MD->isThisDeclarationADefinition()) {
assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
HandleCode(MD, RecVisitorMode);
@@ -329,7 +329,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
}
- bool VisitBlockDecl(BlockDecl *BD) {
+ bool VisitBlockDecl(BlockDecl *BD) override {
if (BD->hasBody()) {
assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
// Since we skip function template definitions, we should skip blocks
>From b58e589a86c06ba28d4d90613864d10be29aa5ba Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Wed, 6 Nov 2024 12:02:35 +0100
Subject: [PATCH 3/5] clang-format
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 26 ++++++++++++------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index abee6b1075b25c..2c33814ace8831 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1152,8 +1152,8 @@ class FallthroughMapper : public DynamicRecursiveASTVisitor {
break;
}
// Don't care about other unreachable statements.
- }
}
+ }
// If there are no unreachable statements, this may be a special
// case in CFG:
// case X: {
@@ -1163,7 +1163,7 @@ class FallthroughMapper : public DynamicRecursiveASTVisitor {
// // <<<< This place is represented by a 'hanging' CFG block.
// case Y:
continue;
- }
+ }
const Stmt *LastStmt = getLastStmt(*P);
if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
@@ -1180,20 +1180,20 @@ class FallthroughMapper : public DynamicRecursiveASTVisitor {
}
++UnannotatedCnt;
- }
- return !!UnannotatedCnt;
}
+ return !!UnannotatedCnt;
+ }
- bool VisitAttributedStmt(AttributedStmt *S) override {
- if (asFallThroughAttr(S))
- FallthroughStmts.insert(S);
- return true;
- }
+ bool VisitAttributedStmt(AttributedStmt *S) override {
+ if (asFallThroughAttr(S))
+ FallthroughStmts.insert(S);
+ return true;
+ }
- bool VisitSwitchStmt(SwitchStmt *S) override {
- FoundSwitchStatements = true;
- return true;
- }
+ bool VisitSwitchStmt(SwitchStmt *S) override {
+ FoundSwitchStatements = true;
+ return true;
+ }
// We don't want to traverse local type declarations. We analyze their
// methods separately.
>From 4c70cbae355e909b769cbe14fb089a7752256b3a Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Wed, 6 Nov 2024 12:57:45 +0100
Subject: [PATCH 4/5] clang-format, again
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 2c33814ace8831..2ec98dc73f44cd 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1181,7 +1181,7 @@ class FallthroughMapper : public DynamicRecursiveASTVisitor {
++UnannotatedCnt;
}
- return !!UnannotatedCnt;
+ return !!UnannotatedCnt;
}
bool VisitAttributedStmt(AttributedStmt *S) override {
>From ac14c86f2ba913bb73efc84255972553e56d1298 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Fri, 15 Nov 2024 06:20:03 +0100
Subject: [PATCH 5/5] Migrate a new visitor that has appeared in the meantime
---
clang/lib/Sema/SemaExpr.cpp | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 961e91de7d2188..c9de7811adfe0a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9202,17 +9202,17 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
// __builtin_counted_by_ref cannot be assigned to a variable, used in
// function call, or in a return.
auto FindBuiltinCountedByRefExpr = [&](Expr *E) -> CallExpr * {
- struct BuiltinCountedByRefVisitor
- : public RecursiveASTVisitor<BuiltinCountedByRefVisitor> {
+ struct BuiltinCountedByRefVisitor : DynamicRecursiveASTVisitor {
CallExpr *TheCall = nullptr;
- bool VisitCallExpr(CallExpr *CE) {
+ bool VisitCallExpr(CallExpr *CE) override {
if (CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) {
TheCall = CE;
return false;
}
return true;
}
- bool VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) {
+ bool
+ VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) override {
// A UnaryExprOrTypeTraitExpr---e.g. sizeof, __alignof, etc.---isn't
// the same as a CallExpr, so if we find a __builtin_counted_by_ref()
// call in one, ignore it.
@@ -13783,13 +13783,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
// subscript on the LHS.
int DiagOption = -1;
auto FindInvalidUseOfBoundsSafetyCounter = [&](Expr *E) -> CallExpr * {
- struct BuiltinCountedByRefVisitor
- : public RecursiveASTVisitor<BuiltinCountedByRefVisitor> {
+ struct BuiltinCountedByRefVisitor : DynamicRecursiveASTVisitor {
CallExpr *CE = nullptr;
bool InvalidUse = false;
int Option = -1;
- bool VisitCallExpr(CallExpr *E) {
+ bool VisitCallExpr(CallExpr *E) override {
if (E->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) {
CE = E;
return false;
@@ -13797,12 +13796,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
return true;
}
- bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+ bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) override {
InvalidUse = true;
Option = 0; // report 'array expression' in diagnostic.
return true;
}
- bool VisitBinaryOperator(BinaryOperator *E) {
+ bool VisitBinaryOperator(BinaryOperator *E) override {
InvalidUse = true;
Option = 1; // report 'binary expression' in diagnostic.
return true;
More information about the cfe-commits
mailing list