summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2019-07-02 16:25:20 -0700
committerAli B <abittin@gmail.com>2019-07-05 19:33:16 +0300
commit9afee4e65dc5f9f5eb371683729ff67b8df81d03 (patch)
tree4cf241d6c9044f91ee8c06e6920174d06f8de0b6 /clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
parent2f19bd722c4c825320d1511c1ed83161b7f95d51 (diff)
Update prebuilt Clang to r353983e.HEADq10.0
clang 9.0.5 (based on r353983e) from build 5696680. Bug: http://b/135931688 Bug: http://b/136008926 Test: N/A Change-Id: I922d17410047d2e2df4625615352c588ee71b203
Diffstat (limited to 'clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h')
-rw-r--r--clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
new file mode 100644
index 00000000..41a448f0
--- /dev/null
+++ b/clang-r353983e/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -0,0 +1,133 @@
+//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// A wrapper class around \c RecursiveASTVisitor that visits each
+/// occurrences of a named symbol.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
+
+#include "clang/AST/AST.h"
+#include "clang/AST/RecursiveASTVisitor.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>>;
+
+public:
+ RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
+ : SM(SM), LangOpts(LangOpts) {}
+
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ return true;
+ }
+
+ // Declaration visitors:
+
+ bool VisitNamedDecl(const NamedDecl *D) {
+ return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
+ }
+
+ bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
+ for (const auto *Initializer : CD->inits()) {
+ // Ignore implicit initializers.
+ if (!Initializer->isWritten())
+ continue;
+ if (const FieldDecl *FD = Initializer->getMember()) {
+ if (!visit(FD, Initializer->getSourceLocation(),
+ Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
+ 0, SM, LangOpts)))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Expression visitors:
+
+ bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+ return visit(Expr->getFoundDecl(), Expr->getLocation());
+ }
+
+ bool VisitMemberExpr(const MemberExpr *Expr) {
+ return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
+ }
+
+ bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
+ for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
+ const OffsetOfNode &Component = S->getComponent(I);
+ if (Component.getKind() == OffsetOfNode::Field) {
+ if (!visit(Component.getField(), Component.getEndLoc()))
+ return false;
+ }
+ // FIXME: Try to resolve dependent field references.
+ }
+ return true;
+ }
+
+ // Other visitors:
+
+ bool VisitTypeLoc(const TypeLoc Loc) {
+ const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
+ const SourceLocation TypeEndLoc =
+ Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
+ if (const auto *TemplateTypeParm =
+ dyn_cast<TemplateTypeParmType>(Loc.getType())) {
+ if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
+ return false;
+ }
+ if (const auto *TemplateSpecType =
+ dyn_cast<TemplateSpecializationType>(Loc.getType())) {
+ if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
+ TypeBeginLoc, TypeEndLoc))
+ return false;
+ }
+ return visit(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
+ }
+
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ // 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);
+ }
+
+private:
+ const SourceManager &SM;
+ const LangOptions &LangOpts;
+
+ bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
+ SourceLocation EndLoc) {
+ return static_cast<T *>(this)->visitSymbolOccurrence(
+ ND, SourceRange(BeginLoc, EndLoc));
+ }
+ bool visit(const NamedDecl *ND, SourceLocation Loc) {
+ return visit(ND, Loc,
+ Loc.getLocWithOffset(ND->getNameAsString().length() - 1));
+ }
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H