diff options
Diffstat (limited to 'include/clang/Tooling')
-rw-r--r-- | include/clang/Tooling/DiagnosticsYaml.h | 15 | ||||
-rw-r--r-- | include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h | 122 | ||||
-rw-r--r-- | include/clang/Tooling/Refactoring/Rename/USRFinder.h | 34 |
3 files changed, 126 insertions, 45 deletions
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h index f32b9fa9c94bf..4d6ff063641b9 100644 --- a/include/clang/Tooling/DiagnosticsYaml.h +++ b/include/clang/Tooling/DiagnosticsYaml.h @@ -56,6 +56,9 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys( Io, D); Io.mapRequired("DiagnosticName", Keys->DiagnosticName); + Io.mapRequired("Message", Keys->Message.Message); + Io.mapRequired("FileOffset", Keys->Message.FileOffset); + Io.mapRequired("FilePath", Keys->Message.FilePath); // FIXME: Export properly all the different fields. @@ -82,17 +85,7 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> { static void mapping(IO &Io, clang::tooling::TranslationUnitDiagnostics &Doc) { Io.mapRequired("MainSourceFile", Doc.MainSourceFile); - - std::vector<clang::tooling::Diagnostic> Diagnostics; - for (auto &Diagnostic : Doc.Diagnostics) { - // FIXME: Export all diagnostics, not just the ones with fixes. - // Update MappingTraits<clang::tooling::Diagnostic>::mapping. - if (Diagnostic.Fix.size() > 0) { - Diagnostics.push_back(Diagnostic); - } - } - Io.mapRequired("Diagnostics", Diagnostics); - Doc.Diagnostics = Diagnostics; + Io.mapRequired("Diagnostics", Doc.Diagnostics); } }; } // end namespace yaml diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h new file mode 100644 index 0000000000000..8b01a61256f6b --- /dev/null +++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -0,0 +1,122 @@ +//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief 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()); + } + + // 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 diff --git a/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/include/clang/Tooling/Refactoring/Rename/USRFinder.h index 28d541af43c08..b74a5d7f70af3 100644 --- a/include/clang/Tooling/Refactoring/Rename/USRFinder.h +++ b/include/clang/Tooling/Refactoring/Rename/USRFinder.h @@ -18,13 +18,9 @@ #include "clang/AST/AST.h" #include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" #include <string> #include <vector> -using namespace llvm; -using namespace clang::ast_matchers; - namespace clang { class ASTContext; @@ -48,36 +44,6 @@ const NamedDecl *getNamedDeclFor(const ASTContext &Context, // Converts a Decl into a USR. std::string getUSRForDecl(const Decl *Decl); -// FIXME: Implement RecursiveASTVisitor<T>::VisitNestedNameSpecifier instead. -class NestedNameSpecifierLocFinder : public MatchFinder::MatchCallback { -public: - explicit NestedNameSpecifierLocFinder(ASTContext &Context) - : Context(Context) {} - - std::vector<NestedNameSpecifierLoc> getNestedNameSpecifierLocations() { - addMatchers(); - Finder.matchAST(Context); - return Locations; - } - -private: - void addMatchers() { - const auto NestedNameSpecifierLocMatcher = - nestedNameSpecifierLoc().bind("nestedNameSpecifierLoc"); - Finder.addMatcher(NestedNameSpecifierLocMatcher, this); - } - - void run(const MatchFinder::MatchResult &Result) override { - const auto *NNS = Result.Nodes.getNodeAs<NestedNameSpecifierLoc>( - "nestedNameSpecifierLoc"); - Locations.push_back(*NNS); - } - - ASTContext &Context; - std::vector<NestedNameSpecifierLoc> Locations; - MatchFinder Finder; -}; - } // end namespace tooling } // end namespace clang |