Skip to content

[Clang] [NFC] Refactor more AST visitors #116823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions clang/include/clang/InstallAPI/Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifndef LLVM_CLANG_INSTALLAPI_VISITOR_H
#define LLVM_CLANG_INSTALLAPI_VISITOR_H

#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/InstallAPI/Context.h"
Expand All @@ -26,35 +26,37 @@ namespace installapi {

/// ASTVisitor for collecting declarations that represent global symbols.
class InstallAPIVisitor final : public ASTConsumer,
public RecursiveASTVisitor<InstallAPIVisitor> {
public DynamicRecursiveASTVisitor {
public:
InstallAPIVisitor(ASTContext &ASTCtx, InstallAPIContext &Ctx,
SourceManager &SrcMgr, Preprocessor &PP)
: Ctx(Ctx), SrcMgr(SrcMgr), PP(PP),
MC(ItaniumMangleContext::create(ASTCtx, ASTCtx.getDiagnostics())),
Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {}
Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {
ShouldVisitTemplateInstantiations = true;
}

void HandleTranslationUnit(ASTContext &ASTCtx) override;
bool shouldVisitTemplateInstantiations() const { return true; }

/// Collect global variables.
bool VisitVarDecl(const VarDecl *D);
bool VisitVarDecl(VarDecl *D) override;

/// Collect global functions.
bool VisitFunctionDecl(const FunctionDecl *D);
bool VisitFunctionDecl(FunctionDecl *D) override;

/// Collect Objective-C Interface declarations.
/// Every Objective-C class has an interface declaration that lists all the
/// ivars, properties, and methods of the class.
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) override;

/// Collect Objective-C Category/Extension declarations.
///
/// The class that is being extended might come from a different library and
/// is therefore itself not collected.
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) override;

/// Collect global c++ declarations.
bool VisitCXXRecordDecl(const CXXRecordDecl *D);
bool VisitCXXRecordDecl(CXXRecordDecl *D) override;

private:
std::string getMangledName(const NamedDecl *D) const;
Expand Down
35 changes: 15 additions & 20 deletions clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,31 @@
#define LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H

#include "clang/AST/AST.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/Lex/Lexer.h"

namespace clang {
namespace tooling {

/// Traverses the AST and visits the occurrence of each named symbol in the
/// given nodes.
template <typename T>
class RecursiveSymbolVisitor
: public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
using BaseType = RecursiveASTVisitor<RecursiveSymbolVisitor<T>>;

class RecursiveSymbolVisitor : public DynamicRecursiveASTVisitor {
public:
RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
: SM(SM), LangOpts(LangOpts) {}

bool visitSymbolOccurrence(const NamedDecl *ND,
ArrayRef<SourceRange> NameRanges) {
virtual bool visitSymbolOccurrence(const NamedDecl *ND,
ArrayRef<SourceRange> NameRanges) {
return true;
}

// Declaration visitors:

bool VisitNamedDecl(const NamedDecl *D) {
bool VisitNamedDecl(NamedDecl *D) override {
return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
}

bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
bool VisitCXXConstructorDecl(CXXConstructorDecl *CD) override {
for (const auto *Initializer : CD->inits()) {
// Ignore implicit initializers.
if (!Initializer->isWritten())
Expand All @@ -61,15 +57,15 @@ class RecursiveSymbolVisitor

// Expression visitors:

bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
bool VisitDeclRefExpr(DeclRefExpr *Expr) override {
return visit(Expr->getFoundDecl(), Expr->getLocation());
}

bool VisitMemberExpr(const MemberExpr *Expr) {
bool VisitMemberExpr(MemberExpr *Expr) override {
return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
}

bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
bool VisitOffsetOfExpr(OffsetOfExpr *S) override {
for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
const OffsetOfNode &Component = S->getComponent(I);
if (Component.getKind() == OffsetOfNode::Field) {
Expand All @@ -83,7 +79,7 @@ class RecursiveSymbolVisitor

// Other visitors:

bool VisitTypeLoc(const TypeLoc Loc) {
bool VisitTypeLoc(TypeLoc Loc) override {
const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
const SourceLocation TypeEndLoc =
Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
Expand All @@ -105,24 +101,24 @@ class RecursiveSymbolVisitor
return true;
}

bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) override {
const SourceLocation TypeEndLoc =
Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
}

bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
// The base visitor will visit NNSL prefixes, so we should only look at
// the current NNS.
if (NNS) {
const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
return false;
}
return BaseType::TraverseNestedNameSpecifierLoc(NNS);
return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNS);
}

bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
bool VisitDesignatedInitExpr(DesignatedInitExpr *E) override {
for (const DesignatedInitExpr::Designator &D : E->designators()) {
if (D.isFieldDesignator()) {
if (const FieldDecl *Decl = D.getFieldDecl()) {
Expand All @@ -140,8 +136,7 @@ class RecursiveSymbolVisitor

bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
SourceLocation EndLoc) {
return static_cast<T *>(this)->visitSymbolOccurrence(
ND, SourceRange(BeginLoc, EndLoc));
return visitSymbolOccurrence(ND, SourceRange(BeginLoc, EndLoc));
}
bool visit(const NamedDecl *ND, SourceLocation Loc) {
return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
Expand Down
20 changes: 10 additions & 10 deletions clang/lib/AST/ASTImporterLookupTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@

#include "clang/AST/ASTImporterLookupTable.h"
#include "clang/AST/Decl.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "llvm/Support/FormatVariadic.h"

namespace clang {

namespace {

struct Builder : RecursiveASTVisitor<Builder> {
struct Builder : DynamicRecursiveASTVisitor {
ASTImporterLookupTable &LT;
Builder(ASTImporterLookupTable &LT) : LT(LT) {}
Builder(ASTImporterLookupTable &LT) : LT(LT) {
ShouldVisitTemplateInstantiations = true;
ShouldVisitImplicitCode = true;
}

bool VisitTypedefNameDecl(TypedefNameDecl *D) {
bool VisitTypedefNameDecl(TypedefNameDecl *D) override {
QualType Ty = D->getUnderlyingType();
Ty = Ty.getCanonicalType();
if (const auto *RTy = dyn_cast<RecordType>(Ty)) {
Expand All @@ -37,7 +41,7 @@ struct Builder : RecursiveASTVisitor<Builder> {
return true;
}

bool VisitNamedDecl(NamedDecl *D) {
bool VisitNamedDecl(NamedDecl *D) override {
LT.add(D);
return true;
}
Expand All @@ -46,7 +50,7 @@ struct Builder : RecursiveASTVisitor<Builder> {
// visitation. However, there are cases when the befriended class is not a
// child, thus it must be fetched explicitly from the FriendDecl, and only
// then can we add it to the lookup table.
bool VisitFriendDecl(FriendDecl *D) {
bool VisitFriendDecl(FriendDecl *D) override {
if (D->getFriendType()) {
QualType Ty = D->getFriendType()->getType();
if (isa<ElaboratedType>(Ty))
Expand Down Expand Up @@ -76,10 +80,6 @@ struct Builder : RecursiveASTVisitor<Builder> {
}
return true;
}

// Override default settings of base.
bool shouldVisitTemplateInstantiations() const { return true; }
bool shouldVisitImplicitCode() const { return true; }
};

} // anonymous namespace
Expand Down
53 changes: 30 additions & 23 deletions clang/lib/AST/ParentMapContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
//===----------------------------------------------------------------------===//

#include "clang/AST/ParentMapContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TemplateBase.h"

using namespace clang;
Expand Down Expand Up @@ -352,19 +353,14 @@ template <> DynTypedNode createDynTypedNode(const ObjCProtocolLoc &Node) {
/// traversal - there are other relationships (for example declaration context)
/// in the AST that are better modeled by special matchers.
class ParentMapContext::ParentMap::ASTVisitor
: public RecursiveASTVisitor<ASTVisitor> {
: public DynamicRecursiveASTVisitor {
public:
ASTVisitor(ParentMap &Map) : Map(Map) {}
ASTVisitor(ParentMap &Map) : Map(Map) {
ShouldVisitTemplateInstantiations = true;
ShouldVisitImplicitCode = true;
}

private:
friend class RecursiveASTVisitor<ASTVisitor>;

using VisitorBase = RecursiveASTVisitor<ASTVisitor>;

bool shouldVisitTemplateInstantiations() const { return true; }

bool shouldVisitImplicitCode() const { return true; }

/// Record the parent of the node we're visiting.
/// MapNode is the child, the parent is on top of ParentStack.
/// Parents is the parent storage (either PointerParents or OtherParents).
Expand Down Expand Up @@ -427,42 +423,53 @@ class ParentMapContext::ParentMap::ASTVisitor
return Result;
}

bool TraverseDecl(Decl *DeclNode) {
bool TraverseDecl(Decl *DeclNode) override {
return TraverseNode(
DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
DeclNode, DeclNode,
[&] { return DynamicRecursiveASTVisitor::TraverseDecl(DeclNode); },
&Map.PointerParents);
}
bool TraverseTypeLoc(TypeLoc TypeLocNode) {
bool TraverseTypeLoc(TypeLoc TypeLocNode) override {
return TraverseNode(
TypeLocNode, DynTypedNode::create(TypeLocNode),
[&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
[&] {
return DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLocNode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this make sense? It's not the same, isn't it? The previous code would call back into ParentMapContext, but the new one doesn't(?) This should basically be this->TraverseTypeLoc(), right? Am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er, unless I misread something horribly somewhere, in both cases this is statically calling the base class implementation (VisitorBase was RecursiveASTVisitor<ASTVisitor>, i.e. the base class of this thing).

},
&Map.OtherParents);
}
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
bool
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) override {
return TraverseNode(
NNSLocNode, DynTypedNode::create(NNSLocNode),
[&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
[&] {
return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(
NNSLocNode);
},
&Map.OtherParents);
}
bool TraverseAttr(Attr *AttrNode) {
bool TraverseAttr(Attr *AttrNode) override {
return TraverseNode(
AttrNode, AttrNode, [&] { return VisitorBase::TraverseAttr(AttrNode); },
AttrNode, AttrNode,
[&] { return DynamicRecursiveASTVisitor::TraverseAttr(AttrNode); },
&Map.PointerParents);
}
bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) {
bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLocNode) override {
return TraverseNode(
ProtocolLocNode, DynTypedNode::create(ProtocolLocNode),
[&] { return VisitorBase::TraverseObjCProtocolLoc(ProtocolLocNode); },
[&] {
return DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc(
ProtocolLocNode);
},
&Map.OtherParents);
}

// Using generic TraverseNode for Stmt would prevent data-recursion.
bool dataTraverseStmtPre(Stmt *StmtNode) {
bool dataTraverseStmtPre(Stmt *StmtNode) override {
addParent(StmtNode, &Map.PointerParents);
ParentStack.push_back(DynTypedNode::create(*StmtNode));
return true;
}
bool dataTraverseStmtPost(Stmt *StmtNode) {
bool dataTraverseStmtPost(Stmt *StmtNode) override {
ParentStack.pop_back();
return true;
}
Expand Down
Loading