clang  6.0.0svn
RecursiveSymbolVisitor.h
Go to the documentation of this file.
1 //===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief A wrapper class around \c RecursiveASTVisitor that visits each
12 /// occurrences of a named symbol.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
17 #define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
18 
19 #include "clang/AST/AST.h"
21 #include "clang/Lex/Lexer.h"
22 
23 namespace clang {
24 namespace tooling {
25 
26 /// Traverses the AST and visits the occurrence of each named symbol in the
27 /// given nodes.
28 template <typename T>
30  : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
32 
33 public:
34  RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
35  : SM(SM), LangOpts(LangOpts) {}
36 
38  ArrayRef<SourceRange> NameRanges) {
39  return true;
40  }
41 
42  // Declaration visitors:
43 
44  bool VisitNamedDecl(const NamedDecl *D) {
45  return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
46  }
47 
49  for (const auto *Initializer : CD->inits()) {
50  // Ignore implicit initializers.
51  if (!Initializer->isWritten())
52  continue;
53  if (const FieldDecl *FD = Initializer->getMember()) {
54  if (!visit(FD, Initializer->getSourceLocation(),
55  Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
56  0, SM, LangOpts)))
57  return false;
58  }
59  }
60  return true;
61  }
62 
63  // Expression visitors:
64 
66  return visit(Expr->getFoundDecl(), Expr->getLocation());
67  }
68 
70  return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
71  }
72 
74  for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
75  const OffsetOfNode &Component = S->getComponent(I);
76  if (Component.getKind() == OffsetOfNode::Field) {
77  if (!visit(Component.getField(), Component.getLocEnd()))
78  return false;
79  }
80  // FIXME: Try to resolve dependent field references.
81  }
82  return true;
83  }
84 
85  // Other visitors:
86 
87  bool VisitTypeLoc(const TypeLoc Loc) {
88  const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
89  const SourceLocation TypeEndLoc =
90  Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
91  if (const auto *TemplateTypeParm =
92  dyn_cast<TemplateTypeParmType>(Loc.getType())) {
93  if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
94  return false;
95  }
96  if (const auto *TemplateSpecType =
97  dyn_cast<TemplateSpecializationType>(Loc.getType())) {
98  if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
99  TypeBeginLoc, TypeEndLoc))
100  return false;
101  }
102  return visit(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
103  }
104 
106  // The base visitor will visit NNSL prefixes, so we should only look at
107  // the current NNS.
108  if (NNS) {
110  if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
111  return false;
112  }
114  }
115 
116 private:
117  const SourceManager &SM;
118  const LangOptions &LangOpts;
119 
120  bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
121  SourceLocation EndLoc) {
122  return static_cast<T *>(this)->visitSymbolOccurrence(
123  ND, SourceRange(BeginLoc, EndLoc));
124  }
125  bool visit(const NamedDecl *ND, SourceLocation Loc) {
126  return visit(ND, Loc,
127  Loc.getLocWithOffset(ND->getNameAsString().length() - 1));
128  }
129 };
130 
131 } // end namespace tooling
132 } // end namespace clang
133 
134 #endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
NamedDecl * getFoundDecl()
Get the NamedDecl through which this reference occurred.
Definition: Expr.h:1078
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD)
Traverses the AST and visits the occurrence of each named symbol in the given nodes.
NamedDecl * getDecl() const
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:506
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2397
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
bool VisitDeclRefExpr(const DeclRefExpr *Expr)
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition: Expr.h:1886
A C++ nested-name-specifier augmented with source location information.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2461
RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
Helper class for OffsetOfExpr.
Definition: Expr.h:1822
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1590
SourceLocation getLocation() const
Definition: Expr.h:1049
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:190
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
DeclAccessPair getFoundDecl() const
Retrieves the declaration found by lookup.
Definition: Expr.h:2487
Expr - This represents one expression.
Definition: Expr.h:106
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:773
const FunctionProtoType * T
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:1876
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of &#39;F&#39;...
Definition: Expr.h:2587
const OffsetOfNode & getComponent(unsigned Idx) const
Definition: Expr.h:1975
Encodes a location in the source.
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
Definition: Decl.h:285
bool VisitOffsetOfExpr(const OffsetOfExpr *S)
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
Dataflow Directional Tag Classes.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
bool VisitMemberExpr(const MemberExpr *Expr)
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition: TypeLoc.h:130
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2387
unsigned getNumComponents() const
Definition: Expr.h:1985
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:956
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:245
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
Definition: Expr.h:1926
SourceLocation getLocEnd() const LLVM_READONLY
Definition: Expr.h:1909
bool visitSymbolOccurrence(const NamedDecl *ND, ArrayRef< SourceRange > NameRanges)
This class handles loading and caching of source files into memory.
SourceLocation getLocation() const
Definition: DeclBase.h:416