Skip to content

Commit 918e91e

Browse files
SirraideKornevNikita
authored andcommitted
[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use DynamicRecursiveASTVisitor (#115144)
This pr refactors all recursive AST visitors in `Sema`, `Analyze`, and `StaticAnalysis` to inherit from DRAV instead. This is over half of the visitors that inherit from RAV directly. See also #115132, #110040, #93462 LLVM Compile-Time Tracker link for this branch: https://llvm-compile-time-tracker.com/compare.php?from=5adb5c05a2e9f31385fbba8b0436cbc07d91a44d&to=b58e589a86c06ba28d4d90613864d10be29aa5ba&stat=instructions%3Au
1 parent 6e21270 commit 918e91e

39 files changed

+542
-564
lines changed

clang/include/clang/Analysis/CallGraph.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
1919

2020
#include "clang/AST/Decl.h"
21-
#include "clang/AST/RecursiveASTVisitor.h"
21+
#include "clang/AST/DeclObjC.h"
22+
#include "clang/AST/DynamicRecursiveASTVisitor.h"
2223
#include "llvm/ADT/DenseMap.h"
2324
#include "llvm/ADT/GraphTraits.h"
2425
#include "llvm/ADT/STLExtras.h"
@@ -40,7 +41,7 @@ class Stmt;
4041
/// The call graph extends itself with the given declarations by implementing
4142
/// the recursive AST visitor, which constructs the graph by visiting the given
4243
/// declarations.
43-
class CallGraph : public RecursiveASTVisitor<CallGraph> {
44+
class CallGraph : public DynamicRecursiveASTVisitor {
4445
friend class CallGraphNode;
4546

4647
using FunctionMapTy =
@@ -116,7 +117,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
116117

117118
/// Part of recursive declaration visitation. We recursively visit all the
118119
/// declarations to collect the root functions.
119-
bool VisitFunctionDecl(FunctionDecl *FD) {
120+
bool VisitFunctionDecl(FunctionDecl *FD) override {
120121
// We skip function template definitions, as their semantics is
121122
// only determined when they are instantiated.
122123
if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
@@ -131,7 +132,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
131132
}
132133

133134
/// Part of recursive declaration visitation.
134-
bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
135+
bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override {
135136
if (includeInGraph(MD)) {
136137
addNodesForBlocks(MD);
137138
addNodeForDecl(MD, true);
@@ -140,11 +141,8 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
140141
}
141142

142143
// We are only collecting the declarations, so do not step into the bodies.
143-
bool TraverseStmt(Stmt *S) { return true; }
144+
bool TraverseStmt(Stmt *S) override { return true; }
144145

145-
bool shouldWalkTypesOfTypeLocs() const { return false; }
146-
bool shouldVisitTemplateInstantiations() const { return true; }
147-
bool shouldVisitImplicitCode() const { return true; }
148146
bool shouldSkipConstantExpressions() const { return ShouldSkipConstexpr; }
149147
void setSkipConstantExpressions(ASTContext &Context) {
150148
Ctx = &Context;

clang/include/clang/Analysis/FlowSensitive/ASTOps.h

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
1515

1616
#include "clang/AST/Decl.h"
17+
#include "clang/AST/DynamicRecursiveASTVisitor.h"
1718
#include "clang/AST/Expr.h"
18-
#include "clang/AST/RecursiveASTVisitor.h"
19+
#include "clang/AST/ExprCXX.h"
1920
#include "clang/AST/Type.h"
2021
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
2122
#include "llvm/ADT/DenseSet.h"
@@ -88,14 +89,14 @@ class RecordInitListHelper {
8889
/// the function to analyze. Don't call `TraverseDecl()` on the function itself;
8990
/// this won't work as `TraverseDecl()` contains code to avoid traversing nested
9091
/// functions.
91-
template <class Derived>
92-
class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
92+
class AnalysisASTVisitor : public DynamicRecursiveASTVisitor {
9393
public:
94-
bool shouldVisitImplicitCode() { return true; }
95-
96-
bool shouldVisitLambdaBody() const { return false; }
94+
AnalysisASTVisitor() {
95+
ShouldVisitImplicitCode = true;
96+
ShouldVisitLambdaBody = false;
97+
}
9798

98-
bool TraverseDecl(Decl *D) {
99+
bool TraverseDecl(Decl *D) override {
99100
// Don't traverse nested record or function declarations.
100101
// - We won't be analyzing code contained in these anyway
101102
// - We don't model fields that are used only in these nested declaration,
@@ -104,30 +105,30 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
104105
if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D))
105106
return true;
106107

107-
return RecursiveASTVisitor<Derived>::TraverseDecl(D);
108+
return DynamicRecursiveASTVisitor::TraverseDecl(D);
108109
}
109110

110111
// Don't traverse expressions in unevaluated contexts, as we don't model
111112
// fields that are only used in these.
112113
// Note: The operand of the `noexcept` operator is an unevaluated operand, but
113114
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
114-
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
115-
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
116-
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) {
115+
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; }
116+
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; }
117+
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override {
117118
if (TIE->isPotentiallyEvaluated())
118-
return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE);
119+
return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE);
119120
return true;
120121
}
121-
bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
122+
bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) override {
122123
return true;
123124
}
124125

125-
bool TraverseBindingDecl(BindingDecl *BD) {
126+
bool TraverseBindingDecl(BindingDecl *BD) override {
126127
// `RecursiveASTVisitor` doesn't traverse holding variables for
127128
// `BindingDecl`s by itself, so we need to tell it to.
128129
if (VarDecl *HoldingVar = BD->getHoldingVar())
129130
TraverseDecl(HoldingVar);
130-
return RecursiveASTVisitor<Derived>::TraverseBindingDecl(BD);
131+
return DynamicRecursiveASTVisitor::TraverseBindingDecl(BD);
131132
}
132133
};
133134

clang/lib/Analysis/CallGraph.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ void CallGraph::addNodesForBlocks(DeclContext *D) {
190190
}
191191

192192
CallGraph::CallGraph() {
193+
ShouldWalkTypesOfTypeLocs = false;
194+
ShouldVisitTemplateInstantiations = true;
195+
ShouldVisitImplicitCode = true;
193196
Root = getOrInsertNode(nullptr);
194197
}
195198

clang/lib/Analysis/CalledOnceCheck.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#include "clang/AST/Attr.h"
1212
#include "clang/AST/Decl.h"
1313
#include "clang/AST/DeclBase.h"
14+
#include "clang/AST/DynamicRecursiveASTVisitor.h"
1415
#include "clang/AST/Expr.h"
1516
#include "clang/AST/ExprObjC.h"
1617
#include "clang/AST/OperationKinds.h"
1718
#include "clang/AST/ParentMap.h"
18-
#include "clang/AST/RecursiveASTVisitor.h"
1919
#include "clang/AST/Stmt.h"
2020
#include "clang/AST/StmtObjC.h"
2121
#include "clang/AST/StmtVisitor.h"
@@ -426,7 +426,7 @@ const Expr *getCondition(const Stmt *S) {
426426
/// of the AST will end up in the results.
427427
/// Results might have duplicate names, if this is a problem, convert to
428428
/// string sets afterwards.
429-
class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
429+
class NamesCollector : public DynamicRecursiveASTVisitor {
430430
public:
431431
static constexpr unsigned EXPECTED_NUMBER_OF_NAMES = 5;
432432
using NameCollection =
@@ -438,12 +438,12 @@ class NamesCollector : public RecursiveASTVisitor<NamesCollector> {
438438
return Impl.Result;
439439
}
440440

441-
bool VisitDeclRefExpr(const DeclRefExpr *E) {
441+
bool VisitDeclRefExpr(DeclRefExpr *E) override {
442442
Result.push_back(E->getDecl()->getName());
443443
return true;
444444
}
445445

446-
bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
446+
bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) override {
447447
llvm::StringRef Name;
448448

449449
if (E->isImplicitProperty()) {

clang/lib/Analysis/FlowSensitive/ASTOps.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,12 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
198198
return nullptr;
199199
}
200200

201-
class ReferencedDeclsVisitor
202-
: public AnalysisASTVisitor<ReferencedDeclsVisitor> {
201+
class ReferencedDeclsVisitor : public AnalysisASTVisitor {
203202
public:
204203
ReferencedDeclsVisitor(ReferencedDecls &Referenced)
205204
: Referenced(Referenced) {}
206205

207-
void TraverseConstructorInits(const CXXConstructorDecl *Ctor) {
206+
void traverseConstructorInits(const CXXConstructorDecl *Ctor) {
208207
for (const CXXCtorInitializer *Init : Ctor->inits()) {
209208
if (Init->isMemberInitializer()) {
210209
Referenced.Fields.insert(Init->getMember());
@@ -225,21 +224,21 @@ class ReferencedDeclsVisitor
225224
}
226225
}
227226

228-
bool VisitDecl(Decl *D) {
227+
bool VisitDecl(Decl *D) override {
229228
insertIfGlobal(*D, Referenced.Globals);
230229
insertIfLocal(*D, Referenced.Locals);
231230
insertIfFunction(*D, Referenced.Functions);
232231
return true;
233232
}
234233

235-
bool VisitDeclRefExpr(DeclRefExpr *E) {
234+
bool VisitDeclRefExpr(DeclRefExpr *E) override {
236235
insertIfGlobal(*E->getDecl(), Referenced.Globals);
237236
insertIfLocal(*E->getDecl(), Referenced.Locals);
238237
insertIfFunction(*E->getDecl(), Referenced.Functions);
239238
return true;
240239
}
241240

242-
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) {
241+
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) override {
243242
// If this is a method that returns a member variable but does nothing else,
244243
// model the field of the return value.
245244
if (MemberExpr *E = getMemberForAccessor(*C))
@@ -248,7 +247,7 @@ class ReferencedDeclsVisitor
248247
return true;
249248
}
250249

251-
bool VisitMemberExpr(MemberExpr *E) {
250+
bool VisitMemberExpr(MemberExpr *E) override {
252251
// FIXME: should we be using `E->getFoundDecl()`?
253252
const ValueDecl *VD = E->getMemberDecl();
254253
insertIfGlobal(*VD, Referenced.Globals);
@@ -258,14 +257,14 @@ class ReferencedDeclsVisitor
258257
return true;
259258
}
260259

261-
bool VisitInitListExpr(InitListExpr *InitList) {
260+
bool VisitInitListExpr(InitListExpr *InitList) override {
262261
if (InitList->getType()->isRecordType())
263262
for (const auto *FD : getFieldsForInitListExpr(InitList))
264263
Referenced.Fields.insert(FD);
265264
return true;
266265
}
267266

268-
bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) {
267+
bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) override {
269268
if (ParenInitList->getType()->isRecordType())
270269
for (const auto *FD : getFieldsForInitListExpr(ParenInitList))
271270
Referenced.Fields.insert(FD);
@@ -281,7 +280,7 @@ ReferencedDecls getReferencedDecls(const FunctionDecl &FD) {
281280
ReferencedDeclsVisitor Visitor(Result);
282281
Visitor.TraverseStmt(FD.getBody());
283282
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&FD))
284-
Visitor.TraverseConstructorInits(CtorDecl);
283+
Visitor.traverseConstructorInits(CtorDecl);
285284

286285
return Result;
287286
}

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ namespace {
298298
// Visitor that builds a map from record prvalues to result objects.
299299
// For each result object that it encounters, it propagates the storage location
300300
// of the result object to all record prvalues that can initialize it.
301-
class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
301+
class ResultObjectVisitor : public AnalysisASTVisitor {
302302
public:
303303
// `ResultObjectMap` will be filled with a map from record prvalues to result
304304
// object. If this visitor will traverse a function that returns a record by
@@ -315,7 +315,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
315315
// called by `RecursiveASTVisitor`; it should be called manually if we are
316316
// analyzing a constructor. `ThisPointeeLoc` is the storage location that
317317
// `this` points to.
318-
void TraverseConstructorInits(const CXXConstructorDecl *Ctor,
318+
void traverseConstructorInits(const CXXConstructorDecl *Ctor,
319319
RecordStorageLocation *ThisPointeeLoc) {
320320
assert(ThisPointeeLoc != nullptr);
321321
for (const CXXCtorInitializer *Init : Ctor->inits()) {
@@ -339,31 +339,31 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
339339
}
340340
}
341341

342-
bool VisitVarDecl(VarDecl *VD) {
342+
bool VisitVarDecl(VarDecl *VD) override {
343343
if (VD->getType()->isRecordType() && VD->hasInit())
344344
PropagateResultObject(
345345
VD->getInit(),
346346
&cast<RecordStorageLocation>(DACtx.getStableStorageLocation(*VD)));
347347
return true;
348348
}
349349

350-
bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) {
350+
bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) override {
351351
if (MTE->getType()->isRecordType())
352352
PropagateResultObject(
353353
MTE->getSubExpr(),
354354
&cast<RecordStorageLocation>(DACtx.getStableStorageLocation(*MTE)));
355355
return true;
356356
}
357357

358-
bool VisitReturnStmt(ReturnStmt *Return) {
358+
bool VisitReturnStmt(ReturnStmt *Return) override {
359359
Expr *RetValue = Return->getRetValue();
360360
if (RetValue != nullptr && RetValue->getType()->isRecordType() &&
361361
RetValue->isPRValue())
362362
PropagateResultObject(RetValue, LocForRecordReturnVal);
363363
return true;
364364
}
365365

366-
bool VisitExpr(Expr *E) {
366+
bool VisitExpr(Expr *E) override {
367367
// Clang's AST can have record-type prvalues without a result object -- for
368368
// example as full-expressions contained in a compound statement or as
369369
// arguments of call expressions. We notice this if we get here and a
@@ -1211,7 +1211,7 @@ Environment::PrValueToResultObject Environment::buildResultObjectMap(
12111211

12121212
ResultObjectVisitor Visitor(Map, LocForRecordReturnVal, *DACtx);
12131213
if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FuncDecl))
1214-
Visitor.TraverseConstructorInits(Ctor, ThisPointeeLoc);
1214+
Visitor.traverseConstructorInits(Ctor, ThisPointeeLoc);
12151215

12161216
return Map;
12171217
}

clang/lib/Analysis/ReachableCode.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
#include "clang/Analysis/Analyses/ReachableCode.h"
1515
#include "clang/AST/Attr.h"
16+
#include "clang/AST/DynamicRecursiveASTVisitor.h"
1617
#include "clang/AST/Expr.h"
1718
#include "clang/AST/ExprCXX.h"
1819
#include "clang/AST/ExprObjC.h"
1920
#include "clang/AST/ParentMap.h"
20-
#include "clang/AST/RecursiveASTVisitor.h"
2121
#include "clang/AST/StmtCXX.h"
2222
#include "clang/Analysis/AnalysisDeclContext.h"
2323
#include "clang/Analysis/CFG.h"
@@ -476,17 +476,19 @@ static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) {
476476
}
477477
if (!CoroStmt)
478478
return false;
479-
struct Checker : RecursiveASTVisitor<Checker> {
479+
struct Checker : DynamicRecursiveASTVisitor {
480480
const Stmt *DeadStmt;
481481
bool CoroutineSubStmt = false;
482-
Checker(const Stmt *S) : DeadStmt(S) {}
483-
bool VisitStmt(const Stmt *S) {
482+
Checker(const Stmt *S) : DeadStmt(S) {
483+
// Statements captured in the CFG can be implicit.
484+
ShouldVisitImplicitCode = true;
485+
}
486+
487+
bool VisitStmt(Stmt *S) override {
484488
if (S == DeadStmt)
485489
CoroutineSubStmt = true;
486490
return true;
487491
}
488-
// Statements captured in the CFG can be implicit.
489-
bool shouldVisitImplicitCode() const { return true; }
490492
};
491493
Checker checker(DeadStmt);
492494
checker.TraverseStmt(const_cast<Stmt *>(CoroStmt));

0 commit comments

Comments
 (0)