clang  14.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_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
16 #define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
17 
18 #include "clang/AST/AST.h"
20 #include "clang/Lex/Lexer.h"
21 
22 namespace clang {
23 namespace tooling {
24 
25 /// Traverses the AST and visits the occurrence of each named symbol in the
26 /// given nodes.
27 template <typename T>
29  : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
31 
32 public:
33  RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
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.getTypedefNameDecl(), 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 (NNS) {
119  if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120  return false;
121  }
123  }
124 
126  for (const DesignatedInitExpr::Designator &D : E->designators()) {
127  if (D.isFieldDesignator() && D.getField()) {
128  const FieldDecl *Decl = D.getField();
129  if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc()))
130  return false;
131  }
132  }
133  return true;
134  }
135 
136 private:
137  const SourceManager &SM;
138  const LangOptions &LangOpts;
139 
140  bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
141  SourceLocation EndLoc) {
142  return static_cast<T *>(this)->visitSymbolOccurrence(
143  ND, SourceRange(BeginLoc, EndLoc));
144  }
145  bool visit(const NamedDecl *ND, SourceLocation Loc) {
146  return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
147  }
148 };
149 
150 } // end namespace tooling
151 } // end namespace clang
152 
153 #endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
clang::NestedNameSpecifierLoc::getLocalEndLoc
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
Definition: NestedNameSpecifier.h:317
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2401
clang::OffsetOfExpr
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2438
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:212
clang::tooling::RecursiveSymbolVisitor::VisitTypeLoc
bool VisitTypeLoc(const TypeLoc Loc)
Definition: RecursiveSymbolVisitor.h:86
clang::DesignatedInitExpr
Represents a C99 designated initializer expression.
Definition: Expr.h:5024
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:88
clang::tooling::RecursiveSymbolVisitor
Traverses the AST and visits the occurrence of each named symbol in the given nodes.
Definition: RecursiveSymbolVisitor.h:28
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:249
clang::OffsetOfNode::getKind
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2388
clang::DynamicInitKind::Initializer
@ Initializer
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2835
clang::NestedNameSpecifierLoc::getLocalBeginLoc
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
Definition: NestedNameSpecifier.h:311
clang::tooling::RecursiveSymbolVisitor::VisitMemberExpr
bool VisitMemberExpr(const MemberExpr *Expr)
Definition: RecursiveSymbolVisitor.h:68
clang::OffsetOfNode::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Expr.h:2421
clang::tooling::RecursiveSymbolVisitor::VisitDeclRefExpr
bool VisitDeclRefExpr(const DeclRefExpr *Expr)
Definition: RecursiveSymbolVisitor.h:64
clang::TypeLoc::getTypePtr
const Type * getTypePtr() const
Definition: TypeLoc.h:136
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:626
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1490
clang::TypeLoc::getBeginLoc
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:191
clang::CXXConstructorDecl::inits
init_range inits()
Definition: DeclCXX.h:2494
clang::tooling::RecursiveSymbolVisitor::VisitDesignatedInitExpr
bool VisitDesignatedInitExpr(const DesignatedInitExpr *E)
Definition: RecursiveSymbolVisitor.h:125
clang::tooling::RecursiveSymbolVisitor::VisitCXXConstructorDecl
bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD)
Definition: RecursiveSymbolVisitor.h:47
clang::RecursiveASTVisitor
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Definition: RecursiveASTVisitor.h:164
clang::tooling::RecursiveSymbolVisitor::visitSymbolOccurrence
bool visitSymbolOccurrence(const NamedDecl *ND, ArrayRef< SourceRange > NameRanges)
Definition: RecursiveSymbolVisitor.h:36
clang::OffsetOfNode::getField
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition: Expr.h:2398
clang::NestedNameSpecifierLoc
A C++ nested-name-specifier augmented with source location information.
Definition: NestedNameSpecifier.h:243
clang::tooling::RecursiveSymbolVisitor::VisitTypedefTypeLoc
bool VisitTypedefTypeLoc(TypedefTypeLoc TL)
Definition: RecursiveSymbolVisitor.h:108
clang::OffsetOfNode
Helper class for OffsetOfExpr.
Definition: Expr.h:2334
clang::DesignatedInitExpr::designators
llvm::MutableArrayRef< Designator > designators()
Definition: Expr.h:5230
clang::NestedNameSpecifier::getAsNamespace
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:169
llvm::ArrayRef
Definition: LLVM.h:34
clang::tooling::RecursiveSymbolVisitor::TraverseNestedNameSpecifierLoc
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Definition: RecursiveSymbolVisitor.h:114
Lexer.h
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::TypeLoc
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
clang::DesignatedInitExpr::Designator
Represents a single C99 designator.
Definition: Expr.h:5099
clang::TypeLoc::getType
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition: TypeLoc.h:132
clang::OffsetOfNode::Field
@ Field
A field.
Definition: Expr.h:2341
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:58
clang::TypedefTypeLoc::getTypedefNameDecl
TypedefNameDecl * getTypedefNameDecl() const
Definition: TypeLoc.h:673
clang
Definition: CalledOnceCheck.h:17
RecursiveASTVisitor.h
clang::NestedNameSpecifierLoc::getNestedNameSpecifier
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Definition: NestedNameSpecifier.h:274
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3162
clang::Lexer::getLocForEndOfToken
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:783
clang::tooling::RecursiveSymbolVisitor::RecursiveSymbolVisitor
RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
Definition: RecursiveSymbolVisitor.h:33
true
#define true
Definition: stdbool.h:16
clang::Expr
This represents one expression.
Definition: Expr.h:109
SM
#define SM(sm)
Definition: Cuda.cpp:78
clang::tooling::RecursiveSymbolVisitor::VisitNamedDecl
bool VisitNamedDecl(const NamedDecl *D)
Definition: RecursiveSymbolVisitor.h:43
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:430
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1217
clang::NamespaceDecl
Represent a C++ namespace.
Definition: Decl.h:542
clang::tooling::RecursiveSymbolVisitor::VisitOffsetOfExpr
bool VisitOffsetOfExpr(const OffsetOfExpr *S)
Definition: RecursiveSymbolVisitor.h:72
clang::RecursiveASTVisitor< RecursiveSymbolVisitor< T > >::TraverseNestedNameSpecifierLoc
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
Definition: RecursiveASTVisitor.h:708
AST.h
clang::TypedefTypeLoc
Wrapper for source info for typedefs.
Definition: TypeLoc.h:669