clang 22.0.0git
RecursiveSymbolVisitor.h
Go to the documentation of this file.
1//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// A wrapper class around \c RecursiveASTVisitor that visits each
11/// occurrences of a named symbol.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H
16#define LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H
17
18#include "clang/AST/AST.h"
20#include "clang/Lex/Lexer.h"
21
22namespace clang {
23namespace tooling {
24
25/// Traverses the AST and visits the occurrence of each named symbol in the
26/// given nodes.
27template <typename T>
29 : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
31
32public:
34 : SM(SM), LangOpts(LangOpts) {}
35
37 ArrayRef<SourceRange> NameRanges) {
38 return true;
39 }
40
41 // Declaration visitors:
42
43 bool VisitNamedDecl(const NamedDecl *D) {
44 return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
45 }
46
48 for (const auto *Initializer : CD->inits()) {
49 // Ignore implicit initializers.
50 if (!Initializer->isWritten())
51 continue;
52 if (const FieldDecl *FD = Initializer->getMember()) {
53 if (!visit(FD, Initializer->getSourceLocation(),
54 Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
55 0, SM, LangOpts)))
56 return false;
57 }
58 }
59 return true;
60 }
61
62 // Expression visitors:
63
65 return visit(Expr->getFoundDecl(), Expr->getLocation());
66 }
67
69 return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
70 }
71
73 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
74 const OffsetOfNode &Component = S->getComponent(I);
75 if (Component.getKind() == OffsetOfNode::Field) {
76 if (!visit(Component.getField(), Component.getEndLoc()))
77 return false;
78 }
79 // FIXME: Try to resolve dependent field references.
80 }
81 return true;
82 }
83
84 // Other visitors:
85
86 bool VisitTypeLoc(const TypeLoc Loc) {
87 const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88 const SourceLocation TypeEndLoc =
89 Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90 if (const auto *TemplateTypeParm =
91 dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92 if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93 return false;
94 }
95 if (const auto *TemplateSpecType =
96 dyn_cast<TemplateSpecializationType>(Loc.getType())) {
97 if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
98 TypeBeginLoc, TypeEndLoc))
99 return false;
100 }
101 if (const Type *TP = Loc.getTypePtr()) {
102 if (TP->getTypeClass() == clang::Type::Record)
103 return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104 }
105 return true;
106 }
107
109 const SourceLocation TypeEndLoc =
110 Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
111 return visit(TL.getDecl(), TL.getBeginLoc(), TypeEndLoc);
112 }
113
115 // The base visitor will visit NNSL prefixes, so we should only look at
116 // the current NNS.
117 if (NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
118 Qualifier.getKind() == NestedNameSpecifier::Kind::Namespace) {
119 const auto *ND = dyn_cast<NamespaceDecl>(
120 Qualifier.getAsNamespaceAndPrefix().Namespace);
121 if (!visit(ND, QualifierLoc.getLocalBeginLoc(),
122 QualifierLoc.getLocalEndLoc()))
123 return false;
124 }
125 return BaseType::TraverseNestedNameSpecifierLoc(QualifierLoc);
126 }
127
129 for (const DesignatedInitExpr::Designator &D : E->designators()) {
130 if (D.isFieldDesignator()) {
131 if (const FieldDecl *Decl = D.getFieldDecl()) {
132 if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc()))
133 return false;
134 }
135 }
136 }
137 return true;
138 }
139
140private:
141 const SourceManager &SM;
142 const LangOptions &LangOpts;
143
144 bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
145 SourceLocation EndLoc) {
146 return static_cast<T *>(this)->visitSymbolOccurrence(
147 ND, SourceRange(BeginLoc, EndLoc));
148 }
149 bool visit(const NamedDecl *ND, SourceLocation Loc) {
150 return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
151 }
152};
153
154} // end namespace tooling
155} // end namespace clang
156
157#endif // LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H
#define SM(sm)
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1270
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getLocation() const
Definition DeclBase.h:439
Represents a single C99 designator.
Definition Expr.h:5528
Represents a C99 designated initializer expression.
Definition Expr.h:5485
MutableArrayRef< Designator > designators()
Definition Expr.h:5718
This represents one expression.
Definition Expr.h:112
Represents a member of a struct/union/class.
Definition Decl.h:3157
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Definition Lexer.cpp:848
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3298
This represents a decl that may have a name.
Definition Decl.h:273
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2527
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2574
unsigned getNumComponents() const
Definition Expr.h:2582
Helper class for OffsetOfExpr.
Definition Expr.h:2421
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition Expr.h:2485
@ Field
A field.
Definition Expr.h:2428
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2475
SourceLocation getEndLoc() const LLVM_READONLY
Definition Expr.h:2508
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Encodes a location in the source.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition TypeLoc.h:133
SourceLocation getBeginLoc() const
Get the begin source location.
Definition TypeLoc.cpp:193
const Type * getTypePtr() const
Definition TypeLoc.h:137
The base class of the type hierarchy.
Definition TypeBase.h:1833
Wrapper for source info for typedefs.
Definition TypeLoc.h:782
bool VisitOffsetOfExpr(const OffsetOfExpr *S)
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)
bool VisitMemberExpr(const MemberExpr *Expr)
bool VisitDesignatedInitExpr(const DesignatedInitExpr *E)
bool VisitDeclRefExpr(const DeclRefExpr *Expr)
RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD)
bool visitSymbolOccurrence(const NamedDecl *ND, ArrayRef< SourceRange > NameRanges)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
const FunctionProtoType * T
#define true
Definition stdbool.h:25